def tearDown(self): from qtools.model import Session Session.delete(self.testUser) Session.delete(self.testProject) Session.delete(self.readQLP) Session.delete(self.unreadQLP) Session.commit()
def runs(self, id=None): c.dg = Session.query(DropletGenerator).get(int(id)) if not c.dg: abort(404) reprocess_config_id = request.params.get('rp_id', None) if reprocess_config_id: reprocess_config_id = int(reprocess_config_id) runs = Session.query(DropletGeneratorRun).filter( and_(DropletGeneratorRun.droplet_generator_id == c.dg.id, DropletGeneratorRun.run_number != None)).all() run_dict = dict([(run.run_number, run) for run in runs]) wells = Session.query(WellMetric, QLBWell.id, QLBWell.sample_name, QLBWell.dg_run_number, QLBWell.consumable_channel_num)\ .join(QLBWell)\ .join(PlateMetric)\ .filter(and_(QLBWell.droplet_generator_id == id, QLBWell.dg_run_number != None, PlateMetric.reprocess_config_id == reprocess_config_id))\ .order_by(QLBWell.dg_run_number, QLBWell.consumable_channel_num).all() sorted_runs = sorted(groupinto(wells, lambda tup: (tup[3])), key=operator.itemgetter(0)) c.runs = [(run_id, run_dict[run_id], sorted(info, key=operator.itemgetter(4))) for run_id, info in sorted_runs if run_dict.get(run_id, None)] #raise Exception, c.runs return render('/product/dg/runs.html')
def apply_setup_to_plate(qlplate, dbplate): """ Determine if a plate has an applicable template, either by explicit setting or by implicit naming. :param qlplate: The QLP file to read :param dbplate: The DB plate to update """ if qlplate.plate_setup_id: setup = Session.query(PlateSetup).get(int(qlplate.plate_setup_id)) if setup: inherit_setup_attributes(dbplate, setup) return True dirname = dbplate.qlbplate.file.dirname basename = dbplate.qlbplate.file.basename complete_name = basename[:-4] # -- .qlp setups = Session.query(PlateSetup).order_by('prefix desc').all() for setup in setups: if complete_name.startswith(setup.prefix): inherit_setup_attributes(dbplate, setup) return True return False
def __vendor_enzymes(self, name): vendor = Session.query(Vendor).filter_by(name=unicode(name)).first() # this might be better off with a regular SQL statement all_enzymes = Session.query(VendorEnzyme, Enzyme.name, Enzyme.cutseq, Enzyme.methylation_sensitivity,\ func.sum(VendorEnzyme.stock_units).label('total_stock_units') ).join(Enzyme).filter(VendorEnzyme.vendor_id == vendor.id).group_by(VendorEnzyme.enzyme_id).all() return all_enzymes
def make_plate_name(plate, experiment_name=None): """ Given a plate and assigned project, operator and experiment, generate a name that conforms to the QTools naming standard. Name will be project_operator_experiment. :param plate: :param experiment_name: :return: """ # this is the hard way, before the relation is saved. if plate.project_id: project = Session.query(Project).get(plate.project_id) if project: if project.code: project_code = project.code else: project_code = project.name else: project_code = '' else: project_code = '' operator = Session.query(Person).get(plate.operator_id) if operator: user_code = operator.name_code else: user_code = '' fields = [project_code, user_code, experiment_name] return '_'.join([field for field in fields if field])
def apply_template_to_plate(qlplate, dbplate): """ Determine if a plate has an applicable template, either by explicit setting or by implicit naming. :param qlplate: The QLP file to read :param dbplate: The DB plate to update """ # new-style: if plate file has plate_template_id in it, # just bind if qlplate.plate_template_id: template = Session.query(PlateTemplate).get(int(qlplate.plate_template_id)) if template: inherit_template_attributes(dbplate, template) return True # otherwise, check the name dirname = dbplate.qlbplate.file.dirname basename = dbplate.qlbplate.file.basename complete_name = basename[:-4] # -- .qlp # duplicate prefixes are possible; use most recent templates = Session.query(PlateTemplate).order_by('prefix desc, id desc').all() for template in templates: if complete_name.startswith(template.prefix): inherit_template_attributes(dbplate, template) return True return False
def by_well_tag(self): well_tag_field = fl.well_tag_field(str(self.form_result['well_tag'])) c.group_by_plate = self.form_result['group_by_plate'] c.tag_id = self.form_result['well_tag'] c.tag_name = Session.query(WellTag).get(c.tag_id).name c.form = h.LiteralFormSelectPatch( value = {'well_tag': well_tag_field['value'], 'group_by_plate': [u'1' if c.group_by_plate else u'0']}, option = {'well_tag': [('--','--')]+well_tag_field['options'], 'group_by_plate': [(u'1', '')]} ) well_tags = Session.query(WellTag).\ filter_by(id=c.tag_id).\ options(joinedload_all(WellTag.tag_wells, QLBWell.plate, QLBPlate.file, innerjoin=True), joinedload_all(WellTag.tag_wells, QLBWell.plate, QLBPlate.plate, innerjoin=True)).\ all() c.label_names = [] if not len(well_tags): c.wells = [] c.well_groups = [] elif c.group_by_plate: wells = sorted(well_tags[0].wells, key=lambda well: (well.plate_id, well.well_name)) well_groups = [(plate, list(wells)) for plate, wells in itertools.groupby(wells, lambda well: well.plate)] c.well_groups = sorted(well_groups, key=lambda tup: tup[0].host_datetime) c.well_groups.reverse() else: c.wells = sorted(well_tags[0].wells, key=lambda well: well.host_datetime) c.wells.reverse() return render('/box2/by_well_tag.html')
def reader_history(self, id=None, admin=True): box2 = self.__setup_box2_context_by_code(id) c.admin = admin != 'False' logs = Session.query(Box2Log).filter_by(box2_id=box2.id)\ .order_by('time_effective desc')\ .options(joinedload_all(Box2Log.circuit))\ .all() statuses = Session.query(DRStatusLog).filter_by(box2_id=box2.id)\ .order_by('time_effective desc')\ .options(joinedload_all(DRStatusLog.reporter))\ .all() fixes = Session.query(DRFixLog).filter_by(box2_id=box2.id)\ .order_by('time_effective desc')\ .all() log_pairs = [(logs[i].time_effective, [logs[i],(logs[i+1] if i < len(logs)-1 else None)]) for i in range(len(logs))] for pair in log_pairs: pair[1].append((sorted(box2log_mv.labeleditems(pair[1][0]).items()), sorted(box2log_mv.labeleditems(pair[1][1]).items()))) status_pairs = [(status.time_effective, status) for status in statuses] fix_pairs = [(fix.time_effective, fix) for fix in fixes] changes = log_pairs + status_pairs + fix_pairs c.changes = sorted(changes, key=operator.itemgetter(0)) c.changes.reverse() return render('/admin/reader_history.html')
def command(self): app = self.load_wsgi_app() min_id = 0 if len(self.args) > 1: min_id = self.args[0] storage = QLStorageSource(app.config) qlbplates = Session.query(QLBPlate).filter(QLBPlate.id > min_id).order_by('id').all() for qlbplate in qlbplates: try: path = storage.qlbplate_path(qlbplate) except Exception: print "Could not find plate: %s (%s)" % (qlbplate.plate.name if qlbplate.plate else 'Name unknown', qlbplate.id) continue try: qlplate = get_plate(path) except Exception: print "Could not read plate: %s (%s)" % (qlbplate.plate.name if qlbplate.plate else 'Name Unknown', qlbplate.id) continue if qlplate.is_fam_vic: qlbplate.dyeset = QLBPlate.DYESET_FAM_VIC elif qlplate.is_fam_hex: qlbplate.dyeset = QLBPlate.DYESET_FAM_HEX elif qlplate.is_eva_green: qlbplate.dyeset = QLBPlate.DYESET_EVA else: qlbplate.dyeset = QLBPlate.DYESET_UNKNOWN print "Assigned dye %s - %s (%s)" % (qlbplate.dyeset, qlbplate.plate.name if qlbplate.plate else 'Name Unknown', qlbplate.id) Session.commit()
def register_algorithm(self): storage = QSAlgorithmSource(config) existing_folders = [tup[0] for tup in Session.query(ReprocessConfig.original_folder).all()] errors = dict() src_dir = self.form_result['src_dir'] if src_dir in existing_folders: errors['src_dir'] = 'This algorithm has already been registered.' elif not storage.source_path_exists(src_dir): errors['src_dir'] = 'This algorithm is not accessible in the file system.' if self.form_result['peak_detection_version'] == (0,0): # this is arbitrary peak_detection_version = (0, QUANTASOFT_DIR_VERSION_RE.search(src_dir).group(1).split('_')[-1]) else: peak_detection_version = self.form_result['peak_detection_version'] if self.form_result['peak_quantitation_version'] == (0,0): peak_quantitation_version = (0, QUANTASOFT_DIR_VERSION_RE.search(src_dir).group(1).split('_')[-1]) else: peak_quantitation_version = self.form_result['peak_quantitation_version'] if errors: resp = self._algorithms_base() defaults = AlgorithmRegisterForm.from_python(self.form_result) return h.render_bootstrap_form(resp, defaults=defaults, errors=errors, error_formatters=h.tw_bootstrap_error_formatters) try: rp = ReprocessConfig(name=src_dir.split(os.path.sep)[0], code=self.form_result['code'], peak_detection_major=peak_detection_version[0], peak_detection_minor=peak_detection_version[1], peak_quant_major=peak_quantitation_version[0], peak_quant_minor=peak_quantitation_version[1], trigger_fixed_width=100, active=True, cluster_mode=ReprocessConfig.CLUSTER_MODE_CLUSTER, original_folder=src_dir) storage.add_reprocessor(src_dir, self.form_result['code']) Session.add(rp) Session.commit() session['flash'] = 'New algorithm reprocessor created.' session.save() return redirect(url(controller='product', action='algorithms')) except shutil.Error: session['flash'] = 'Could not copy source algorithm to destination.' session['flash_class'] = 'error' session.save() return redirect(url(controller='product', action='algorithms')) except IOError: session['flash'] = "Could not access the algorithm's file system." session['flash_class'] = 'error' session.save() return redirect(url(controller='product', action='algorithms'))
def batch_plate_template_download(self, id=None): plate = self.__load_batch_plate(id) box2 = Session.query(Box2).get(self.form_result['box2_id']) if not plate or not box2: abort(404) code = plate.batch.plate_type.code if self.form_result['qc_plate']: plate.qc_plate = self.form_result['qc_plate'] Session.commit() # TODO FIXFIX or incorporate into model if plate.qc_plate: serial = 'QC' else: serial = box2.name.split(' ')[-1] # only mfgco supported right now if code == 'mfgco': qlt_file = "%s/carryover.qlt" % config['qlb.setup_template_store'] elif code == 'fvtitr': qlt_file = "%s/fvbatch_QC.qlt" % config['qlb.setup_template_store'] else: abort(404) response.headers['Content-Type'] = 'application/quantalife-template' h.set_download_response_header(request, response, "%s_%s.qlt" % (serial, plate.name)) response.headers['Pragma'] = 'no-cache' response.headers['Cache-Control'] = 'no-cache' return forward(FileApp(qlt_file, response.headerlist))
def batch_csfv_unhook(self): plate = self.__load_batch_plate(self.form_result['batch_plate_id']) plate.plate_id = None Session.commit() session['flash'] = 'CSFV QC plate discarded.' session.save() return redirect(url(controller='product', action='batch_plates', id=plate.mfg_batch_id))
def __update_batch_plate_record(self, record): record.dg_method = self.form_result['dg_method'] record.qc_plate = self.form_result['qc_plate'] and True or False record.plate_notes = self.form_result['plate_notes'] record.thermal_cycler_id = self.form_result['thermal_cycler_id'] Session.add(record) Session.commit()
def plate_query(): # writing it this way because the .join seems to muck up # filter_by statements downstream box2s = [tup[0] for tup in Session.query(Box2.id).all()] query = Session.query(Plate).filter(Plate.box2_id.in_(box2s)) return query
def sensitivity(self): enz = Session.query(Enzyme).get(self.form_result['enzyme']) if not self.form_result['sensitivity']: enz.methylation_sensitivity = None else: enz.methylation_sensitivity = self.form_result['sensitivity'] Session.commit() return "OK"
def save(self): if self.form_result['plate_setup_id']: ps = Session.query(PlateSetup).get(self.form_result['plate_setup_id']) prefix = ps.prefix elif self.form_result['plate_template_id']: pt = Session.query(PlateTemplate).get(self.form_result['plate_template_id']) prefix = pt.prefix else: prefix = 'output' response.headers['Content-Type'] = 'application/quantalife-template' h.set_download_response_header(request, response, "%s.qlt" % prefix) response.headers['Pragma'] = 'no-cache' # build a plate # TODO: add default fields plate = ExperimentMetadataQLPlate(channel_names=['FAM','VIC'], host_datetime=datetime.now(), host_machine='QTools', host_user='******', plate_template_id=self.form_result['plate_template_id'], plate_setup_id=self.form_result['plate_setup_id']) for cell in sorted(self.form_result['cells'], key=lambda c: c['cell_name']): well = ExperimentMetadataQLWell(name=cell['cell_name'], num_channels=2, sample=cell['sample'], experiment_comment=cell['experiment_comment'], experiment_name=cell['experiment_name'], experiment_type=cell['experiment_type'], temperature=cell['temperature'], enzyme=cell['enzyme'], enzyme_conc=cell['enzyme_conc'], additive=cell['additive'], additive_conc=cell['additive_conc'], expected_cpd=cell['expected_cpd'], expected_cpul=cell['expected_cpul'], target_copy_num=cell['target_copy_num'], ref_copy_num=cell['ref_copy_num'], dg_cartridge=cell['cartridge'], supermix=cell['supermix']) well.channels[0].target = cell['fam_target'] well.channels[0].type = cell['fam_type'] well.channels[1].target = cell['vic_target'] well.channels[1].type = cell['vic_type'] plate.wells[str(cell['cell_name'])] = well # generate QLT # TODO: rowcol order writer = QLTWriter(rowcol_order=self.form_result['rowcol_order'], fgcolorfunc=self.__qlt_fgcolorfunc, bgcolorfunc=self.__qlt_bgcolorfunc) qlt = writer.getbytes(plate) return qlt
def instock(self): enz = Session.query(VendorEnzyme).get(self.form_result['vendor_enzyme_id']) if self.form_result['in_stock']: enz.stock_units = 1 else: enz.stock_units = 0 Session.commit() return 'OK'
def _list_base(self): groove_test = Session.query(Project).filter_by(name="GrooveTest").first() query = Session.query(PlateSetup).filter_by(project_id=groove_test.id).order_by("time_updated desc, name") c.paginator = paginate.Page(query, page=int(request.params.get("page", 1)), items_per_page=20) c.pager_kwargs = {} c.plate_type_field = groove_plate_type_field() return render("/product/groove/list.html")
def enzyme_conc_create(self): conc = EnzymeConcentration() for k, v in self.form_result.items(): setattr(conc, k, v) Session.add(conc) Session.commit() redirect(url(controller="assay", action="view", id=self.form_result["assay_id"]))
def save_reagents(self, id=None): self.__load_context() setup, struct = self.__load_setup(id) if not setup: abort(404) for k, v in self.form_result.items(): setattr(setup, k, v) Session.commit() redirect(url(controller='setup', action='dg', id=id, beta=c.beta))
def _algcommand_base(self): ags = Session.query(AnalysisGroup).filter_by(active=True).order_by(AnalysisGroup.name).all() rps = Session.query(ReprocessConfig).filter_by(active=True).order_by(ReprocessConfig.name).all() c.analysis_groups = {'value': '', 'options': [(ag.id, ag.name) for ag in ags]} c.reprocess_configs = {'value': '', 'options': [(rp.id, rp.name) for rp in rps]} return render('/product/algorithms/select.html')
def update_reader(self): log_entry = self.__make_box2_log_entry(self.form_result) Session.add(log_entry) Session.commit() box2 = Session.query(Box2).get(self.form_result['box2_id']) session['flash'] = 'Configuration for %s updated.' % box2.name session.save() redirect(url(controller='admin', action='reader_history', id=box2.code))
def __form_to_model(self, form, model=None): if not model: model = SequenceGroupTag() Session.add(model) model.name = form['name'] model.notes = form['notes'] model.owner_id = form['owner_id'] Session.merge(model) return model
def update(self, id=None): batch = self.__batch(id) batch.manufacturer = self.form_result["manufacturer"] batch.insert = self.form_result["insert"] batch.consumable_molding_style_id = self.form_result["molding_style"] batch.consumable_bonding_style_id = self.form_result["bonding_style"] batch.manufacturing_date = self.form_result["manufacture_date"] batch.bside = self.form_result["bside"] Session.commit() session.flash = "Updated batch %s" % batch.lot_num return redirect(url(controller="consumable", action="details", id=batch.id))
def donotrun(self, id=None): c.beta = True setup, struct = self.__load_setup(id) if not setup: abort(404) setup.donotrun = True Session.commit() session['flash'] = "Marked %s as skipped." % setup.name session.save() redirect(url(controller='setup', action='list', beta=c.beta))
def __save_setup(self, setup, key, block): setup_obj = json.loads(setup.setup or '{}') # Hack. if type(block) == type(dict()) and block.get('notes', None) is not None: notes = block.pop('notes') setup.notes = notes setup_obj[key] = block setup.setup = json.dumps(setup_obj) if key == 'progress': setup.completed = (self.__check_progress(setup_obj) == 'Done') Session.commit()
def create(self): self.__load_context() plate_setup = PlateSetup() plate_setup.project_id = self.form_result['project_id'] plate_setup.author_id = self.form_result['author_id'] plate_setup.name = self.form_result['name'] plate_setup.prefix = make_setup_name(plate_setup) Session.add(plate_setup) Session.commit() redirect(url(controller='setup', action='consumable', id=plate_setup.id, beta=c.beta))
def delete_file(self, id=None): self.__setup_box2_code_context(id) thefile = self.__file_id_query(c.box2.id, self.form_result['file_id']) if not thefile: abort(404) Session.delete(thefile) Session.commit() session['flash'] = 'File deleted.' session.save() return redirect(url(controller='metrics', action='certification', id=c.box2.code))
def save_name(self, id=None): self.__load_context() setup, struct = self.__load_setup(id) if not setup: abort(404) for k, v in self.form_result.items(): setattr(setup, k, v) setup.prefix = make_setup_name(setup) Session.commit() redirect(url(controller='setup', action='consumable', id=id, beta=c.beta))
def command(self): self.load_wsgi_app() qlbplates = Session.query(QLBPlate).\ filter(and_(QLBPlate.file_id != None, QLBPlate.plate_id != None)).\ order_by(desc(QLBPlate.id)).\ options(joinedload_all(QLBPlate.plate, innerjoin=True)) for qlbplate in qlbplates: qlbplate.plate.score = Plate.compute_score(qlbplate.plate) print "%s: %s points" % (qlbplate.plate.id, qlbplate.plate.score) Session.commit()