-
Notifications
You must be signed in to change notification settings - Fork 3
Initial draft proposal, version 0.0.2
Version 0.0.1 was supposed to start a discussion – but did not. Looking back, it was rather underdeveloped, and we should probably continue to ignore it. The idea behind this version is to start agreeing on at least the overall structure of the model we want to build. The key point is about the minimum number of objects and crosslinks between them that we need in order to accommodate our data. Class names and details can change, classes can be split and merged, and we may want to add more complex data structures (like unit cells or reflection shell data) but I think we shall need at least this much structure.
For a relevant use case, I am thinking about a workflow-driven multi-sweep crystallography experiment. For such experiments it is crucial that data input and processing result can be given in terms of a set of selected sweeps. Organisation in terms of single sweeps is obviously inadequate for the purpose, and organisation in terms of Samples not only precludes straightforward representation of multi-sample processing results, but also lacks a way of distinguishing which of the multiple sweeps, mesh scans, or experiments performed on a sample actually are (or should be) processed together.
We should remember that the model is meant to specify an interface between programs and LIMS systems. People are free to use any internal organisation they find practical, as long as they are able to read and re-export data according to the model.

Abstract classes defining the model structure and the links between them. For those unused to UML note the cardinalities: ‘1’ (mandatory), ‘0..1’ (optional), and ‘*’ (0 to many)
* These are abstract classes - actual classes will be subtypes. The **Job** class is used both for describing actual experiments and for processing runs (calculations), with **Input** and **Result** collecting the input resp. output for one **Job**. Everything we think of as data are subtypes of the **Data** class, which might be Sweep, Mesh scan, Line scan, Model, Map, MTZ file etc. ... The **InputData** class serves only to hold parameters that describe how a particular **Data** object fits in as input to a particular **Job**. Note that only the **Data** class will have links to files.
-
The model is intended as an API, i.e. for describing messages, so in practice each message would contain copies of the relevant objects as necessary. The need for proper objects and crosslinks is more urgent for LIMS and storage, where you do not want a lot of maybe identical data structures cluttering up your databases. I would propose that each of the six abstract classes shown in the diagram should have an UUID attribute, so it is possible to track the history, origin and identity of the information. -
All classes should have a slot for program-specific name-spaced data. -
Any **Job** (experiment or processing) will have some parameters or results that refer to the entire **Job** rather than to any individual input or output file. Accordingly, each **Job** is connected to one **Input** and one **Result** object that can hold these parameters, as well as grouping multiple data sets. Note that **Results** are only connected to one **Job**, and that the same Input in practice will rarely be used more than once. -
Each **Data** object is produced by a single **Job** (of whatever type), and so can hold parameters that are only defined relative to that **Job**, like the distinction between characterisation sweeps and acquisition sweeps, or overall maps and early-minus-late maps. -
**Data** objects can serve as input for many different **Jobs**, so we need the **InputData** class to sit between the **Data** and **Input** classes and specify parameters that describe how the data fit into this particular **Job**. There may not be that many attributes here, but we might need e.g. a role (characterisation versus acquisition, input versus reference mtz files, …), information on included/excluded image ranges, possibly a weight, or program-specific parameters. Note that **InputData** are specific to a given **Input** object, and so the link between the two is mandatory. -
We should limit the number of different subtypes by using the same classes in different contexts. E.g. a Sweep **Data** type could be used as part of a diffraction plan (partially populated and without a file Url), as part of a message to the acquisition queue (with a Url but no data file as yet), to store the data collection result, and as part of the input for a processing program (linked to an **InputData** object). **InputData** objects could similarly be used as part of a processing plan. -
As currently drafted, the model assumes that each **Job** (experimental or processing) is connected to (at most) one single **Sample**. For single-crystal experiments, the sample would be equivalent to the crystal. This could be extended to multi-crystal experiments later, as long as the composition, history, expected crystal form etc. is the same for all the crystals in the same well / chip / vial. Where it is appropriate, we can link a **Sample** also to **Result** objects or to processing **Input**. Processing jobs are not in principle limited to using data from a single sample, but there is no explicit support for processing multi-sample data in the model, except by following inter-object links back to the **Sample** record. The alternative of connecting the **Sample** record to the **Data** object would give full support for multi-sample experiments and processing but would severely complicate the more common case of doing an experiment or processing on a single sample and wanting to find the relevant **Sample** record.
The ICAT model objects do not fit exactly with what we need to do here, so storing these data in ICAT would require a certain amount of crafting. One problem is that ICAT links the sample to the Dataset rather than the DataCollection. A more basic problem is that ICAT does not have crosslinks between Datasets but only between Datafiles, and that the ICAT Datafile strictly describes a file object, with location, checksum, etc. Considering that our Data object can correspond to a file, to a set of mini-cbf files, to only part of the data inside an HDF5 file, or to no file at all, this does not suggest an obvious mapping. The diagram below shows one possible way that the model presented might be stored in ICAT.

Possible ICAT implementation of the draft model. InputData and Data are handled by a combination of a Dataset and a Datafile with a 1:1 link between them. To reproduce the draft model would require a hack that somehow connected each DataCollection with a single, optional Sample.