Esempio n. 1
0
    def test_set_placements_list(self):
        a1 = Artifact(uri='http://testgenologics.com:4040/artifacts/a1', lims=self.lims)
        a2 = Artifact(uri='http://testgenologics.com:4040/artifacts/a2', lims=self.lims)
        c1 = Container(uri='http://testgenologics.com:4040/containers/c1', lims=self.lims)
        c2 = Container(uri='http://testgenologics.com:4040/containers/c2', lims=self.lims)

        s = StepPlacements(uri=self.lims.get_uri('steps', 's1', 'placements'), lims=self.lims)
        with patch('requests.Session.get',
                   return_value=Mock(content=self.original_step_placements_xml, status_code=200)):
            new_placements = [[a1, (c1, '3:1')], [a2, (c1, '4:1')]]
            s.set_placement_list(new_placements)
            assert elements_equal(s.root, ElementTree.fromstring(self.modloc_step_placements_xml))
Esempio n. 2
0
def copy_layout(lims, process_id):
    """Copy placement layout from previous steps."""
    process = Process(lims, id=process_id)
    used_placements = []
    # Get parent container layout
    parent_container = None
    for parent_process in process.parent_processes():
        if parent_process:
            for container in parent_process.output_containers():
                if container.type != Containertype(lims, id='2'):  # skip tubes
                    parent_container = container

    if parent_container:
        parent_placements = {}
        for placement in parent_container.placements:
            sample = parent_container.placements[placement].samples[0].name
            parent_placements[sample] = placement

        # Create new container and copy layout
        new_container = Container.create(lims, type=parent_container.type)
        placement_list = []
        for artifact in process.analytes()[0]:
            sample_name = artifact.samples[0].name
            if sample_name in parent_placements:
                placement = parent_placements[sample_name]
                if placement not in used_placements:
                    placement_list.append([artifact, (new_container, placement)])
                    used_placements.append(placement)

        process.step.placements.set_placement_list(placement_list)
        process.step.placements.post()
Esempio n. 3
0
 def __get__(self, instance, cls):
     from genologics.entities import Container
     instance.get()
     node = instance.root.find(self.tag)
     if node is None:
         return (None, None)
     uri = node.find('container').attrib['uri']
     return Container(instance.lims, uri=uri), node.find('value').text
Esempio n. 4
0
 def save_containers(self, container_details: ObjectifiedElement):
     """Save a batch of containers."""
     container_uri = f"{self.get_uri()}/containers/batch/create"
     results = self.save_xml(container_uri, container_details)
     container_map = {}
     for link in results.findall("link"):
         lims_container = Container(self, uri=link.attrib["uri"])
         container_map[lims_container.name] = lims_container
     return container_map
Esempio n. 5
0
 def test_get_placements_list(self):
     s = StepPlacements(uri=self.lims.get_uri('steps', 's1', 'placements'), lims=self.lims)
     with patch('requests.Session.get',
                return_value=Mock(content=self.original_step_placements_xml, status_code=200)):
         a1 = Artifact(uri='http://testgenologics.com:4040/artifacts/a1', lims=self.lims)
         a2 = Artifact(uri='http://testgenologics.com:4040/artifacts/a2', lims=self.lims)
         c1 = Container(uri='http://testgenologics.com:4040/containers/c1', lims=self.lims)
         expected_placements = [[a1, (c1, '1:1')], [a2, (c1, '2:1')]]
         assert s.get_placement_list() == expected_placements
