Light Sensitivity Experiment:

Reporting a repeated treatment design with ISA create mode

This example creates ISA study descriptor for study with sequential treatments organized in an arm. This shows how to use objects from the isatools.create component in a granular fashion. It creates each Element of the Study Arm at a time. Finally, the study design plan is shown by serializing the ISA Study Design Model content as an ISA_design JSON document, which can be rendered in various ways (tables, figures).

Study metadata

# If executing the notebooks on `Google Colab`,uncomment the following command 
# and run it to install the required python libraries. Also, make the test datasets available.

# !pip install -r requirements.txt
import os
import datetime
import json
from collections import OrderedDict
from isatools.model import (
    Investigation,
    Study,
    Sample,
    OntologyAnnotation,
    StudyFactor,
    FactorValue,
    Characteristic,
    Source,
    Protocol,
    Process
)
from isatools.create.model import (
    Treatment,
    NonTreatment,
    StudyDesign,
    StudyCell,
    StudyArm,
    ProductNode,
    SampleAndAssayPlan,
    AssayGraph
)
from isatools.create.constants import (
    BASE_FACTORS,
    SCREEN,
    RUN_IN,
    WASHOUT,
    FOLLOW_UP,
    SAMPLE,
    EXTRACT,
    LABELED_EXTRACT,
    DATA_FILE
)
from isatools.isatab import dumps
from isatools.isajson import ISAJSONEncoder
investigation = Investigation()
investigation1 = Investigation() # to be used with the study create function
study = Study(filename="s_study_xover.txt")
study.identifier = "elifesprint2019-1"
study.title = "elifesprint2019-1: light sensitivity"
study.description = "a study about light sensitivity difference between a control population (n=10) and a genotype A population (n=10)."
study.submission_date = str(datetime.datetime.today())
study.public_release_date = str(datetime.datetime.today())
study.sources = [Source(name="source1")]
study.samples = [Sample(name="sample1")]
study.protocols = [Protocol(name="sample collection")]
study.process_sequence = [Process(executes_protocol=study.protocols[-1], inputs=[study.sources[-1]], outputs=[study.samples[-1]])]
investigation.studies = [study]
# Let's see the object :
investigation
isatools.model.Investigation(identifier='', filename='', title='', submission_date='', public_release_date='', ontology_source_references=[], publications=[], contacts=[], studies=[isatools.model.Study(filename='s_study_xover.txt', identifier='elifesprint2019-1', title='elifesprint2019-1: light sensitivity', description='a study about light sensitivity difference between a control population (n=10) and a genotype A population (n=10).', submission_date='2021-07-21 17:43:54.131318', public_release_date='2021-07-21 17:43:54.131358', contacts=[], design_descriptors=[], publications=[], factors=[], protocols=[isatools.model.Protocol(name='sample collection', protocol_type=isatools.model.OntologyAnnotation(term='', term_source=None, term_accession='', comments=[]), uri='', version='', parameters=[], components=[], comments=[])], assays=[], sources=[isatools.model.Source(name='source1', characteristics=[], comments=[])], samples=[isatools.model.Sample(name='sample1', characteristics=[], factor_values=[], derives_from=[], comments=[])], process_sequence=[isatools.model.Process(id="". name="None", executes_protocol=Protocol(
    name=sample collection
    protocol_type=
    uri=
    version=
    parameters=0 ProtocolParameter objects
    components=0 OntologyAnnotation objects
    comments=0 Comment objects
), date="None", performer="None", inputs=[isatools.model.Source(name='source1', characteristics=[], comments=[])], outputs=[isatools.model.Sample(name='sample1', characteristics=[], factor_values=[], derives_from=[], comments=[])])], other_material=[], characteristic_categories=[], comments=[], units=[])], comments=[])
# print(dumps(investigation))
# print(json.dumps(investigation, cls=ISAJSONEncoder, sort_keys=True, indent=4, separators=(',', ': ')))

1. Creation of the first ISA Study Design Element and setting both element_type AND duration_unit attributes

# IMPORTANT: note how duration_unit value is supplied as an OntologyAnnotation object
nte1 = NonTreatment(element_type='screen', duration_unit=OntologyAnnotation(term="days"))
print(nte1)
NonTreatment(
            type='screen',
            duration=isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='DURATION', factor_type=isatools.model.OntologyAnnotation(term='time', term_source=None, term_accession='', comments=[]), comments=[]), value=0.0, unit=isatools.model.OntologyAnnotation(term='days', term_source=None, term_accession='', comments=[]))
        )

