Exemple #1
0
 def test_patch_plate_discarded_handler(self):
     tester = Plate(21)
     data = {'op': 'replace', 'path': '/discarded/', 'value': True}
     response = self.patch('/plate/21/', data)
     self.assertEqual(response.code, 200)
     self.assertEqual(tester.discarded, True)
     tester.discarded = False
Exemple #2
0
 def test_patch_plate_handler(self):
     tester = Plate(21)
     data = {'op': 'replace', 'path': '/name/', 'value': 'NewName'}
     response = self.patch('/plate/21/', data)
     self.assertEqual(response.code, 200)
     self.assertEqual(tester.external_id, 'NewName')
     tester.external_id = 'Test plate 1'
Exemple #3
0
    def post(self):
        plates_info = self.get_argument('plates_info')
        volume = self.get_argument('volume')
        preparation_date = self.get_argument('preparation_date')

        month, day, year = map(int, preparation_date.split('/'))
        preparation_date = date(year, month, day)

        processes = [
            LibraryPrep16SProcess.create(
                self.current_user,
                Plate(pid),
                Plate(pp),
                pn,
                Equipment(ep),
                Equipment(ep300),
                Equipment(ep50),
                ReagentComposition.from_external_id(mm),
                ReagentComposition.from_external_id(w),
                volume,
                preparation_date=preparation_date).id
            for pid, pn, pp, ep, ep300, ep50, mm, w in json_decode(plates_info)
        ]

        self.write({'processes': processes})
Exemple #4
0
def get_primer_plate(is_96):
    plates = [
        Plate(item['plate_id']) for item in Plate.list_plates(['primer'])
    ]

    if is_96:
        # use different plates for 16S
        shuffle(plates)
        hit = None
        for plate in plates:
            pc = plate.plate_configuration
            if pc.description == '96-well microtiter plate':
                hit = plate
                break
        if hit is None:
            raise ValueError("Unable to identify a primer plate")
        return (hit, None)
    else:
        # not shuffling as the order of the plates implicitly matters
        hits = []
        for plate in plates:
            pc = plate.plate_configuration
            if pc.description == '384-well microtiter plate':
                if 'primer' in plate.external_id.lower():
                    hits.append(plate)
        hits = hits[:2]
        if len(hits) != 2:
            raise ValueError("Unable to identify two primer plates")
        return hits
Exemple #5
0
    def get(self):
        plate_ids = self.get_arguments('plate_id')
        process_id = self.get_argument('process_id', None)
        gdna_plate = None
        epmotion = None
        epmotion_tm300 = None
        epmotion_tm50 = None
        primer_plate = None
        master_mix = None
        water_lot = None
        volume = None
        prep_date = None
        if process_id is not None:
            try:
                process = LibraryPrep16SProcess(process_id)
            except LabControlUnknownIdError:
                raise HTTPError(404,
                                reason="Amplicon process %s doesn't exist" %
                                process_id)
            gdna_plate = process.gdna_plate.id
            epmotion = process.epmotion.id
            epmotion_tm300 = process.epmotion_tm300_tool.id
            epmotion_tm50 = process.epmotion_tm50_tool.id
            master_mix = process.mastermix.external_lot_id
            water_lot = process.water_lot.external_lot_id
            primer_plate = process.primer_plate.id
            volume = process.volume
            prep_date = process.date.strftime(process.get_date_format())

        robots = Equipment.list_equipment('EpMotion')
        tools_tm300_8 = Equipment.list_equipment(
            'tm 300 8 channel pipette head')
        tools_tm50_8 = Equipment.list_equipment('tm 50 8 channel pipette head')

        primer_plates = []
        for pp in Plate.list_plates(['primer']):
            plate = Plate(pp['plate_id'])
            if plate.process.primer_set.target_name == 'Amplicon':
                primer_plates.append(pp)

        self.render('library_prep_16S.html',
                    plate_ids=plate_ids,
                    robots=robots,
                    tools_tm300_8=tools_tm300_8,
                    tools_tm50_8=tools_tm50_8,
                    primer_plates=primer_plates,
                    process_id=process_id,
                    gdna_plate=gdna_plate,
                    epmotion=epmotion,
                    epmotion_tm300=epmotion_tm300,
                    epmotion_tm50=epmotion_tm50,
                    master_mix=master_mix,
                    water_lot=water_lot,
                    primer_plate=primer_plate,
                    preparationDate=prep_date,
                    volume=volume)
