Creating the Investigation File
Table of contents
Usually it makes sense to build up the Investigation file first and define all the Parameters, Protocols, Ontologies etc. that you want to use in your corresponding Study and Assay files. With only a few exceptions, isa4j classes and attributes are named in keeping with the ISA model, so if you’re familiar with those or the python API, isa4j will feel quite intuitive. Alternatively, you can read this documentation to understand the general design concept. All ISA related classes are located in the de.ipk_gatersleben.bit.bi.isa4j.components
package.
If you’re new to ISATab, it may be also helpful to look at the TestInvestigation.writeToStream Unit test and read the Investigation File generated by it in parallel, so you can see what ends up where. If something is still unclear, feel free to get in touch with us.
Investigations
To start a new Investigation project, simply create an Investigation object:
Investigation investigation = new Investigation("InvestigationID");
investigation.setTitle("Investigation Title");
investigation.setDescription("Investigation Description");
investigation.setSubmissionDate(LocalDate.of(2019, 12, 22));
investigation.setPublicReleaseDate(LocalDate.of(2020, 1, 16));
Ontologies
To refer to an ontology later on in the Investigation, Study or Assay files, define them at a central place and add them to your Investigation.
Ontology creditOntology = new Ontology(
"CRediT", // Name of the ontology
new URL("http://purl.org/credit/ontology"), // URL to the ontology
"1.2", // Version of the ontology
"CASRAI Contributor Roles Taxonomy (CRediT)" // Short description of the ontotlogy
);
investigation.addOntology(creditOntology);
OntologyAnnotations
To improve the re-usability and quality of your metadata it is often helpful to use OntologyAnnotation
s for descriptive attributes instead of simple Strings. They allow you to connect a term
to an ontology (term source
) and identify it with a term accession number
. The latter two are optional though, and if you don’t set them an OntologyAnnotation will be formatted like a simple String in most cases.
OntologyAnnotation paperPublished = new OntologyAnnotation(
"Published", // Term
"<TermAccessionNumber>", // Term Accession Number (optional)
creditOntology // Ontology object (optional)
);
Publications
To link a publication to the Investigation, you can do so similarly to ontologies:
Publication statsStories = new Publication("Five Things ... about Statistics that is", "Philip M. Dixon");
statsStories.setDOI("https://doi.org/10.4148/2475-7772.1013");
statsStories.setStatus(paperPublished); // this is the OntologyAnnotation we defined before
investigation.addPublication(statsStories);
Contacts
Contacts can be added using the Person
type:
Person schlomo = new Person(
"Schlomo", // First Name
"Hootkins", // Last Name
"schlomoHootkins@miofsiwa.foo", // Email
"Ministry of Silly Walks", // Affiliation
"4 Hanover House, 14 Hanover Square, London W1S 1HP" // Address
);
Person agatha = new Person("Agatha", "Stroganoff", null, "Stroganoff Essential Eels", null);
agatha.setFax("+49 3553N714L 33l2"); // Agatha doesn't have an email or a postal address, but a fax number
// Add them as investigation contacts
investigation.addContact(schlomo);
investigation.addContact(agatha);
Comments
Various components of the data model can be enriched with comments. Their CommentCollection
is accessible through the .comments()
method and provides the methods add(Comment)
, getAll
, and getByName(String)
.
schlomo.comments().add(new Comment("method name", "MyMethod"));
schlomo.comments().add(new Comment("analysis software", "Analyzer Pro"));
schlomo.comments().getAll(); // Returns a List<Comment>
schlomo.comments().getByName("method name"); // Returns an Optional<Comment>
investigation.comments().add(new Comment("Usability", "high"));
Studies
At some point you will want to create one or more Study objects and attach them to your Investigation. Each Study needs an identifier and a filename, if no filename is given it will be automatically constructed from the identifier.
Study study1 = new Study("Study1ID", "s_study1.txt");
Study study2 = new Study("Study2ID"); // now the filename will be automatically set to "s_Study2ID.txt"
investigation.addStudy(study1);
investigation.addStudy(study2);
Study objects are very similar to Investigation objects in that they can also have a title and description and that you can also populate them with Contacts, Publications. In addition to Investigations, Studies can also contain Factors and Protocols which can then be referenced from the Study File of that Study (keep in mind, we’re still constructing the Investigation File here, even though we are talking about Studies).
Factor soilCoverage = new Factor("soil coverage", new OntologyAnnotation("Factor Type"));
study1.addFactor(soilCoverage);
Protocol plantTalking = new Protocol("Plant Talking");
plantTalking.addComponent(new ProtocolComponent("Component Name", new OntologyAnnotation("Component Type")));
ProtocolParameter toneOfVoice = new ProtocolParameter("Tone of Voice");
plantTalking.addParameter(toneOfVoice);
Assays
Finally each Study can contain one or more Assays. They only need a filename/path and do not take an identifier.
Assay assay1 = new Assay("a_assay.txt");
study1.addAssay(assay1);
Writing the File
When you have added everything, you can simply write the Investigation File to a location you specify:
investigation.writeToFile("./i_investigation.txt");
Please note that unlike the isatab.dump
method from the python API, this only writes the Investigation File and no Study or Assay Files. They have to be written separately (see sections below).
Instead of writing to a file, you can also write to an open outputstream (e.g. if you’re using isa4j in a REST server application)
OutputStream os = new ByteArrayOutputStream(); // of course you would already have a stream
investigation.writeToStream(os);
The stream will not be closed by this method so you can keep using it if you want to send anything after the investigation file content.