Exemplo n.º 1
0
class ProtocolStep(Entity):
    """Steps key in the Protocol object"""

    _TAG = 'step'

    name = StringAttributeDescriptor("name")
    type = EntityDescriptor('process-type', Processtype)
    permittedcontainers = NestedStringListDescriptor('container-type',
                                                     'container-types')
    queue_fields = NestedAttributeListDescriptor('queue-field', 'queue-fields')
    step_fields = NestedAttributeListDescriptor('step-field', 'step-fields')
    sample_fields = NestedAttributeListDescriptor('sample-field',
                                                  'sample-fields')
    step_properties = NestedAttributeListDescriptor('step-property',
                                                    'step-properties')
    epp_triggers = NestedAttributeListDescriptor('epp-trigger', 'epp-triggers')
Exemplo n.º 2
0
class Project(Entity):
    "Project concerning a number of samples; associated with a researcher."

    _URI = 'projects'
    _TAG = 'project'
    _PREFIX = 'prj'

    name = StringDescriptor('name')
    open_date = StringDescriptor('open-date')
    close_date = StringDescriptor('close-date')
    invoice_date = StringDescriptor('invoice-date')
    researcher = EntityDescriptor('researcher', Researcher)
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    files = EntityListDescriptor(nsmap('file:file'), File)
    externalids = ExternalidListDescriptor()
Exemplo n.º 3
0
class ProtocolStep(Entity):
    """Steps key in the Protocol object"""

    _TAG = 'step'

    name = StringAttributeDescriptor("name")
    type = EntityDescriptor('process-type', Processtype)
    permittedcontainers = NestedStringListDescriptor('container-type',
                                                     'permitted-containers')
    permitted_control_types = NestedEntityListDescriptor(
        'control-type', ControlType, 'permitted-control-types')
    required_reagent_kits = NestedEntityListDescriptor(
        'reagent-kit', ReagentKit, 'required-reagent-kits')
    queue_fields = NestedAttributeListDescriptor('queue-field', 'queue-fields')
    step_fields = NestedAttributeListDescriptor('step-field', 'step-fields')
    sample_fields = NestedAttributeListDescriptor('sample-field',
                                                  'sample-fields')
    step_properties = NestedAttributeListDescriptor('step-property',
                                                    'step-properties')
    epp_triggers = NestedAttributeListDescriptor('epp-trigger', 'epp-triggers')
Exemplo n.º 4
0
class Container(Entity):
    "Container for analyte artifacts."

    _URI = 'containers'
    _PREFIX = 'con'

    name = StringDescriptor('name')
    type = EntityDescriptor('type', Containertype)
    occupied_wells = IntegerDescriptor('occupied-wells')
    placements = PlacementDictionaryDescriptor('placement')
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    state = StringDescriptor('state')

    def get_placements(self):
        """Get the dictionary of locations and artifacts
        using the more efficient batch call."""
        result = self.placements.copy()
        self.lims.get_batch(list(result.values()))
        return result
Exemplo n.º 5
0
class Researcher(Entity):
    "Person; client scientist or lab personnel. Associated with a lab."

    _URI = 'researchers'
    _PREFIX = 'res'

    first_name = StringDescriptor('first-name')
    last_name = StringDescriptor('last-name')
    phone = StringDescriptor('phone')
    fax = StringDescriptor('fax')
    email = StringDescriptor('email')
    initials = StringDescriptor('initials')
    lab = EntityDescriptor('lab', Lab)
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    externalids = ExternalidListDescriptor()

    # credentials XXX

    @property
    def name(self):
        return "%s %s" % (self.first_name, self.last_name)
Exemplo n.º 6
0
class Step(Entity):
    "Step, as defined by the genologics API."

    _URI = 'steps'
    _PREFIX = 'stp'

    current_state = StringAttributeDescriptor('current-state')
    _reagent_lots = EntityDescriptor('reagent-lots', StepReagentLots)
    actions = EntityDescriptor('actions', StepActions)
    placements = EntityDescriptor('placements', StepPlacements)
    details = EntityDescriptor('details', StepDetails)
    step_pools = EntityDescriptor('pools', StepPools)
    program_status = EntityDescriptor('program-status', StepProgramStatus)
    reagents = EntityDescriptor('reagents', StepReagents)

    def advance(self):
        self.get()
        self.root = self.lims.post(uri="{0}/advance".format(self.uri),
                                   data=self.lims.tostring(
                                       ElementTree.ElementTree(self.root)))

    @property
    def reagent_lots(self):
        return self._reagent_lots.reagent_lots
