Beispiel #1
0
class File(Entity):
    "File attached to a project or a sample."

    attached_to = StringDescriptor('attached-to')
    content_location = StringDescriptor('content-location')
    original_location = StringDescriptor('original-location')
    is_published = BooleanDescriptor('is-published')
Beispiel #2
0
class ProcessTypeProcessOutput(object):

    instance = None
    name = None
    root = None
    tag = ''

    artifact_type = StringDescriptor('artifact-type')
    display_name = StringDescriptor('display-name')
    output_generation_type = StringDescriptor('output-generation-type')
    variability_type = StringDescriptor('variability-type')
    number_of_outputs = IntegerDescriptor('number-of-outputs')
    output_name = StringDescriptor('output-name')
    field_definitions = EntityListDescriptor('field-definition', Udfconfig)

    def __init__(self, pt_instance, node):
        self.instance = pt_instance
        self.root = node
        self.lims = pt_instance.lims

    def __repr__(self):
        return "{0}({1})".format(self.__class__.__name__, self.output_name)

    def get(self):
        pass
Beispiel #3
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)
    date_started = StringDescriptor('date-started')
    date_completed = StringDescriptor('date-completed')
    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
Beispiel #4
0
class ReagentKit(Entity):
    """Type of Reagent with information about the provider"""
    _URI = "reagentkits"
    _TAG = "reagent-kit"
    _PREFIX = 'kit'

    name = StringDescriptor('name')
    supplier = StringDescriptor('supplier')
    website = StringDescriptor('website')
    archived = BooleanDescriptor('archived')
Beispiel #5
0
class Sample(Entity):
    "Customer's sample to be analyzed; associated with a project."

    _URI = 'samples'
    _PREFIX = 'smp'

    name = StringDescriptor('name')
    date_received = StringDescriptor('date-received')
    date_completed = StringDescriptor('date-completed')
    project = EntityDescriptor('project', Project)
    submitter = EntityDescriptor('submitter', Researcher)
    # artifact: defined below
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    notes = EntityListDescriptor('note', Note)
    files = EntityListDescriptor(nsmap('file:file'), File)
    externalids = ExternalidListDescriptor()
    # biosource XXX

    @classmethod
    def create(cls, lims, container, position, **kwargs):
        """Create an instance of Sample from attributes then post it to the LIMS

        Udfs can be sent in with the kwarg `udfs`. It should be a dictionary-like.
        """
        if not isinstance(container, Container):
            raise TypeError('%s is not of type Container' % container)
        udfs = kwargs.pop("udfs", None)
        instance = super(Sample, cls)._create(lims,
                                              creation_tag='samplecreation',
                                              **kwargs)

        location = ElementTree.SubElement(instance.root, 'location')
        ElementTree.SubElement(location, 'container', dict(uri=container.uri))
        position_element = ElementTree.SubElement(location, 'value')
        position_element.text = position

        # NOTE: This is a quick fix. I assume that it must be possible to initialize samples
        # with UDFs
        for key, value in udfs.items():
            attrib = {
                "name": key,
                "xmlns:udf": "http://genologics.com/ri/userdefined",
            }
            udf = ElementTree.SubElement(instance.root,
                                         'udf:field',
                                         attrib=attrib)
            udf.text = value

        data = lims.tostring(ElementTree.ElementTree(instance.root))
        instance.root = lims.post(uri=lims.get_uri(cls._URI), data=data)
        instance._uri = instance.root.attrib['uri']
        return instance
Beispiel #6
0
class Instrument(Entity):
    """Lab Instrument
    """
    _URI = "instruments"
    _TAG = "instrument"
    _PREFIX = "inst"

    name = StringDescriptor('name')
    type = StringDescriptor('type')
    serial_number = StringDescriptor('serial-number')
    expiry_date = StringDescriptor('expiry-date')
    archived = BooleanDescriptor('archived')
