Example #1
0
    def get(self, process_id):
        try:
            process = PoolingProcess(int(process_id))
        except LabmanUnknownIdError:
            raise HTTPError(404, reason='PoolingProcess %s does not exist'
                                        % process_id)
        text = process.generate_pool_file()
        plate_names_set = {x[0].container.plate.external_id for x in
                           process.components}

        # Note that PoolingProcess objects (what `process` is above) definitely
        # *can* validly have components from multiple plates: a user could
        # chose to make a "plate pool" from more than one amplicon library prep
        # plate.  However, as of 10/09/2018, the wet lab apparently currently
        # chooses not to do this, and instead chooses to make one pool per
        # library prep plate.  Given this self-imposed limitation, they expect
        # to be able to have the (one-and-only) library plate name embedded in
        # the name of the resulting normpool file.  This
        # *file naming convention* won't work--or at least, won't work as they
        # expect it to--if there are multiple plates represented in the pool,
        # so if that happens we generate an error below, at the point where the
        #  *file name* is generated.  If they decide they want to allow
        # themselves to make plate pools from multiple plates, all they need to
        # do is decide on a more flexible naming convention, and
        # we can change this naming code and remove this error condition.
        if len(plate_names_set) > 1:
            raise ValueError("Unable to generate normpool file name for pool "
                             "based on more than one plate: " +
                             ", ".join(str(x) for x in plate_names_set))

        plate_name = plate_names_set.pop()
        name_pieces = [plate_name, "normpool"]
        self.deliver_text(name_pieces, process, text, extension="csv")
Example #2
0
 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})
Example #3
0
    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'])
            pool_name = 'Pool from plate %s (%s)' % (
                plate.external_id,
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            # create input molar percentages
            pcts = calc_pool_pcts(plate_result['comp_vals'],
                                  plate_result['pool_vals'])
            quant_process = plate.quantification_process
            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))
Example #4
0
    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})
Example #5
0
def create_pools_pool_process(user, quant_process, pools):
    input_compositions = [
        {'composition': p, 'input_volume': 1, 'percentage_of_output': 1/9.0}
        for p in pools]
    pool_process = PoolingProcess.create(
        user, quant_process, 'New pool name %s' % datetime.now(), 5,
        input_compositions, {"function": "amplicon_pool", "parameters": {}})
    return pool_process
Example #6
0
 def test_properties(self):
     tester = Tube(7)
     self.assertEqual(tester.external_id, 'Test Pool from Plate 1')
     self.assertFalse(tester.discarded)
     self.assertEqual(tester.remaining_volume, 96)
     self.assertIsNone(tester.notes)
     self.assertEqual(tester.latest_process, PoolingProcess(1))
     self.assertEqual(tester.container_id, 3079)
     self.assertEqual(tester.composition, PoolComposition(1))
Example #7
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 LabmanUnknownIdError:
                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, plate.quantification_process)

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

            if pool_func_data['function'] == 'amplicon':
                pool_func_data['parameters']['epmotion-'] = process.robot.id
                pool_func_data['parameters'][
                    'dest-tube-'] = process.destination
        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')

        epmotions = Equipment.list_equipment('EpMotion')
        self.render('library_pooling.html',
                    plate_ids=plate_ids,
                    epmotions=epmotions,
                    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)
Example #8
0
    def get(self, process_id):
        try:
            process = PoolingProcess(int(process_id))
        except LabmanUnknownIdError:
            raise HTTPError(404, reason='PoolingProcess %s does not exist'
                            % process_id)
        text = process.generate_pool_file()

        filename = 'PoolFile_%s_%s.csv' % (
            re.sub('[^0-9a-zA-Z\-\_]+', '_',
                   process.pool.container.external_id), process.id)

        self.set_header('Content-Type', 'text/csv')
        self.set_header('Expires', '0')
        self.set_header('Cache-Control', 'no-cache')
        self.set_header('Content-Disposition', 'attachment; filename='
                        '%s.csv' % filename)
        self.write(text)
        self.finish()
Example #9
0
def create_plate_pool_process(user, quant_process, plate, func_data):
    input_compositions = []
    echo = Equipment(8)
    for well in chain.from_iterable(plate.layout):
        if well is not None:
            input_compositions.append({
                'composition': well.composition, 'input_volume': 1,
                'percentage_of_output': 1/9.0})
    pool_process = PoolingProcess.create(
        user, quant_process, 'New test pool name %s' % datetime.now(),
        4, input_compositions, func_data, robot=echo)
    return pool_process
Example #10
0
 def get(self):
     pool_ids = self.get_arguments('pool_id')
     process_id = self.get_argument('process_id', None)
     pool_comp_info = None
     pool_name = None
     if process_id is not None:
         try:
             process = PoolingProcess(process_id)
         except LabmanUnknownIdError:
             raise HTTPError(404, reason="Pooling process %s doesn't exist"
                                         % process_id)
         pool_comp_info = [[p.id, p.raw_concentration]
                           for p, _ in process.components]
         pool_name = process.pool.container.external_id
     self.render('pool_pooling.html', pool_ids=pool_ids,
                 process_id=process_id, pool_comp_info=pool_comp_info,
                 pool_name=pool_name)
Example #11
0
    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