Exemplo n.º 1
0
    def get(self, process_id):
        try:
            process = PoolingProcess(int(process_id))
        except LabControlUnknownIdError:
            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")
Exemplo n.º 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 pooling
     # 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})
Exemplo n.º 3
0
    def _compute_pools(self, plate_info):
        super()._compute_pools(plate_info)

        self.params['total_each'] = False
        self.params['vol_constant'] = 10 ** 9
        pool_vals = self.function(self.raw_concs, **self.params)

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

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

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

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

        return output
Exemplo n.º 4
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))
Exemplo n.º 5
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)
Exemplo n.º 6
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
Exemplo n.º 7
0
    def _compute_pools(self, plate_info):
        super()._compute_pools(plate_info)

        # pool_vals looks like its needed in the output
        pool_vals = self.function(self.raw_concs, **self.params)

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

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

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

        # store output values
        output = {}
        output['pool_vals'] = pool_vals
        output['pool_blanks'] = self.comp_blanks.tolist()
        output['plate_names'] = self.plate_names.tolist()
        output['plate_id'] = self.plate_id
        output['destination'] = self.params['destination']
        output['robot'] = self.params['robot']
        output['blank_vol'] = self.params['blank_vol']
        output['blank_num'] = self.params['blank_num']
        output['total_conc'] = total_c
        output['total_vol'] = total_v
        output['quant-process-id'] = self.quant_process_id

        return output
Exemplo n.º 8
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 LabControlUnknownIdError:
             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)
Exemplo n.º 9
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'])

            # 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))
Exemplo n.º 10
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
Exemplo n.º 11
0
    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)
Exemplo n.º 12
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)

        # 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