def runpgm(self,pgm,duration,waitForCompletion=True,volume=10,hotlidmode="TRACKING",hotlidtemp=1): if self.ptcrunning: logging.error("Attempt to start a progam on PTC when it is already running") if len(pgm)>8: logging.error("PTC program name (%s) too long (max is 8 char)"%pgm) # move to thermocycler worklist.flushQueue() self.lihahome() cmt="run %s"%pgm worklist.comment(cmt) #print "*",cmt worklist.pyrun("PTC\\ptclid.py OPEN") self.moveplate(decklayout.SAMPLEPLATE,"PTC") worklist.vector("Hotel 1 Lid",decklayout.HOTELPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) worklist.vector("PTC200lid",decklayout.PTCPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) worklist.romahome() worklist.pyrun("PTC\\ptclid.py CLOSE") # pgm="PAUSE30" # For debugging assert hotlidmode=="TRACKING" or hotlidmode=="CONSTANT" assert (hotlidmode=="TRACKING" and hotlidtemp>=0 and hotlidtemp<=45) or (hotlidmode=="CONSTANT" and hotlidtemp>30) worklist.pyrun('PTC\\ptcrun.py %s CALC %s,%d %d'%(pgm,hotlidmode,hotlidtemp,volume)) self.pgmStartTime=clock.pipetting self.pgmEndTime=duration*60+clock.pipetting self.ptcrunning=True Sample.addallhistory("{%s}"%pgm,addToEmpty=False,onlyplate=decklayout.SAMPLEPLATE.name) if waitForCompletion: self.waitpgm()
def waitpgm(self, sanitize=True): if not self.ptcrunning: return #print "* Wait for PTC to finish" if sanitize: self.sanitize() # Sanitize tips before waiting for this to be done worklist.comment("Wait for PTC") while self.pgmEndTime-clock.pipetting > 120: # Run any idle programs oldElapsed=clock.pipetting for ip in self.idlePgms: if self.pgmEndTime-clock.pipetting > 120: #print "Executing idle program with %.0f seconds"%(self.pgmEndTime-clock.pipetting) ip(self.pgmEndTime-clock.pipetting-120) if oldElapsed==clock.pipetting: # Nothing was done break worklist.flushQueue() # Just in case clock.pipandthermotime+=(clock.pipetting-self.pgmStartTime) clock.thermotime+=(self.pgmEndTime-clock.pipetting) clock.pipetting=self.pgmStartTime #print "Waiting for PTC with %.0f seconds expected to remain"%(self.pgmEndTime-clock.pipetting) self.lihahome() worklist.pyrun('PTC\\ptcwait.py') worklist.pyrun("PTC\\ptclid.py OPEN") # worklist.pyrun('PTC\\ptcrun.py %s CALC ON'%"COOLDOWN") # worklist.pyrun('PTC\\ptcwait.py') worklist.vector("PTC200lid",decklayout.PTCPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) worklist.vector("Hotel 1 Lid",decklayout.HOTELPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) worklist.vector("PTC200WigglePos",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.DONOTMOVE) worklist.vector("PTC200Wiggle",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.CLOSE,True) worklist.vector("PTC200Wiggle",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.OPEN,True) worklist.vector("PTC200WigglePos",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.DONOTMOVE) worklist.vector("PTC200Wiggle2Pos",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.DONOTMOVE) worklist.vector("PTC200Wiggle2",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.CLOSE,True) worklist.vector("PTC200Wiggle2",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.OPEN,True) worklist.vector("PTC200Wiggle2Pos",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.DONOTMOVE) worklist.vector("PTC200WigglePos",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.DONOTMOVE) worklist.vector("PTC200Wiggle",decklayout.PTCPOS,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.CLOSE,True) worklist.vector("PTC200Wiggle",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.OPEN,True) worklist.vector("PTC200WigglePos",decklayout.PTCPOS,worklist.ENDTOSAFE,False,worklist.DONOTMOVE,worklist.DONOTMOVE) self.ptcrunning=False self.moveplate(decklayout.SAMPLEPLATE,"Home") # Mark all samples on plate as unmixed (due to condensation) Sample.notMixed(decklayout.SAMPLEPLATE.name) # Verify plate is in place worklist.vector(decklayout.SAMPLEPLATE.vectorName,decklayout.SAMPLEPLATE,worklist.SAFETOEND,False,worklist.DONOTMOVE,worklist.CLOSE) worklist.vector(decklayout.SAMPLEPLATE.vectorName,decklayout.SAMPLEPLATE,worklist.ENDTOSAFE,False,worklist.OPEN,worklist.DONOTMOVE) worklist.romahome() #worklist.userprompt("Plate should be back on deck. Press return to continue") # Wash tips again to remove any drips that may have formed while waiting for PTC worklist.wash(15,1,5,True)
def moveplate(self,plate,dest="Home",returnHome=True): if self.ptcrunning and plate==decklayout.SAMPLEPLATE: self.waitpgm() # move to given destination (one of "Home","Magnet","Shaker","PTC" ) if plate!=decklayout.SAMPLEPLATE and plate!=decklayout.DILPLATE: print "Only able to move %s or %s plates, not %s"%(decklayout.SAMPLEPLATE.name,decklayout.DILPLATE.name,plate.name) assert False if plate.curloc==dest: #print "Plate %s is already at %s"%(plate.name,dest) return #print "Move plate %s from %s to %s"%(plate.name,plate.curloc,dest) worklist.flushQueue() self.lihahome() cmt="moveplate %s %s"%(plate.name,dest) worklist.comment(cmt) if plate.curloc=="Home": worklist.vector(plate.vectorName,plate,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) elif plate.curloc=="Magnet": worklist.vector("Magplate",decklayout.MAGPLATELOC,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) elif plate.curloc=="Shaker": worklist.vector("Shaker",decklayout.SHAKERPLATELOC,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) elif plate.curloc=="PTC": worklist.vector("PTC200",decklayout.PTCPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.CLOSE) else: print "Plate %s is in unknown location: %s"%(plate.name,plate.curloc) assert False if dest=="Home": plate.movetoloc(dest) worklist.vector(plate.vectorName,plate,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) elif dest=="Magnet": plate.movetoloc(dest,decklayout.MAGPLATELOC) worklist.vector("Magplate",decklayout.MAGPLATELOC,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) elif dest=="Shaker": plate.movetoloc(dest,decklayout.SHAKERPLATELOC) worklist.vector("Shaker",decklayout.SHAKERPLATELOC,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) elif dest=="PTC": plate.movetoloc(dest,decklayout.PTCPOS) worklist.vector("PTC200",decklayout.PTCPOS,worklist.SAFETOEND,True,worklist.DONOTMOVE,worklist.OPEN) else: print "Attempt to move plate %s to unknown location: %s"%(plate.name,dest) assert False Sample.addallhistory("{->%s}"%dest,onlyplate=plate.name) if returnHome: worklist.romahome()
def runpgm(self, pgm, duration, waitForCompletion=True, volume=10, hotlidmode="TRACKING", hotlidtemp=1): if self.ptcrunning: logging.error( "Attempt to start a progam on PTC when it is already running") if len(pgm) > 8: logging.error("PTC program name (%s) too long (max is 8 char)" % pgm) # move to thermocycler worklist.flushQueue() self.lihahome() cmt = "run %s" % pgm worklist.comment(cmt) #print "*",cmt worklist.pyrun("PTC\\ptclid.py OPEN") self.moveplate(decklayout.SAMPLEPLATE, "PTC") worklist.vector("Hotel 1 Lid", decklayout.HOTELPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) worklist.vector("PTC200lid", decklayout.PTCPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) worklist.romahome() worklist.pyrun("PTC\\ptclid.py CLOSE") # pgm="PAUSE30" # For debugging assert hotlidmode == "TRACKING" or hotlidmode == "CONSTANT" assert (hotlidmode == "TRACKING" and hotlidtemp >= 0 and hotlidtemp <= 45) or (hotlidmode == "CONSTANT" and hotlidtemp > 30) worklist.pyrun('PTC\\ptcrun.py %s CALC %s,%d %d' % (pgm, hotlidmode, hotlidtemp, volume)) self.pgmStartTime = clock.pipetting self.pgmEndTime = duration * 60 + clock.pipetting self.ptcrunning = True Sample.addallhistory("{%s}" % pgm, addToEmpty=False, onlyplate=decklayout.SAMPLEPLATE.name, type="ptc") if waitForCompletion: self.waitpgm()
def sanitize(self,nmix=1,deepvol=20,force=False): 'Deep wash including RNase-Away treatment' fixedTips=(~self.DITIMASK)&15 worklist.flushQueue() if not force and fixedTips==self.cleanTips: # print no sanitize needed worklist.comment("Sanitize not needed cleanTips=%d"%self.cleanTips) return worklist.comment("Sanitize (cleanTips=%d)"%self.cleanTips) worklist.wash(15,1,2) fixedWells=[] if not self.overrideSanitize: for i in range(4): if (fixedTips & (1<<i)) != 0: fixedWells.append(i) decklayout.BLEACH.addhistory("SANITIZE",0,1<<i) worklist.mix(fixedTips,fixedWells,decklayout.BLEACH.mixLC,200,decklayout.BLEACH.plate,nmix,False) worklist.wash(fixedTips,1,deepvol,True) self.cleanTips|=fixedTips # print "* Sanitize" worklist.comment(clock.statusString())
def sanitize(self, nmix=1, deepvol=20, force=False): 'Deep wash including RNase-Away treatment' fixedTips = (~self.DITIMASK) & 15 worklist.flushQueue() if not force and fixedTips == self.cleanTips: # print no sanitize needed worklist.comment("Sanitize not needed cleanTips=%d" % self.cleanTips) return worklist.comment("Sanitize (cleanTips=%d)" % self.cleanTips) worklist.wash(15, 1, 2) fixedWells = [] if not self.overrideSanitize: for i in range(4): if (fixedTips & (1 << i)) != 0: fixedWells.append(i) decklayout.BLEACH.addhistory("SANITIZE", 0, 1 << i) worklist.mix(fixedTips, fixedWells, decklayout.BLEACH.mixLC, 200, decklayout.BLEACH.plate, nmix, False) worklist.wash(fixedTips, 1, deepvol, True) self.cleanTips |= fixedTips # print "* Sanitize" worklist.comment(clock.statusString())
def savegem(self, filename): worklist.flushQueue() worklist.savegem(decklayout.headerfile, filename)
def waitpgm(self, sanitize=True): if not self.ptcrunning: return #print "* Wait for PTC to finish" if sanitize: self.sanitize() # Sanitize tips before waiting for this to be done worklist.comment("Wait for PTC") while self.pgmEndTime - clock.pipetting > 120: # Run any idle programs oldElapsed = clock.pipetting for ip in self.idlePgms: if self.pgmEndTime - clock.pipetting > 120: #print "Executing idle program with %.0f seconds"%(self.pgmEndTime-clock.pipetting) ip(self.pgmEndTime - clock.pipetting - 120) if oldElapsed == clock.pipetting: # Nothing was done break worklist.flushQueue() # Just in case clock.pipandthermotime += (clock.pipetting - self.pgmStartTime) clock.thermotime += (self.pgmEndTime - clock.pipetting) clock.pipetting = self.pgmStartTime #print "Waiting for PTC with %.0f seconds expected to remain"%(self.pgmEndTime-clock.pipetting) worklist.pyrun('PTC\\ptcwait.py') worklist.pyrun("PTC\\ptclid.py OPEN") # worklist.pyrun('PTC\\ptcrun.py %s CALC ON'%"COOLDOWN") # worklist.pyrun('PTC\\ptcwait.py') worklist.vector("PTC200lid", decklayout.PTCPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) worklist.vector("Hotel 1 Lid", decklayout.HOTELPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) worklist.vector("PTC200WigglePos", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.DONOTMOVE) worklist.vector("PTC200Wiggle", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.CLOSE, True) worklist.vector("PTC200Wiggle", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.OPEN, True) worklist.vector("PTC200WigglePos", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.DONOTMOVE) worklist.vector("PTC200Wiggle2Pos", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.DONOTMOVE) worklist.vector("PTC200Wiggle2", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.CLOSE, True) worklist.vector("PTC200Wiggle2", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.OPEN, True) worklist.vector("PTC200Wiggle2Pos", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.DONOTMOVE) worklist.vector("PTC200WigglePos", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.DONOTMOVE) worklist.vector("PTC200Wiggle", decklayout.PTCPOS, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.CLOSE, True) worklist.vector("PTC200Wiggle", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.OPEN, True) worklist.vector("PTC200WigglePos", decklayout.PTCPOS, worklist.ENDTOSAFE, False, worklist.DONOTMOVE, worklist.DONOTMOVE) self.ptcrunning = False self.moveplate(decklayout.SAMPLEPLATE, "Home") # Mark all samples on plate as unmixed (due to condensation) Sample.notMixed(decklayout.SAMPLEPLATE.name) # Verify plate is in place worklist.vector(decklayout.SAMPLEPLATE.vectorName, decklayout.SAMPLEPLATE, worklist.SAFETOEND, False, worklist.DONOTMOVE, worklist.CLOSE) worklist.vector(decklayout.SAMPLEPLATE.vectorName, decklayout.SAMPLEPLATE, worklist.ENDTOSAFE, False, worklist.OPEN, worklist.DONOTMOVE) worklist.romahome() #worklist.userprompt("Plate should be back on deck. Press return to continue") # Wash tips again to remove any drips that may have formed while waiting for PTC worklist.wash(15, 1, 5, True)
def moveplate(self, plate, dest="Home", returnHome=True): if self.ptcrunning and plate == decklayout.SAMPLEPLATE: self.waitpgm() # move to given destination (one of "Home","Magnet","Shaker","PTC" ) if plate != decklayout.SAMPLEPLATE and plate != decklayout.DILPLATE: print "Only able to move %s or %s plates, not %s" % ( decklayout.SAMPLEPLATE.name, decklayout.DILPLATE.name, plate.name) assert False if plate.curloc == dest: #print "Plate %s is already at %s"%(plate.name,dest) return #print "Move plate %s from %s to %s"%(plate.name,plate.curloc,dest) worklist.flushQueue() self.lihahome() cmt = "moveplate %s %s" % (plate.name, dest) worklist.comment(cmt) if plate.curloc == "Home": worklist.vector(plate.vectorName, plate, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) elif plate.curloc == "Magnet": worklist.vector("Magplate", decklayout.MAGPLATELOC, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) elif plate.curloc == "Shaker": worklist.vector("Shaker", decklayout.SHAKERPLATELOC, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) elif plate.curloc == "PTC": worklist.vector("PTC200", decklayout.PTCPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.CLOSE) else: print "Plate %s is in unknown location: %s" % (plate.name, plate.curloc) assert False if dest == "Home": plate.movetoloc(dest) worklist.vector(plate.vectorName, plate, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) elif dest == "Magnet": plate.movetoloc(dest, decklayout.MAGPLATELOC) worklist.vector("Magplate", decklayout.MAGPLATELOC, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) elif dest == "Shaker": plate.movetoloc(dest, decklayout.SHAKERPLATELOC) worklist.vector("Shaker", decklayout.SHAKERPLATELOC, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) elif dest == "PTC": plate.movetoloc(dest, decklayout.PTCPOS) worklist.vector("PTC200", decklayout.PTCPOS, worklist.SAFETOEND, True, worklist.DONOTMOVE, worklist.OPEN) else: print "Attempt to move plate %s to unknown location: %s" % ( plate.name, dest) assert False Sample.addallhistory("{->%s}" % dest, onlyplate=plate.name) if returnHome: worklist.romahome()
def volcheck(self,tipMask,well,volToRemove): '''Check if the well contains the expected volume''' if self.lastvolcheck is not None: # Decide if a volume check is needed if volToRemove==0: # No need to check if not removing anything and it has been checked previously (i.e. lastvolcheck is not None) return if self.volume-volToRemove > max(30,self.lastvolcheck-200) or self.volume-volToRemove>200: # Not needed return self.lastvolcheck=self.volume height=self.plate.getliquidheight(self.volume) gemvol=self.plate.getgemliquidvolume(height) # Volume that would be reported by Gemini for this height if gemvol is None: logging.warning( "No volume equation for %s, skipping initial volume check"%self.name) return volwarn=self.volume*0.80 heightwarn=min(self.plate.getliquidheight(volwarn),height-1.0) # threshold is lower of 1mm or 80% gemvolwarn=self.plate.getgemliquidvolume(heightwarn) # Volume that would be reported by Gemini for this height volcrit=self.plate.unusableVolume*0.8+volToRemove heightcrit=self.plate.getliquidheight(volcrit) gemvolcrit=self.plate.getgemliquidvolume(heightcrit) # Volume that would be reported by Gemini for this height worklist.flushQueue() worklist.comment( "Check that %s contains %.1f ul (warn< %.1f, crit<%.1f), (gemvol=%.1f (warn<%.1f,crit<%.1f); height=%.1f (>%.1f) )"%(self.name,self.volume,volwarn,volcrit,gemvol,gemvolwarn,gemvolcrit,height,heightwarn)) tipnum=0 tm=tipMask while tm>0: tm=tm>>1 tipnum+=1 volvar='detected_volume_%d'%tipnum worklist.variable(volvar,-2) worklist.detectLiquid(tipMask,well,self.inliquidLC,self.plate) doneLabel=worklist.getlabel() worklist.condition(volvar,">",gemvolwarn,doneLabel) ptmp=clock.pipetting; warnLabel=worklist.getlabel() worklist.condition(volvar,">",gemvolcrit,warnLabel) worklist.moveliha(worklist.WASHLOC) # Get LiHa out of the way msg="Failed volume check of %s - should have %.0f ul (gemvol=~%s~, crit=%.0f)"%(self.name,self.volume,volvar,gemvolcrit) worklist.email(dest='*****@*****.**',subject=msg) worklist.stringvariable("response","retry",msg+" Enter 'ignore' to ignore and continue, otherwise will retry.") worklist.condition("response","==","ignore",doneLabel) # Retry worklist.detectLiquid(tipMask,well,self.inliquidLC,self.plate) worklist.condition(volvar,">",gemvolcrit,doneLabel) worklist.stringvariable("response","retry","Still have <%.0f. Enter 'ignore' to ignore and continue, otherwise will retry."%self.volume) worklist.condition("response","==","ignore",doneLabel) # Retry again worklist.detectLiquid(tipMask,well,self.inliquidLC,self.plate) worklist.condition(volvar,">",gemvolcrit,doneLabel) worklist.stringvariable("response","ignore","Still have <%.0f. Will continue regardless."%self.volume) worklist.condition("response","!=","warn",doneLabel) worklist.comment(warnLabel) msg="Warning: volume check of %s - should have %.0f ul (gemvol=~%s~, warn=%.0f, crit=%.0f)"%(self.name,self.volume,volvar,gemvolwarn,gemvolcrit) worklist.email(dest='*****@*****.**',subject=msg) worklist.comment(doneLabel) clock.pipetting=ptmp # All the retries don't usually happen, so don't count in total time self.addhistory("LD",0,tipMask)
def savegem(self,filename): worklist.comment("Completed (%s-%s)"%(sys.argv[0],self.checksum)) worklist.flushQueue() worklist.savegem(decklayout.headerfile,filename)
def volcheck(self, tipMask, well, volToRemove): '''Check if the well contains the expected volume''' if self.lastvolcheck is not None: # Decide if a volume check is needed if volToRemove == 0: # No need to check if not removing anything and it has been checked previously (i.e. lastvolcheck is not None) return if self.volume - volToRemove > max( 30, self.lastvolcheck - 200) or self.volume - volToRemove > 200: # Not needed return self.lastvolcheck = self.volume height = self.plate.getliquidheight(self.volume) gemvol = self.plate.getgemliquidvolume( height) # Volume that would be reported by Gemini for this height if gemvol is None: logging.warning( "No volume equation for %s, skipping initial volume check" % self.name) return volcrit = self.plate.unusableVolume * 0.8 + volToRemove volwarn = min(volcrit, self.volume * 0.80) heightwarn = min(self.plate.getliquidheight(volwarn), height - 1.0) # threshold is lower of 1mm or 80% gemvolwarn = self.plate.getgemliquidvolume( heightwarn ) # Volume that would be reported by Gemini for this height heightcrit = self.plate.getliquidheight(volcrit) gemvolcrit = self.plate.getgemliquidvolume( heightcrit ) # Volume that would be reported by Gemini for this height worklist.flushQueue() worklist.comment( "Check that %s contains %.1f ul (warn< %.1f, crit<%.1f), (gemvol=%.1f (warn<%.1f,crit<%.1f); height=%.1f (>%.1f) )" % (self.name, self.volume, volwarn, volcrit, gemvol, gemvolwarn, gemvolcrit, height, heightwarn)) tipnum = 0 tm = tipMask while tm > 0: tm = tm >> 1 tipnum += 1 volvar = 'detected_volume_%d' % tipnum worklist.variable(volvar, -2) worklist.detectLiquid(tipMask, well, self.inliquidLC, self.plate) doneLabel = worklist.getlabel() worklist.condition(volvar, ">", gemvolwarn, doneLabel) ptmp = clock.pipetting warnLabel = worklist.getlabel() worklist.condition(volvar, ">", gemvolcrit, warnLabel) worklist.moveliha(worklist.WASHLOC) # Get LiHa out of the way msg = "Failed volume check of %s - should have %.0f ul (gemvol=~%s~, crit=%.0f)" % ( self.name, self.volume, volvar, gemvolcrit) worklist.email(dest='*****@*****.**', subject=msg) worklist.stringvariable( "response", "retry", msg + " Enter 'ignore' to ignore and continue, otherwise will retry.") worklist.condition("response", "==", "ignore", doneLabel) # Retry worklist.detectLiquid(tipMask, well, self.inliquidLC, self.plate) worklist.condition(volvar, ">", gemvolcrit, doneLabel) worklist.stringvariable( "response", "retry", "Still have <%.0f. Enter 'ignore' to ignore and continue, otherwise will retry." % self.volume) worklist.condition("response", "==", "ignore", doneLabel) # Retry again worklist.detectLiquid(tipMask, well, self.inliquidLC, self.plate) worklist.condition(volvar, ">", gemvolcrit, doneLabel) worklist.stringvariable( "response", "ignore", "Still have <%.0f. Will continue regardless." % self.volume) worklist.condition("response", "!=", "warn", doneLabel) worklist.comment(warnLabel) msg = "Warning: volume check of %s - should have %.0f ul (gemvol=~%s~, warn=%.0f, crit=%.0f)" % ( self.name, self.volume, volvar, gemvolwarn, gemvolcrit) worklist.email(dest='*****@*****.**', subject=msg) worklist.comment(doneLabel) clock.pipetting = ptmp # All the retries don't usually happen, so don't count in total time self.addhistory("LD", 0, tipMask, "detect")
def savegem(self,filename): worklist.flushQueue() worklist.savegem(decklayout.headerfile,filename)
def savegem(self, filename): worklist.comment("Completed (%s-%s)" % (sys.argv[0], self.checksum)) worklist.flushQueue() worklist.savegem(decklayout.headerfile, filename)