Newer
Older
brinn
committed
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
brinn
committed
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
brinn
committed
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
brinn
committed
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
brinn
committed
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
brinn
committed
import ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet;
import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss;
import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO;
import ch.systemsx.cisd.openbis.generic.client.cli.Login;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.AndDataSetFilter;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.PropertiesBasedDataSetFilter;
import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.TypeBasedDataSetFilter;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.IScreeningOpenbisServiceFacade;
import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.IScreeningOpenbisServiceFacadeFactory;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacade.IImageOutputStreamProvider;
import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacadeFactory;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVector;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorWithDescription;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Geometry;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureCodesProvider;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageDatasetMetadata;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageDatasetReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.MaterialIdentifier;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.MaterialTypeIdentifier;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateImageReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellMaterialMapping;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellIdentifier;
brinn
committed
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellPosition;
/**
* Simple Matlab interface for openBIS for Screening. It is meant to be used in one Matlab session
* at a time, i.e. it is <i>not</i> multi-threading safe.
brinn
committed
* <p>
* While written in Java, the API is idiomatic for Matlab, i.e. values are returned as
* multi-dimensional arrays. For the <code>get...</code> and <code>load...</code> methods the first
* index will contain the actual data, while the second index will contain per-row annotations. For
* <code>getFeatureMatrix</code>, the third index contains per-column annotations. This allows
* simple access with Matlab's slicing operator, see doc of e.g.
* {@link #getFeatureMatrix(String, String, String[])}.
brinn
committed
* <p>
* A typical Matlab session looks like:
*
* <pre>
* % Add the API jar file to the classpath
* javaaddpath('/home/brinn/matlab/openbis_screening_api-batteries_included.jar')
* % Login to server
* OpenBISScreeningML.login('user', 'secret', 'https://www.infectome.org')
brinn
committed
*
* % ...perform calls on the server...
*
* % Logout to close the session on the server
* OpenBISScreeningML.logout()
brinn
committed
* </pre>
*
* <i>Note: using this login your password will end up in the Matlab command history. An alternative
* that avoids this is to call the {@link ch.systemsx.cisd.openbis.generic.client.cli.Login} class.
* Logging in on the console will grant this class access to the openBIS server.</i>
* <p>
* To learn the API one needs to understand three basic notions: code, augmented code and perm id.
* Space, project, experiment, plate and well have their own <b>code</b>, which is unique only in
* the context of the parent.<br>
* That's why one needs <b>augmented code</b> to point e.g. to one experiment, because two different
* projects can have experiments with the same code.<br>
* Such an augmented code for experiment has a form of "/space-code/project-code/experiment-code".<br>
* For plate it has a form of "/space-code/plate-code" (note that plate code is unique on the space
* level). <br>
* The drawback of an augmented code is that it's not persistent. If someone e.g. moves the
* experiment from one space to the other augmented code of the experiment becomes invalid. That is
* why experiments, plates and datasets have <b>perm id</b> (permament identifier) which never
* change and allow to refer to them with one "magic" identifier, e.g. 20110516124520378-737166.
* </p>
brinn
committed
* @author Bernd Rinn
*/
public class OpenBISScreeningML
brinn
committed
{
private static interface ITileNumberIterable extends Iterable<Integer>
{
public void setMaximumNumberOfTiles(int numberOfTiles);
public int getMaximumNumberOfTiles();
}
private static final class ImageReferenceAndFile
{
private final PlateImageReference imageReference;
private final File imageFile;
private BufferedOutputStream outputStream;
ImageReferenceAndFile(PlateImageReference imageReference, File imageFile)
{
this.imageReference = imageReference;
this.imageFile = imageFile;
}
public PlateImageReference getImageReference()
{
return imageReference;
}
public File getImageFile()
{
return imageFile;
}
public OutputStream open() throws IOException
{
if (outputStream == null)
{
outputStream = new BufferedOutputStream(new FileOutputStream(imageFile));
}
return outputStream;
}
public void close() throws IOException
{
if (outputStream != null)
{
outputStream.close();
}
outputStream = null;
}
}
private static final class IndexSet<T extends Comparable<T>>
{
private final Map<T, Integer> indexMap = new HashMap<T, Integer>();
private final Set<T> set = new TreeSet<T>();
public void add(T item)
{
set.add(item);
}
public int getIndex(T item)
{
if (set.size() != indexMap.size())
{
List<T> items = new ArrayList<T>(set);
for (int i = 0; i < items.size(); i++)
{
indexMap.put(items.get(i), i);
}
}
Integer index = indexMap.get(item);
if (index == null)
{
throw new IllegalArgumentException("Unknown item: " + item);
}
return index;
}
public int size()
{
return set.size();
}
}
static final String DATASETS_FOLDER = "openbis_datasets";
private static File temporarySessionDir;
private static Map<PlateImageReference, File> loadedImages;
static IScreeningOpenbisServiceFacadeFactory facadeFactory =
ScreeningOpenbisServiceFacadeFactory.INSTANCE;
brinn
committed
private static IScreeningOpenbisServiceFacade openbis = null;
private static List<ExperimentIdentifier> experiments = null;
private static List<Plate> plates = null;
private static Map<String, List<Plate>> experimentToPlateMap =
new HashMap<String, List<Plate>>();
private static Map<String, ExperimentIdentifier> experimentCodeToExperimentMap =
new HashMap<String, ExperimentIdentifier>();
private static Map<String, Plate> plateCodeToPlateMap = new HashMap<String, Plate>();
private OpenBISScreeningML()
brinn
committed
{
// Not to be constructed.
}
brinn
committed
//
// Versioning
//
/**
* The version of the API.
*/
public static final String VERSION = "1";
brinn
committed
/**
* The required version ("major.minor") of the screening API on the openBIS application server.
brinn
committed
*/
public static final String REQUIRES_OPENBIS_AS_API = "1.7";
brinn
committed
/**
* The required version ("major.minor") of the screening API on the openBIS datastore server.
brinn
committed
*/
public static final String REQUIRES_OPENBIS_DSS_API = "1.1";
private static File dataSetsDir;
/**
* Root temporary directory for data sets and images. By default <code>java.io.tmpdir</code> is
* used.
*/
static File tempDir = new File(System.getProperty("java.io.tmpdir"));
static final String TEMP_DIR_PREFIX = "openbis_";
static final String TEMP_DIR_POSTFIX = "_temp_dir";
brinn
committed
//
// Authentication methods
//
/**
* Login to the openBIS server given as <var>url</var>.
* <p>
* Matlab example:
*
* <pre>
* OpenBISScreeningML.login('user', 'secret', 'https://www.infectome.org')
brinn
committed
* </pre>
*
* @param user The user id on the server
* @param password The password on the server
* @param url The URL, e.g. <code>https://www.infectome.org</var>
*/
public static void login(String user, String password, String url)
{
IScreeningOpenbisServiceFacade facade = facadeFactory.tryToCreate(user, password, url);
if (facade == null)
brinn
committed
{
throw new RuntimeException("Login failed.");
}
init(facade);
}
private static void init(IScreeningOpenbisServiceFacade openBisFacade)
openbis = openBisFacade;
dataSetsDir = new File(tempDir, DATASETS_FOLDER);
if (dataSetsDir.isDirectory() == false && dataSetsDir.mkdirs() == false)
{
throw new RuntimeException("Couldn't create a data set directory.");
}
temporarySessionDir =
new File(tempDir, TEMP_DIR_PREFIX + System.currentTimeMillis() / 1000
+ TEMP_DIR_POSTFIX);
if (temporarySessionDir.mkdirs() == false)
{
throw new RuntimeException("Couldn't create a temporary directory.");
}
temporarySessionDir.deleteOnExit();
loadedImages = new HashMap<PlateImageReference, File>();
brinn
committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
experiments = openbis.listExperiments();
experimentCodeToExperimentMap.clear();
for (ExperimentIdentifier e : experiments)
{
experimentCodeToExperimentMap.put(e.getAugmentedCode(), e);
}
plates = openbis.listPlates();
plateCodeToPlateMap.clear();
experimentToPlateMap.clear();
for (Plate p : plates)
{
final String plateCode = p.getAugmentedCode();
plateCodeToPlateMap.put(plateCode, p);
final String experimentCode = p.getExperimentIdentifier().getAugmentedCode();
List<Plate> experimentPlates = experimentToPlateMap.get(experimentCode);
if (experimentPlates == null)
{
experimentPlates = new ArrayList<Plate>();
experimentToPlateMap.put(experimentCode, experimentPlates);
}
experimentPlates.add(p);
}
}
/**
* Logs out and closes the session on the server.
* <p>
* Matlab example:
*
* <pre>
* OpenBISScreeningML.logout()
brinn
committed
* </pre>
*/
public static void logout()
{
if (openbis == null)
{
return;
}
openbis.logout();
if (Login.OPENBIS_TOKEN_FILE.exists())
{
Login.OPENBIS_TOKEN_FILE.delete();
}
delete(temporarySessionDir);
brinn
committed
openbis = null;
}
private static void delete(File file)
{
if (file.isDirectory())
{
File[] files = file.listFiles();
for (File child : files)
{
delete(child);
}
}
file.delete();
}
brinn
committed
//
// Information methods
//
/**
* Lists all experiment.
* <p>
* Matlab example:
*
* <pre>
* % Get the experiments
* exps = OpenBISScreeningML.listExperiments();
brinn
committed
* % How many experiments do we have?
* length(exps)
* % Get all information about experiment 3
* exp3 = exps(3,:)
* % Get the perm ids for all experiments
* permids = exps(:,2)
* </pre>
*
* @return Each row contains information about one experiment:
brinn
committed
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
* <p>
* <code>{ experiment augmented code, experiment perm id, experiment space code,
* experiment project code, experiment code }</code>
*/
public static Object[][] listExperiments()
{
checkLoggedIn();
final Object[][] result = new Object[experiments.size()][5];
for (int i = 0; i < experiments.size(); ++i)
{
final Object[] annotations =
new Object[]
{ experiments.get(i).getAugmentedCode(), experiments.get(i).getPermId(),
experiments.get(i).getSpaceCode(),
experiments.get(i).getProjectCode(),
experiments.get(i).getExperimentCode() };
System.arraycopy(annotations, 0, result[i], 0, annotations.length);
}
return result;
}
/**
* Lists all plates.
* <p>
* Matlab example:
*
* <pre>
* % Get the plates
* plates = OpenBISScreeningML.listPlates();
brinn
committed
* % How many plates do we have?
* length(plates)
* % Get all information about plate 2
* plate2 = plates(2,:)
* % Get the simple plate codes for all plates
* codes = plates(:,4)
* </pre>
*
* @return Each row contains information about one plate:
* <p>
* <code>{ plate augmented code, plate perm id, plate space code, plate code,
* experiment augmented code, experiment perm id, experiment space code,
* experiment project code, experiment code }</code>
*/
public static Object[][] listPlates()
{
checkLoggedIn();
return listPlates(plates);
brinn
committed
}
brinn
committed
/**
* Lists the plates of <var>experiment</var>.
* <p>
* Matlab example:
*
* <pre>
* % Get the plates of experiment MYEXP in project PROJ of space SPACE
* plates = OpenBISScreeningML.listPlates('/SPACE/PROJ/MYEXP');
brinn
committed
* % How many plates do we have?
* length(plates)
* % Get all information about plate 2
* plate2 = plates(2,:)
* % Get the augmented plate codes for all plates
* acodes = plates(:,1)
* </pre>
*
* @param experiment The augmented code of the experiment to list the plates for
* @return Each row contains information about one plate:
* <p>
* <code>{ plate augmented code, plate perm id, plate space code, plate code,
* experiment augmented code, experiment perm id, experiment space code,
* experiment project code, experiment code }</code>
*/
public static Object[][] listPlates(String experiment)
{
checkLoggedIn();
final List<Plate> experimentPlates = experimentToPlateMap.get(experiment);
if (experimentPlates == null)
{
throw new RuntimeException("No experiment with that code found.");
}
return listPlates(experimentPlates);
}
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
/**
* Lists the plates of <var>experiment</var> and analysis procedure. Each returned plate has at
* least one data set with the specified analysis procedure.
* <p>
* Matlab example:
*
* <pre>
* % Get all plates having data sets with analysis procedure 'PROC' in the experiment MYEXP in project PROJ of space SPACE
* plates = OpenBISScreeningML.listPlates('/SPACE/PROJ/MYEXP', 'PROC');
* % Get all information about plate 2
* plate2 = plates(2,:)
* % Get the augmented plate codes for all plates
* acodes = plates(:,1)
* </pre>
*
* @param experiment The augmented code of the experiment to list the plates for
* @param analysisProcedure The analysis procedure
* @return Each row contains information about one plate:
* <p>
* <code>{ plate augmented code, plate perm id, plate space code, plate code,
* experiment augmented code, experiment perm id, experiment space code,
* experiment project code, experiment code }</code>
*/
public static Object[][] listPlates(String experiment, String analysisProcedure)
{
checkLoggedIn();
ExperimentIdentifier experimentIdentifier = getExperimentIdentifierOrFail(experiment);
List<Plate> resultPlates = openbis.listPlates(experimentIdentifier, analysisProcedure);
return listPlates(resultPlates);
}
private static Object[][] listPlates(final List<Plate> list)
{
final Object[][] result = new Object[list.size()][9];
for (int i = 0; i < list.size(); ++i)
brinn
committed
{
final Object[] annotations =
new Object[]
{ list.get(i).getAugmentedCode(), plates.get(i).getPermId(),
list.get(i).tryGetSpaceCode(), plates.get(i).getPlateCode(),
list.get(i).getExperimentIdentifier().getAugmentedCode(),
list.get(i).getExperimentIdentifier().getPermId(),
list.get(i).getExperimentIdentifier().getSpaceCode(),
list.get(i).getExperimentIdentifier().getProjectCode(),
list.get(i).getExperimentIdentifier().getExperimentCode(), };
brinn
committed
System.arraycopy(annotations, 0, result[i], 0, annotations.length);
}
return result;
}
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
/**
* Returns an alphabetically sorted list of analysis procedure codes of all data sets of a
* specified experiment.
* <p>
* Matlab example:
*
* <pre>
* % Get the analysis procedures for experiment MYEXP in project PROJ of space SPACE
* analysisProcedures = OpenBISScreeningML.listAnalysisProcedures('/SPACE/PROJ/MYEXP');
* % How many analysis procedures do we have?
* length(analysisProcedures)
* % Get all the analysis procedure codes
* acodes = analysisProcedures(:,1)
* </pre>
*
* @param experiment The augmented code of the experiment to list analysis procedures for
* @return Each row contains information about one analysis procedure:
* <p>
* <code>{ analysis procedure code }</code>
*/
public static Object[][] listAnalysisProcedures(String experiment)
{
checkLoggedIn();
ExperimentIdentifier experimentIdentifier = getExperimentIdentifierOrFail(experiment);
List<String> proceduresList = openbis.listAnalysisProcedures(experimentIdentifier);
return listAnalysisProcedures(proceduresList);
}
private static Object[][] listAnalysisProcedures(final List<String> list)
{
final Object[][] result = new Object[list.size()][1];
for (int i = 0; i < list.size(); ++i)
{
result[i][0] = list.get(i);
}
return result;
}
/**
* Returns the properties of specified well for specified plate.
* <p>
* Matlab example:
*
* <pre>
* % Get properties for well A03 of plate P005 in space SPACE
* properties = OpenBISScreeningML.getWellProperties('/SPACE/P005', 1, 3)
* % Get property type code of first property
* properties(1,1)
* % Get property value of first property
* properties(1,2)
* </pre>
*
* @param augmentedPlateCode The augmented plate code
* @param row The row in the plate to get the well properties for
* @param column The column in the plate to get the well properties for
* @return A two dimensional array where the first column contains the property codes and the
* second column the corresponding property values.
*/
public static Object[][] getWellProperties(String augmentedPlateCode, int row, int column)
{
checkLoggedIn();
WellPosition wellPosition = new WellPosition(row, column);
WellIdentifier wellIdentifier = getWell(augmentedPlateCode, wellPosition);
Map<String, String> wellProperties = openbis.getWellProperties(wellIdentifier);
return listProperties(wellProperties);
/**
* Updates properties of specified well for specified plate.
* <p>
* Matlab example:
*
* <pre>
* % Updates properties DESCRIPTION and NUMBER for well A03 of plate P005 in space SPACE
* properties = {'DESCRIPTION' 'hello example'; 'NUMBER' 3.14}
* OpenBISScreeningML.updateWellProperties('/SPACE/P005', 1, 3, properties)
* </pre>
*
* @param augmentedPlateCode The augmented plate code
* @param row The row in the plate to get the well properties for
* @param column The column in the plate to get the well properties for
* @param properties A two dimensional array where the first column contains the property codes
* and the second column the corresponding property values.
*/
public static void updateWellProperties(String augmentedPlateCode, int row, int column,
Object[][] properties)
{
checkLoggedIn();
WellPosition wellPosition = new WellPosition(row, column);
WellIdentifier wellIdentifier = getWell(augmentedPlateCode, wellPosition);
openbis.updateWellProperties(wellIdentifier, createMap(properties));
}
private static WellIdentifier getWell(String augmentedPlateCode, WellPosition wellPosition)
{
Plate plate = getPlate(augmentedPlateCode);
List<WellIdentifier> wells = openbis.listPlateWells(plate);
for (WellIdentifier wellIdentifier : wells)
{
if (wellIdentifier.getWellPosition().equals(wellPosition))
{
return wellIdentifier;
}
}
throw new RuntimeException("Plate '" + augmentedPlateCode + "' has no well at "
+ wellPosition + ".");
}
brinn
committed
/**
* Fetches metadata of the image datasets for the specified <var>plate</var>.
* <p>
* Matlab example:
*
* <pre>
* % Get the metadata of image datasets of plate P005 from space SPACE
* imagesMetadata = OpenBISScreeningML.getImagesMetadata('/SPACE/P005');
* % How many image datasets do we have? Usually there will be just one.
* length(imagesMetadata)
* % What is the number of tiles in the first image dataset?
* imagesMetadata(1, 3)
* </pre>
*
* @param augmentedPlateCode The augmented plate code.
* @return <code>{ images width, images height, number of tiles in the well,
* number of tiles rows, number of tiles columns, number of plate rows, number of plate columns }</code>
* .
*/
public static Object[][] getImagesMetadata(String augmentedPlateCode)
{
checkLoggedIn();
final Plate plateId = getPlate(augmentedPlateCode);
final List<ImageDatasetReference> imageDatasets = listRawImageDatasets(plateId);
final List<ImageDatasetMetadata> metaList = openbis.listImageMetadata(imageDatasets);
Object[][] result = new Object[metaList.size()][];
for (int i = 0; i < metaList.size(); ++i)
{
ImageDatasetMetadata meta = metaList.get(i);
ImageDatasetReference imageDatasetReference = imageDatasets.get(i);
Geometry plateGeometry = imageDatasetReference.getPlateGeometry();
result[i] =
new Object[]
{ meta.getWidth(), meta.getHeight(), meta.getNumberOfTiles(),
meta.getTilesRows(), meta.getTilesCols(),
plateGeometry.getNumberOfRows(), plateGeometry.getNumberOfColumns() };
brinn
committed
/**
* Lists all channels measured in <var>experiment</var>.
* <p>
* Matlab example:
*
* <pre>
* % Get the channels of experiment MYEXP in project PROJ of space SPACE
* channels = OpenBISScreeningML.listChannels('/SPACE/PROJ/MYEXP');
brinn
committed
* % How many channels do we have?
* length(channels)
* % What is the name of channel 1?
* channels(1)
* </pre>
*
* @param experiment The augmented code of the experiment to list the channels for
* @return Each row contains information about one channel. Currently the only information
* available is the channel name.
*/
public static Object[][] listChannels(String experiment)
{
checkLoggedIn();
final List<Plate> experimentPlates = experimentToPlateMap.get(experiment);
if (experimentPlates == null)
{
throw new RuntimeException("No experiment with that code found.");
}
if (experimentPlates.isEmpty())
{
return new Object[0][];
}
final List<ImageDatasetReference> imageDatasets =
openbis.listRawImageDatasets(experimentPlates);
brinn
committed
if (imageDatasets.isEmpty())
{
return new Object[0][];
}
return extractChannels(imageDatasets.get(0));
brinn
committed
}
private static List<String> getChannelCodes(final List<ImageDatasetMetadata> meta)
{
return meta.get(0).getChannelCodes();
brinn
committed
/**
* Lists all features computed for <var>experiment</var> using specified analysis procedure.
brinn
committed
* <p>
* Matlab example:
*
* <pre>
* % Get the features of experiment MYEXP in project PROJ of space SPACE
* features = OpenBISScreeningML.listFeatures('/SPACE/PROJ/MYEXP', []);
* % Get the features of experiment MYEXP in project PROJ of space SPACE which are computed
* % with analysis procedure AP-4711
* features = OpenBISScreeningML.listFeatures('/SPACE/PROJ/MYEXP', 'AP-4711');
brinn
committed
* % How many features do we have?
* length(features)
* % What is the name of features 1?
* features(1)
* </pre>
*
* @param experiment The augmented code of the experiment to list the features for
* @param analysisProcedureOrNull The analysis procedure used to filter the result. That is, the
* result is restricted to feature vector data sets with a value of property
* <code>ANALYSIS_PROCEDURE</code> as specified. If <code>null</code> (or
* <code>[]</code> in MatLab) no restriction applies.
brinn
committed
* @return Each row contains information about one feature. Currently the only information
* available is the feature name.
*/
public static Object[][] listFeatures(String experiment, String analysisProcedureOrNull)
brinn
committed
{
checkLoggedIn();
final List<Plate> experimentPlates = experimentToPlateMap.get(experiment);
if (experimentPlates == null)
{
throw new RuntimeException("No experiment with that code found.");
}
if (experimentPlates.isEmpty())
{
return new Object[0][];
}
final List<FeatureVectorDatasetReference> featureDatasets =
openbis.listFeatureVectorDatasets(experimentPlates, analysisProcedureOrNull);
brinn
committed
if (featureDatasets.isEmpty())
{
return new Object[0][];
}
List<String> featureCodes = openbis.listAvailableFeatureCodes(featureDatasets);
Collections.sort(featureCodes);
Object[][] result = new Object[featureCodes.size()][1];
brinn
committed
for (int i = 0; i < result.length; ++i)
{
result[i][0] = featureCodes.get(i);
brinn
committed
}
return result;
}
/**
* Loads data sets for specified plate code. For each data set the path to the root of the data
* set is returned. If it is possible the path points directly into the data set store. No data
* is copied. Otherwise the data is retrieved from the data store server.<br>
* If the same dataset is loaded for the second time in one session it will be immediately
* returned from the local cache.
* <p>
* Matlab example:
*
* <pre>
* % Load all data sets of plate P005 in space SPACE
* dsinfo = OpenBISScreeningML.loadDataSets('/SPACE/P005', 'HCS_ANALYSIS_CELL_FEATURES_CC_MAT', '/mount/openbis-store')
* % Get the data set codes
* dsinfo(:,1)
* % Get root path of first data set (assuming there is at least one)
* dsginfo(1,2)
* % Get the properties for the first data set
* props = dsginfo(1,3)
* % Get property key of first property
* props(1,1)
* % Get property value of first property
* props(1,2)
* </pre>
*
* @param augmentedPlateCode The augmented plate code.
* @param dataSetTypeCodePattern only datasets of the type which matches the specified pattern
* will be returned. To fetch all datasets specify ".*".
* @param overrideStoreRootPathOrNull A path, in the context of the local file system mounts, to
* the DSS' store root. If null, paths are returned in the context of the DSS' file
* system mounts.
* @return Each row contains information about one data set:
* <p>
* <code>{ data set code, data set root path, { {key1, value1}, {key2, value2} ...} }</code>
*/
public static Object[][] loadDataSets(String augmentedPlateCode, String dataSetTypeCodePattern,
{
return loadDataSets(augmentedPlateCode, dataSetTypeCodePattern, new Object[0][],
overrideStoreRootPathOrNull);
}
/**
* Loads data sets for specified plate code. For each data set the path to the root of the data
* set is returned. If it is possible the path points directly into the data set store. No data
* is copied. Otherwise the data is retrieved from the data store server.<br>
* If the same dataset is loaded for the second time in one session it will be immediately
* returned from the local cache.
* <p>
* Matlab example:
*
* <pre>
* % Load all data sets of plate P005 in space SPACE
* properties = {'ANALYSIS_PROCEDURE' 'AX87'}
* dsinfo = OpenBISScreeningML.loadDataSets('/SPACE/P005', 'HCS_ANALYSIS_CELL_FEATURES_CC_MAT', properties, '/mount/openbis-store')
* % Get the data set codes
* dsinfo(:,1)
* % Get root path of first data set (assuming there is at least one)
* % Get the properties for the first data set
* % Get property key of first property
* props(1,1)
* % Get property value of first property
* props(1,2)
* </pre>
*
* @param augmentedPlateCode The augmented plate code.
* @param dataSetTypeCodePattern only data sets of the type which matches the specified pattern
* will be returned. To fetch all data sets specify ".*".
* @param properties Only data set with specified property values will be returned. This is a
* two dimensional array where the first column contains the property codes and the
* second column the corresponding property values.
* @return Each row contains information about one data set:
* @param overrideStoreRootPathOrNull A path, in the context of the local file system mounts, to
* the DSS' store root. If null, paths are returned in the context of the DSS' file
* system mounts.
* <p>
* <code>{ data set code, data set root path, { {key1, value1}, {key2, value2} ...} }</code>
*/
public static Object[][] loadDataSets(String augmentedPlateCode,
final String dataSetTypeCodePattern, final Object[][] properties,
String overrideStoreRootPathOrNull)
checkLoggedIn();
Plate plateIdentifier = getPlate(augmentedPlateCode);
List<DataSet> dataSets =
openbis.getFullDataSets(plateIdentifier, new AndDataSetFilter(
new TypeBasedDataSetFilter(dataSetTypeCodePattern),
new PropertiesBasedDataSetFilter(createMap(properties))));
Object[][] result = new Object[dataSets.size()][];
try
{
for (int i = 0; i < dataSets.size(); i++)
{
DataSet dataSet = dataSets.get(i);
String code = dataSet.getCode();
File file = new File(dataSetsDir, code);
if (file.exists() == false)
{
file =
dataSet.getLinkOrCopyOfContents(overrideStoreRootPathOrNull,
dataSetsDir);
}
Object[][] dataSetProperties = listProperties(dataSet.getProperties());
{ code, file.getPath(), dataSetProperties };
}
return result;
} catch (Exception ex)
{
throw new RuntimeException("Loading data sets for plate '" + augmentedPlateCode
+ "' failed: " + ex, ex);
}
}
/**
* Loads file/folder of specified data set and specified file/folder path inside the data set.
* If it is possible the path points directly into the data set store. No data is copied.
* Otherwise the data is retrieved from the data store server.
* <p>
* Matlab example:
*
* <pre>
* % List all data sets of plate P005 in space SPACE. The query is restricted to data sets
* % of a type starting with HCS_IMAGE
* files = OpenBISScreeningML.listDataSetsFiles('/SPACE/P005', 'HCS_IMAGE.*')
* % Load from the first data set (assuming at least one data set found) the third file/folder
* % (assuming at least three files/folders)
* file = OpenBISScreeningML.loadDataSetFile(files(1,1), files(1,2,3), [])
* </pre>
*
* @param dataSetCode The code of the data set.
* @param pathInDataSet Path inside the data set pointing to the file/folder which should be
* down loaded. Use '/' if all files are requested.
* @param overrideStoreRootPathOrNull A path, in the context of the local file system mounts, to
* the DSS' store root. If null, paths are returned in the context of the DSS' file
* system mounts.
* @return path to the down loaded file/folder.
*/
public static Object loadDataSetFile(String dataSetCode, String pathInDataSet,
String overrideStoreRootPathOrNull)
{
checkLoggedIn();
IDataSetDss dataSet = openbis.getDataSet(dataSetCode);
return dataSet.getLinkOrCopyOfContent(overrideStoreRootPathOrNull, temporarySessionDir,
pathInDataSet).toString();
}
/**
* Lists all files of all data sets for specifies plate and data set type code matching
* specified regular expression pattern.
* <p>
* Matlab example:
*
* <pre>
* % List all data sets of plate P005 in space SPACE. The query is restricted to data sets
* % of a type starting with HCS_IMAGE
* files = OpenBISScreeningML.listDataSetsFiles('/SPACE/P005', 'HCS_IMAGE.*')
* % Codes of all found data sets
* files(:,1)
* % Code of third data set (assuming at least three data sets found)
* files(3,1)
* % Files of third data set (assuming at least three data sets found)
* files(3,2,:)
* </pre>
*
* @param augmentedPlateCode The augmented plate code.
* @param dataSetTypeCodePattern only data sets of the type which matches the specified pattern
* will be returned. To fetch all data sets specify ".*".
* @return <code>{data set code, file/folder paths}</code>
*/
public static Object[][][] listDataSetsFiles(String augmentedPlateCode,
String dataSetTypeCodePattern)
{
checkLoggedIn();
Plate plateIdentifier = getPlate(augmentedPlateCode);
List<IDataSetDss> dataSets =
openbis.getDataSets(plateIdentifier, new TypeBasedDataSetFilter(
dataSetTypeCodePattern));
Object[][][] result = new Object[dataSets.size()][][];
for (int i = 0; i < dataSets.size(); i++)
{
IDataSetDss dataSet = dataSets.get(i);
FileInfoDssDTO[] fileInfos = dataSet.listFiles("/", true);
String code = dataSet.getCode();
result[i] = new Object[2][];
result[i][0] = new Object[]
{ code };
result[i][1] = new Object[fileInfos.length];
for (int j = 0; j < fileInfos.length; j++)
{
FileInfoDssDTO fileInfo = fileInfos[j];
result[i][1][j] = fileInfo.getPathInDataSet();
}
}
return result;
}
/**
* Uploads specified data set for specified plate. The data set code will be returned.
* <p>
* Matlab example:
*
* <pre>
* % Upload data set /path/to/my-data-set with properties DESCRIPTION and NUMBER for
* % plate P005 in space SPACE
* properties = {'DESCRIPTION' 'hello example'; 'NUMBER' 3.14}
* datasetcode = OpenBISScreeningML.uploadDataSet('/SPACE/P005', '/path/to/my-data-set', 'HCS_IMAGE', properties)
* </pre>
*
* @param augmentedPlateCode The augmented plate code.
* @param dataSetFilePath Path to the data set file/folder to be uploaded.
* @param dataSetType Data set type.
* @param dataSetProperties A two dimensional array where the first column contains the property
* codes and the second column the corresponding property values.
*/
public static Object uploadDataSet(String augmentedPlateCode, String dataSetFilePath,
String dataSetType, Object[][] dataSetProperties)
{
checkLoggedIn();
Plate plateIdentifier = getPlate(augmentedPlateCode);
File dataSetFile = new File(dataSetFilePath);
if (dataSetFile.exists() == false)
{
throw new RuntimeException("Unknown data set file path '" + dataSetFilePath + "'.");
}
try
{
Map<String, String> map = createMap(dataSetProperties);
IDataSetDss dataSet =
openbis.putDataSet(plateIdentifier, dataSetFile, new NewDataSetMetadataDTO(
dataSetType, map));
return dataSet.getCode();
} catch (Exception ex)
{
throw new RuntimeException("Couldn't upload data set for plate '" + augmentedPlateCode
+ "'.", ex);