2. Creation of another ISA Study Design Element, of type Treatment

te1 = Treatment()
te1.type='radiological intervention'
print(te1)
"Treatment
        (type=radiological intervention, 
        factor_values=[])
        

2.1 defining the first treatment as a vector of ISA factor values:

Under “ISA Study Design Create mode”, a Study Design Element of type Treatment needs to be defined by a vector of Factors and their respective associated Factor Values. This is done as follows:

f1 = StudyFactor(name='light', factor_type=OntologyAnnotation(term="electromagnetic energy"))
f1v = FactorValue(factor_name=f1, value="visible light at 3000K produced by LED array")
f2 = StudyFactor(name='dose', factor_type=OntologyAnnotation(term="quantity"))

# IMPORTANT: note how *FactorValue value* is supplied as an *numeral*
f2v = FactorValue(factor_name=f2, value=250, unit=OntologyAnnotation(term='lux'))
f3 = StudyFactor(name='duration', factor_type=OntologyAnnotation(term="time"))
f3v = FactorValue(factor_name=f3, value=1, unit=OntologyAnnotation(term='hr'))

print(f1v,f2v)
FactorValue(
    factor_name=light
    value='visible light at 3000K produced by LED array'
    unit=
) FactorValue(
    factor_name=dose
    value=250
    unit=lux
)
#assigning the factor values declared above to the ISA treatment element
te1.factor_values = [f1v,f2v,f3v]
print(te1)
"Treatment
        (type=radiological intervention, 
        factor_values=[isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='dose', factor_type=isatools.model.OntologyAnnotation(term='quantity', term_source=None, term_accession='', comments=[]), comments=[]), value=250, unit=isatools.model.OntologyAnnotation(term='lux', term_source=None, term_accession='', comments=[])), isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='duration', factor_type=isatools.model.OntologyAnnotation(term='time', term_source=None, term_accession='', comments=[]), comments=[]), value=1, unit=isatools.model.OntologyAnnotation(term='hr', term_source=None, term_accession='', comments=[])), isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='light', factor_type=isatools.model.OntologyAnnotation(term='electromagnetic energy', term_source=None, term_accession='', comments=[]), comments=[]), value='visible light at 3000K produced by LED array', unit=None)])
        

3. Creation of a second ISA Study Design Element, of type Treatment, following the same pattern.

te3 = Treatment()
te3.type = 'radiological intervention'
rays = StudyFactor(name='light', factor_type=OntologyAnnotation(term="electromagnetic energy"))

raysv = FactorValue(factor_name=rays, value='visible light at 3000K produced by LED array')
rays_intensity = StudyFactor(name='dose', factor_type=OntologyAnnotation(term="quantity"))
rays_intensityv= FactorValue(factor_name=rays_intensity, value = 250, unit=OntologyAnnotation(term='lux'))
rays_duration =  StudyFactor(name = 'duration', factor_type=OntologyAnnotation(term="time"))
rays_durationv = FactorValue(factor_name=rays_duration, value=1, unit=OntologyAnnotation(term='hour'))

te3.factor_values = [raysv,rays_intensityv,rays_durationv]
print(te3)
                
"Treatment
        (type=radiological intervention, 
        factor_values=[isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='dose', factor_type=isatools.model.OntologyAnnotation(term='quantity', term_source=None, term_accession='', comments=[]), comments=[]), value=250, unit=isatools.model.OntologyAnnotation(term='lux', term_source=None, term_accession='', comments=[])), isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='duration', factor_type=isatools.model.OntologyAnnotation(term='time', term_source=None, term_accession='', comments=[]), comments=[]), value=1, unit=isatools.model.OntologyAnnotation(term='hour', term_source=None, term_accession='', comments=[])), isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='light', factor_type=isatools.model.OntologyAnnotation(term='electromagnetic energy', term_source=None, term_accession='', comments=[]), comments=[]), value='visible light at 3000K produced by LED array', unit=None)])
        

4. Creation of ‘wash out’ period as an ISA Study Design Element.

# Creation of another ISA element, which is not a Treatment element, which is of type `screen` by default
# nte2 = NonTreatment()
# nte2.type = 'washout'
# net2.duration_unit=OntologyAnnotation(term="days")