Esempio n. 6
0
def submit_dx_samples():
    form = SubmitDXSampleForm()

    if form.validate_on_submit():
        container_type = Containertype(lims, id='2')  # Tube
        workflow = Workflow(lims, id=app.config['LIMS_DX_SAMPLE_SUBMIT_WORKFLOW'])

        for sample_name in form.parsed_samples:
            # Get or create project
            lims_projects = lims.get_projects(name=form.parsed_samples[sample_name]['project'])
            if not lims_projects:
                lims_project = Project.create(lims, name=form.parsed_samples[sample_name]['project'], researcher=form.researcher, udf={'Application': 'DX'})
            else:
                lims_project = lims_projects[0]

            # Set sample udf data
            udf_data = form.parsed_worklist[sample_name]
            udf_data['Sample Type'] = form.parsed_samples[sample_name]['type']
            udf_data['Dx Fragmentlengte (bp) Externe meting'] = form.pool_fragment_length.data
            udf_data['Dx Conc. (ng/ul) Externe meting'] = form.pool_concentration.data
            udf_data['Dx Exoomequivalent'] = form.parsed_samples[sample_name]['exome_count']

            # Create sample
            container = Container.create(lims, type=container_type, name=udf_data['Dx Fractienummer'])
            sample = Sample.create(lims, container=container, position='1:1', project=lims_project, name=sample_name, udf=udf_data)
            print sample.name, sample.artifact.name

            # Add reagent label (barcode)
            artifact = sample.artifact
            artifact_xml_dom = minidom.parseString(artifact.xml())

            for artifact_name_node in artifact_xml_dom.getElementsByTagName('name'):
                parent = artifact_name_node.parentNode
                reagent_label = artifact_xml_dom.createElement('reagent-label')
                reagent_label.setAttribute('name', form.parsed_samples[sample_name]['barcode'])
                parent.appendChild(reagent_label)
                lims.put(artifact.uri, artifact_xml_dom.toxml(encoding='utf-8'))

            lims.route_artifacts([sample.artifact], workflow_uri=workflow.uri)

        return render_template('submit_dx_samples_done.html', title='Submit DX samples', project_name=lims_project.name, form=form)
    return render_template('submit_dx_samples.html', title='Submit DX samples', form=form)
Esempio n. 7
0
 def test_create_entity(self):
     with patch('genologics.lims.requests.post',
                return_value=Mock(content=self.sample_creation, status_code=201)) as patch_post:
         l = Sample.create(
             self.lims,
             project=Project(self.lims, uri='project'),
             container=Container(self.lims, uri='container'),
             position='1:1',
             name='s1',
         )
         data = '''<?xml version=\'1.0\' encoding=\'utf-8\'?>
         <smp:samplecreation xmlns:smp="http://genologics.com/ri/sample">
         <name>s1</name>
         <project uri="project" limsid="project" />
         <location>
           <container uri="container" />
           <value>1:1</value>
         </location>
         </smp:samplecreation>'''
         assert elements_equal(ElementTree.fromstring(patch_post.call_args_list[0][1]['data']),
                               ElementTree.fromstring(data))
Esempio n. 8
0
    def get(self):
        limsl = lims.Lims(BASEURI, USERNAME, PASSWORD)
        #qPCR queues
        queues = {}
        queues['MiSeq'] = Queue(limsl, id='1002')
        queues['NovaSeq'] = Queue(limsl, id='1666')
        queues['LibraryValidation'] = Queue(limsl, id='41')

        methods = queues.keys()
        pools = {}

        for method in methods:
            pools[method] = {}
            if queues[method].artifacts:
                tree = ET.fromstring(queues[method].xml())
                if tree.find('next-page') is not None:
                    flag = True
                    next_page_uri = tree.find('next-page').attrib['uri']
                    while flag:
                        next_page = ET.fromstring(
                            Queue(limsl, uri=next_page_uri).xml())
                        for elem in next_page.findall('artifacts'):
                            tree.insert(0, elem)
                        if next_page.find('next-page') is not None:
                            next_page_uri = next_page.find(
                                'next-page').attrib['uri']
                        else:
                            flag = False
                for artifact in tree.iter('artifact'):
                    queue_time = artifact.find('queue-time').text
                    container = Container(limsl,
                                          uri=artifact.find('location').find(
                                              'container').attrib['uri']).name
                    art = Artifact(limsl, uri=artifact.attrib['uri'])
                    value = artifact.find('location').find('value').text
                    library_type = ''
                    runmode = ''
                    if not 'lambda DNA' in art.name:
                        library_type = art.samples[0].project.udf[
                            "Library construction method"]
                        try:
                            runmode = art.samples[0].project.udf[
                                'Sequencing platform']
                        except KeyError:
                            runmode = 'NA'
                    if container in pools[method]:
                        pools[method][container]['samples'].append({
                            'name':
                            art.name,
                            'well':
                            value,
                            'queue_time':
                            queue_time
                        })
                        if library_type and library_type not in pools[method][
                                container]['library_types']:
                            pools[method][container]['library_types'].append(
                                library_type)
                        if runmode and runmode not in pools[method][container][
                                'runmodes']:
                            pools[method][container]['runmodes'].append(
                                runmode)
                    else:
                        pools[method][container] = {
                            'samples': [{
                                'name': art.name,
                                'well': value,
                                'queue_time': queue_time
                            }],
                            'library_types': [library_type],
                            'runmodes': [runmode]
                        }

        self.set_header("Content-type", "application/json")
        self.write(json.dumps(pools))