Exemplo n.º 7
0
class Artifact(Entity):
    "Any process input or output; analyte or file."

    _URI = 'artifacts'
    _TAG = 'artifact'
    _PREFIX = 'art'

    name = StringDescriptor('name')
    type = StringDescriptor('type')
    output_type = StringDescriptor('output-type')
    parent_process = EntityDescriptor('parent-process', Process)
    volume = StringDescriptor('volume')
    concentration = StringDescriptor('concentration')
    qc_flag = StringDescriptor('qc-flag')
    location = LocationDescriptor('location')
    working_flag = BooleanDescriptor('working-flag')
    samples = EntityListDescriptor('sample', Sample)
    udf = UdfDictionaryDescriptor()
    files = EntityListDescriptor(nsmap('file:file'), File)
    reagent_labels = ReagentLabelList()

    # artifact_flags XXX
    # artifact_groups XXX

    def input_artifact_list(self):
        """Returns the input artifact ids of the parrent process."""
        input_artifact_list = []
        try:
            for tuple in self.parent_process.input_output_maps:
                if tuple[1]['limsid'] == self.id:
                    input_artifact_list.append(tuple[0]['uri'])  # ['limsid'])
        except:
            pass
        return input_artifact_list

    def get_state(self):
        "Parse out the state value from the URI."
        parts = urlparse(self.uri)
        params = parse_qs(parts.query)
        try:
            return params['state'][0]
        except (KeyError, IndexError):
            return None

    @property
    def container(self):
        "The container where the artifact is located, or None"
        try:
            return self.location[0]
        except:
            return None

    def stateless(self):
        "returns the artefact independently of it's state"
        parts = urlparse(self.uri)
        if 'state' in parts[4]:
            stateless_uri = urlunparse(
                [parts[0], parts[1], parts[2], parts[3], '', ''])
            return Artifact(self.lims, uri=stateless_uri)
        else:
            return self

    # XXX set_state ?
    state = property(get_state)
    stateless = property(stateless)

    def _get_workflow_stages_and_statuses(self):
        self.get()
        result = []
        rootnode = self.root.find('workflow-stages')
        for node in rootnode.findall('workflow-stage'):
            result.append((Stage(self.lims, uri=node.attrib['uri']),
                           node.attrib['status'], node.attrib['name']))
        return result

    workflow_stages_and_statuses = property(_get_workflow_stages_and_statuses)
