/*
* $Id$
*
* Copyright 2009 Glencoe Software, Inc. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.services.roi.test;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ome.api.local.LocalUpdate;
import ome.model.IObject;
import ome.model.annotations.FileAnnotation;
import ome.model.annotations.ImageAnnotationLink;
import ome.model.annotations.XmlAnnotation;
import ome.model.core.Image;
import ome.model.core.OriginalFile;
import ome.services.blitz.measurements.MeasurementStore;
import ome.services.blitz.measurements.OmeroMeasurementStore;
import omero.ApiUsageException;
import omero.RType;
import omero.grid.Column;
import omero.grid.FileColumn;
import omero.grid.ImageColumn;
import omero.grid.LongColumn;
import omero.grid.RoiColumn;
import omero.grid.StringColumn;
import omero.grid.TablePrx;
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
import org.jmock.core.Constraint;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
*
*/
@Test(groups = { "rois", "measurements" })
public class MeasurementStoreUnitTest extends MockObjectTestCase {
Image image;
Mock tMock, uMock;
LocalUpdate update;
TablePrx table;
OmeroMeasurementStore mea;
@BeforeMethod
protected void beforeMethod() throws Exception {
tMock = mock(TablePrx.class);
table = (TablePrx) tMock.proxy();
uMock = mock(LocalUpdate.class);
update = (LocalUpdate) uMock.proxy();
image = new Image();
}
public void testBasicUsage() throws Exception {
Column[] cols = new Column[] { new RoiColumn(), new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.initialize(new String[] { "roi_id", "value_1" },
new String[] { "Roi" }, new Class[] { Long.class }, null);
mea.addRows(new Object[][] {//
new Object[] { "Roi:1", 1L },//
new Object[] { "Roi:2", 0L },//
new Object[] { "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
public void testMultipleFileUsage() throws Exception {
Column[] cols = new Column[] { new FileColumn(), new RoiColumn(),
new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.addObject("Image:1", image);
mea.initialize(new String[] { "source", "roi_id", "value_1" },
new String[] { "File", "Roi" }, new Class[] { Long.class },
null);
mea.addRows(new Object[][] {//
new Object[] { "File:1", "Roi:1", 1L },//
new Object[] { "File:1", "Roi:2", 0L },//
new Object[] { "File:1", "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
public void testImageColumnWithNoImage() throws Exception {
fail();
Column[] cols = new Column[] { new FileColumn(), new RoiColumn(),
new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.addObject("Image:1", image);
mea.initialize(new String[] { "source", "roi_id", "value_1" },
new String[] { "File", "Roi" }, new Class[] { Long.class },
null);
mea.addRows(new Object[][] {//
new Object[] { "File:1", "Roi:1", 1L },//
new Object[] { "File:1", "Roi:2", 0L },//
new Object[] { "File:1", "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
public void testImageColumnWithAnImage() throws Exception {
fail();
Column[] cols = new Column[] { new FileColumn(), new RoiColumn(),
new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.addObject("Image:1", image);
mea.initialize(new String[] { "source", "roi_id", "value_1" },
new String[] { "File", "Roi" }, new Class[] { Long.class },
null);
mea.addRows(new Object[][] {//
new Object[] { "File:1", "Roi:1", 1L },//
new Object[] { "File:1", "Roi:2", 0L },//
new Object[] { "File:1", "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
@Test(expectedExceptions = ApiUsageException.class)
public void testSaveMustFollowAddRowsFails() throws Exception {
fail();
}
public void testSaveMustFollowAddRowsPasses() throws Exception {
fail();
}
private Map<XmlAnnotation, List<ImageAnnotationLink>> imagemodel() {
Image i1 = new Image();
Image i2 = new Image();
OriginalFile of1a = new OriginalFile();
OriginalFile of1b = new OriginalFile();
OriginalFile of2a = new OriginalFile();
OriginalFile of2b = new OriginalFile();
Map<XmlAnnotation, List<ImageAnnotationLink>> rv = new HashMap<XmlAnnotation, List<ImageAnnotationLink>>();
List<ImageAnnotationLink> linksA = new ArrayList<ImageAnnotationLink>();
List<ImageAnnotationLink> linksB = new ArrayList<ImageAnnotationLink>();
FileAnnotation fa1a = new FileAnnotation();
fa1a.setFile(of1a);
linksA.add(i1.linkAnnotation(fa1a));
FileAnnotation fa1b = new FileAnnotation();
fa1b.setFile(of1b);
linksB.add(i1.linkAnnotation(fa1b));
FileAnnotation fa2a = new FileAnnotation();
fa2a.setFile(of2a);
linksA.add(i2.linkAnnotation(fa2a));
FileAnnotation fa2b = new FileAnnotation();
fa2b.setFile(of2b);
linksB.add(i2.linkAnnotation(fa2b));
XmlAnnotation measA = new XmlAnnotation();
fa1a.linkAnnotation(measA);
fa2a.linkAnnotation(measA);
rv.put(measA, linksA);
XmlAnnotation measB = new XmlAnnotation();
fa1b.linkAnnotation(measB);
fa2b.linkAnnotation(measB);
rv.put(measB, linksB);
return rv;
}
/**
* During import, the intent is that after all companion files have been
* properly uploaded and attached to image/well/plate/etc that a query will
* be done to find them, most likely based on the file format, and that
*/
public void testRealUsage() throws Exception {
table.initialize(new Column[] {
new ImageColumn("image_id", null, null),
new RoiColumn("roi_id", null, null),
new LongColumn("colA", null, null),
new LongColumn("colB", null, null) });
Map<XmlAnnotation, List<ImageAnnotationLink>> linksPerMeasurement = imagemodel();
for (XmlAnnotation measurement : linksPerMeasurement.keySet()) {
List<ImageAnnotationLink> links = linksPerMeasurement
.get(measurement);
for (ImageAnnotationLink link : links) {
Image image = link.parent();
OriginalFile file = ((FileAnnotation) link.child()).getFile();
OmeroMeasurementStore store = new MeasurementStore(update,
table);
// HOW TO JOIN ALL THE TABLES TOGETHER
}
}
}
public void testNoRoisNoneAdded() throws Exception {
Column[] cols = new Column[] { new StringColumn(), new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.initialize(new String[] { "roi_lsid", "value_1" }, new String[] {},
new Class[] { String.class, Long.class }, null);
mea.addRows(new Object[][] {//
new Object[] { "Roi:1", 1L },//
new Object[] { "Roi:2", 0L },//
new Object[] { "Roi:3", 1L } //
});
mea.save();
}
public void testNoRoisButAdded() throws Exception {
Column[] cols = new Column[] { new StringColumn(), new LongColumn() };
initialize(cols);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.initialize(new String[] { "roi_lsid", "value_1" }, new String[] {},
new Class[] { String.class, Long.class }, null);
mea.addRows(new Object[][] {//
new Object[] { "Roi:1", 1L },//
new Object[] { "Roi:2", 0L },//
new Object[] { "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
public void testMetadata() throws Exception {
Map<String, Object> metadata = new HashMap<String, Object>();
metadata.put("omero.RString", "this is a string");
metadata.put("omero.RLong", Long.valueOf(1));
metadata.put("omero.RInt", Integer.valueOf(1));
metadata.put("omero.RBool", Boolean.TRUE);
metadata.put("omero.RDouble", Double.valueOf(0));
metadata.put("omero.RFloat", Float.valueOf(0));
Column[] cols = new Column[] { new StringColumn(), new LongColumn() };
initialize(cols);
metadataCK(metadata);
save(new long[] { 1L, 2L, 3L });
data(cols, 3);
mea = new MeasurementStore(update, table);
mea.initialize(new String[] { "roi_lsid", "value_1" }, new String[] {},
new Class[] { String.class, Long.class }, null);
mea.addRows(new Object[][] {//
new Object[] { "Roi:1", 1L },//
new Object[] { "Roi:2", 0L },//
new Object[] { "Roi:3", 1L } //
});
mea.addCircle("Roi:1", 5, 5, 1);
mea.addCircle("Roi:2", 5, 5, 2);
mea.addCircle("Roi:3", 5, 5, 3);
mea.save();
}
// Helpers
// =========================================================================
boolean colmatch(Column[] testcols, Column[] foundcols, Integer size) {
boolean failed = false;
failed |= (testcols.length != foundcols.length);
for (int i = 0; i < testcols.length; i++) {
failed |= (!(testcols[i].getClass().equals(foundcols[i].getClass())));
}
try {
for (int i = 0; i < foundcols.length; i++) {
Column col = foundcols[i];
Field f = col.getClass().getField("values");
Object o = f.get(col);
if (size == null) {
failed |= (o != null);
} else {
failed |= (size.intValue() != Array.getLength(o));
}
}
} catch (Exception e) {
failed = true;
}
return !failed;
}
void initialize(final Column[] testcols) {
tMock.expects(once()).method("initialize").with(new Constraint() {
public boolean eval(Object arg0) {
Column[] foundcols = (Column[]) arg0;
return colmatch(testcols, foundcols, null);
}
public StringBuffer describeTo(StringBuffer arg0) {
arg0.append("proper columns");
return arg0;
}
});
}
void metadataCK(Map<String, Object> metadata) {
tMock.expects(once()).method("setAllMetadata").with(new Constraint() {
public boolean eval(Object arg0) {
Map<String, RType> dict = (Map<String, RType>) arg0;
boolean maps = true;
for (Map.Entry<String, RType> entry : dict.entrySet()) {
String k = entry.getKey();
try {
maps &= Class.forName(k).isAssignableFrom(
entry.getValue().getClass());
} catch (ClassNotFoundException e) {
maps = false;
}
}
return maps;
}
public StringBuffer describeTo(StringBuffer arg0) {
arg0.append("properly parsed metadata");
return arg0;
}
});
}
void save(long[] arr) {
uMock.expects(once()).method("saveAndReturnIds").with(new Constraint() {
public boolean eval(Object arg0) {
IObject[] rois = (IObject[]) arg0;
return rois.length == 3;
}
public StringBuffer describeTo(StringBuffer arg0) {
arg0.append("saves all");
return arg0;
}
}).will(returnValue(arr));
}
void data(final Column[] testcols, final int size) {
tMock.expects(once()).method("addData").with(new Constraint() {
public boolean eval(Object arg0) {
Column[] foundcols = (Column[]) arg0;
return colmatch(testcols, foundcols, size);
}
public StringBuffer describeTo(StringBuffer arg0) {
arg0.append("proper data");
return arg0;
}
});
}
}