def generate_output(project_id, dest_plate_list, best_sample_struct,total_lanes, req_lanes, lane_maps, rounded_ratios, target_clusters, clusters_per_lane, extra_lanes, lane_volume, pool_excess, final_pool_sizes, volume_ratios, desired_ratios): """"Gathers the container id and well name for all samples in project""" timestamp = datetime.fromtimestamp(time()).strftime('%Y-%m-%d_%H:%M') #Cred to Denis for providing a base epp location = dict() lims = Lims(BASEURI, USERNAME, PASSWORD) allProjects = lims.get_projects() for proj in allProjects: if proj.id == project_id: projName = proj.name break #Sets up source id #All normalization processes for project norms=['Library Normalization (MiSeq) 4.0', 'Library Normalization (Illumina SBS) 4.0','Library Normalization (HiSeq X) 1.0'] pros=lims.get_processes(type=norms, projectname=projName) #For all processes for p in pros: #For all artifacts in process for o in p.all_outputs(): #If artifact is analyte type and has project name in sample if o.type=="Analyte" and project_id in o.name: location[o.name.split()[0]] = list() location[o.name.split()[0]].append(o.location[0].id) location[o.name.split()[0]].append(o.location[1]) #Continue coding from here generate_summary(projName, best_sample_struct, timestamp, project_id, dest_plate_list, total_lanes, req_lanes, lane_maps, rounded_ratios, target_clusters, clusters_per_lane, extra_lanes, volume_ratios, desired_ratios, lane_volume, pool_excess) generate_csv(projName, timestamp, location, dest_plate_list, total_lanes, best_sample_struct, rounded_ratios, lane_volume, pool_excess, final_pool_sizes) generate_dumpfile(projName, timestamp, location, dest_plate_list, total_lanes, best_sample_struct, rounded_ratios, lane_volume, pool_excess, final_pool_sizes)
def main(args): log = [] lims = Lims(BASEURI, USERNAME, PASSWORD) process = Process(lims, id=args.pid) for swp_iomap in process.input_output_maps: if swp_iomap[1]['output-generation-type'] != 'PerInput': continue inp_artifact = swp_iomap[0]['uri'] amount_check_pros = lims.get_processes( type='Amount confirmation QC', inputartifactlimsid=inp_artifact.id) amount_check_pros.sort(reverse=True, key=lambda x: x.date_run) try: correct_amount_check_pro = amount_check_pros[0] except KeyError: sys.exit( "Cannot find an Amount Confirmation QC step for artifact {}". format(inp_artifact.id)) else: for iomap in correct_amount_check_pro.input_output_maps: if iomap[1]['output-generation-type'] != 'PerInput': continue if iomap[0]['limsid'] == inp_artifact.id: for udf_name in [ 'Concentration', 'Conc. Units', 'Total Volume (uL)' ]: try: swp_iomap[1]['uri'].udf[udf_name] = iomap[1][ 'uri'].udf[udf_name] except: import pdb pdb.set_trace() swp_iomap[1]['uri'].udf['Amount taken (ng)'] = iomap[1][ 'uri'].udf['Amount to take (ng)'] swp_iomap[1]['uri'].put()
def main(args): log = [] lims = Lims(BASEURI,USERNAME,PASSWORD) process = Process(lims, id=args.pid) for swp_iomap in process.input_output_maps: if swp_iomap[1]['output-generation-type'] != 'PerInput': continue inp_artifact = swp_iomap[0]['uri'] amount_check_pros = lims.get_processes(type='Amount confirmation QC', inputartifactlimsid=inp_artifact.id) amount_check_pros.sort(reverse=True, key=lambda x:x.date_run) try: correct_amount_check_pro = amount_check_pros[0] except KeyError: sys.exit("Cannot find an Amount Confirmation QC step for artifact {}".format(inp_artifact.id)) else: for iomap in correct_amount_check_pro.input_output_maps: if iomap[1]['output-generation-type'] != 'PerInput': continue if iomap[0]['limsid'] == inp_artifact.id: for udf_name in ['Concentration', 'Conc. Units', 'Total Volume (uL)']: try: swp_iomap[1]['uri'].udf[udf_name] = iomap[1]['uri'].udf[udf_name] except: import pdb;pdb.set_trace() swp_iomap[1]['uri'].udf['Amount taken (ng)'] = iomap[1]['uri'].udf['Amount to take (ng)'] swp_iomap[1]['uri'].put()
def main(args): log = [] lims = Lims(BASEURI, USERNAME, PASSWORD) process = Process(lims, id=args.pid) for io in process.input_output_maps: if io[1]['output-generation-type'] != 'PerInput': continue try: starting_amount = obtain_amount(io[0]['uri']) except Exception as e: log.append(str(e)) starting_amount = 0 log.append("Starting amount of {} : {} ng".format( io[0]['uri'].samples[0].name, starting_amount)) current_amount = starting_amount #preps preps = lims.get_processes( inputartifactlimsid=io[0]['uri'].id, type=["Setup Workset/Plate", "Amount confirmation QC"]) for pro in preps: if pro.id == args.pid: continue # skip the current step for prepio in pro.input_output_maps: if prepio[1]['output-generation-type'] == 'PerInput' and prepio[ 0]['uri'].id == io[0]['uri'].id: if "Amount taken (ng)" in prepio[1][ 'uri'].udf: #should always be true prep_amount = prepio[1]['uri'].udf["Amount taken (ng)"] log.append( "Removing {} ng for prep {} for sample {}".format( prep_amount, pro.id, io[0]['uri'].samples[0].name)) current_amount = current_amount - prep_amount else: log.append( "No Amount Taken found for prep {} of sample {}". format(pro.id, io[0]['uri'].samples[0].name)) if current_amount < 0: log.append( "Estimated amount for sample {} is {}, correcting to zero". format(io[0]['uri'].samples[0].name, current_amount)) current_amount = 0 update_output_values(io[0]['uri'], io[1]['uri'], current_amount) with open("amount_check_log.txt", "w") as f: f.write("\n".join(log)) for out in process.all_outputs(): if out.name == "QC Assignment Log File": for f in out.files: lims.request_session.delete(f.uri) lims.upload_new_file(out, "amount_check_log.txt")
def test_C(server_test1): # GIVEN: A lims with a process with: # process type: 'CG002 - qPCR QC (Library Validation) (Dev)' # input artifact: '2-1155237' # Udf 'Instrument Used': 'Cava' # WHEN creating a genologics Lims object and filtering on the fields. lims = Lims("http://127.0.0.1:8000", 'dummy', 'dummy') processes = lims.get_processes(type=['CG002 - qPCR QC (Library Validation) (Dev)'], inputartifactlimsid=['2-1155237'], udf={'Instrument Used': 'Cava'}) # Then the process should be found assert processes == [Process(lims, id='24-168017')]
def main(args): log = [] lims = Lims(BASEURI,USERNAME,PASSWORD) process = Process(lims, id=args.pid) for io in process.input_output_maps: if io[1]['output-generation-type'] != 'PerInput': continue try: starting_amount = obtain_amount(io[0]['uri']) except Exception as e: log.append(str(e)) starting_amount = 0 log.append("Starting amount of {} : {} ng".format(io[0]['uri'].samples[0].name, starting_amount)) current_amount = starting_amount #preps preps = lims.get_processes(inputartifactlimsid=io[0]['uri'].id, type=["Setup Workset/Plate", "Amount confirmation QC"]) for pro in preps: if pro.id == args.pid: continue # skip the current step for prepio in pro.input_output_maps: if prepio[1]['output-generation-type'] == 'PerInput' and prepio[0]['uri'].id == io[0]['uri'].id: if "Amount taken (ng)" in prepio[1]['uri'].udf: #should always be true prep_amount = prepio[1]['uri'].udf["Amount taken (ng)"] log.append("Removing {} ng for prep {} for sample {}".format(prep_amount, pro.id, io[0]['uri'].samples[0].name)) current_amount = current_amount - prep_amount else: log.append("No Amount Taken found for prep {} of sample {}".format(pro.id, io[0]['uri'].samples[0].name)) if current_amount < 0: log.append("Estimated amount for sample {} is {}, correcting to zero".format(io[0]['uri'].samples[0].name, current_amount)) current_amount = 0 update_output_values(io[0]['uri'], io[1]['uri'], current_amount) with open("amount_check_log.txt", "w") as f: f.write("\n".join(log)) for out in process.all_outputs(): if out.name == "QC Assignment Log File" : for f in out.files: lims.request_session.delete(f.uri) lims.upload_new_file(out, "amount_check_log.txt")
NOTE: You need to set the BASEURI, USERNAME AND PASSWORD. Per Kraulis, Science for Life Laboratory, Stockholm, Sweden. """ from genologics.lims import Lims # Login parameters for connecting to a LIMS instance. # NOTE: Modify according to your setup. from genologics.site_cloud import BASEURI, USERNAME, PASSWORD # Create the LIMS interface instance, and check the connection and version. lims = Lims(BASEURI, USERNAME, PASSWORD) lims.check_version() # Get the list of all processes. processes = lims.get_processes() print len(processes), 'processes in total' process = processes[0] print process, process.type, process.type.name for process in lims.get_processes(type=process.type.name): print process name = '1a. Fragment DNA (TruSeq DNA) 3.0' print name for process in lims.get_processes(type=name): print process
def namesetter(PID): lims = Lims(BASEURI, USERNAME, PASSWORD) lims.check_version() #Find LIMS entry with same PID allProjects = lims.get_projects() for proj in allProjects: if proj.id == PID: limsproject = proj.name break #Error handling if not 'limsproject' in locals(): print("{} not available in LIMS.".format(PID)) return None #Enter project summary process stepname=['Project Summary 1.3'] process=lims.get_processes(type=stepname, projectname=limsproject) #Error handling if process == []: print("{} for {} is not available in LIMS.".format(stepname, limsproject)) return None loop = True while loop: if "Bioinfo responsible" in process[0].udf: response = process[0].udf["Bioinfo responsible"] else: response = "Unassigned" print("Existing Bioinfo responsible for project {} aka {} is: {}".format(limsproject, PID, response.encode('utf-8'))) #Checks for valid name in_responsibles = False config_responsibles =Udfconfig(lims, id="1128") while not in_responsibles: if sys.version_info[0] == 3: newname = input("Enter name of new Bioinfo responsible: ") elif sys.version_info[0] == 2: newname = raw_input("Enter name of new Bioinfo responsible: ") for names in config_responsibles.presets: if newname in names: in_responsibles = True newname = names if not in_responsibles: print("Subset {} not found in accepted Bioinfo responsible list.".format(newname)) else: print("Suggested name is {}".format(newname)) if sys.version_info[0] == 3: confirmation = input("Project {} aka {} will have {} as new Bioinfo responsible, is this correct (Y/N)? ".format(limsproject, PID, newname)) elif sys.version_info[0] == 2: confirmation = raw_input("Project {} aka {} will have {} as new Bioinfo responsible, is this correct (Y/N)? ".format(limsproject, PID, newname)) if confirmation == 'Y' or confirmation == 'y': try: newname.encode('ascii') process[0].udf["Bioinfo responsible"] = str(newname) process[0].put() print("Project {} aka {} assigned to {}".format(limsproject, PID, newname)) return None except (UnicodeDecodeError, UnicodeEncodeError): #Weird solution due to put function process[0].udf["Bioinfo responsible"] = response print("ERROR: You tried to use a special character, didn't you? Don't do that. New standards and stuff...") elif confirmation == 'N' or confirmation == 'n': loop = False else: print("Invalid answer.")
def generate_output(project, destid, total_lanes, req_lanes, lane_maps, acc_ratios): #Gathers the container id and well name for all samples in project #Cred to Denis for providing a base epp location = dict() lims = Lims(BASEURI, USERNAME, PASSWORD) allProjects = lims.get_projects() for proj in allProjects: if proj.id == project: projName = proj.name break #All normalization processes for project norms=['Library Normalization (MiSeq) 4.0', 'Library Normalization (Illumina SBS) 4.0','Library Normalization (HiSeq X) 1.0'] pros=lims.get_processes(type=norms, projectname=projName) #For all processes for p in pros: #For all artifacts in process for o in p.all_outputs(): #If artifact is analyte type and has project name in sample if o.type=="Analyte" and project in o.name: location[o.name.split()[0]] = list() location[o.name.split()[0]].append(o.location[0].id) location[o.name.split()[0]].append(o.location[1]) #PRINT section #Print stats including duplicates timestamp = datetime.fromtimestamp(time()).strftime('%Y-%m-%d_%H:%M') sumName = projName, "_summary_", timestamp,".txt" sumName = ''.join(sumName) with open(sumName, "w") as summary: if sum(req_lanes.values()) != 0: OPT = sum(total_lanes)/sum(req_lanes.values()) else: OPT = 0 output = "Ideal lanes (same schema): ", str(sum(req_lanes.values())) , ", Total lanes: ", str(sum(total_lanes)), ", OPT: ", str(round(OPT,3)),'\n' output = ''.join(output) summary.write( output ) output = "Unique pools: ", str(len(total_lanes)), ", Average pool duplication: ", str(sum(total_lanes)/float(len(total_lanes))) ,'\n' output = ''.join(output) summary.write( output ) bin = 0 for index in xrange(1, len(lane_maps)+1): bin += 1 summary.write('\n') output = "Wells ", str(bin) , '-' , str(bin+int(total_lanes[index-1])-1),':','\n' output = ''.join(output) summary.write( output ) bin += int(total_lanes[index-1]-1) for counter in xrange(1, len(lane_maps[index])): output = str(lane_maps[index][counter]),' ', str(acc_ratios[index][counter]), "%",'\n' output = ''.join(output) summary.write( output ) #Creates csv name = projName,"_repool_",timestamp,".csv" name = ''.join(name) wells = ['Empty','A','B','C','D','E','F','G','H'] #Index 0 is number, index 1 is Letter wellIndex = [1, 1] destNo = 0 with open(name, 'w') as csvfile: writer = csv.writer(csvfile) for index in xrange(1, len(lane_maps)+1): for dupes in xrange(1, int(total_lanes[index-1])+1): if lane_maps[index] == 0: raise Exception('Error: Project not logged in x_flowcells database!') for counter in xrange(1, len(lane_maps[index])): #<source plate ID>,<source well>,<volume>,<destination plate ID>,<destination well> #Destination well 200 microL, minimum pipette 2 microL; acc_ratios multiplied by 2. sample = lane_maps[index][counter] position = wells[wellIndex[1]],':',str(wellIndex[0]) position = ''.join(position) try: output = location[sample][0],location[sample][1],str(int(acc_ratios[index][counter]*2)),str(destid[destNo]),position except KeyError: print "Error: Samples incorrectly parsed into database, thus causing sample name conflicts!" if not acc_ratios[index][counter] == 0: writer.writerow(output) #Increment wellsindex if not acc_ratios[index][counter] == 0: if not wellIndex[1] >= 8: wellIndex[1] += 1 else: wellIndex[1] = 1 if not wellIndex[0] >= 8: wellIndex[0] += 1 else: wellIndex[0] = 1 destNo += 1 try: destid[destNo] except IndexError: print "Critical error; not enough destination plates provided"
def namesetter(PID): lims = Lims(BASEURI, USERNAME, PASSWORD) lims.check_version() #Find LIMS entry with same PID allProjects = lims.get_projects() for proj in allProjects: if proj.id == PID: limsproject = proj.name break #Error handling if not 'limsproject' in locals(): print "{} not available in LIMS.".format(PID) return None #Enter project summary process stepname=['Project Summary 1.3'] process=lims.get_processes(type=stepname, projectname=limsproject) #Error handling if process == []: print "{} for {} is not available in LIMS.".format(stepname, limsproject) return None loop = True while loop: if "Bioinfo responsible" in process[0].udf: response = process[0].udf["Bioinfo responsible"] else: response = "Unassigned" print "Existing Bioinfo responsible for project {} aka {} is: {}".format(limsproject, PID, response.encode('utf-8')) #Checks for valid name in_responsibles = False config_responsibles =Udfconfig(lims, id="1128") while not in_responsibles: newname = raw_input("Enter name of new Bioinfo responsible: ") for names in config_responsibles.presets: if newname in names: in_responsibles = True newname = names if not in_responsibles: print "Subset {} not found in accepted Bioinfo responsible list.".format(newname) else: print "Suggested name is {}".format(newname) confirmation = raw_input("Project {} aka {} will have {} as new Bioinfo responsible, is this correct (Y/N)? ".format(limsproject, PID, newname)) if confirmation == 'Y' or confirmation == 'y': try: newname.decode('ascii') process[0].udf["Bioinfo responsible"] = unicode(newname) process[0].put() print "Project {} aka {} assigned to {}".format(limsproject, PID, newname) return None except UnicodeDecodeError: #Weird solution due to put function process[0].udf["Bioinfo responsible"] = response print "ERROR: You tried to use a special character, didn't you? Don't do that. New standards and stuff..." elif confirmation == 'N' or confirmation == 'n': loop = False else: print "Invalid answer."