nte2 = NonTreatment(element_type='washout', duration_unit=OntologyAnnotation(term="days"))
print(nte2)
NonTreatment(
            type='washout',
            duration=isatools.model.FactorValue(factor_name=isatools.model.StudyFactor(name='DURATION', factor_type=isatools.model.OntologyAnnotation(term='time', term_source=None, term_accession='', comments=[]), comments=[]), value=0.0, unit=isatools.model.OntologyAnnotation(term='days', term_source=None, term_accession='', comments=[]))
        )
# setting the factor values associated with 'default' DURATION Factor associated with such elements
nte2.duration.value=2
nte2.duration.unit=OntologyAnnotation(term="weeks")

5. Creation of ‘follow-up’ period as an ISA Study Design Element.

nte3 = NonTreatment(element_type='follow-up', duration_value=1, duration_unit=OntologyAnnotation(term="month"))
#print(nte3)

6. Creation of the associated container, known as an ISA Cell for each ISA Element.

In this example, a single Element is hosted by a Cell, which must be named. In more complex designs (e.g. study designs with assymetric arms), a Cell may contain more than one Element, hence the list attribute.

st_cl1= StudyCell(name="st_cl1", elements=[nte1])
st_cl2= StudyCell(name="st_cl2", elements=[te1])
st_cl3= StudyCell(name="st_cl3", elements=[nte2])
st_cl4= StudyCell(name="st_cl4", elements=[te3])
st_cl5= StudyCell(name="st_cl5", elements=[nte3])

7. Creation of an ISA Study Arm and setting the number of subjects associated to that unique sequence of ISA Cells.

genotype_cat = OntologyAnnotation(term="genotype")
genotype_value1 = OntologyAnnotation(term="control - normal")
genotype_value2 = OntologyAnnotation(term="mutant")

arm1 = StudyArm(
    name='Arm 1', 
    group_size=2
)

arm1.source_type=Characteristic(
    category=genotype_cat,
    value=genotype_value1
)

print(arm1)
"StudyArm(
               name=Arm 1,
               source_type=Characteristic(
    category=genotype
    value=control - normal
    unit=
    comments=0 Comment objects
),
               group_size=2, 
               no. cells=0,
               no. sample_assay_plans=0
               )

8. Declaring an ISA Sample Assay Plan, defining which Sample are to be collected and which Assays to be used

whole_patient=ProductNode(
    id_="MAT1",
    name="subject",
    node_type=SAMPLE,
    size=1,
    characteristics=[
        Characteristic(
            category=OntologyAnnotation(term='organism part'), 
            value=OntologyAnnotation(term='whole organism')
        )
    ]
)

saliva=ProductNode(
    id_="MAT2",
    name="saliva",
    node_type=SAMPLE,
    size=1,
    characteristics=[
        Characteristic(
            category=OntologyAnnotation(term='organism part'),
            value=OntologyAnnotation(term='saliva')
        )
    ]
)

Here we load an isa assay definition in the form of an ordered dictionary. It corresponds to an ISA configuration assay table but expressed in JSON.

We now show how to create an new AssayGraph structure from scratch, as if we were defining a completely new assay type.

light_sensitivity_phenotyping_1 = OrderedDict([
    ('measurement_type', OntologyAnnotation(term='melatonine concentration')),
    ('technology_type', OntologyAnnotation(term='radioimmunoprecipitation assay')),
     ('extraction', {}),
            ('extract', [
                {
                    'node_type': EXTRACT,
                    'characteristics_category': OntologyAnnotation(term='extract type'),
                    'characteristics_value': OntologyAnnotation(term='extract'),
                    'size': 1,
                    'technical_replicates': None,
                    'is_input_to_next_protocols': True
                }]),
                
    ('radioimmunoprecipitation', {
                OntologyAnnotation(term='instrument'): [OntologyAnnotation(term='Beckon Dickison XYZ')],
                OntologyAnnotation(term='antibody'): [OntologyAnnotation(term='AbCam antiMelatonine ')],
                OntologyAnnotation(term='time point'): [OntologyAnnotation(term='1 hr'),
                                                        OntologyAnnotation(term='2 hr')]
            }),
            ('raw_data_file', [
                {
                    'node_type': DATA_FILE,
                    'size': 1,
                    'technical_replicates': 1,
                    'is_input_to_next_protocols': False
                }
            ])
])