Esempio n. 9
0
    def get(self):
        limsl = lims.Lims(BASEURI, USERNAME, PASSWORD)
        #sequencing queues are currently taken as the following
        #Miseq- Step 7: Denature, Dilute and load sample
        #Novaseq Step 11: Load to flow cell
        queues = {}
        queues['MiSeq'] = Queue(limsl, id='55')
        queues['NovaSeq'] = Queue(limsl, id='1662')

        methods = queues.keys()
        pools = {}

        for method in methods:
            pools[method] = {}
            if queues[method].artifacts:
                tree = ET.fromstring(queues[method].xml())
                for artifact in tree.iter('artifact'):
                    queue_time = artifact.find('queue-time').text
                    container = Container(limsl,
                                          uri=artifact.find('location').find(
                                              'container').attrib['uri']).name
                    attr_name = Artifact(limsl,
                                         uri=artifact.attrib['uri']).name
                    value = artifact.find('location').find('value').text
                    proj_and_samples = {}
                    conc_qpcr = ''
                    is_rerun = False
                    art = Artifact(limsl, uri=artifact.attrib['uri'])
                    if method is 'MiSeq':
                        #FinishedLibrary
                        if 'Concentration' in dict(art.udf.items()).keys():
                            conc_qpcr = art.udf['Concentration']
                        #InhouseLibrary
                        elif 'Pool Conc. (nM)' in dict(art.udf.items()).keys():
                            conc_qpcr = str(art.udf['Pool Conc. (nM)'])
                        else:
                            pass
                        is_rerun = art.udf["Rerun"]
                    elif method is 'NovaSeq':
                        if 'Concentration' in dict(art.udf.items()).keys():
                            conc_qpcr = art.udf["Concentration"]
                            if 'Rerun' in dict(art.udf.items()).keys():
                                is_rerun = art.udf["Rerun"]
                        else:
                            new_art = art.parent_process.input_output_maps[0][
                                0]
                            # The loop iterates 4 times as the values were found within the first 4 preceding
                            # parent processes(through trial and error). If the values are not found within 4 iterations, they can be looked up
                            # manually in LIMS. The loop is structured so as its not very clear in the genologics API which of the parent processes
                            # will contain the values in post process and 4 seemed to get everything for the data at hand.
                            i = 0
                            while i < 4:
                                if 'Concentration' in dict(
                                        new_art['post-process-uri'].udf.items(
                                        )).keys():
                                    conc_qpcr = new_art[
                                        'post-process-uri'].udf[
                                            "Concentration"]
                                    if 'Rerun' in dict(
                                            new_art['post-process-uri'].udf.
                                            items()).keys():
                                        is_rerun = new_art[
                                            'post-process-uri'].udf["Rerun"]
                                    break
                                else:
                                    new_art = new_art[
                                        'parent-process'].input_output_maps[0][
                                            0]
                                    i = i + 1

                    for sample in art.samples:
                        project = sample.project.id
                        if project in pools[method]:
                            if container in pools[method][project]['plates']:
                                pools[method][project]['plates'][container][
                                    'samples'].append(sample.name)
                            else:
                                pools[method][project]['plates'][container] = {
                                    'samples': [sample.name],
                                    'well': value,
                                    'queue_time': queue_time,
                                    'conc_pool_qpcr': conc_qpcr,
                                    'is_rerun': is_rerun
                                }
                        else:
                            setup = sample.project.udf['Sequencing setup']
                            lanes = sample.project.udf[
                                'Sequence units ordered (lanes)']
                            librarytype = sample.project.udf[
                                'Library construction method']
                            runmode = sample.project.udf['Sequencing platform']
                            final_loading_conc = 'TBD'
                            if method is 'NovaSeq':
                                try:
                                    final_loading_conc = Artifact(
                                        limsl, uri=artifact.attrib['uri']
                                    ).udf['Final Loading Concentration (pM)']
                                except KeyError:
                                    pass
                            pools[method][project] = {
                                'name': sample.project.name,
                                'setup': setup,
                                'lanes': lanes,
                                'runmode': runmode,
                                'final_loading_conc': final_loading_conc,
                                'librarytype': librarytype,
                                'plates': {
                                    container: {
                                        'samples': [sample.name],
                                        'well': value,
                                        'queue_time': queue_time,
                                        'conc_pool_qpcr': conc_qpcr,
                                        'is_rerun': is_rerun
                                    }
                                }
                            }
        self.set_header("Content-type", "application/json")
        self.write(json.dumps(pools))
