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']) # create input molar percentages pcts = calc_pool_pcts(plate_result['comp_vals'], plate_result['pool_vals']) 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))
def create_pool_quantification_process(user, pools): concentrations = np.around(np.random.rand(len(pools)), 6) concentrations = [{ 'composition': p, 'concentration': c } for p, c in zip(pools, concentrations)] return QuantificationProcess.create_manual(user, concentrations)
def post(self): pool_name = self.get_argument('pool_name') pools_info = json_decode(self.get_argument('pools_info')) concentrations = [] input_compositions = [] for p_info in pools_info: pool_comp = PoolComposition(p_info['pool_id']) concentrations.append({ 'composition': pool_comp, 'concentration': p_info['concentration'] }) input_compositions.append({ 'composition': pool_comp, 'input_volume': p_info['volume'], 'percentage_of_output': p_info['percentage'] }) # Create the quantification process (DNA conc) q_process = QuantificationProcess.create_manual( self.current_user, concentrations) # Create the pool - Magic number 5 - > the volume for this poolings # is always 5 according to the wet lab. p_process = PoolingProcess.create(self.current_user, q_process, pool_name, 5, input_compositions, { "function": "amplicon_pool", "parameters": {} }) self.write({'process': p_process.id})
def post(self): user = self.current_user plates_info = self.get_argument('plates_info') water = self.get_argument('water') total_vol = self.get_argument('total_vol') ng = self.get_argument('ng') min_vol = self.get_argument('min_vol') max_vol = self.get_argument('max_vol') resolution = self.get_argument('resolution') reformat = self.get_argument('reformat') processes = [[ plate_id, NormalizationProcess.create( user, QuantificationProcess(quantification_process_id), ReagentComposition.from_external_id(water), plate_name, total_vol=float(total_vol), ng=float(ng), min_vol=float(min_vol), max_vol=float(max_vol), resolution=float(resolution), reformat=reformat).id ] for plate_id, plate_name, quantification_process_id in json_decode( plates_info)] self.write({'processes': processes})
def post(self): plate_id = self.get_argument('plate-id') concentrations = json_decode(self.get_argument('concentrations')) concentrations = np.asarray(concentrations) plate = Plate(plate_id) q_process = QuantificationProcess.create(self.current_user, plate, concentrations) pool_name = 'Pool - %s' % plate.external_id input_compositions = [] concentrations = q_process.concentrations total_vol = 0 for conc in concentrations: in_vol = conc[1] total_vol += in_vol input_compositions.append({ 'composition': conc[0], 'input_volume': in_vol, 'percentage_of_output': in_vol }) for ic in input_compositions: ic['percentage_of_output'] = ic['percentage_of_output'] / total_vol process = PoolingProcess.create(self.current_user, q_process, pool_name, total_vol, input_compositions) self.write({'process': process.id})
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)
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})
def post(self): plate_id = self.get_argument('plate-select') # Magic number 0 -> there is only 1 file attached file_content = self.request.files['plate-reader-fp'][0]['body'].decode( 'utf-8') concentrations = QuantificationProcess.parse(file_content) plate = Plate(plate_id) self.render('quantification.html', concentrations=concentrations.tolist(), plate_name=plate.external_id, plate_id=plate.id, plate_conf=plate.plate_configuration.description)
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) plates.append({'plate_name': plate.external_id, 'plate_id': plate_id, 'concentrations': concentrations.tolist()}) self.render('quantification.html', plates=plates)
def create_quantification_process(user, plate): plate_config = plate.plate_configuration concentrations = np.around( np.random.rand(plate_config.num_rows, plate_config.num_columns), 6) quant_process = QuantificationProcess.create(user, plate, concentrations) return quant_process
def test_properties(self): # Plate 21 - Defined in the test DB tester = Plate(21) self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual(tester.plate_configuration, PlateConfiguration(1)) self.assertFalse(tester.discarded) self.assertIsNone(tester.notes) obs_layout = tester.layout self.assertEqual(len(obs_layout), 8) for row in obs_layout: self.assertEqual(len(row), 12) self.assertEqual(tester.studies, {Study(1)}) self.assertIsNone(tester.quantification_process) self.assertEqual(tester.process, SamplePlatingProcess(10)) # Test changing the name of the plate tester.external_id = 'Some new name' self.assertEqual(tester.external_id, 'Some new name') tester.external_id = 'Test plate 1' self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual( Plate(23).quantification_process, QuantificationProcess(1)) self.assertEqual(Plate(22).process, GDNAExtractionProcess(1)) exp = { '1.SKB1.640202': [ Well(3073), Well(3253), Well(3433), Well(3613), Well(3793), Well(3973) ], '1.SKB2.640194': [ Well(3088), Well(3268), Well(3448), Well(3628), Well(3808), Well(3988) ], '1.SKB3.640195': [ Well(3103), Well(3283), Well(3463), Well(3643), Well(3823), Well(4003) ], '1.SKB4.640189': [ Well(3118), Well(3298), Well(3478), Well(3658), Well(3838), Well(4018) ], '1.SKB5.640181': [ Well(3133), Well(3313), Well(3493), Well(3673), Well(3853), Well(4033) ], '1.SKB6.640176': [ Well(3148), Well(3328), Well(3508), Well(3688), Well(3868), Well(4048) ], '1.SKB7.640196': [ Well(3163), Well(3343), Well(3523), Well(3703), Well(3883), Well(4063) ], '1.SKB8.640193': [ Well(3178), Well(3358), Well(3538), Well(3718), Well(3898), Well(4078) ], '1.SKB9.640200': [ Well(3193), Well(3373), Well(3553), Well(3733), Well(3913), Well(4093) ], '1.SKD1.640179': [ Well(3208), Well(3388), Well(3568), Well(3748), Well(3928), Well(4108) ], '1.SKD2.640178': [ Well(3223), Well(3403), Well(3583), Well(3763), Well(3943), Well(4123) ], '1.SKD3.640198': [ Well(3238), Well(3418), Well(3598), Well(3778), Well(3958), Well(4138) ] } self.assertEqual(tester.duplicates, exp)
def test_properties(self): # Plate 21 - Defined in the test DB tester = Plate(21) self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual(tester.plate_configuration, PlateConfiguration(1)) self.assertFalse(tester.discarded) tester.discarded = True self.assertTrue(tester.discarded) self.assertIsNone(tester.notes) obs_layout = tester.layout self.assertEqual(len(obs_layout), 8) for row in obs_layout: self.assertEqual(len(row), 12) self.assertEqual(tester.studies, {Study(1)}) self.assertIsNone(tester.quantification_process) self.assertEqual(tester.process, SamplePlatingProcess(10)) # Test changing the name of the plate tester.external_id = 'Some new name' self.assertEqual(tester.external_id, 'Some new name') tester.external_id = 'Test plate 1' self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual( Plate(23).quantification_process, QuantificationProcess(1)) self.assertEqual(Plate(22).process, GDNAExtractionProcess(1)) exp = { '1.SKB1.640202': [[Well(3073), '1.SKB1.640202.21.A1'], [Well(3253), '1.SKB1.640202.21.B1'], [Well(3433), '1.SKB1.640202.21.C1'], [Well(3613), '1.SKB1.640202.21.D1'], [Well(3793), '1.SKB1.640202.21.E1'], [Well(3973), '1.SKB1.640202.21.F1']], '1.SKB2.640194': [[Well(3088), '1.SKB2.640194.21.A2'], [Well(3268), '1.SKB2.640194.21.B2'], [Well(3448), '1.SKB2.640194.21.C2'], [Well(3628), '1.SKB2.640194.21.D2'], [Well(3808), '1.SKB2.640194.21.E2'], [Well(3988), '1.SKB2.640194.21.F2']], '1.SKB3.640195': [[Well(3103), '1.SKB3.640195.21.A3'], [Well(3283), '1.SKB3.640195.21.B3'], [Well(3463), '1.SKB3.640195.21.C3'], [Well(3643), '1.SKB3.640195.21.D3'], [Well(3823), '1.SKB3.640195.21.E3'], [Well(4003), '1.SKB3.640195.21.F3']], '1.SKB4.640189': [[Well(3118), '1.SKB4.640189.21.A4'], [Well(3298), '1.SKB4.640189.21.B4'], [Well(3478), '1.SKB4.640189.21.C4'], [Well(3658), '1.SKB4.640189.21.D4'], [Well(3838), '1.SKB4.640189.21.E4'], [Well(4018), '1.SKB4.640189.21.F4']], '1.SKB5.640181': [[Well(3133), '1.SKB5.640181.21.A5'], [Well(3313), '1.SKB5.640181.21.B5'], [Well(3493), '1.SKB5.640181.21.C5'], [Well(3673), '1.SKB5.640181.21.D5'], [Well(3853), '1.SKB5.640181.21.E5'], [Well(4033), '1.SKB5.640181.21.F5']], '1.SKB6.640176': [[Well(3148), '1.SKB6.640176.21.A6'], [Well(3328), '1.SKB6.640176.21.B6'], [Well(3508), '1.SKB6.640176.21.C6'], [Well(3688), '1.SKB6.640176.21.D6'], [Well(3868), '1.SKB6.640176.21.E6'], [Well(4048), '1.SKB6.640176.21.F6']], '1.SKB7.640196': [[Well(3163), '1.SKB7.640196.21.A7'], [Well(3343), '1.SKB7.640196.21.B7'], [Well(3523), '1.SKB7.640196.21.C7'], [Well(3703), '1.SKB7.640196.21.D7'], [Well(3883), '1.SKB7.640196.21.E7'], [Well(4063), '1.SKB7.640196.21.F7']], '1.SKB8.640193': [[Well(3178), '1.SKB8.640193.21.A8'], [Well(3358), '1.SKB8.640193.21.B8'], [Well(3538), '1.SKB8.640193.21.C8'], [Well(3718), '1.SKB8.640193.21.D8'], [Well(3898), '1.SKB8.640193.21.E8'], [Well(4078), '1.SKB8.640193.21.F8']], '1.SKB9.640200': [[Well(3193), '1.SKB9.640200.21.A9'], [Well(3373), '1.SKB9.640200.21.B9'], [Well(3553), '1.SKB9.640200.21.C9'], [Well(3733), '1.SKB9.640200.21.D9'], [Well(3913), '1.SKB9.640200.21.E9'], [Well(4093), '1.SKB9.640200.21.F9']], '1.SKD1.640179': [[Well(3208), '1.SKD1.640179.21.A10'], [Well(3388), '1.SKD1.640179.21.B10'], [Well(3568), '1.SKD1.640179.21.C10'], [Well(3748), '1.SKD1.640179.21.D10'], [Well(3928), '1.SKD1.640179.21.E10'], [Well(4108), '1.SKD1.640179.21.F10']], '1.SKD2.640178': [[Well(3223), '1.SKD2.640178.21.A11'], [Well(3403), '1.SKD2.640178.21.B11'], [Well(3583), '1.SKD2.640178.21.C11'], [Well(3763), '1.SKD2.640178.21.D11'], [Well(3943), '1.SKD2.640178.21.E11'], [Well(4123), '1.SKD2.640178.21.F11']], '1.SKD3.640198': [[Well(3238), '1.SKD3.640198.21.A12'], [Well(3418), '1.SKD3.640198.21.B12'], [Well(3598), '1.SKD3.640198.21.C12'], [Well(3778), '1.SKD3.640198.21.D12'], [Well(3958), '1.SKD3.640198.21.E12'], [Well(4138), '1.SKD3.640198.21.F12']] } self.assertEqual(tester.duplicates, exp) self.assertEqual(tester.unknown_samples, []) exp = tester.get_well(1, 1) exp.composition.update('Unknown') self.assertEqual(tester.unknown_samples, [exp]) exp.composition.update('1.SKB1.640202')
def test_properties(self): # Plate 21 - Defined in the test DB tester = Plate(21) self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual(tester.plate_configuration, PlateConfiguration(1)) self.assertFalse(tester.discarded) tester.discarded = True self.assertTrue(tester.discarded) self.assertIsNone(tester.notes) obs_layout = tester.layout self.assertEqual(len(obs_layout), 8) for row in obs_layout: self.assertEqual(len(row), 12) self.assertEqual(tester.studies, {Study(1)}) self.assertListEqual(tester.quantification_processes, []) self.assertEqual(tester.process, SamplePlatingProcess(10)) # Test changing the name of the plate tester.external_id = 'Some new name' self.assertEqual(tester.external_id, 'Some new name') tester.external_id = 'Test plate 1' self.assertEqual(tester.external_id, 'Test plate 1') self.assertEqual(len(Plate(23).quantification_processes), 1) self.assertEqual( Plate(23).quantification_processes[0], QuantificationProcess(1)) self.assertEqual(Plate(22).process, GDNAExtractionProcess(1)) exp = { '1.SKB1.640202': [[Well(3073), '1.SKB1.640202.21.A1'], [Well(3121), '1.SKB1.640202.21.A2'], [Well(3169), '1.SKB1.640202.21.A3'], [Well(3217), '1.SKB1.640202.21.A4'], [Well(3265), '1.SKB1.640202.21.A5'], [Well(3313), '1.SKB1.640202.21.A6'], [Well(3361), '1.SKB1.640202.21.A7'], [Well(3409), '1.SKB1.640202.21.A8'], [Well(3457), '1.SKB1.640202.21.A9'], [Well(3505), '1.SKB1.640202.21.A10'], [Well(3553), '1.SKB1.640202.21.A11'], [Well(3601), '1.SKB1.640202.21.A12']], '1.SKB2.640194': [[Well(3079), '1.SKB2.640194.21.B1'], [Well(3127), '1.SKB2.640194.21.B2'], [Well(3175), '1.SKB2.640194.21.B3'], [Well(3223), '1.SKB2.640194.21.B4'], [Well(3271), '1.SKB2.640194.21.B5'], [Well(3319), '1.SKB2.640194.21.B6'], [Well(3367), '1.SKB2.640194.21.B7'], [Well(3415), '1.SKB2.640194.21.B8'], [Well(3463), '1.SKB2.640194.21.B9'], [Well(3511), '1.SKB2.640194.21.B10'], [Well(3559), '1.SKB2.640194.21.B11'], [Well(3607), '1.SKB2.640194.21.B12']], '1.SKB3.640195': [[Well(3085), '1.SKB3.640195.21.C1'], [Well(3133), '1.SKB3.640195.21.C2'], [Well(3181), '1.SKB3.640195.21.C3'], [Well(3229), '1.SKB3.640195.21.C4'], [Well(3277), '1.SKB3.640195.21.C5'], [Well(3325), '1.SKB3.640195.21.C6'], [Well(3373), '1.SKB3.640195.21.C7'], [Well(3421), '1.SKB3.640195.21.C8'], [Well(3469), '1.SKB3.640195.21.C9'], [Well(3517), '1.SKB3.640195.21.C10'], [Well(3565), '1.SKB3.640195.21.C11'], [Well(3613), '1.SKB3.640195.21.C12']], '1.SKB4.640189': [[Well(3091), '1.SKB4.640189.21.D1'], [Well(3139), '1.SKB4.640189.21.D2'], [Well(3187), '1.SKB4.640189.21.D3'], [Well(3235), '1.SKB4.640189.21.D4'], [Well(3283), '1.SKB4.640189.21.D5'], [Well(3331), '1.SKB4.640189.21.D6'], [Well(3379), '1.SKB4.640189.21.D7'], [Well(3427), '1.SKB4.640189.21.D8'], [Well(3475), '1.SKB4.640189.21.D9'], [Well(3523), '1.SKB4.640189.21.D10'], [Well(3571), '1.SKB4.640189.21.D11'], [Well(3619), '1.SKB4.640189.21.D12']], '1.SKB5.640181': [[Well(3097), '1.SKB5.640181.21.E1'], [Well(3145), '1.SKB5.640181.21.E2'], [Well(3193), '1.SKB5.640181.21.E3'], [Well(3241), '1.SKB5.640181.21.E4'], [Well(3289), '1.SKB5.640181.21.E5'], [Well(3337), '1.SKB5.640181.21.E6'], [Well(3385), '1.SKB5.640181.21.E7'], [Well(3433), '1.SKB5.640181.21.E8'], [Well(3481), '1.SKB5.640181.21.E9'], [Well(3529), '1.SKB5.640181.21.E10'], [Well(3577), '1.SKB5.640181.21.E11'], [Well(3625), '1.SKB5.640181.21.E12']], '1.SKB6.640176': [[Well(3103), '1.SKB6.640176.21.F1'], [Well(3151), '1.SKB6.640176.21.F2'], [Well(3199), '1.SKB6.640176.21.F3'], [Well(3247), '1.SKB6.640176.21.F4'], [Well(3295), '1.SKB6.640176.21.F5'], [Well(3343), '1.SKB6.640176.21.F6'], [Well(3391), '1.SKB6.640176.21.F7'], [Well(3439), '1.SKB6.640176.21.F8'], [Well(3487), '1.SKB6.640176.21.F9'], [Well(3535), '1.SKB6.640176.21.F10'], [Well(3583), '1.SKB6.640176.21.F11'], [Well(3631), '1.SKB6.640176.21.F12']] } self.assertEqual(tester.duplicates, exp) self.assertEqual(tester.unknown_samples, []) exp = tester.get_well(1, 1) exp.composition.update('Unknown') self.assertEqual(tester.unknown_samples, [exp]) exp.composition.update('1.SKB1.640202') # test that the quantification_processes attribute correctly # orders multiple processes in order from oldest to newest tester2 = Plate(26) self.assertEqual(len(tester2.quantification_processes), 2) self.assertEqual( tester2.quantification_processes[0].date, datetime.strptime("2017-10-25 19:10:25-0700", '%Y-%m-%d %H:%M:%S%z')) self.assertEqual( tester2.quantification_processes[1].date, datetime.strptime("2017-10-26 03:10:25-0700", '%Y-%m-%d %H:%M:%S%z'))
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) if plate_type == '16S library prep': # for 16S, we calculate each sample independently params['total_each'] = True # constant accounts for both concentrations (ng/uL) and volumes # (uL) in the same unit params['vol_constant'] = 1 pool_vals = function(raw_concs, **params) if plate_type == 'shotgun library prep': # for shotgun, we calculate to a target total pool size params['total_each'] = False # constant handles volumes in nanoliters and concentrations in # molarity (mol / L) params['vol_constant'] = 10 ** 9 pool_vals = function(comp_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