light_sensitivity_phenotyping_2 = OrderedDict([
        ('measurement_type', OntologyAnnotation(term='light sensitivity')),
        ('technology_type', OntologyAnnotation(term='electroencephalography')),
            ('data_collection', {
                OntologyAnnotation(term='instrument'): [OntologyAnnotation(term='Somnotouch')],
                OntologyAnnotation(term='sampling_rate'): [OntologyAnnotation(term='200 Hz')],
                OntologyAnnotation(term='time point'): [OntologyAnnotation(term='1 hr'),
                                                        OntologyAnnotation(term='2 hr')]
            }),
            ('raw_data_file', [
                {
                    'node_type': DATA_FILE,
                    'size': 1,
                    'technical_replicates': 1,
                    'is_input_to_next_protocols': False
                }
            ])
])

light_sensitivity_phenotyping_3 = OrderedDict([
        ('measurement_type', OntologyAnnotation(term='light sensitivity phenotyping')),
        ('technology_type', OntologyAnnotation(term='direct measurement')),
            ('data_collection', {
                OntologyAnnotation(term='variables'): [OntologyAnnotation(term='sleepiness'),
                                                       OntologyAnnotation(term='heart rate'),
                                                       OntologyAnnotation(term='pupilla size')],
                OntologyAnnotation(term='time point'): [OntologyAnnotation(term='1 hr'),
                                                        OntologyAnnotation(term='2 hr')]
            }),
            ('raw_data_file', [
                {
                    'node_type': DATA_FILE,
                    'size': 1,
                    'technical_replicates': 1,
                    'is_input_to_next_protocols': False
                }
            ])
])
alterness_assay_graph = AssayGraph.generate_assay_plan_from_dict(light_sensitivity_phenotyping_1)
melatonine_assay_graph = AssayGraph.generate_assay_plan_from_dict(light_sensitivity_phenotyping_2)
general_phenotyping_assay_graph = AssayGraph.generate_assay_plan_from_dict(light_sensitivity_phenotyping_3)
sap1 = SampleAndAssayPlan(name='sap1', sample_plan=[whole_patient,saliva],assay_plan=[alterness_assay_graph,melatonine_assay_graph,general_phenotyping_assay_graph])

sap1.add_element_to_map(sample_node=saliva, assay_graph=melatonine_assay_graph)
sap1.add_element_to_map(sample_node=whole_patient, assay_graph=alterness_assay_graph)
sap1.add_element_to_map(sample_node=whole_patient,assay_graph=general_phenotyping_assay_graph)

9. Declaration of an ISA assay and linking specimen type and data acquisition plan for this assay