Beispiel #7
0
class Lab(Entity):
    "Lab; container of researchers."

    _URI = 'labs'
    _PREFIX = 'lab'

    name = StringDescriptor('name')
    billing_address = StringDictionaryDescriptor('billing-address')
    shipping_address = StringDictionaryDescriptor('shipping-address')
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    externalids = ExternalidListDescriptor()
    website = StringDescriptor('website')
class Controltype(Entity):
    """Control sample."""

    _URI = 'controltypes'
    _TAG = 'control-type'
    _PREFIX = 'ctrltp'

    name = StringAttributeDescriptor('name')
    supplier = StringDescriptor('supplier')
    catalogue_number = StringDescriptor('catalogue-number')
    website = StringDescriptor('website')
    concentration = StringDescriptor('concentration')
    archived = BooleanDescriptor('archived')
    single_step = BooleanDescriptor('single-step')
Beispiel #9
0
class Project(Entity):
    "Project concerning a number of samples; associated with a researcher."

    _URI = 'projects'
    _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()
Beispiel #10
0
class Udfconfig(Entity):
    "Instance of field type (cnf namespace)."
    _URI = 'configuration/udfs'

    name = StringDescriptor('name')
    attach_to_name = StringDescriptor('attach-to-name')
    attach_to_category = StringDescriptor('attach-to-category')
    show_in_lablink = BooleanDescriptor('show-in-lablink')
    allow_non_preset_values = BooleanDescriptor('allow-non-preset-values')
    first_preset_is_default_value = BooleanDescriptor(
        'first-preset-is-default-value')
    show_in_tables = BooleanDescriptor('show-in-tables')
    is_editable = BooleanDescriptor('is-editable')
    is_deviation = BooleanDescriptor('is-deviation')
    is_controlled_vocabulary = BooleanDescriptor('is-controlled-vocabulary')
    presets = StringListDescriptor('preset')
Beispiel #11
0
class Role(Entity):
    """Clarity Role, hosting permissions"""
    name = StringDescriptor('name')
    researchers = NestedEntityListDescriptor('researcher', Researcher,
                                             'researchers')
    permissions = NestedEntityListDescriptor('permission', Permission,
                                             'permissions')
class ProcessTypeProcessInput(object):

    instance = None
    name = None
    root = None
    tag = ''

    artifact_type = StringDescriptor('artifact-type')
    display_name = StringDescriptor('display-name')
    remove_working_flag = BooleanDescriptor('remove-working-flag')

    def __init__(self, pt_instance, node):
        self.instance = pt_instance
        self.root = node

    def get(self):
        pass
Beispiel #13
0
class ControlType(Entity):
    _URI = "controltypes"
    _TAG = "control-type"
    _PREFIX = 'ctrltp'

    name = StringAttributeDescriptor('name')
    supplier = StringDescriptor('supplier')
    archived = BooleanDescriptor('archived')
    single_step = BooleanDescriptor('single_step')
Beispiel #14
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
class ProcessTypeParameter(object):

    instance = None
    name = None
    root = None
    tag = 'parameter'

    string = StringDescriptor('string')
    run_program_per_event = StringDescriptor('run-program-per-event')
    channel = StringDescriptor('channel')
    invocation_type = StringDescriptor('invocation-type')
    file = EntityListDescriptor(nsmap('file:file'), File)

    def __init__(self, pt_instance, node):
        self.instance = pt_instance
        self.root = node
        self.name = self.root.attrib['name']

    def get(self):
        pass
class ProcessTypeProcessOutput(object):

    instance = None
    name = None
    root = None
    tag = ''

    artifact_type = StringDescriptor('artifact-type')
    display_name = StringDescriptor('display-name')
    output_generation_type = StringDescriptor('output-generation-type')
    variability_type = StringDescriptor('variability-type')
    number_of_outputs = IntegerDescriptor('number-of-outputs')
    output_name = StringDescriptor('output-name')

    def __init__(self, pt_instance, node):
        self.instance = pt_instance
        self.root = node

    def get(self):
        pass
