def mccBurstSetNumShot(self, iNumShots, iBurstRate): if self.bSimMode: return False print "Settings Mcc Burst Shot %d rate %d" % (iNumShots, iBurstRate) caput(pvMccBurstNumShot, iNumShots) # Set # of bursts caput(pvMccBurstRate , iBurstRate) return 0
def mccBurstSetNumShot(self, iNumShots, fBurstRate): if self.bSimMode: return False print "Settings Mcc Burst Shot %d rate %f (%d)" % (iNumShots, fBurstRate, self.dictBeamToBurstRate[fBurstRate]) caput(pvMccBurstNumShot, iNumShots) # Set # of bursts self.mccBurstSetRate(fBurstRate) return 0
def runOnce(self): caput(pvPlayMode, (0, )) # PlayMode = Once caput(pvPlayCtrl, (1, )) # PlayCtrl = Play while True: if caget(pvPlayStat).find("Stopped") != -1: break time.sleep(0.05)
def stopAtSeqEnd(self): if caget(pvPlayStat).find("Stopped") != -1: return iPlayCountOld = caget(pvPlayCount) print "Waiting for current round to finish..." while True: iPlayCountNew = caget(pvPlayCount) if iPlayCountNew != iPlayCountOld: caput(pvPlayCtrl, (0, )) # PlayCtrl = Stop if caget(pvPlayStat).find("Stopped") != -1: break time.sleep(0.05) print "Done." return
def run(self, princetonDaq, iShutter): iFail = princetonDaq.init() if iFail != 0: return 1 princetonDaq.begin(princetonDaq.controls) try: while True: # # Wait for the user to continue # print('--Enter a number + <Enter> to get more images, or just Hit <Enter> to end run and exit--') sMoreImage = raw_input("> ") try: iMoreImage = int(sMoreImage) except: iMoreImage = 0 if iMoreImage <= 0: break print("Will get %d more images..." % iMoreImage) princetonDaq.getMoreImages(iMoreImage) # go to next loop to get more Images #end of while True: daq = princetonDaq.daq print "# (If Record Run is ON) Experiment %d Run %d (%d images)" % (daq.experiment(),daq.runnumber(), princetonDaq.numTotalImage()) princetonDaq.deinit() time.sleep(0.5) except: print if iShutter != 0: for pvLaserShutter in princetonController.lPvShutter: caput(pvLaserShutter, princetonController.iShutterCloseVal) time.sleep(0.5) iLaserShutterState = int(caget(pvLaserShutter)) if iLaserShutterState != princetonController.iShutterCloseVal: print "!!! Shutter %s Not Close: Current value = %d (expected %d)" % (pvLaserShutter, iLaserShutterState, princetonController.iShutterCloseVal) print "!!! Please remember to check if laser shutters are closed" print "!!! Script exits abnormally (may be interrupted by user)" return 0
def getMoreImages(self, iNumImage): for iImage in xrange(iNumImage): if (not self.bSimMode) and self.mccBurst.mccBurstCheckStatusChange(): print "Burst Mode status changed" break timeBeforeImage = time.time() print "# Image %d/%d (%d Shots) [total images: %d]" % (1+iImage, iNumImage, self.iNumShot, self.iNumTotalImage) iEventStart = self.daq.eventnum() caput(pvPlayCtrl, 1) # PlayCtrl = Play timeAfterPlay = time.time() time.sleep(0.05) while True: if caget(pvPlayStat).find("Stopped") != -1: break if self.bSimMode: iSeqStep = int(caget(pvPlayCurStep)) print "Burst count: %d / %d\r" % (iSeqStep, self.iNumShot), sys.stdout.flush() time.sleep(0.05) if self.pvLaserShutter: caput(self.pvLaserShutter, self.iShutterOpenVal) time.sleep(0.5) iLaserShutterState = int(caget(self.pvLaserShutter)) if iLaserShutterState != self.iShutterOpenVal: print "!!! Shutter %s Not Open: Current value = %d (expected %d)" % (self.pvLaserShutter, iLaserShutterState, self.iShutterOpenVal) if not self.bSimMode: time.sleep(0.02) while True: if self.mccBurst.mccBurstIsComplete(): break iNumBurstCount = self.mccBurst.mccBurstCount() print "Burst count: %d / %d\r" % (iNumBurstCount, self.iNumShot), sys.stdout.flush() time.sleep(0.05) timeAfterBurstComplete = time.time() if self.pvLaserShutter: caput(self.pvLaserShutter, self.iShutterCloseVal) time.sleep(0.5) iLaserShutterState = int(caget(self.pvLaserShutter)) if iLaserShutterState != self.iShutterCloseVal: print "!!! Shutter %s Not Closed: Current value = %d (expected %d)" % (self.pvLaserShutter, iLaserShutterState, self.iShutterCloseVal) while True: if self.daq.eventnum() >= iEventStart + self.iNumShot: break print "DAQ event: %d / %d\r" % (self.daq.eventnum(), iEventStart + self.iNumShot), sys.stdout.flush() time.sleep(0.05) print " \r", self.iNumTotalImage += 1
def load(self, verbose=False): if verbose: print_file = sys.stdout else: print_file = open(os.devnull, 'w') bPrintSet = True # Always print "set ..." in caput() print >> print_file, caput( pvSeqEvent , self.event_codes , verbose=bPrintSet) print >> print_file, caput( pvSeqBeamDelay, self.beam_delays , verbose=bPrintSet) print >> print_file, caput( pvSeqFiduDelay, self.fiducial_delays, verbose=bPrintSet) print >> print_file, caput( pvSeqBurst , self.burst_requests , verbose=bPrintSet) print >> print_file, caput( pvSeqLen , self.length , verbose=bPrintSet) print >> print_file, caput( pvSeqUpdate , 1 , verbose=bPrintSet) sSeqStatus = caget(pvSeqStatus) iErrorIndex = int(caget(pvSeqErrorIndex)) if sSeqStatus.find("Valid Sequence") != -1: print "Status: %s" % sSeqStatus return 0 print "!! Status: %s Error Index: %d" % (sSeqStatus, iErrorIndex) return 1
def mccBurstSetRate(self, fBurstRate): if self.bSimMode: return True if caget(pvBeamOwner) != caget(pvHutchId): print "Settings Test Burst Rate %f (%d)" % (fBurstRate, self.dictBeamToBurstRate[fBurstRate]) caput(pvMccTestBurstDep , 0) caput(pvMccTestBurstRate , self.dictBeamToBurstRate[fBurstRate]) else: print "Settings Mcc Burst Rate %f (%d)" % (fBurstRate, self.dictBeamToBurstRate[fBurstRate]) caput(pvMccBurstRate , self.dictBeamToBurstRate[fBurstRate]) return 0
def getMoreImages(self, iNumImage): for iImage in xrange(iNumImage): if (not self.bSimMode) and self.mccBurst.mccBurstCheckStatusChange(): print "Burst Mode status changed" break timeBeforeImage = time.time() print "# Image %d/%d (%d Shots) [total images: %d]" % (1+iImage, iNumImage, self.iNumShot, self.iNumTotalImage) iEventStart = self.daq.eventnum() timeAfterImageBegin = time.time() # # Add a retry loop in case the EVR isn't ready when the sequence runs # while True: caput(pvPlayCtrl, 1) # PlayCtrl = Play timeAfterPlay = time.time() time.sleep(0.05) while True: if caget(pvPlayStat).find("Stopped") != -1: break if self.bSimMode: iSeqStep = int(caget(pvPlayCurStep)) print "Burst count: %d / %d\r" % (iSeqStep, self.iNumShot), sys.stdout.flush() time.sleep(0.05) if self.pvLaserShutter: caput(self.pvLaserShutter, self.iShutterOpenVal) time.sleep(0.5) iLaserShutterState = int(caget(self.pvLaserShutter)) if iLaserShutterState != self.iShutterOpenVal: print "!!! Shutter %s Not Open: Current value = %d (expected %d)" % (self.pvLaserShutter, iLaserShutterState, self.iShutterOpenVal) timeBeforeBurst = time.time() if not self.bSimMode: time.sleep(0.02) while True: if self.mccBurst.mccBurstIsComplete(): break iNumBurstCount = self.mccBurst.mccBurstCount() print "Burst count: %d / %d\r" % (iNumBurstCount, self.iNumShot), sys.stdout.flush() time.sleep(0.05) timeAfterBurstComplete = time.time() if self.pvLaserShutter: caput(self.pvLaserShutter, self.iShutterCloseVal) time.sleep(0.5) iLaserShutterState = int(caget(self.pvLaserShutter)) if iLaserShutterState != self.iShutterCloseVal: print "!!! Shutter %s Not Closed: Current value = %d (expected %d)" % (self.pvLaserShutter, iLaserShutterState, self.iShutterCloseVal) print "Waiting for device readout... " if self.fPostDelay > 0: print "Sleeping for %.1f seconds... " % (self.fPostDelay), sys.stdout.flush() time.sleep(self.fPostDelay) # post delay: wait for DAQ to really ends if data valume is too large print "done." print "Waiting for princeton images (* may not wait long enough with multiple readout groups)" timeToRetry = time.time() + 15 while True: nevents = self.daq.eventnum() if nevents >= iEventStart + self.iNumShot: break if time.time() > timeToRetry: break print "DAQ event: %d / %d\r" % (self.daq.eventnum(), iEventStart + self.iNumShot), sys.stdout.flush() time.sleep(0.05) print " \r", timeEndImage = time.time() print "time (sec): Image %.2f Begin %.2f SeqPvSet %.2f PlaySeq %.2f Burst %.2f End %.2f" %\ (timeEndImage-timeBeforeImage, \ timeAfterImageBegin - timeBeforeImage, timeAfterPlay - timeAfterImageBegin, \ timeBeforeBurst - timeAfterPlay, timeAfterBurstComplete - timeBeforeBurst, \ timeEndImage-timeAfterBurstComplete ) if nevents >= iEventStart + self.iNumShot: self.iNumTotalImage += 1 break print "Failed to receive image... moving on." break
def init(self): self.pvLaserShutter = None if self.iShutter > 0 and self.iShutter <= len(self.lPvShutter): self.pvLaserShutter = self.lPvShutter[self.iShutter-1] fBeamFullRate = float(caget(pvBeamRate)); if not self.bSimMode: print "\n## Beam rate = %.1f HZ" % (fBeamFullRate) if not (self.dictBeamToBurstRate.has_key(fBeamFullRate)): print "!!! Beam rate is not stable, please wait for beam to stablize and run the script again" return 1 self.mccBurst.mccBurstCheckInit() caput(pvPlayMode , 0) # PlayMode = Once caput(pvMccSeqSyncMarker , 6) # Set sequencer sync marker to 120Hz caput(pvMccSeqBeamRequest, 0) # Set seuqencer rate to be 120Hz (TS4|TS1) if self.bSimMode: caput(pvMccSynEvtBurst , 0) # Diable SEB support else: caput(pvMccSynEvtBurst , 1) # Enable SEB support if self.fBurstRate == -1: if self.bSimMode: self.fBurstRate = 120.0 else: self.fBurstRate = fBeamFullRate if not self.bSimMode: self.mccBurst.mccBurstSetNumShot(self.iNumShot, self.dictBeamToBurstRate[self.fBurstRate]) print "## Burst rate = %.1f HZ" % (self.fBurstRate) print "## Multiple shot: %d" % (self.iNumShot) self.codeCommand = self.setPrincetonExposureSequence() # Exposure Time = # delay from "real" princeton open and SEB burst start event (0 second) # delay from SEB burst start event and MCC firing beam ( max( 1/60, 1/self.fBurstRate) ) # (x) + laser shutter open delay (Pv set + shutter physical open) (0.5 second) # + manual sleep (fExpDelay) # + exposure Time ((self.iNumShot / self.fBurstRate) second) # = 0.0 + (self.iNumShot / self.fBurstRate) + fExpDelay second # Setup Time = # delay between setting pvPlayCtrl and the "real" princeton open (0.2 second) # = 0.2 self.fSetupTime = 0.1 self.fExposureTime = 0.0 + self.fExpDelay + self.iNumShot / float(self.fBurstRate) + max(1.0/120, 1.0/self.fBurstRate) + self.iSlowCamOpenDelay / 360.0 self.daq = pydaq.Control(self.daq_host, self.daq_platform) print ' *** PrincetonDaqMultipleShot.init(): self.controls =', self.controls # # Send the structure the first time to put the control variables # in the file header print "daq connect...", sys.stdout.flush() try: self.daq.connect() # get dbpath and key from DAQ except Exception, e: print e print "Please select devices and click Select button in DAQ Control window"
def getMoreImages(self, iNumImage, x_motor=None, token_x=None, destination=None, delayT=None): for iImage in xrange(iNumImage): if (not self.bShutterMode ) and self.mccBurst.mccBurstCheckStatusChange(): print "Burst Mode status changed" break timeBeforeImage = time.time() print "# Image %d/%d (%d Shots) [total images: %d]" % ( 1 + iImage, iNumImage, self.iNumShot, self.iNumTotalImage) iEventStart = self.getEventNum() timeAfterImageBegin = time.time() if x_motor is not None: # should be close to the 1st event print "Scan on X starts now from %s mm to %s mm" % ( token_x, destination) print "DAQ starts recording 1st event %s s after motor started." % delayT print "Time right before moving motor ", datetime.datetime.now( ).time() x_motor.mv(destination) # user specficy delay in distance time.sleep(delayT) print "Motor position before first DAQ event:", float( caget("MEC:USR:MMS:17.RBV")), " mm" caput(pvPlayCtrl, 1) # PlayCtrl = Play timeAfterPlay = time.time() print "###################### Event sequence played at:", timeAfterPlay time.sleep(0.02) while True: if caget(pvPlayStat).find("Stopped") != -1: break if self.bShutterMode: iSeqStep = int(caget(pvPlayCurStep)) print "Sequence step: %d\r" % (iSeqStep), sys.stdout.flush() time.sleep(0.05) timeBeforeBurst = time.time() if not self.bShutterMode and caget(pvBeamOwner) == caget( pvHutchId): time.sleep(0.02) while True: if self.mccBurst.mccBurstIsComplete(): break iNumBurstCount = self.mccBurst.mccBurstCount() print "Burst count: %d / %d\r" % (iNumBurstCount, self.iNumShot), sys.stdout.flush() time.sleep(0.05) timeAfterBurstComplete = time.time() print "Waiting for device readout... " if self.fPostDelay > 0: print "Sleeping for %.1f seconds... " % (self.fPostDelay), sys.stdout.flush() time.sleep( self.fPostDelay ) # post delay: wait for DAQ to really ends if data valume is too large print "done." print "Waiting for DAQ event: %d" % self.iNumShot time.sleep(1) # while True: # print "GOING TO READOUT EVENTNUM" # eventnum = self.getEventNum() # if eventnum >= iEventStart + self.iNumShot: # if x_motor is not None: # print "Time after DAQ ", datetime.datetime.time(datetime.datetime.now()) # print "Motor position after last DAQ event:" , float( caget("MEC:USR:MMS:17.RBV") ), " mm" # break # print "DAQ event: %d / %d\r" % (eventnum, iEventStart + self.iNumShot), # sys.stdout.flush() # time.sleep(0.05) # print " \r", if self.bShutterMode: if ShutterArm(self.iNumShot) != 0: print "\nShutter Arm Failed" break timeEndImage = time.time() print "time (sec): Image %.2f Begin %.2f SeqPvSet %.2f PlaySeq %.2f Burst %.2f End %.2f" %\ (timeEndImage-timeBeforeImage, \ timeAfterImageBegin - timeBeforeImage, timeAfterPlay - timeAfterImageBegin, \ timeBeforeBurst - timeAfterPlay, timeAfterBurstComplete - timeBeforeBurst, \ timeEndImage-timeAfterBurstComplete ) self.iNumTotalImage += 1
def init(self, controls=None, bDaqBegin=True): while True: fBeamFullRate = float(caget(pvBeamRate)) if fBeamFullRate == 0.5 or float( int(fBeamFullRate)) == fBeamFullRate: break if not self.bSimMode: if not (self.mccBurst.isLegalBeamRate(fBeamFullRate)): print "!!! Beam rate %g is not stable, please wait for beam to stablize and run the script again" % ( fBeamFullRate) return 1 self.mccBurst.mccBurstCheckInit() if self.fBurstRate == -1: self.fBurstRate = fBeamFullRate if not (self.fBurstRate in dictRateToSyncMarker): print "!!! Burst rate %g not supported" % (self.fBurstRate) return 1 caput(pvPlayMode, 0) # PlayMode = Once caput(pvMccSeqSyncMarker, dictRateToSyncMarker[self.fBurstRate]) caput(pvMccSeqBeamRequest, 0) # Set seuqencer rate to be 120Hz (TS4|TS1) caget(pvMccSeqSyncMarker ) # caget bug: need to get twice to have latest value print "\n## Beam rate = %g HZ, Sync marker = %g HZ" % ( fBeamFullRate, dictSyncMarkerToRate[int( caget(pvMccSeqSyncMarker, bGetNumEnum=True))]) if not self.bSimMode: if caget(pvBeamOwner) != caget(pvHutchId): if self.fBurstRate == 60: print "!!! Test Burst rate %g is not supported by MCC" % ( self.fBurstRate) return 1 self.mccBurst.mccBurstSetRate(self.fBurstRate) elif self.fBurstRate == fBeamFullRate: self.mccBurst.mccBurstSetRate(0) elif self.fBurstRate < fBeamFullRate: if self.fBurstRate == 60: print "!!! Burst rate %g is not supported by MCC" % ( self.fBurstRate) return 1 self.mccBurst.mccBurstSetRate(self.fBurstRate) else: print "!!! Burst rate %g is faster than Beam rate %g" % ( self.fBurstRate, fBeamFullRate) return 1 print "## Multiple shot: %d" % (self.iNumShot) # Exposure Time = # camear open (clean CCD) delay ( self.iSlowCamOpenDelay: 0 for PI, 5*120Hz for FLI) # + manual sleep (fExpDelay) # + exposure Time ((self.iNumShot / self.fBurstRate) second) # = 0.0 + max(1, self.iSlowCamOpenDelay)/120.0 + (self.iNumShot / self.fBurstRate) + fExpDelay second self.fExposureTime = 0.0 + self.iSlowCamOpenDelay / 120.0 + self.fExpDelay + self.iNumShot / float( self.fBurstRate) print "CREATE DAQ CONTROL OBJECT" self.daq = pydaq.Control(self.daq_host, self.daq_platform) try: print "daq connect...", sys.stdout.flush() self.daq.connect() # get dbpath and key from DAQ print " done." except: print "!! daq.connect() failed" print "!! Possibly because 1. DAQ devices has NOT been allocated" print "!! or 2. You are running DAQ control GUI in remote machines" print "!! Please check 1. DAQ is in good state and re-select the devices" print "!! 2. If the restart script actually runs DAQ in another machine" print "ERROR", sys.exc_info()[0] return 1 if self.bSimMode: self.alias = "PRINCETON_SIM" else: self.alias = "SLOW_CAMERA" if self.daq.dbalias() != self.alias: print "!!! the current DAQ config type is %s" % ( self.daq.dbalias()) print "!!! please switch to %s to run this script" % (self.alias) print "daq disconnect...", sys.stdout.flush() self.daq.disconnect() print " done." return 2 print "CONFIGURE DAQ" if controls is None: iFail = self.configure(controls=[]) else: iFail = self.configure(controls=controls) if iFail != 0: print "daq disconnect...", sys.stdout.flush() self.daq.disconnect() print " done." return 3 if self.bShutterMode: if ShutterInit(self.iNumShot) != 0: print "Shutter Init Failed" return 4 print "SET CAMERA CONTROL SEQUENCE" self.setCameraControlSequence() self.iNumTotalImage = 0 print "## Please make sure" if not self.bSimMode: print "## - MCC has switched to Burst Mode," print "## - Andor/Princeton camera is selected (if you need it)," print "## - chiller is running and the cooling temperature is set properly." if bDaqBegin: # cpo changed this line self.beginCycle(controls) return 0
def stop(self): caput(pvPlayCtrl, (0, )) # PlayCtrl = Stop
def run(self): caput(pvPlayMode, (2, )) # PlayMode = forever caput(pvPlayCtrl, (1, )) # PlayCtrl = Play
def runN(self, n): caput(pvPlayMode, (1, )) # PlayMode = Repeat N caput(pvRepCount, (n, )) # RepCount = n caput(pvPlayCtrl, (1, )) # PlayCtrl = Play