Esempio n. 10
0
    def get(self):
        limsl = lims.Lims(BASEURI, USERNAME, PASSWORD)
        #qPCR queues
        queues = {}
        queues['MiSeq'] = Queue(limsl, id='1002')
        queues['NovaSeq'] = Queue(limsl, id='1666')
        queues['LibraryValidation'] = Queue(limsl, id='41')

        methods = queues.keys()
        pools = {}
        qpcr_control_names = [
            'AM7852', 'E.Coli genDNA', 'Endogenous Positive Control',
            'Exogenous Positive Control', 'Human Brain Reference RNA',
            'lambda DNA', 'mQ Negative Control', 'NA10860', 'NA11992',
            'NA11993', 'NA12878', 'NA12891', 'NA12892',
            'No Amplification Control', 'No Reverse Transcriptase Control',
            'No Template Control', 'PhiX v3', 'Universal Human Reference RNA',
            'lambda DNA (qPCR)'
        ]
        for method in methods:
            pools[method] = {}
            if queues[method].artifacts:
                tree = ET.fromstring(queues[method].xml())
                if tree.find('next-page') is not None:
                    flag = True
                    next_page_uri = tree.find('next-page').attrib['uri']
                    while flag:
                        next_page = ET.fromstring(
                            Queue(limsl, uri=next_page_uri).xml())
                        for elem in next_page.findall('artifacts'):
                            tree.insert(0, elem)
                        if next_page.find('next-page') is not None:
                            next_page_uri = next_page.find(
                                'next-page').attrib['uri']
                        else:
                            flag = False
                for artifact in tree.iter('artifact'):
                    queue_time = artifact.find('queue-time').text
                    container = Container(limsl,
                                          uri=artifact.find('location').find(
                                              'container').attrib['uri']).name
                    art = Artifact(limsl, uri=artifact.attrib['uri'])
                    value = artifact.find('location').find('value').text
                    library_type = ''
                    runmode = ''

                    #skip if the Artifact is a control
                    if art.name in qpcr_control_names:
                        continue

                    library_type = art.samples[0].project.udf.get(
                        "Library construction method", 'NA')
                    try:
                        runmode = art.samples[0].project.udf[
                            'Sequencing platform']
                    except KeyError:
                        runmode = 'NA'
                    if container in pools[method]:
                        pools[method][container]['samples'].append({
                            'name':
                            art.name,
                            'well':
                            value,
                            'queue_time':
                            queue_time
                        })
                        if library_type and library_type not in pools[method][
                                container]['library_types']:
                            pools[method][container]['library_types'].append(
                                library_type)
                        if runmode and runmode not in pools[method][container][
                                'runmodes']:
                            pools[method][container]['runmodes'].append(
                                runmode)
                    else:
                        pools[method][container] = {
                            'samples': [{
                                'name': art.name,
                                'well': value,
                                'queue_time': queue_time
                            }],
                            'library_types': [library_type],
                            'runmodes': [runmode]
                        }

        self.set_header("Content-type", "application/json")
        self.write(json.dumps(pools))
