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 shake(self,plate,dur=60,speed=None,accel=5,returnPlate=True,samps=None,force=False): if self.ptcrunning and plate==decklayout.SAMPLEPLATE: self.waitpgm() # Move the plate to the shaker, run for the given time, and bring plate back allsamps=Sample.getAllOnPlate(plate) if samps is None: samps=allsamps if all([x.isMixed() for x in samps]) and not force: logging.notice( "No need to shake "+plate.name+", but doing so anyway.") minspeed=0 maxspeed=2000 for x in samps: (a,b)=x.getmixspeeds() minspeed=max([a,minspeed]) maxspeed=min([b,maxspeed]) if speed is None: if minspeed<maxspeed: speed=max((maxspeed+minspeed)/2,maxspeed-50) # Mix as fast as safely possible (but always above minspeed) else: speed=maxspeed if speed<minspeed-2 or speed>maxspeed+2: others="" for x in allsamps: (a,b)=x.getmixspeeds() if b<minspeed or a>maxspeed: if a is not None and a>0: others+=" {%s: %.1ful,G=%.2f%%,min=%.0f,max=%.0f}"%(x.name,x.volume,x.glycerolfrac()*100,a,b) else: others+=" {%s: %.1ful,G=%.2f%%,max=%.0f}"%(x.name,x.volume,x.glycerolfrac()*100,b) logging.mixwarning("Mixing %s at %.0f RPM; minspeed(%.0f) > maxspeed(%.0f), limits=[%s]"%(plate.name,speed,minspeed,maxspeed,others)) else: logging.notice("Mixing %s at %.0f RPM ( min RPM=%.0f, max RPM=%.f)"%(plate.name, speed, minspeed, maxspeed)) oldloc=plate.curloc self.moveplate(plate,"Shaker",returnHome=False) global __shakerActive __shakerActive=True worklist.pyrun("BioShake\\bioexec.py setElmLockPos") worklist.pyrun("BioShake\\bioexec.py setShakeTargetSpeed%d"%speed) worklist.pyrun("BioShake\\bioexec.py setShakeAcceleration%d"%accel) worklist.pyrun("BioShake\\bioexec.py shakeOn") self.starttimer() Sample.shaken(plate.name,speed) Sample.addallhistory("(S%d@%.0f)"%(dur,speed),onlyplate=plate.name) self.waittimer(dur) worklist.pyrun("BioShake\\bioexec.py shakeOff") self.starttimer() self.waittimer(accel+4) worklist.pyrun("BioShake\\bioexec.py setElmUnlockPos") __shakerActive=False if returnPlate: self.moveplate(plate,oldloc)
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 pause(self, duration): self.starttimer() self.waittimer(duration) Sample.addallhistory("(%ds)" % duration)
def shake(self, plate, dur=60, speed=None, accel=5, returnPlate=True, samps=None): if self.ptcrunning and plate == decklayout.SAMPLEPLATE: self.waitpgm() # Move the plate to the shaker, run for the given time, and bring plate back allsamps = Sample.getAllOnPlate(plate) if samps is None: samps = allsamps if all([x.isMixed() for x in samps]): print "No need to shake ", plate maxvol = max([x.volume for x in allsamps]) minvol = min([x.volume for x in samps if not x.isMixed()] + [200]) (minspeed, maxspeed) = plate.getmixspeeds( minvol * 0.95, maxvol + 5) # Assume volumes could be off if minspeed > maxspeed: print "minspeed(", minspeed, ") > maxspeed (", maxspeed, ")" if speed is None: if minspeed < maxspeed: speed = (maxspeed + minspeed) / 2 else: speed = maxspeed warned = False if speed > maxspeed: print "WARNING: %s plate contains wells with up to %.2f ul, which may spill at %d RPM: " % ( plate.name, maxvol, speed), for x in samps: tmp = plate.getmixspeeds(x.volume, x.volume) if tmp[1] < speed: print "%s[%.1ful, max=%.0f RPM] " % (x.name, x.volume, tmp[1]), print warned = True if globals.verbose and speed < minspeed: print "NOTICE: %s plate contains unmixed wells that may not be mixed at %d RPM: " % ( plate.name, speed), for x in samps: if x.isMixed(): continue tmp = plate.getmixspeeds(x.volume * 0.95, x.volume + 5) if speed < tmp[0]: print "%s[%.1ful, min=%.0f RPM, max=%.0f RPM] " % ( x.name, x.volume, tmp[0], tmp[1]), print warned = True if warned or globals.verbose: print " Mixing %s at %.0f RPM (min unmixed vol=%.0ful -> min RPM=%.0f; max vol=%.0ful -> max RPM=%.f)" % ( plate.name, speed, minvol, minspeed, maxvol, maxspeed) oldloc = plate.curloc self.moveplate(plate, "Shaker", returnHome=False) global __shakerActive __shakerActive = True worklist.pyrun("BioShake\\bioexec.py setElmLockPos") worklist.pyrun("BioShake\\bioexec.py setShakeTargetSpeed%d" % speed) worklist.pyrun("BioShake\\bioexec.py setShakeAcceleration%d" % accel) worklist.pyrun("BioShake\\bioexec.py shakeOn") self.starttimer() Sample.shaken(plate.name, speed) Sample.addallhistory("(S%d@%.0f)" % (dur, speed), onlyplate=plate.name) self.waittimer(dur) worklist.pyrun("BioShake\\bioexec.py shakeOff") self.starttimer() self.waittimer(accel + 4) worklist.pyrun("BioShake\\bioexec.py setElmUnlockPos") __shakerActive = False if returnPlate: self.moveplate(plate, oldloc)
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 pause(self,duration): self.starttimer() self.waittimer(duration) Sample.addallhistory("(%ds)"%duration)
def shake(self,plate,dur=60,speed=None,accel=5,returnPlate=True,samps=None): if self.ptcrunning and plate==decklayout.SAMPLEPLATE: self.waitpgm() # Move the plate to the shaker, run for the given time, and bring plate back allsamps=Sample.getAllOnPlate(plate) if samps is None: samps=allsamps if all([x.isMixed() for x in samps]): print "No need to shake ",plate maxvol=max([x.volume for x in allsamps]) minvol=min([x.volume for x in samps if not x.isMixed() ]+[200]) (minspeed,maxspeed)=plate.getmixspeeds(minvol*0.95,maxvol+5) # Assume volumes could be off if minspeed>maxspeed: print "minspeed(",minspeed,") > maxspeed (",maxspeed,")" if speed is None: if minspeed<maxspeed: speed=(maxspeed+minspeed)/2 else: speed=maxspeed warned=False if speed>maxspeed: print "WARNING: %s plate contains wells with up to %.2f ul, which may spill at %d RPM: "%(plate.name, maxvol, speed), for x in samps: tmp=plate.getmixspeeds(x.volume,x.volume) if tmp[1]<speed: print "%s[%.1ful, max=%.0f RPM] "%(x.name,x.volume,tmp[1]), print warned=True if globals.verbose and speed<minspeed: print "NOTICE: %s plate contains unmixed wells that may not be mixed at %d RPM: "%(plate.name, speed), for x in samps: if x.isMixed(): continue tmp=plate.getmixspeeds(x.volume*0.95,x.volume+5) if speed<tmp[0]: print "%s[%.1ful, min=%.0f RPM, max=%.0f RPM] "%(x.name,x.volume,tmp[0],tmp[1]), print warned=True if warned or globals.verbose: print " Mixing %s at %.0f RPM (min unmixed vol=%.0ful -> min RPM=%.0f; max vol=%.0ful -> max RPM=%.f)"%(plate.name, speed, minvol, minspeed, maxvol, maxspeed) oldloc=plate.curloc self.moveplate(plate,"Shaker",returnHome=False) global __shakerActive __shakerActive=True worklist.pyrun("BioShake\\bioexec.py setElmLockPos") worklist.pyrun("BioShake\\bioexec.py setShakeTargetSpeed%d"%speed) worklist.pyrun("BioShake\\bioexec.py setShakeAcceleration%d"%accel) worklist.pyrun("BioShake\\bioexec.py shakeOn") self.starttimer() Sample.shaken(plate.name,speed) Sample.addallhistory("(S%d@%.0f)"%(dur,speed),onlyplate=plate.name) self.waittimer(dur) worklist.pyrun("BioShake\\bioexec.py shakeOff") self.starttimer() self.waittimer(accel+4) worklist.pyrun("BioShake\\bioexec.py setElmUnlockPos") __shakerActive=False if returnPlate: self.moveplate(plate,oldloc)
def shake(self, plate, dur=60, speed=None, accel=5, returnPlate=True, samps=None, force=False): if self.ptcrunning and plate == decklayout.SAMPLEPLATE: self.waitpgm() # Move the plate to the shaker, run for the given time, and bring plate back allsamps = Sample.getAllOnPlate(plate) if samps is None: samps = allsamps if all([x.isMixed() for x in samps]) and not force: logging.notice("No need to shake " + plate.name + ", but doing so anyway.") minspeed = 0 maxspeed = 2000 for x in samps: (a, b) = x.getmixspeeds() minspeed = max([a, minspeed]) for x in allsamps: (a, b) = x.getmixspeeds() maxspeed = min([b, maxspeed]) if speed is None: if minspeed < maxspeed: speed = max( (maxspeed + minspeed) / 2, maxspeed - 50 ) # Mix as fast as safely possible (but always above minspeed) else: speed = maxspeed if speed < minspeed - 2 or speed > maxspeed + 2: others = "" for x in allsamps: (a, b) = x.getmixspeeds() if b < minspeed or a > maxspeed: if a is not None and a > 0: others += " {%s: %.1ful,G=%.2f%%,min=%.0f,max=%.0f}" % ( x.name, x.volume, x.glycerolfrac() * 100, a, b) else: others += " {%s: %.1ful,G=%.2f%%,max=%.0f}" % ( x.name, x.volume, x.glycerolfrac() * 100, b) logging.mixwarning( "Mixing %s at %.0f RPM; minspeed(%.0f) > maxspeed(%.0f), limits=[%s]" % (plate.name, speed, minspeed, maxspeed, others)) else: logging.notice( "Mixing %s at %.0f RPM ( min RPM=%.0f, max RPM=%.f)" % (plate.name, speed, minspeed, maxspeed)) oldloc = plate.curloc self.moveplate(plate, "Shaker", returnHome=False) global __shakerActive __shakerActive = True worklist.pyrun("BioShake\\bioexec.py setElmLockPos") worklist.pyrun("BioShake\\bioexec.py setShakeTargetSpeed%d" % speed) worklist.pyrun("BioShake\\bioexec.py setShakeAcceleration%d" % accel) worklist.pyrun("BioShake\\bioexec.py shakeOn") self.starttimer() Sample.shaken(plate.name, speed) Sample.addallhistory("(S%d@%.0f)" % (dur, speed), onlyplate=plate.name, type="shake") self.waittimer(dur) worklist.pyrun("BioShake\\bioexec.py shakeOff") self.starttimer() self.waittimer(accel + 4) worklist.pyrun("BioShake\\bioexec.py setElmUnlockPos") __shakerActive = False if returnPlate: self.moveplate(plate, oldloc)