diff --git a/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java b/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java index 0ee29e5885408a5b00168725c278b9928aead1a2..691d18834b4164dc97b4b53d1417c606729ec47c 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java +++ b/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java @@ -91,12 +91,21 @@ public class DataStructureV1_0 extends AbstractDataStructure /** * Returns the directory containing the original data. */ - public IDirectory getOriginalData() + public final IDirectory getOriginalData() { assertOpenOrCreated(); return Utilities.getOrCreateSubDirectory(getDataDirectory(), DIR_ORIGINAL); } + /** + * Returns the directory containing the standardized data. + */ + public final IDirectory getStandardData() + { + assertOpenOrCreated(); + return Utilities.getOrCreateSubDirectory(getDataDirectory(), DIR_STANDARD); + } + /** * Returns the formated data. This method can be called only after method {@link #setFormat(Format)} has been * invoked. If the format is not known {@link UnknownFormat1_0} will be assumed. @@ -110,8 +119,8 @@ public class DataStructureV1_0 extends AbstractDataStructure { throw new DataStructureException("Couldn't create formated data because of unspecified format."); } - IDirectory metaData = getMetaDataDirectory(); - return FormatedDataFactory.createFormatedData(metaData, format, UnknownFormat1_0.UNKNOWN_1_0, formatParameters); + return FormatedDataFactory.createFormatedData(getDataDirectory(), format, UnknownFormat1_0.UNKNOWN_1_0, + formatParameters); } /** diff --git a/bds/source/java/ch/systemsx/cisd/bds/Utilities.java b/bds/source/java/ch/systemsx/cisd/bds/Utilities.java index 74b298c397fea3bf1b0257f7c9252a7abf2a60f4..1dd9765b4d744a2c58752f52cde3c5837cdb5839 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/Utilities.java +++ b/bds/source/java/ch/systemsx/cisd/bds/Utilities.java @@ -59,7 +59,8 @@ public class Utilities INode node = directory.tryToGetNode(name); if (node == null) { - throw new DataStructureException("No directory named '" + name + "' found in " + directory); + throw new DataStructureException(String.format("No directory named '%s' found in directory '%s'.", name, + directory)); } if (node instanceof IDirectory == false) { diff --git a/bds/source/java/ch/systemsx/cisd/bds/hcs/IHCSFormattedData.java b/bds/source/java/ch/systemsx/cisd/bds/hcs/IHCSFormattedData.java index b8be51ad8238b848e8fbbfc5c20251dca749f231..8549e0f1f7eaf980e0af46e58ecc2949c2efd6c8 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/hcs/IHCSFormattedData.java +++ b/bds/source/java/ch/systemsx/cisd/bds/hcs/IHCSFormattedData.java @@ -27,7 +27,7 @@ import ch.systemsx.cisd.bds.storage.INode; * * @author Christian Ribeaud */ -public interface IHCSFormattedData +public interface IHCSFormattedData extends IFormattedData { /** diff --git a/bds/source/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedData.java b/bds/source/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedData.java index c155ae38f06b5e4a3026083f544b4149bb0bdc08..32c8fb762dcc64b0c85b413a24e8ea6d54cca9e0 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedData.java +++ b/bds/source/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedData.java @@ -36,16 +36,14 @@ import ch.systemsx.cisd.bds.storage.INode; * * @author Christian Ribeaud */ -// TODO 2007-11-15, Christian Ribeaud: Make a test of this class. Maybe we can extract some of -// 'HCSDataStructureV1_0Test' class. public final class ImageHCSFormattedData extends AbstractFormattedData implements IHCSFormattedData { /** The <i>column</i> (or <i>x</i>) coordinate. */ - private static final String COLUMN = "column"; + public static final String COLUMN = "column"; /** The <i>row</i> (or <i>y</i>) coordinate. */ - private static final String ROW = "row"; + public static final String ROW = "row"; /** * The mandatory format parameters that must be defined so that this implementation is able to work properly. @@ -103,16 +101,17 @@ public final class ImageHCSFormattedData extends AbstractFormattedData implement } } - private final static String createWellFileName(final Location wellLocation) + /** From given <var>wellLocation</var> creates the leaf file name that is found in <code>data/standard</code>. */ + final static String createWellFileName(final Location wellLocation) { - return ROW + wellLocation.y + COLUMN + wellLocation.x + ".tiff"; + assert wellLocation != null : "Well location can not be null."; + return ROW + wellLocation.y + "_" + COLUMN + wellLocation.x + ".tiff"; } // // IHCSFormattedData // - // TODO 2007-11-15, Christian Ribeaud: Should we consider to use 'standard_original_mapping' here? public final INode getNodeAt(final int channel, final Location plateLocation, final Location wellLocation) throws DataStructureException { diff --git a/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/AbstractNode.java b/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/AbstractNode.java index c667619d9d7e9cd8715e6c2cf6c46a043b5fcf01..f80754a8a5aa839b5bce4057143ae96ddf849127 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/AbstractNode.java +++ b/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/AbstractNode.java @@ -24,6 +24,8 @@ import ch.systemsx.cisd.bds.storage.StorageException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; /** + * An abstract implementation of <code>INode</code>. + * * @author Franz-Josef Elmer */ abstract class AbstractNode implements INode @@ -39,8 +41,8 @@ abstract class AbstractNode implements INode final boolean successful = source.renameTo(destination); if (successful == false) { - throw EnvironmentFailureException.fromTemplate("Couldn't not move file '%s' to directory '%s'.", - source.getAbsolutePath(), directory.getAbsolutePath()); + throw EnvironmentFailureException.fromTemplate("Couldn't not move file '%s' to directory '%s'.", source + .getAbsolutePath(), directory.getAbsolutePath()); } } } @@ -48,36 +50,49 @@ abstract class AbstractNode implements INode protected final File nodeFile; AbstractNode(File file) + { + checkFile(file); + this.nodeFile = file; + } + + static void checkFile(final File file) { if (file == null) { - throw new StorageException("Unspecified file"); + throw new StorageException("Unspecified file."); } if (file.exists() == false) { - throw new StorageException("Non existing file " + file); + throw new StorageException(String.format("Non existing file '%s'.", file.getAbsolutePath())); } - this.nodeFile = file; } - public String getName() + // + // INode + // + + public final String getName() { return nodeFile.getName(); } - public IDirectory tryToGetParent() + public final IDirectory tryToGetParent() { File dir = nodeFile.getParentFile(); return dir == null ? null : new Directory(dir); } - public void moveTo(File directory) + public final void moveTo(final File directory) { moveFileToDirectory(nodeFile, directory); } + // + // Object + // + @Override - public String toString() + public final String toString() { return nodeFile.getAbsolutePath(); } diff --git a/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/Directory.java b/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/Directory.java index 963379eea42293a396259a6f343754b45004c649..e71d1f7f7897a2381baa6a3e2348e104f177d9c8 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/Directory.java +++ b/bds/source/java/ch/systemsx/cisd/bds/storage/filesystem/Directory.java @@ -34,7 +34,7 @@ import ch.systemsx.cisd.common.utilities.FileUtilities; * * @author Franz-Josef Elmer */ -class Directory extends AbstractNode implements IDirectory +final class Directory extends AbstractNode implements IDirectory { Directory(java.io.File directory) @@ -42,7 +42,7 @@ class Directory extends AbstractNode implements IDirectory super(directory); if (directory.isDirectory() == false) { - throw new StorageException("Not a directory: " + directory.getAbsolutePath()); + throw new StorageException(String.format("Not a directory '%s'.", directory.getAbsolutePath())); } } @@ -50,8 +50,9 @@ class Directory extends AbstractNode implements IDirectory // IDirectory // - public INode tryToGetNode(String name) + public final INode tryToGetNode(final String name) { + assert name != null : "Given name can not be null."; final java.io.File[] files = FileUtilities.listFiles(nodeFile); for (java.io.File file : files) { @@ -63,8 +64,9 @@ class Directory extends AbstractNode implements IDirectory return null; } - public IDirectory makeDirectory(String name) + public final IDirectory makeDirectory(final String name) { + assert name != null : "Given name can not be null."; java.io.File dir = new java.io.File(nodeFile, name); if (dir.exists()) { @@ -83,15 +85,18 @@ class Directory extends AbstractNode implements IDirectory return new Directory(dir); } - public IFile addKeyValuePair(String key, String value) + public final IFile addKeyValuePair(final String key, final String value) { + assert key != null : "Given key can not be null."; + assert value != null : "Given value can not be null."; java.io.File file = new java.io.File(nodeFile, key); FileUtilities.writeToFile(file, value); return new File(file); } - public INode addFile(final java.io.File file, final boolean move) + public final INode addFile(final java.io.File file, final boolean move) { + checkFile(file); final java.io.File newFile = new java.io.File(nodeFile, file.getName()); if (move) { @@ -116,13 +121,13 @@ class Directory extends AbstractNode implements IDirectory return NodeFactory.createNode(newFile); } - public ILink addLink(String name, INode node) + public final ILink addLink(final String name, final INode node) { // TODO Auto-generated method stub return null; } - public Iterator<INode> iterator() + public final Iterator<INode> iterator() { return new Iterator<INode>() { diff --git a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java index c98844fd8d21043d367f581d16c0ffb398a64888..d4237b1ee297e7a7d7ac7a82b2bdd9ebde734b5a 100644 --- a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java +++ b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java @@ -32,6 +32,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import ch.systemsx.cisd.bds.storage.IDirectory; +import ch.systemsx.cisd.bds.storage.IStorage; import ch.systemsx.cisd.bds.storage.StorageException; import ch.systemsx.cisd.bds.storage.filesystem.FileStorage; import ch.systemsx.cisd.common.utilities.AbstractFileSystemTestCase; @@ -530,7 +531,12 @@ public final class DataStructureV1_0Test extends AbstractFileSystemTestCase assertEquals(UnknownFormat1_0.UNKNOWN_1_0, dataStructure.getFormattedData().getFormat()); } - private void createExampleDataStructure() + private final void createExampleDataStructure() + { + createExampleDataStructure(storage); + } + + public final static void createExampleDataStructure(final IStorage storage) { storage.mount(); IDirectory root = storage.getRoot(); diff --git a/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/HCSDataStructureV1_0Test.java b/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/HCSDataStructureV1_0Test.java index cd1f917e94a704e574935ae04b5ed31378016488..a4b19b867d689fbb8578303aabf121f0ff62e263 100644 --- a/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/HCSDataStructureV1_0Test.java +++ b/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/HCSDataStructureV1_0Test.java @@ -21,33 +21,30 @@ import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; +import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Date; import java.util.List; +import org.apache.commons.io.FileUtils; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import ch.systemsx.cisd.bds.DataStructureException; import ch.systemsx.cisd.bds.DataStructureLoader; import ch.systemsx.cisd.bds.DataStructureV1_0; -import ch.systemsx.cisd.bds.ExperimentIdentifier; -import ch.systemsx.cisd.bds.ExperimentRegistrator; -import ch.systemsx.cisd.bds.ExperimentRegistratorDate; +import ch.systemsx.cisd.bds.DataStructureV1_0Test; import ch.systemsx.cisd.bds.Format; import ch.systemsx.cisd.bds.FormatParameter; import ch.systemsx.cisd.bds.IDataStructure; import ch.systemsx.cisd.bds.IFormattedData; -import ch.systemsx.cisd.bds.MeasurementEntity; -import ch.systemsx.cisd.bds.ProcessingType; -import ch.systemsx.cisd.bds.Version; import ch.systemsx.cisd.bds.storage.IDirectory; +import ch.systemsx.cisd.bds.storage.INode; import ch.systemsx.cisd.bds.storage.filesystem.FileStorage; import ch.systemsx.cisd.common.utilities.AbstractFileSystemTestCase; /** - * Test cases for corresponding {@link DataStructureV1_0} class. + * Test cases for corresponding {@link DataStructureV1_0} class specific to <i>HCS (High-Content Screening) with Images</i>. * * @author Christian Ribeaud */ @@ -57,6 +54,11 @@ public final class HCSDataStructureV1_0Test extends AbstractFileSystemTestCase private DataStructureV1_0 dataStructure; + public HCSDataStructureV1_0Test() + { + super(false); + } + private final static ChannelList createChannelList() { final List<Channel> list = new ArrayList<Channel>(); @@ -65,24 +67,6 @@ public final class HCSDataStructureV1_0Test extends AbstractFileSystemTestCase return new ChannelList(list); } - private final void createExampleDataStructure() - { - storage.mount(); - IDirectory root = storage.getRoot(); - new Version(1, 0).saveTo(root); - final IDirectory data = root.makeDirectory(DataStructureV1_0.DIR_DATA); - final IDirectory originalDataDir = data.makeDirectory(DataStructureV1_0.DIR_ORIGINAL); - originalDataDir.addKeyValuePair("hello", "world"); - final IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); - new ExperimentIdentifier("g", "p", "e").saveTo(metaData); - new ExperimentRegistratorDate(new Date(0)).saveTo(metaData); - new ExperimentRegistrator("john", "doe", "j@doe").saveTo(metaData); - new MeasurementEntity("a", "b").saveTo(metaData); - metaData.addKeyValuePair(DataStructureV1_0.MAPPING_FILE, ""); - ProcessingType.COMPUTED_DATA.saveTo(metaData); - storage.unmount(); - } - private final void setFormatAndFormatParameters() { dataStructure.setFormat(ImageHCSFormat1_0.IMAGE_HCS_1_0); @@ -120,9 +104,53 @@ public final class HCSDataStructureV1_0Test extends AbstractFileSystemTestCase // Nothing to do here } setFormatAndFormatParameters(); - final IFormattedData formatedData = dataStructure.getFormattedData(); - assertTrue(formatedData instanceof ImageHCSFormattedData); - assertEquals(format, formatedData.getFormat()); + final IFormattedData formattedData = dataStructure.getFormattedData(); + assertTrue(formattedData instanceof IHCSFormattedData); + assertEquals(format, formattedData.getFormat()); + } + + @Test + public final void testGetNodeAt() throws IOException + { + dataStructure.create(); + DataStructureV1_0Test.createExampleDataStructure(storage); + setFormatAndFormatParameters(); + final IDirectory standardData = dataStructure.getStandardData(); + final IDirectory channelDir = standardData.makeDirectory(Channel.CHANNEL + "1"); + final IDirectory plateRowDir = channelDir.makeDirectory(ImageHCSFormattedData.ROW + "1"); + final IDirectory plateColumnDir = plateRowDir.makeDirectory(ImageHCSFormattedData.COLUMN + "1"); + final String wellFileName = ImageHCSFormattedData.createWellFileName(new Location(1, 1)); + final File wellFile = new File(workingDirectory, wellFileName); + FileUtils.writeStringToFile(wellFile, "This is an image..."); + plateColumnDir.addFile(wellFile, true); + final IHCSFormattedData formattedData = (IHCSFormattedData) dataStructure.getFormattedData(); + try + { + formattedData.getNodeAt(3, new Location(1, 1), new Location(1, 1)); + fail("3 > 2"); + } catch (IndexOutOfBoundsException ex) + { + // Nothing to do here. + } + try + { + formattedData.getNodeAt(2, new Location(1, 1), new Location(1, 1)); + fail("No directory named 'channel2' found."); + } catch (DataStructureException ex) + { + assertTrue(ex.getMessage().indexOf("'channel2'") > -1); + } + try + { + formattedData.getNodeAt(1, new Location(1, 3), new Location(1, 1)); + fail("Given geometry '2x3' does not contain location '[x=1,y=3]'."); + } catch (IllegalArgumentException ex) + { + assertTrue(ex.getMessage().indexOf("does not contain location") > -1); + } + final INode node = formattedData.getNodeAt(1, new Location(1, 1), new Location(1, 1)); + assertEquals("row1_column1.tiff", node.getName()); + dataStructure.close(); } @Test @@ -130,7 +158,7 @@ public final class HCSDataStructureV1_0Test extends AbstractFileSystemTestCase { // Creating... dataStructure.create(); - createExampleDataStructure(); + DataStructureV1_0Test.createExampleDataStructure(storage); setFormatAndFormatParameters(); dataStructure.close(); // And loading... diff --git a/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedDataTest.java b/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedDataTest.java index f005cf4394c4cdfbc9e087e6e5f263a678e5fb99..5935ac4ad37370d6c3d2e8092a2c18bd309c377c 100644 --- a/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedDataTest.java +++ b/bds/sourceTest/java/ch/systemsx/cisd/bds/hcs/ImageHCSFormattedDataTest.java @@ -16,6 +16,9 @@ package ch.systemsx.cisd.bds.hcs; +import org.testng.annotations.Test; +import static org.testng.AssertJUnit.*; + /** * Test cases for corresponding {@link ImageHCSFormattedData} class. * @@ -24,4 +27,19 @@ package ch.systemsx.cisd.bds.hcs; public class ImageHCSFormattedDataTest { -} + @Test + public final void testCreateWellFileName() + { + try + { + ImageHCSFormattedData.createWellFileName(null); + fail("Location can not be null."); + } catch (AssertionError ex) + { + // Nothing to do here. + } + final Location location = new Location(1, 2); + final String expected = "row2_column1.tiff"; + assertEquals(expected, ImageHCSFormattedData.createWellFileName(location)); + } +} \ No newline at end of file