class Sample(Entity):
    "Customer's sample to be analyzed; associated with a project."

    _URI = 'samples'
    _TAG = 'sample'
    _PREFIX = 'smp'

    name = StringDescriptor('name')
    date_received = StringDescriptor('date-received')
    date_completed = StringDescriptor('date-completed')
    project = EntityDescriptor('project', Project)
    submitter = EntityDescriptor('submitter', Researcher)
    # artifact: defined below
    udf = UdfDictionaryDescriptor()
    udt = UdtDictionaryDescriptor()
    notes = EntityListDescriptor('note', Note)
    files = EntityListDescriptor(nsmap('file:file'), File)
    externalids = ExternalidListDescriptor()
    # biosource XXX
    control_type = EntityDescriptor('control-type', Controltype)

    @classmethod
    def create(cls, lims, container, position, udfs=None, **kwargs):
        """Create an instance of Sample from attributes then post it to the LIMS"""
        if udfs is None:
            udfs = {}
        if not isinstance(container, Container):
            raise TypeError('%s is not of type Container' % container)
        instance = super(Sample, cls)._create(lims,
                                              creation_tag='samplecreation',
                                              udfs=udfs,
                                              **kwargs)

        location = ElementTree.SubElement(instance.root, 'location')
        ElementTree.SubElement(location, 'container', dict(uri=container.uri))
        position_element = ElementTree.SubElement(location, 'value')
        position_element.text = position
        data = lims.tostring(ElementTree.ElementTree(instance.root))
        instance.root = lims.post(uri=lims.get_uri(cls._URI), data=data)
        instance._uri = instance.root.attrib['uri']
        return instance
Beispiel #18
0
class ProcessTypeProcessInput(object):

    instance = None
    name = None
    root = None
    tag = ''

    artifact_type = StringDescriptor('artifact-type')
    display_name = StringDescriptor('display-name')
    remove_working_flag = BooleanDescriptor('remove-working-flag')

    def __init__(self, pt_instance, node):
        self.instance = pt_instance
        self.root = node
        self.lims = pt_instance.lims

    def __repr__(self):
        return "{0}({1})".format(self.__class__.__name__, self.display_name)

    def get(self):
        pass
Beispiel #19
0
class ReagentType(Entity):
    """Reagent Type, usually, indexes for sequencing"""
    _URI = "reagenttypes"
    _TAG = "reagent-type"
    _PREFIX = 'rtp'

    category = StringDescriptor('reagent-category')

    def __init__(self, lims, uri=None, id=None):
        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")
Beispiel #20
0
class ReagentLot(Entity):
    """Reagent Lots contain information about a particualr lot of reagent used in a step"""
    _URI = "reagentlots"
    _TAG = "reagent-lot"
    _PREFIX = 'lot'

    reagent_kit = EntityDescriptor('reagent-kit', ReagentKit)
    name = StringDescriptor('name')
    lot_number = StringDescriptor('lot-number')
    created_date = StringDescriptor('created-date')
    last_modified_date = StringDescriptor('last-modified-date')
    expiry_date = StringDescriptor('expiry-date')
    created_by = EntityDescriptor('created-by', Researcher)
    last_modified_by = EntityDescriptor('last-modified-by', Researcher)
    status = StringDescriptor('status')
    usage_count = IntegerDescriptor('usage-count')
Beispiel #21
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)
Beispiel #22
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)
Beispiel #23
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)
Beispiel #24
0
class StepProgramStatus(Entity):
    """Allows custom handling of program status.
    message supports HTML. Cross handling of EPPs is possible.
    Supports PUT"""
    status = StringDescriptor('status')
    message = StringDescriptor('message')
Beispiel #25
0
class Note(Entity):
    "Note attached to a project or a sample."

    content = StringDescriptor(None)  # root element
Beispiel #26
0
class Reagent_label(Entity):
    """Reagent label element"""
    reagent_label = StringDescriptor('reagent-label')
Beispiel #27
0
class StepReagents(Entity):

    reagent_category = StringDescriptor('reagent-category')
    output_reagents = OutputReagentList(Artifact)
Beispiel #28
0
class Permission(Entity):
    """A Clarity permission. Only supports GET"""
    name = StringDescriptor('name')
    action = StringDescriptor('action')
    description = StringDescriptor('description')