Exemple #6
0
 def test_get_well(self):
     # Plate 21 - Defined in the test DB
     tester = Plate(21)
     self.assertEqual(tester.get_well(1, 1), Well(3073))
     self.assertEqual(tester.get_well(1, 2), Well(3121))
     self.assertEqual(tester.get_well(7, 2), Well(3157))
     self.assertEqual(tester.get_well(8, 12), Well(3643))
     with self.assertRaises(LabControlError):
         tester.get_well(8, 13)
     with self.assertRaises(LabControlError):
         tester.get_well(9, 12)
    def _compute_pools(self, plate_info):
        self.plate_id = plate_info['plate-id']
        self.func_name = plate_info['pool-func']
        self.plate_type = plate_info['plate-type']
        self.quant_process_id = plate_info['quant-process-id']
        func_info = POOL_FUNCS[self.func_name]
        self.function = func_info['function']

        plate = Plate(self.plate_id)
        quant_process = QuantificationProcess(self.quant_process_id)

        # make params dictionary for function
        params = {}
        for arg, pfx in func_info['parameters']:
            param_key = '%s%s' % (pfx, self.plate_id)
            if param_key not in plate_info:
                raise HTTPError(400, reason='Missing parameter %s' % param_key)
            # empty strings are sent when we have disabled inputs.
            # we are testing for them explicitly where expected.
            if plate_info[param_key] != '':
                params[arg] = float(plate_info[param_key])
            else:
                params[arg] = plate_info[param_key]

        self.params = params

        # compute molar concentrations
        quant_process.compute_concentrations(size=params['size'])

        # calculate pooled values
        self.raw_concs, self.comp_concs, self.comp_blanks, \
        self.plate_names = make_2D_arrays(plate, quant_process)
Exemple #8
0
    def post(self):
        user = self.current_user
        plates_info = self.get_argument('plates_info')
        volume = self.get_argument('volume')
        kapa_hyperplus_kit = self.get_argument('kapa_hyperplus_kit')
        stub_lot = self.get_argument('stub_lot')

        processes = [[
            pid,
            LibraryPrepShotgunProcess.create(
                user, Plate(pid), plate_name,
                ReagentComposition.from_external_id(kapa_hyperplus_kit),
                ReagentComposition.from_external_id(stub_lot), volume,
                Plate(i5p), Plate(i7p)).id
        ] for pid, plate_name, i5p, i7p in json_decode(plates_info)]

        self.write({'processes': processes})
Exemple #9
0
 def test_get_wells_by_sample(self):
     tester = Plate(21)
     exp = [
         Well(3073),
         Well(3121),
         Well(3169),
         Well(3217),
         Well(3265),
         Well(3313),
         Well(3361),
         Well(3409),
         Well(3457),
         Well(3505),
         Well(3553),
         Well(3601)
     ]
     self.assertEqual(tester.get_wells_by_sample('1.SKB1.640202'), exp)
     self.assertEqual(tester.get_wells_by_sample('1.SKM1.640183'), [])
Exemple #10
0
    def test_plate_list_include_timestamp(self):
        # ...limit pathological failures by testing within an hour of creation
        exp = datetime.datetime.now()
        exp = str(datetime.datetime(exp.year, exp.month,
                                    exp.day)).split(None, 1)[0]

        for i in Plate.list_plates():
            obs = i['creation_timestamp'].split(None, 1)[0]
            self.assertEqual(obs, exp)
Exemple #11
0
 def test_properties(self):
     tester = Well(3073)
     self.assertEqual(tester.plate, Plate(21))
     self.assertEqual(tester.row, 1)
     self.assertEqual(tester.column, 1)
     self.assertEqual(tester.remaining_volume, 10)
     self.assertIsNone(tester.notes)
     self.assertEqual(tester.latest_process, SamplePlatingProcess(11))
     self.assertEqual(tester.container_id, 3082)
     self.assertEqual(tester.composition, SampleComposition(1))