Esempio n. 11
0
def from_helix(lims, email_settings, input_file):
    """Upload samples from helix export file."""
    project_name = 'Dx {filename}'.format(filename=input_file.name.rstrip('.csv').split('/')[-1])
    helix_initials = project_name.split('_')[-1]

    # Try lims connection
    try:
        lims.check_version()
    except ConnectionError:
        subject = "ERROR Lims Helix Upload: {0}".format(project_name)
        message = "Can't connect to lims server, please contact a lims administrator."
        send_email(email_settings['server'], email_settings['from'], email_settings['to_import_helix'], subject, message)
        sys.exit(message)

    # Get researcher using helix initials
    for researcher in lims.get_researchers():
        if researcher.fax == helix_initials:  # Use FAX as intials field as the lims initials field can't be edited via the 5.0 web interface.
            email_settings['to_import_helix'].append(researcher.email)
            break
    else:   # No researcher found
        subject = "ERROR Lims Helix Upload: {0}".format(project_name)
        message = "Can't find researcher with initials: {0}.".format(helix_initials)
        send_email(email_settings['server'], email_settings['from'], email_settings['to_import_helix'], subject, message)
        sys.exit(message)

    # Create project
    if not lims.get_projects(name=project_name):
        project = Project.create(lims, name=project_name, researcher=researcher, udf={'Application': 'DX'})
    else:
        subject = "ERROR Lims Helix Upload: {0}".format(project_name)
        message = "Duplicate project / werklijst. Samples not loaded."
        send_email(email_settings['server'], email_settings['from'], email_settings['to_import_helix'], subject, message)
        sys.exit(message)

    container_type = Containertype(lims, id='2')  # Tube

    # match header and udf fields
    udf_column = {
        'Dx Onderzoeknummer': {'column': 'Onderzoeknummer'},
        'Dx Fractienummer': {'column': 'Fractienummer'},
        'Dx Monsternummer': {'column': 'Monsternummer'},
        'Dx Concentratie (ng/ul)': {'column': 'Concentratie (ng/ul)'},
        'Dx Materiaal type': {'column': 'Materiaal'},
        'Dx Foetus': {'column': 'Foetus'},
        'Dx Foetus ID': {'column': 'Foet_id'},
        'Dx Foetus geslacht': {'column': 'Foetus_geslacht'},
        'Dx Overleden': {'column': 'Overleden'},
        'Dx Opslaglocatie': {'column': 'Opslagpositie'},
        'Dx Spoed': {'column': 'Spoed'},
        'Dx NICU Spoed': {'column': 'NICU Spoed'},
        'Dx Persoons ID': {'column': 'Persoons_id'},
        'Dx Werklijstnummer': {'column': 'Werklijstnummer'},
        'Dx Familienummer': {'column': 'Familienummer'},
        'Dx Geslacht': {'column': 'Geslacht'},
        'Dx Geboortejaar': {'column': 'Geboortejaar'},
        'Dx Meet ID': {'column': 'Stof_meet_id'},
        'Dx Stoftest code': {'column': 'Stoftestcode'},
        'Dx Stoftest omschrijving': {'column': 'Stoftestomschrijving'},
        'Dx Onderzoeksindicatie': {'column': 'Onderzoeksindicatie'},
        'Dx Onderzoeksreden': {'column': 'Onderzoeksreden'},
        'Dx Protocolcode': {'column': 'Protocolcode'},
        'Dx Protocolomschrijving': {'column': 'Protocolomschrijving'},
        'Dx Einddatum': {'column': 'Einddatum'},
        'Dx Gerelateerde onderzoeken': {'column': 'Gerelateerde onderzoeken'},
    }
    header = input_file.readline().rstrip().split(',')  # expect header on first line
    for udf in udf_column:
        udf_column[udf]['index'] = header.index(udf_column[udf]['column'])

    # Setup email
    subject = "Lims Helix Upload: {0}".format(project_name)
    message = "Project: {0}\n\nSamples:\n".format(project_name)

    # Parse samples
    for line in input_file:
        data = line.rstrip().strip('"').split('","')

        udf_data = {'Sample Type': 'DNA isolated', 'Dx Import warning': ''}  # required lims input
        for udf in udf_column:
            # Transform specific udf
            if udf in ['Dx Overleden', 'Dx Spoed', 'Dx NICU Spoed']:
                udf_data[udf] = clarity_epp.upload.utils.char_to_bool(data[udf_column[udf]['index']])
            elif udf in ['Dx Geslacht', 'Dx Foetus geslacht']:
                udf_data[udf] = clarity_epp.upload.utils.transform_sex(data[udf_column[udf]['index']])
            elif udf == 'Dx Foetus':
                udf_data[udf] = bool(data[udf_column[udf]['index']].strip())
            elif udf == 'Dx Concentratie (ng/ul)':
                udf_data[udf] = data[udf_column[udf]['index']].replace(',', '.')
            elif udf in ['Dx Monsternummer', 'Dx Fractienummer']:
                udf_data[udf] = clarity_epp.upload.utils.transform_sample_name(data[udf_column[udf]['index']])
            elif udf == 'Dx Gerelateerde onderzoeken':
                udf_data[udf] = data[udf_column[udf]['index']].replace(',', ';')
            elif udf == 'Dx Einddatum':
                date = datetime.strptime(data[udf_column[udf]['index']], '%d-%m-%Y')  # Helix format (14-01-2021)
                udf_data[udf] = date.strftime('%Y-%m-%d')  # LIMS format (2021-01-14)
            else:
                udf_data[udf] = data[udf_column[udf]['index']]

        sample_name = udf_data['Dx Monsternummer']

        # Set 'Dx Handmatig' udf
        if udf_data['Dx Foetus'] or udf_data['Dx Overleden'] or udf_data['Dx Materiaal type'] not in ['BL', 'BLHEP', 'BM', 'BMEDTA']:
            udf_data['Dx Handmatig'] = True
        else:
            udf_data['Dx Handmatig'] = False

        # Set 'Dx Familie status' udf
        if udf_data['Dx Onderzoeksreden'] == 'Bevestiging diagnose':
            udf_data['Dx Familie status'] = 'Kind'
        elif udf_data['Dx Onderzoeksreden'] == 'Prenataal onderzoek':
            udf_data['Dx Familie status'] = 'Kind'
        elif udf_data['Dx Onderzoeksreden'] == 'Eerstegraads-verwantenond':
            udf_data['Dx Familie status'] = 'Kind'
        elif udf_data['Dx Onderzoeksreden'] == 'Partneronderzoek':
            udf_data['Dx Familie status'] = 'Kind'
        elif udf_data['Dx Onderzoeksreden'] == 'Informativiteitstest':
            udf_data['Dx Familie status'] = 'Ouder'
        else:
            udf_data['Dx Import warning'] = ';'.join(['Onbekende onderzoeksreden, familie status niet ingevuld.', udf_data['Dx Import warning']])

        # Set 'Dx Geslacht' and 'Dx Geboortejaar' with 'Foetus' information if 'Dx Foetus == True'
        if udf_data['Dx Foetus']:
            udf_data['Dx Geslacht'] = udf_data['Dx Foetus geslacht']
            udf_data['Dx Geboortejaar'] = ''

        # Set 'Dx Geslacht = Onbekend' if 'Dx Onderzoeksindicatie == DSD00'
        if udf_data['Dx Onderzoeksindicatie'] == 'DSD00' and udf_data['Dx Familie status'] == 'Kind':
            udf_data['Dx Geslacht'] = 'Onbekend'

        # Check 'Dx Familienummer' and correct
        if '/' in udf_data['Dx Familienummer']:
            udf_data['Dx Import warning'] = ';'.join([
                'Meerdere familienummers, laatste wordt gebruikt. ({0})'.format(udf_data['Dx Familienummer']),
                udf_data['Dx Import warning']
            ])
            udf_data['Dx Familienummer'] = udf_data['Dx Familienummer'].split('/')[-1].strip(' ')

        sample_list = lims.get_samples(name=sample_name)

        if sample_list:
            sample = sample_list[0]
            if udf_data['Dx Protocolomschrijving'] in sample.udf['Dx Protocolomschrijving']:
                message += "{0}\tERROR: Duplicate sample and Protocolomschrijving code: {1}.\n".format(sample_name, udf_data['Dx Protocolomschrijving'])
            else:
                # Update existing sample if new Protocolomschrijving and thus workflow.

                # Append udf fields
                append_udf = [
                    'Dx Onderzoeknummer', 'Dx Onderzoeksindicatie', 'Dx Onderzoeksreden', 'Dx Werklijstnummer', 'Dx Protocolcode', 'Dx Protocolomschrijving',
                    'Dx Meet ID', 'Dx Stoftest code', 'Dx Stoftest omschrijving'
                ]
                for udf in append_udf:
                    sample.udf[udf] = ';'.join([udf_data[udf], str(sample.udf[udf])])

                # Update udf fields
                update_udf = ['Dx Overleden', 'Dx Spoed', 'Dx NICU Spoed', 'Dx Handmatig', 'Dx Opslaglocatie', 'Dx Import warning']
                for udf in update_udf:
                    sample.udf[udf] = udf_data[udf]

                # Add to new workflow
                workflow = clarity_epp.upload.utils.stoftestcode_to_workflow(lims, udf_data['Dx Stoftest code'])
                if workflow:
                    sample.put()
                    lims.route_artifacts([sample.artifact], workflow_uri=workflow.uri)
                    message += "{0}\tUpdated and added to workflow: {1}.\n".format(sample.name, workflow.name)
                else:
                    message += "{0}\tERROR: Stoftest code {1} is not linked to a workflow.\n".format(sample.name, udf_data['Dx Stoftest code'])

        else:
            # Check other samples from patient
            sample_list = lims.get_samples(udf={'Dx Persoons ID': udf_data['Dx Persoons ID']})
            for sample in sample_list:
                if sample.udf['Dx Protocolomschrijving'] == udf_data['Dx Protocolomschrijving'] and sample.udf['Dx Foetus'] == udf_data['Dx Foetus']:
                    udf_data['Dx Import warning'] = ';'.join(['Onderzoek reeds uitgevoerd.', udf_data['Dx Import warning']])

            # Add sample to workflow
            workflow = clarity_epp.upload.utils.stoftestcode_to_workflow(lims, udf_data['Dx Stoftest code'])
            if workflow:
                container = Container.create(lims, type=container_type, name=udf_data['Dx Fractienummer'])
                sample = Sample.create(lims, container=container, position='1:1', project=project, name=sample_name, udf=udf_data)
                lims.route_artifacts([sample.artifact], workflow_uri=workflow.uri)
                message += "{0}\tCreated and added to workflow: {1}.\n".format(sample.name, workflow.name)
            else:
                message += "{0}\tERROR: Stoftest code {1} is not linked to a workflow.\n".format(sample_name, udf_data['Dx Stoftest code'])

    # Send final email
    send_email(email_settings['server'], email_settings['from'], email_settings['to_import_helix'], subject, message)