sap1.sample_to_assay_map
{isatools.create.model.ProductNode(id=MAT2, type=sample, name=saliva, characteristics=[isatools.model.Characteristic(category=isatools.model.OntologyAnnotation(term='organism part', term_source=None, term_accession='', comments=[]), value=isatools.model.OntologyAnnotation(term='saliva', term_source=None, term_accession='', comments=[]), unit=None, comments=[])], size=1, extension=None): {isatools.create.model.AssayGraph(id=cce3713d-dfd3-4942-8d87-cb391156d756, measurement_type=OntologyAnnotation(
      term=light sensitivity
      term_source=
      term_accession=
      comments=0 Comment objects
  ), technology_type=OntologyAnnotation(
      term=electroencephalography
      term_source=
      term_accession=
      comments=0 Comment objects
  ), nodes={isatools.create.model.ProductNode(id=raw_data_file_000_001, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=data_collection_001, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='instrument', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='Somnotouch', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='sampling_rate', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='200 Hz', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='2 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProtocolNode(id=data_collection_000, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='instrument', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='Somnotouch', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='sampling_rate', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='200 Hz', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='1 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_000, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None)}, links=[('data_collection_000', 'raw_data_file_000_000'), ('data_collection_001', 'raw_data_file_000_001')], quality_control=None)},
 isatools.create.model.ProductNode(id=MAT1, type=sample, name=subject, characteristics=[isatools.model.Characteristic(category=isatools.model.OntologyAnnotation(term='organism part', term_source=None, term_accession='', comments=[]), value=isatools.model.OntologyAnnotation(term='whole organism', term_source=None, term_accession='', comments=[]), unit=None, comments=[])], size=1, extension=None): {isatools.create.model.AssayGraph(id=05599bfb-d02b-471e-b9b1-6ce6758791db, measurement_type=OntologyAnnotation(
      term=melatonine concentration
      term_source=
      term_accession=
      comments=0 Comment objects
  ), technology_type=OntologyAnnotation(
      term=radioimmunoprecipitation assay
      term_source=
      term_accession=
      comments=0 Comment objects
  ), nodes={isatools.create.model.ProductNode(id=extract_000_000, type=extract, name=extract, characteristics=[isatools.model.Characteristic(category=isatools.model.OntologyAnnotation(term='extract type', term_source=None, term_accession='', comments=[]), value=isatools.model.OntologyAnnotation(term='extract', term_source=None, term_accession='', comments=[]), unit=None, comments=[])], size=1, extension=None), isatools.create.model.ProtocolNode(id=extraction_000, name=assay0 - extraction, protocol_type=OntologyAnnotation(
      term=assay0 - extraction
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[]), isatools.create.model.ProtocolNode(id=radioimmunoprecipitation_001_000, name=assay0 - radioimmunoprecipitation, protocol_type=OntologyAnnotation(
      term=assay0 - radioimmunoprecipitation
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='instrument', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='Beckon Dickison XYZ', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='antibody', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='AbCam antiMelatonine ', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='2 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_001, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=radioimmunoprecipitation_000_000, name=assay0 - radioimmunoprecipitation, protocol_type=OntologyAnnotation(
      term=assay0 - radioimmunoprecipitation
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='instrument', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='Beckon Dickison XYZ', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='antibody', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='AbCam antiMelatonine ', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='1 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_000, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None)}, links=[('extract_000_000', 'radioimmunoprecipitation_000_000'), ('extract_000_000', 'radioimmunoprecipitation_001_000'), ('extraction_000', 'extract_000_000'), ('radioimmunoprecipitation_000_000', 'raw_data_file_000_000'), ('radioimmunoprecipitation_001_000', 'raw_data_file_000_001')], quality_control=None),
  isatools.create.model.AssayGraph(id=d7726069-1823-4f49-b10c-8856036ad082, measurement_type=OntologyAnnotation(
      term=light sensitivity phenotyping
      term_source=
      term_accession=
      comments=0 Comment objects
  ), technology_type=OntologyAnnotation(
      term=direct measurement
      term_source=
      term_accession=
      comments=0 Comment objects
  ), nodes={isatools.create.model.ProductNode(id=raw_data_file_000_002, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProductNode(id=raw_data_file_000_003, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=data_collection_004, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='pupilla size', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='1 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_004, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=data_collection_000, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='sleepiness', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='1 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_001, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=data_collection_002, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='heart rate', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='1 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProtocolNode(id=data_collection_005, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='pupilla size', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='2 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProtocolNode(id=data_collection_003, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='heart rate', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='2 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_005, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None), isatools.create.model.ProtocolNode(id=data_collection_001, name=assay0 - data_collection, protocol_type=OntologyAnnotation(
      term=assay0 - data_collection
      term_source=
      term_accession=
      comments=0 Comment objects
  ), uri=, description=, version=, parameter_values=[isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='variables', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='sleepiness', term_source=None, term_accession='', comments=[]), unit=None, comments=[]), isatools.model.ParameterValue(category=isatools.model.ProtocolParameter(parameter_name=isatools.model.OntologyAnnotation(term='time point', term_source=None, term_accession='', comments=[]), comments=[]), value=isatools.model.OntologyAnnotation(term='2 hr', term_source=None, term_accession='', comments=[]), unit=None, comments=[])]), isatools.create.model.ProductNode(id=raw_data_file_000_000, type=data file, name=raw_data_file, characteristics=[], size=1, extension=None)}, links=[('data_collection_000', 'raw_data_file_000_000'), ('data_collection_001', 'raw_data_file_000_001'), ('data_collection_002', 'raw_data_file_000_002'), ('data_collection_003', 'raw_data_file_000_003'), ('data_collection_004', 'raw_data_file_000_004'), ('data_collection_005', 'raw_data_file_000_005')], quality_control=None)}}

10. Build an ISA Study Design Arm by adding the first set of ISA Cells and setting the Sample Assay Plan

arm1.add_item_to_arm_map(st_cl1, sap1)
# print(arm1)

11 Now expanding the Arm by adding a new Cell, which uses the same Sample Assay Plan as the one used in Cell #1.

Of course, the Sample Assay Plan for this new Cell could be different. It would have to be to built as shown before.

arm1.add_item_to_arm_map(st_cl2, sap1)
# Adding the last section of the Arm, with a cell which also uses the same sample assay plan.
arm1.add_item_to_arm_map(st_cl3, sap1)
arm1.add_item_to_arm_map(st_cl4, sap1)
arm1.add_item_to_arm_map(st_cl5, sap1)

12. Creation of additional ISA Study Arms and setting the number of subjects associated to that unique sequence of ISA Cells.

arm2 = StudyArm(name='Arm 2')
arm2.group_size=2
arm2.source_type=Characteristic(category=genotype_cat,
                                value=genotype_value2)

# st_cl6= StudyCell(name="st_cl6", elements=[nte1])
# st_cl7= StudyCell(name="st_cl7", elements=[te1])
# st_cl8= StudyCell(name="st_cl8", elements=[nte2])
# st_cl9= StudyCell(name="st_cl9", elements=[te3])
# st_cl10= StudyCell(name="st_cl10", elements=[nte3])



arm2.source_type.category
arm2.add_item_to_arm_map(st_cl1,sap1)
arm2.add_item_to_arm_map(st_cl4,sap1)
arm2.add_item_to_arm_map(st_cl3,sap1)
arm2.add_item_to_arm_map(st_cl2,sap1)
arm2.add_item_to_arm_map(st_cl5,sap1)
arm3 = StudyArm(name='Arm 3')
arm3.group_size=2
arm3.source_type=Characteristic(category=genotype_cat,
                                value=genotype_value1
                               )
arm3.add_item_to_arm_map(st_cl1,sap1)
arm3.add_item_to_arm_map(st_cl2,sap1)
arm3.add_item_to_arm_map(st_cl3,sap1)
arm3.add_item_to_arm_map(st_cl4,sap1)
arm3.add_item_to_arm_map(st_cl5,sap1)
arm4 = StudyArm(name='Arm 4')
arm4.group_size=2
arm4.source_type=Characteristic(category=genotype_cat,
                                value=genotype_value2)

arm4.add_item_to_arm_map(st_cl1,sap1)
arm4.add_item_to_arm_map(st_cl4,None)
arm4.add_item_to_arm_map(st_cl3,sap1)
arm4.add_item_to_arm_map(st_cl2,None)
arm4.add_item_to_arm_map(st_cl5,sap1)

14. We can now create the ISA Study Design object, which will receive the Arms defined by the user.

study_design_final= StudyDesign(name='trial design #1')
# print(sd)
# Adding a study arm to the study design object.
study_design_final.add_study_arm(arm1)
study_design_final.add_study_arm(arm2)
study_design_final.add_study_arm(arm3)
study_design_final.add_study_arm(arm4)

study_finale = study_design_final.generate_isa_study()
investigation1.studies.append(study_finale)
# print(investigation1.studies[0].name)
# Let's now serialize the ISA study design to JSON
from isatools.create.model import StudyDesignEncoder

f=json.dumps(study_design_final, cls=StudyDesignEncoder, sort_keys=True, indent=4, separators=(',', ': '))

final_dir = os.path.abspath(os.path.join('notebook-output', 'isa-study-custom-assay-light-sensitivity'))

with open(os.path.join(final_dir,'./light-sensitivity-study_design_final.json'), 'w') as isa_sdf_jf:
    json.dump(json.loads(f), isa_sdf_jf)
# print(json.dumps(investigation, cls=ISAJSONEncoder, sort_keys=True, indent=4, separators=(',', ': ')))
from isatools import isatab
isatab.dump(investigation1, final_dir)

from isatools.isatab import dump_tables_to_dataframes as dumpdf
dataframes = dumpdf(investigation)
2021-07-21 17:43:54,822 [INFO]: isatab.py(_all_end_to_end_paths:1131) >> [3, 4, 5, 6]
2021-07-21 17:43:54,828 [WARNING]: isatab.py(write_study_table_files:1194) >> [8, 7, 3, 10, 9, 12, 11, 14, 13, 16, 15, 18, 17, 20, 19, 22, 21, 24, 23, 26, 25, 28, 27, 30, 29, 32, 31, 34, 33, 36, 35, 38, 37, 40, 39, 42, 41, 44, 43, 46, 45, 48, 47, 4, 50, 49, 52, 51, 54, 53, 56, 55, 58, 57, 60, 59, 62, 61, 64, 63, 66, 65, 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, 86, 85, 88, 87, 5, 90, 89, 92, 91, 94, 93, 96, 95, 98, 97, 100, 99, 102, 101, 104, 103, 106, 105, 108, 107, 110, 109, 112, 111, 114, 113, 116, 115, 118, 117, 120, 119, 122, 121, 124, 123, 126, 125, 128, 127, 6, 130, 129, 132, 131, 134, 133, 136, 135, 138, 137, 140, 139, 142, 141, 144, 143, 146, 145, 148, 147, 150, 149]
2021-07-21 17:43:54,829 [INFO]: isatab.py(_longest_path_and_attrs:1091) >> [[3, 8, 7], [3, 10, 9], [3, 12, 11], [3, 14, 13], [3, 16, 15], [3, 18, 17], [3, 20, 19], [3, 22, 21], [3, 24, 23], [3, 26, 25], [3, 28, 27], [3, 30, 29], [3, 32, 31], [3, 34, 33], [3, 36, 35], [3, 38, 37], [3, 40, 39], [3, 42, 41], [3, 44, 43], [3, 46, 45], [4, 48, 47], [4, 50, 49], [4, 52, 51], [4, 54, 53], [4, 56, 55], [4, 58, 57], [4, 60, 59], [4, 62, 61], [4, 64, 63], [4, 66, 65], [4, 68, 67], [4, 70, 69], [4, 72, 71], [4, 74, 73], [4, 76, 75], [4, 78, 77], [4, 80, 79], [4, 82, 81], [4, 84, 83], [4, 86, 85], [5, 88, 87], [5, 90, 89], [5, 92, 91], [5, 94, 93], [5, 96, 95], [5, 98, 97], [5, 100, 99], [5, 102, 101], [5, 104, 103], [5, 106, 105], [5, 108, 107], [5, 110, 109], [5, 112, 111], [5, 114, 113], [5, 116, 115], [5, 118, 117], [5, 120, 119], [5, 122, 121], [5, 124, 123], [5, 126, 125], [6, 130, 129], [6, 132, 131], [6, 134, 133], [6, 136, 135], [6, 138, 137], [6, 140, 139], [6, 142, 141], [6, 144, 143], [6, 146, 145], [6, 148, 147], [6, 150, 149], [6, 128, 127]]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/var/folders/5n/rl6lqnks4rqb59pbtpvvntqw0000gr/T/ipykernel_17990/2479725034.py in <module>
      1 # print(json.dumps(investigation, cls=ISAJSONEncoder, sort_keys=True, indent=4, separators=(',', ': ')))
      2 from isatools import isatab
----> 3 isatab.dump(investigation1, final_dir)
      4 
      5 from isatools.isatab import dump_tables_to_dataframes as dumpdf

~/.pyenv/versions/3.9.0/envs/isa-api-py39/lib/python3.9/site-packages/isatools/isatab.py in dump(isa_obj, output_path, i_file_name, skip_dump_tables, write_factor_values_in_assay_table)
   1047         pass
   1048     else:
-> 1049         write_study_table_files(investigation, output_path)
   1050         write_assay_table_files(
   1051             investigation, output_path, write_factor_values_in_assay_table)

~/.pyenv/versions/3.9.0/envs/isa-api-py39/lib/python3.9/site-packages/isatools/isatab.py in write_study_table_files(inv_obj, output_dir)
   1295                         fvlabel = "{0}.Factor Value[{1}]".format(
   1296                             olabel, fv.factor_name.name)
-> 1297                         write_value_columns(df_dict, fvlabel, fv)
   1298         """if isinstance(pbar, ProgressBar):
   1299             pbar.finish()"""

~/.pyenv/versions/3.9.0/envs/isa-api-py39/lib/python3.9/site-packages/isatools/isatab.py in write_value_columns(df_dict, label, x)
   1715     if isinstance(x.value, (int, float)) and x.unit:
   1716         if isinstance(x.unit, OntologyAnnotation):
-> 1717             df_dict[label][-1] = x.value
   1718             df_dict[label + ".Unit"][-1] = x.unit.term
   1719             df_dict[label + ".Unit.Term Source REF"][-1] = \

KeyError: 'Sample Name.0.Factor Value[DURATION]'