Exemple #12
0
    def get(self):
        plate_ids = self.get_arguments('plate_id')
        process_id = self.get_argument('process_id', None)
        input_plate = None
        pool_func_data = None
        pool_values = []
        pool_blanks = []
        plate_names = []
        plate_type = None
        if process_id is not None:
            try:
                process = PoolingProcess(process_id)
            except LabControlUnknownIdError:
                raise HTTPError(404,
                                reason="Pooling process %s doesn't exist" %
                                process_id)
            plate = process.components[0][0].container.plate
            input_plate = plate.id
            pool_func_data = process.pooling_function_data

            _, pool_values, pool_blanks, plate_names = \
                make_2D_arrays(plate, process.quantification_process)

            pool_values = pool_values.tolist()
            pool_blanks = pool_blanks.tolist()
            plate_names = plate_names.tolist()

        elif len(plate_ids) > 0:
            content_types = {
                type(Plate(pid).get_well(1, 1).composition)
                for pid in plate_ids
            }

            if len(content_types) > 1:
                raise HTTPError(400,
                                reason='Plates contain different types '
                                'of compositions')
            plate_type = ('16S library prep'
                          if content_types.pop() == LibraryPrep16SComposition
                          else 'shotgun library prep')

        robots = (Equipment.list_equipment('EpMotion') +
                  Equipment.list_equipment('echo'))

        self.render('library_pooling.html',
                    plate_ids=plate_ids,
                    robots=robots,
                    pool_params=HTML_POOL_PARAMS,
                    input_plate=input_plate,
                    pool_func_data=pool_func_data,
                    process_id=process_id,
                    pool_values=pool_values,
                    plate_type=plate_type,
                    pool_blanks=pool_blanks,
                    plate_names=plate_names)
    def post(self):
        # We will receive as many files as plates the user has selected
        # The key of the self.request.files dictionary is of the form
        # plate-file-<PLATE_ID> so use the keys to know the plates
        # that we need to quantify
        plates = []
        for key in self.request.files:
            plate_id = key.rsplit('-', 1)[1]
            # The 0 is because for each key we have a single file
            file_content = self.request.files[key][0]['body'].decode('utf-8')
            plate = Plate(plate_id)
            pc = plate.plate_configuration
            concentrations = QuantificationProcess.parse(
                file_content, rows=pc.num_rows, cols=pc.num_columns)

            names = np.empty_like(plate.layout, dtype='object')
            blanks = np.zeros_like(plate.layout, dtype=bool)

            # fetch the sample names and whether or not the samples are blanks
            # by default these are set to be None and False.
            for i, full_row in enumerate(plate.layout):
                for j, well in enumerate(full_row):

                    # some wells have no compositions at all so skip those
                    if well is None:
                        continue
                    comp = well.composition

                    # cache the sample compositions to avoid extra intermediate
                    # queries
                    if isinstance(comp, GDNAComposition):
                        smp = comp.sample_composition
                    elif isinstance(comp, (CompressedGDNAComposition,
                                           LibraryPrep16SComposition)):
                        smp = comp.gdna_composition.sample_composition
                    elif isinstance(comp, LibraryPrepShotgunComposition):
                        smp = comp.normalized_gdna_composition\
                            .compressed_gdna_composition.gdna_composition\
                            .sample_composition
                    else:
                        raise ValueError('This composition type is not '
                                         'supported')

                    blanks[i][j] = smp.sample_composition_type == 'blank'
                    names[i][j] = smp.sample_id

            plates.append({'plate_name': plate.external_id,
                           'plate_id': plate_id,
                           'concentrations': concentrations.tolist(),
                           'names': names.tolist(),
                           'blanks': blanks.tolist(),
                           'type': plate.process._process_type
                           })

        self.render('quantification.html', plates=plates)
Exemple #14
0
 def get(self, plate_id):
     urls = {
         SamplePlatingProcess: '/plate',
         GDNAExtractionProcess: '/process/gdna_extraction',
         LibraryPrep16SProcess: '/process/library_prep_16S',
         LibraryPrepShotgunProcess: '/process/library_prep_shotgun',
         NormalizationProcess: '/process/normalize',
         GDNAPlateCompressionProcess: '/process/gdna_compression'
     }
     process = Plate(plate_id).process
     self.redirect(urls[process.__class__] + '?process_id=%s' % process.id)
    def post(self):
        plates_info = json_decode(self.get_argument('plates-info'))
        processes = []
        for pinfo in plates_info:
            plate = Plate(pinfo['plate_id'])
            concentrations = np.asarray(pinfo['concentrations'])

            processes.append(QuantificationProcess.create(
                self.current_user, plate, concentrations).id)

        self.write({'processes': processes})
Exemple #16
0
    def post(self):
        plates = self.get_argument('plates')
        plate_ext_id = self.get_argument('plate_ext_id')
        robot = self.get_argument('robot')

        plates = [Plate(pid) for pid in json_decode(plates)]

        process = GDNAPlateCompressionProcess.create(self.current_user, plates,
                                                     plate_ext_id,
                                                     Equipment(robot))

        self.write({'process': process.id})