Esempio n. 12
0
def submit_samples():
    form = SubmitSampleForm()

    if form.validate_on_submit():
        # Create lims project
        lims_project = Project.create(
            lims,
            name=app.config['LIMS_INDICATIONS'][form.indicationcode.data]['project_name_prefix'],
            researcher=form.researcher,
            udf={'Application': form.indicationcode.data}
        )
        lims_project.name = '{0}_{1}'.format(lims_project.name, lims_project.id)
        lims_project.put()

        # Save attachment
        attachment = form.attachment.data
        if attachment:
            temp_dir = mkdtemp()
            attachment_path = path.join(temp_dir, secure_filename(attachment.filename))
            attachment.save(attachment_path)
            print attachment_path
            lims.upload_new_file(lims_project, attachment_path)
            rmtree(temp_dir)

        # Create Samples
        lims_container_type = Containertype(lims, id='2')  # Tube
        sample_artifacts = []
        for sample in form.parsed_samples:
            lims_container = Container.create(lims, type=lims_container_type, name=sample['name'])
            sample_udf_data = {
                'Sample Type': 'DNA library',
                'Dx Fragmentlengte (bp) Externe meting': form.pool_fragment_length.data,
                'Dx Conc. (ng/ul) Externe meting': form.pool_concentration.data,
                'Dx Exoomequivalent': sample['exome_count'],
            }
            lims_sample = Sample.create(lims, container=lims_container, position='1:1', project=lims_project, name=sample['name'], udf=sample_udf_data)
            print lims_sample.name, lims_sample.artifact.name
            artifact = lims_sample.artifact
            sample_artifacts.append(artifact)

            # Add reagent label (barcode)
            artifact_xml_dom = minidom.parseString(artifact.xml())
            for artifact_name_node in artifact_xml_dom.getElementsByTagName('name'):
                parent = artifact_name_node.parentNode
                reagent_label = artifact_xml_dom.createElement('reagent-label')
                reagent_label.setAttribute('name', sample['barcode'])
                parent.appendChild(reagent_label)
                lims.put(artifact.uri, artifact_xml_dom.toxml(encoding='utf-8'))

        # Route artifacts to workflow
        workflow = Workflow(lims, id=app.config['LIMS_INDICATIONS'][form.indicationcode.data]['workflow_id'])
        lims.route_artifacts(sample_artifacts, workflow_uri=workflow.uri)

        # Send email
        subject = "Clarity Portal Sample Upload - {0}".format(lims_project.name)
        message = "Gebruikersnaam\t{0}\n".format(form.username.data)
        message += "Indicatie code\t{0}\n".format(form.indicationcode.data)
        message += "Lims Project naam\t{0}\n".format(lims_project.name)
        message += "Pool - Fragment lengte\t{0}\n".format(form.pool_fragment_length.data)
        message += "Pool - Concentratie\t{0}\n".format(form.pool_concentration.data)
        message += "Pool - Exoom equivalenten\t{0}\n\n".format(form.sum_exome_count)
        message += "Sample naam\tBarcode\tExome equivalenten\tSample type\n"

        for sample in form.parsed_samples:
            message += "{0}\t{1}\t{2}\t{3}\n".format(sample['name'], sample['barcode'], sample['exome_count'], sample['type'])
        send_email(app.config['EMAIL_FROM'], app.config['LIMS_INDICATIONS'][form.indicationcode.data]['email_to'], subject, message)

        return render_template('submit_samples_done.html', title='Submit samples', project_name=lims_project.name, form=form)
    return render_template('submit_samples.html', title='Submit samples', form=form)
Esempio n. 13
0
def main(args):
    lims = Lims(BASEURI, USERNAME, PASSWORD)
    cont = Container(lims, id=args.flowcell)
    cont.name = cont.id
    cont.put()