Exemplo n.º 8
0
class Process(Entity):
    "Process (instance of Processtype) executed producing ouputs from inputs."

    _URI = 'processes'
    _PREFIX = 'prc'

    type = EntityDescriptor('type', Processtype)
    date_run = StringDescriptor('date-run')
    technician = EntityDescriptor('technician', Researcher)
    protocol_name = StringDescriptor('protocol-name')
    input_output_maps = InputOutputMapList()
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    files = EntityListDescriptor(nsmap('file:file'), File)
    process_parameter = StringDescriptor('process-parameter')
    instrument = EntityDescriptor('instrument', Instrument)

    # process_parameters XXX

    def outputs_per_input(self,
                          inart,
                          ResultFile=False,
                          SharedResultFile=False,
                          Analyte=False):
        """Getting all the output artifacts related to a particual input artifact"""

        inouts = [
            io for io in self.input_output_maps if io[0]['limsid'] == inart
        ]
        if ResultFile:
            inouts = [
                io for io in inouts if io[1]['output-type'] == 'ResultFile'
            ]
        elif SharedResultFile:
            inouts = [
                io for io in inouts
                if io[1]['output-type'] == 'SharedResultFile'
            ]
        elif Analyte:
            inouts = [io for io in inouts if io[1]['output-type'] == 'Analyte']
        outs = [io[1]['uri'] for io in inouts]
        return outs

    def input_per_sample(self, sample):
        """gettiung all the input artifacts dereved from the specifyed sample"""
        ins_all = self.all_inputs()
        ins = []
        for inp in ins_all:
            for samp in inp.samples:
                if samp.name == sample and inp not in ins:
                    ins.append(inp)
        return ins

    def all_inputs(self, unique=True, resolve=False):
        """Retrieving all input artifacts from input_output_maps
        if unique is true, no duplicates are returned.
        """
        # if the process has no input, that is not standard and we want to know about it
        try:
            ids = [io[0]['limsid'] for io in self.input_output_maps]
        except TypeError:
            logger.error("Process ", self, " has no input artifacts")
            raise TypeError
        if unique:
            ids = list(frozenset(ids))
        if resolve:
            return self.lims.get_batch(
                [Artifact(self.lims, id=id) for id in ids if id is not None])
        else:
            return [Artifact(self.lims, id=id) for id in ids if id is not None]

    def all_outputs(self, unique=True, resolve=False):
        """Retrieving all output artifacts from input_output_maps
        if unique is true, no duplicates are returned.
        """
        # Given how ids is structured, io[1] might be None : some process don't have an output.
        ids = [
            io[1]['limsid'] for io in self.input_output_maps
            if io[1] is not None
        ]
        if unique:
            ids = list(frozenset(ids))
        if resolve:
            return self.lims.get_batch(
                [Artifact(self.lims, id=id) for id in ids if id is not None])
        else:
            return [Artifact(self.lims, id=id) for id in ids if id is not None]

    def shared_result_files(self):
        """Retreve all resultfiles of output-generation-type PerAllInputs."""
        artifacts = self.all_outputs(unique=True)
        return [a for a in artifacts if a.output_type == 'SharedResultFile']

    def result_files(self):
        """Retreve all resultfiles of output-generation-type perInput."""
        artifacts = self.all_outputs(unique=True)
        return [a for a in artifacts if a.output_type == 'ResultFile']

    def analytes(self):
        """Retreving the output Analytes of the process, if existing. 
        If the process is not producing any output analytes, the input 
        analytes are returned. Input/Output is returned as a information string.
        Makes aggregate processes and normal processes look the same."""
        info = 'Output'
        artifacts = self.all_outputs(unique=True)
        analytes = [a for a in artifacts if a.type == 'Analyte']
        if len(analytes) == 0:
            artifacts = self.all_inputs(unique=True)
            analytes = [a for a in artifacts if a.type == 'Analyte']
            info = 'Input'
        return analytes, info

    def parent_processes(self):
        """Retrieving all parent processes through the input artifacts"""
        return [i_a.parent_process for i_a in self.all_inputs(unique=True)]

    def output_containers(self):
        """Retrieve all unique output containers"""
        cs = []
        for o_a in self.all_outputs(unique=True):
            if o_a.container:
                cs.append(o_a.container)
        return list(frozenset(cs))

    @property
    def step(self):
        """Retrive the Step coresponding to this process. They share the same id"""
        return Step(self.lims, id=self.id)
Exemplo n.º 9
0
class Stage(Entity):
    """Holds Protocol/Workflow"""
    name = StringAttributeDescriptor('name')
    index = IntegerAttributeDescriptor('index')
    protocol = EntityDescriptor('protocol', Protocol)
    step = EntityDescriptor('step', ProtocolStep)
Exemplo n.º 10
0
        super(ReagentType, self).__init__(lims, uri, id)
        assert self.uri is not None
        self.root = lims.get(self.uri)
        self.sequence = None
        for t in self.root.findall('special-type'):
            if t.attrib.get("name") == "Index":
                for child in t.findall("attribute"):
                    if child.attrib.get("name") == "Sequence":
                        self.sequence = child.attrib.get("value")


class Queue(Entity):
    """Queue of a given step. Will recursively get all the pages of artifacts, and therefore, can be quite slow to load"""
    _URI = "queues"
    _TAG = "queue"
    _PREFIX = "que"

    artifacts = MultiPageNestedEntityListDescriptor("artifact", Artifact,
                                                    "artifacts")


Sample.artifact = EntityDescriptor('artifact', Artifact)
StepActions.step = EntityDescriptor('step', Step)
Stage.workflow = EntityDescriptor('workflow', Workflow)
Artifact.workflow_stages = NestedEntityListDescriptor('workflow-stage', Stage,
                                                      'workflow-stages')
Step.configuration = EntityDescriptor('configuration', ProtocolStep)
StepProgramStatus.configuration = EntityDescriptor('configuration',
                                                   ProtocolStep)
Researcher.roles = NestedEntityListDescriptor('role', Role, 'credentials')