Exemple #17
0
    def test_plate_handler_patch_request(self):
        tester = Plate(21)
        user = User('*****@*****.**')

        # Incorrect path parameter
        regex = 'Incorrect path parameter'
        with self.assertRaisesRegex(HTTPError, regex):
            plate_handler_patch_request(user, 21, 'replace', '/name/newname',
                                        'NewName', None)

        # Unknown attribute
        regex = 'Attribute unknown not recognized'
        with self.assertRaisesRegex(HTTPError, regex):
            plate_handler_patch_request(user, 21, 'replace', '/unknown/',
                                        'NewName', None)

        # Unknown operation
        regex = ('Operation add not supported. Current supported '
                 'operations: replace')
        with self.assertRaisesRegex(HTTPError, regex):
            plate_handler_patch_request(user, 21, 'add', '/name/', 'NewName',
                                        None)

        # Plate doesn't exist
        regex = 'Plate 100 doesn\'t exist'
        with self.assertRaisesRegex(HTTPError, regex):
            plate_handler_patch_request(user, 100, 'replace', '/name/',
                                        'NewName', None)

        # Test success - Name
        plate_handler_patch_request(user, 21, 'replace', '/name/', 'NewName',
                                    None)
        self.assertEqual(tester.external_id, 'NewName')
        tester.external_id = 'Test plate 1'

        # Test success - discarded
        plate_handler_patch_request(user, 21, 'replace', '/discarded/', True,
                                    None)
        self.assertEqual(tester.discarded, True)
        tester.discarded = False
Exemple #18
0
    def get(self):
        plate_ids = self.get_arguments('plate_id')
        process_id = self.get_argument('process_id', None)
        kapa = None
        stub = None
        volume = None
        norm_plate = None
        i5plate = None
        i7plate = None
        if process_id is not None:
            try:
                process = LibraryPrepShotgunProcess(process_id)
            except LabControlUnknownIdError:
                raise HTTPError(404,
                                reason="Shotgun library prep process %s "
                                "doesn't exist" % process_id)
            kapa = process.kapa_hyperplus_kit.external_lot_id
            stub = process.stub_lot.external_lot_id
            norm_plate = process.normalized_plate.id
            i5plate = process.i5_primer_plate.id
            i7plate = process.i7_primer_plate.id
            volume = process.volume

        primer_plates = []
        for pp in Plate.list_plates(['primer']):
            plate = Plate(pp['plate_id'])
            if plate.process.primer_set.target_name == 'Shotgun':
                primer_plates.append(pp)

        self.render('library_prep_shotgun.html',
                    plate_ids=plate_ids,
                    primer_plates=primer_plates,
                    process_id=process_id,
                    kapa=kapa,
                    stub=stub,
                    volume=volume,
                    norm_plate=norm_plate,
                    i5plate=i5plate,
                    i7plate=i7plate)
Exemple #19
0
 def test_create(self):
     plate_conf = PlateConfiguration.create('96-well Test desc', 8, 12)
     obs = Plate.create('New plate', plate_conf)
     self.assertEqual(obs.external_id, 'New plate')
     self.assertEqual(obs.plate_configuration, plate_conf)
     self.assertFalse(obs.discarded)
     self.assertIsNone(obs.notes)
     # This is a weird case and it should never happen in normal execution
     # of the code: the plate has been created without any well, hence all
     # the None values. In reality, all the plate creation is handled
     # by one of the Process classes, which ensures the creation of all
     # the wells.
     self.assertEqual(obs.layout, [[None] * 12] * 8)
 def test_primer_set_attributes(self):
     obs = PrimerSet(1)
     self.assertEqual(obs.external_id, 'EMP 16S V4 primer set')
     self.assertEqual(obs.target_name, 'Amplicon')
     self.assertIsNone(obs.notes)
     self.assertEqual(obs.plates, [
         Plate(1),
         Plate(2),
         Plate(3),
         Plate(4),
         Plate(5),
         Plate(6),
         Plate(7),
         Plate(8)
     ])
    def get(self, plate_id):

        plate = Plate(plate_id)
        quant_processes = plate.quantification_processes

        quant_values = []

        for quant in quant_processes:
            concentrations = np.zeros_like(plate.layout, dtype=float)
            names = np.empty_like(plate.layout, dtype='object')
            blanks = np.zeros_like(plate.layout, dtype=bool)

            # Get sample_composition (`smp`) from each well.
            # Currently this requires ugly logic because you have to go
            # through a named subclass that depends on plate type.
            # TODO: replace this with a direct SQL query in a dedicated
            # method of the composition class.
            for comp, raw_conc, _ in quant.concentrations:
                container = comp.container
                row, col = container.row - 1, container.column - 1

                if isinstance(comp, GDNAComposition):
                    smp = comp.sample_composition
                elif isinstance(comp, (CompressedGDNAComposition,
                                       LibraryPrep16SComposition)):
                    smp = comp.gdna_composition.sample_composition
                elif isinstance(comp, LibraryPrepShotgunComposition):
                    smp = comp.normalized_gdna_composition\
                        .compressed_gdna_composition.gdna_composition\
                        .sample_composition
                else:
                    raise ValueError('This composition type is not '
                                     'supported')

                blanks[row, col] = smp.sample_composition_type == 'blank'
                names[row, col] = smp.sample_id
                concentrations[row, col] = raw_conc

            quant_values.append({'quant_id': quant.id,
                                 'person': quant.personnel.name,
                                 'date': quant.date.isoformat(),
                                 'notes': quant.notes,
                                 'concs': concentrations.tolist(),
                                 'blanks': blanks.tolist(),
                                 'names': names.tolist()})

        self.render('view_quantifications.html',
                    quantifications=quant_values,
                    plate_type=plate.process._process_type,
                    plate_name=plate.external_id)
Exemple #22
0
    def post(self):
        plate_comment_keywords = self.get_argument("plate_comment_keywords")
        well_comment_keywords = self.get_argument("well_comment_keywords")
        operation = self.get_argument("operation")
        sample_names = json_decode(self.get_argument('sample_names'))

        res = {
            "data": [[p.id, p.external_id]
                     for p in Plate.search(samples=sample_names,
                                           plate_notes=plate_comment_keywords,
                                           well_notes=well_comment_keywords,
                                           query_type=operation)]
        }

        self.write(res)
Exemple #23
0
    def get(self):
        plate_type = self.get_argument('plate_type', None)
        only_quantified = self.get_argument('only_quantified', False)
        plate_type = (json_decode(plate_type)
                      if plate_type is not None else None)
        only_quantified = True if only_quantified == 'true' else False

        rows_list = [[
            p['plate_id'], p['external_id'], p['creation_timestamp'],
            p['studies'] if p['studies'] is not None else []
        ] for p in Plate.list_plates(plate_type,
                                     only_quantified=only_quantified,
                                     include_study_titles=True)]
        res = {"data": rows_list}

        self.write(res)
    def post(self):
        plates_info = json_decode(self.get_argument('plates-info'))
        results = []
        for pinfo in plates_info:

            plate_result = self._compute_pools(pinfo)
            plate = Plate(plate_result['plate_id'])

            # calculate estimated molar fraction for each element of pool
            amts = plate_result['comp_vals'] * plate_result['pool_vals']
            pcts = amts / amts.sum()

            quant_process = QuantificationProcess(
                plate_result['quant-process-id'])
            pool_name = 'Pool from plate %s (%s)' % (
                plate.external_id, datetime.now().strftime(
                    quant_process.get_date_format()))
            input_compositions = []
            for comp, _, _ in quant_process.concentrations:
                well = comp.container
                row = well.row - 1
                column = well.column - 1
                input_compositions.append({
                    'composition':
                    comp,
                    'input_volume':
                    plate_result['pool_vals'][row][column],
                    'percentage_of_output':
                    pcts[row][column]
                })
            robot = (Equipment(plate_result['robot'])
                     if plate_result['robot'] is not None else None)
            process = PoolingProcess.create(
                self.current_user,
                quant_process,
                pool_name,
                plate_result['pool_vals'].sum(),
                input_compositions,
                plate_result['func_data'],
                robot=robot,
                destination=plate_result['destination'])
            results.append({'plate-id': plate.id, 'process-id': process.id})

        self.write(json_encode(results))
Exemple #25
0
def _get_plate(plate_id):
    """Returns the plate object if it exists

    Parameters
    ----------
    plate_id : str
        The plate id

    Raises
    ------
    HTTPError
        404, if the plate doesn't exist
    """
    plate_id = int(plate_id)
    try:
        plate = Plate(plate_id)
    except LabControlUnknownIdError:
        raise HTTPError(404, 'Plate %s doesn\'t exist' % plate_id)
    return plate
    def post(self):
        plates_info = self.get_argument('plates_info')
        extraction_date = self.get_argument('extraction_date')
        volume = self.get_argument('volume')

        month, day, year = map(int, extraction_date.split('/'))
        extraction_date = date(year, month, day)

        # We create one process per plate
        processes = []
        for pid, ee, kf, ep, ept, kit, p_name, nt in json_decode(plates_info):
            # Check whether plate was externally extracted
            if ee is True:
                # find the id of null things
                eq_no = \
                  Equipment.list_equipment('Not applicable')[0]['equipment_id']
                ep = ept = kf = Equipment(eq_no)
                kit = ReagentComposition.from_external_id('Not applicable')
            else:
                kf = Equipment(kf)
                ep = Equipment(ep)
                ept = Equipment(ept)
                kit = ReagentComposition.from_external_id(kit)
            processes.append(
                GDNAExtractionProcess.create(self.current_user,
                                             Plate(pid),
                                             kf,
                                             ep,
                                             ept,
                                             kit,
                                             volume,
                                             p_name,
                                             externally_extracted=ee,
                                             extraction_date=extraction_date,
                                             notes=nt).id)

        self.write({'processes': processes})
    def get(self):
        pool_type = 'shotgun_plate'
        plate_ids = self.get_arguments('plate_id')
        process_id = self.get_argument('process_id', None)
        input_plate = None
        pool_func_data = None
        pool_values = []
        pool_blanks = []
        plate_names = []
        if process_id is not None:
            try:
                process = PoolingProcess(process_id)
            except LabControlUnknownIdError:
                raise HTTPError(404, reason="Pooling process %s doesn't exist"
                                            % process_id)
            plate = process.components[0][0].container.plate
            input_plate = plate.id
            pool_func_data = process.pooling_function_data
            content_type = type(plate.get_well(1, 1).composition)
            id_plate_type = PLATE_TYPES[content_type]
            plate_type_mapped = PLATE_TYPE_TO_POOL_TYPE[id_plate_type]
            if plate_type_mapped != pool_type:
                raise HTTPError(400, reason='Pooling process type does not '
                                            'match pooling type')

            _, pool_values, pool_blanks, plate_names = \
                make_2D_arrays(plate, process.quantification_process)

            pool_values = pool_values.tolist()
            pool_blanks = pool_blanks.tolist()
            plate_names = plate_names.tolist()

        elif len(plate_ids) > 0:
            content_types = {type(Plate(pid).get_well(1, 1).composition)
                             for pid in plate_ids}

            if len(content_types) > 1:
                raise HTTPError(400, reason='Plates contain different types '
                                            'of compositions')

            # check if the observed plates are the same type as the pooling
            # type (i.e., no shotgun plates for 16S pooling)
            content_type = content_types.pop()
            id_plate_type = PLATE_TYPES[content_type]
            plate_type_mapped = PLATE_TYPE_TO_POOL_TYPE[id_plate_type]
            if plate_type_mapped != pool_type:
                raise HTTPError(400, reason='Plate type does not match '
                                            'pooling type')

        pool_type_stripped = POOL_TYPE_PARAMS[pool_type]['abbreviation']
        plate_type = POOL_TYPE_TO_PLATE_TYPE[pool_type]

        robots = (Equipment.list_equipment('EpMotion') +
                  Equipment.list_equipment('echo'))

        template = POOL_TYPE_PARAMS[pool_type]['template']

        self.render(template, plate_ids=plate_ids,
                    robots=robots, pool_params=HTML_POOL_PARAMS,
                    input_plate=input_plate, pool_func_data=pool_func_data,
                    process_id=process_id, pool_values=pool_values,
                    plate_type=plate_type, pool_blanks=pool_blanks,
                    plate_names=plate_names, pool_type=pool_type_stripped)
    def _compute_pools(self, plate_info):
        plate_id = plate_info['plate-id']
        func_name = plate_info['pool-func']
        plate_type = plate_info['plate-type']
        quant_process_id = plate_info['quant-process-id']
        func_info = POOL_FUNCS[func_name]
        function = func_info['function']

        plate = Plate(plate_id)
        quant_process = QuantificationProcess(quant_process_id)

        # make params dictionary for function
        params = {}
        for arg, pfx in func_info['parameters']:
            param_key = '%s%s' % (pfx, plate_id)
            if param_key not in plate_info:
                raise HTTPError(
                    400, reason='Missing parameter %s' % param_key)
            # empty strings are sent when we have disabled inputs.
            # we are testing for them explicitly where expected.
            if plate_info[param_key] != '':
                params[arg] = float(plate_info[param_key])
            else:
                params[arg] = plate_info[param_key]

        # compute molar concentrations
        quant_process.compute_concentrations(size=params['size'])

        # calculate pooled values
        raw_concs, comp_concs, comp_blanks, \
        plate_names = make_2D_arrays(plate, quant_process)

        # for 16S, we calculate each sample independently
        pool_type = PLATE_TYPE_TO_POOL_TYPE[plate_type]
        params['total_each'] = POOL_TYPE_PARAMS[pool_type]['total_each']
        params['vol_constant'] = POOL_TYPE_PARAMS[pool_type]['vol_constant']
        pool_vals = function(raw_concs, **params)

        # if adjust blank volume, do that
        if params['blank_vol'] != '':
            pool_vals = PoolingProcess.adjust_blank_vols(pool_vals,
                                                         comp_blanks,
                                                         params['blank_vol'])

        # if only pool some blanks, do that
        if params['blank_num'] != '':
            pool_vals = PoolingProcess.select_blanks(pool_vals,
                                                     raw_concs,
                                                     comp_blanks,
                                                     int(params['blank_num']))

        # estimate pool volume and concentration
        total_c, total_v = PoolingProcess.estimate_pool_conc_vol(pool_vals,
                                                                 comp_concs)

        # store output values
        output = {}
        output['func_data'] = {'function': func_name,
                               'parameters': params}
        output['raw_vals'] = raw_concs
        output['comp_vals'] = comp_concs
        output['pool_vals'] = pool_vals
        output['pool_blanks'] = comp_blanks.tolist()
        output['plate_names'] = plate_names.tolist()
        output['plate_id'] = plate_id
        output['destination'] = params['destination']
        output['robot'] = params['robot']
        output['blank_vol'] = params['blank_vol']
        output['blank_num'] = params['blank_num']
        output['total_conc'] = total_c
        output['total_vol'] = total_v
        output['quant-process-id'] = quant_process_id

        return output
Exemple #29
0
    def test_get_plate_handler(self):
        response = self.get('/plate/21/')
        self.assertEqual(response.code, 200)
        obs = json_decode(response.body)
        exp = {
            'plate_id':
            21,
            'plate_name':
            'Test plate 1',
            'discarded':
            False,
            'plate_configuration': [1, '96-well deep-well plate', 8, 12],
            'notes':
            None,
            'studies': [1],
            'duplicates': [[1, 1, '1.SKB1.640202.Test.plate.1.A1'],
                           [1, 2, '1.SKB1.640202.Test.plate.1.A2'],
                           [1, 3, '1.SKB1.640202.Test.plate.1.A3'],
                           [1, 4, '1.SKB1.640202.Test.plate.1.A4'],
                           [1, 5, '1.SKB1.640202.Test.plate.1.A5'],
                           [1, 6, '1.SKB1.640202.Test.plate.1.A6'],
                           [1, 7, '1.SKB1.640202.Test.plate.1.A7'],
                           [1, 8, '1.SKB1.640202.Test.plate.1.A8'],
                           [1, 9, '1.SKB1.640202.Test.plate.1.A9'],
                           [1, 10, '1.SKB1.640202.Test.plate.1.A10'],
                           [1, 11, '1.SKB1.640202.Test.plate.1.A11'],
                           [1, 12, '1.SKB1.640202.Test.plate.1.A12'],
                           [2, 1, '1.SKB2.640194.Test.plate.1.B1'],
                           [2, 2, '1.SKB2.640194.Test.plate.1.B2'],
                           [2, 3, '1.SKB2.640194.Test.plate.1.B3'],
                           [2, 4, '1.SKB2.640194.Test.plate.1.B4'],
                           [2, 5, '1.SKB2.640194.Test.plate.1.B5'],
                           [2, 6, '1.SKB2.640194.Test.plate.1.B6'],
                           [2, 7, '1.SKB2.640194.Test.plate.1.B7'],
                           [2, 8, '1.SKB2.640194.Test.plate.1.B8'],
                           [2, 9, '1.SKB2.640194.Test.plate.1.B9'],
                           [2, 10, '1.SKB2.640194.Test.plate.1.B10'],
                           [2, 11, '1.SKB2.640194.Test.plate.1.B11'],
                           [2, 12, '1.SKB2.640194.Test.plate.1.B12'],
                           [3, 1, '1.SKB3.640195.Test.plate.1.C1'],
                           [3, 2, '1.SKB3.640195.Test.plate.1.C2'],
                           [3, 3, '1.SKB3.640195.Test.plate.1.C3'],
                           [3, 4, '1.SKB3.640195.Test.plate.1.C4'],
                           [3, 5, '1.SKB3.640195.Test.plate.1.C5'],
                           [3, 6, '1.SKB3.640195.Test.plate.1.C6'],
                           [3, 7, '1.SKB3.640195.Test.plate.1.C7'],
                           [3, 8, '1.SKB3.640195.Test.plate.1.C8'],
                           [3, 9, '1.SKB3.640195.Test.plate.1.C9'],
                           [3, 10, '1.SKB3.640195.Test.plate.1.C10'],
                           [3, 11, '1.SKB3.640195.Test.plate.1.C11'],
                           [3, 12, '1.SKB3.640195.Test.plate.1.C12'],
                           [4, 1, '1.SKB4.640189.Test.plate.1.D1'],
                           [4, 2, '1.SKB4.640189.Test.plate.1.D2'],
                           [4, 3, '1.SKB4.640189.Test.plate.1.D3'],
                           [4, 4, '1.SKB4.640189.Test.plate.1.D4'],
                           [4, 5, '1.SKB4.640189.Test.plate.1.D5'],
                           [4, 6, '1.SKB4.640189.Test.plate.1.D6'],
                           [4, 7, '1.SKB4.640189.Test.plate.1.D7'],
                           [4, 8, '1.SKB4.640189.Test.plate.1.D8'],
                           [4, 9, '1.SKB4.640189.Test.plate.1.D9'],
                           [4, 10, '1.SKB4.640189.Test.plate.1.D10'],
                           [4, 11, '1.SKB4.640189.Test.plate.1.D11'],
                           [4, 12, '1.SKB4.640189.Test.plate.1.D12'],
                           [5, 1, '1.SKB5.640181.Test.plate.1.E1'],
                           [5, 2, '1.SKB5.640181.Test.plate.1.E2'],
                           [5, 3, '1.SKB5.640181.Test.plate.1.E3'],
                           [5, 4, '1.SKB5.640181.Test.plate.1.E4'],
                           [5, 5, '1.SKB5.640181.Test.plate.1.E5'],
                           [5, 6, '1.SKB5.640181.Test.plate.1.E6'],
                           [5, 7, '1.SKB5.640181.Test.plate.1.E7'],
                           [5, 8, '1.SKB5.640181.Test.plate.1.E8'],
                           [5, 9, '1.SKB5.640181.Test.plate.1.E9'],
                           [5, 10, '1.SKB5.640181.Test.plate.1.E10'],
                           [5, 11, '1.SKB5.640181.Test.plate.1.E11'],
                           [5, 12, '1.SKB5.640181.Test.plate.1.E12'],
                           [6, 1, '1.SKB6.640176.Test.plate.1.F1'],
                           [6, 2, '1.SKB6.640176.Test.plate.1.F2'],
                           [6, 3, '1.SKB6.640176.Test.plate.1.F3'],
                           [6, 4, '1.SKB6.640176.Test.plate.1.F4'],
                           [6, 5, '1.SKB6.640176.Test.plate.1.F5'],
                           [6, 6, '1.SKB6.640176.Test.plate.1.F6'],
                           [6, 7, '1.SKB6.640176.Test.plate.1.F7'],
                           [6, 8, '1.SKB6.640176.Test.plate.1.F8'],
                           [6, 9, '1.SKB6.640176.Test.plate.1.F9'],
                           [6, 10, '1.SKB6.640176.Test.plate.1.F10'],
                           [6, 11, '1.SKB6.640176.Test.plate.1.F11']],
            'previous_plates': [
                [[1, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 1],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 2],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 3],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 4],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 5],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 6],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 7],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 8],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 9],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 10],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[6, 11],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[1, 12],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[2, 12],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[3, 12],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[4, 12],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
                [[5, 12],
                 [{
                     'plate_id': 27,
                     'plate_name': 'Test plate 2'
                 }, {
                     'plate_id': 30,
                     'plate_name': 'Test plate 3'
                 }, {
                     'plate_id': 33,
                     'plate_name': 'Test plate 4'
                 }]],
            ],
            'process_notes':
            None,
            'unknowns': [],
            'quantitation_processes': []
        }
        obs_duplicates = obs.pop('duplicates')
        exp_duplicates = exp.pop('duplicates')
        self.assertEqual(obs, exp)
        self.assertCountEqual(obs_duplicates, exp_duplicates)

        # Plate doesn't exist
        response = self.get('/plate/100/')
        self.assertEqual(response.code, 404)

        # Plate has multiple quantitation processes
        # Note: cannot hard-code the date in the below known-good object
        # because date string representation is specific to physical location
        # in which system running the tests is located!
        tester = Plate(26)
        first_date_str = datetime.strftime(
            tester.quantification_processes[0].date, Process.get_date_format())
        second_date_str = datetime.strftime(
            tester.quantification_processes[1].date, Process.get_date_format())

        response = self.get('/plate/26/')
        self.assertEqual(response.code, 200)
        obs = json_decode(response.body)
        exp = {
            'plate_id':
            26,
            'plate_name':
            'Test shotgun library plates 1-4',
            'discarded':
            False,
            'plate_configuration': [3, '384-well microtiter plate', 16, 24],
            'notes':
            None,
            'studies': [1],
            'duplicates': [],
            'previous_plates': [],
            'process_notes':
            None,
            'unknowns': [],
            'quantitation_processes':
            [[4, 'Dude', first_date_str, None],
             [5, 'Dude', second_date_str, 'Requantification--oops']]
        }
        obs_duplicates = obs.pop('duplicates')
        exp_duplicates = exp.pop('duplicates')
        self.assertEqual(obs, exp)
        self.assertCountEqual(obs_duplicates, exp_duplicates)
Exemple #30
0
 def test_get_plate(self):
     self.assertEqual(_get_plate('21'), Plate(21))
     regex = 'Plate 100 doesn\'t exist'
     with self.assertRaisesRegex(HTTPError, regex):
         _get_plate(100)