def __init__(self): self.boardAddress = "192.168.0.175" self.program = SimpleGlibProgram( os.path.join( INSTALLATION_PATH, "runcontrol", "GlibSuper.xml" ) ) # Need to specify the environment variables required to run XDAQ. To get them use the system # settings in runcontrol/environmentVariables.py. I can't get them from the current environment # because they might not be set for the current user (apache won't have any of them set). environmentVariables=getEnvironmentVariables() self.program.setEnvironmentVariables( environmentVariables ) self.program.initialiseCBCs() # Do the necessary initialisation to get information about the CBCs # Need to provide the full executable path because this might not be in the path for different users # When the analyser is spawned it takes on the environment of this script, so I'll modify that directly self.analysisControl = AnalyserControl( "127.0.0.1", "50000", True, environmentVariables ) self.analysisControl.reset() # Directory where the user can save their I2C files self.userI2cDirectory=INSTALLATION_PATH+"/runcontrol/user_i2c/" # The members below are for handling the thread that takes data self.dataTakingThread=None self.dataTakingFractionComplete=1 self.dataTakingStatusString="Not taking data"
from pythonlib.AnalyserControl import AnalyserControl # Create an object that informs the user when the run is finished class PrintStatus(object): def currentStatus(self, fractionComplete, statusString): print "%3d%% - %s" % (int(fractionComplete * 100 + 0.5), statusString) def finished(self): print "Finished taking data" daqProgram = SimpleGlibProgram("GlibSuper.xml") # Temporary hack. At the moment I can't get this to run as myself so I'll start # as the xtaldaq user daqProgram.contexts[0].forcedEnvironmentVariables["USER"] = "******" daqProgram.contexts[0].forcedEnvironmentVariables["SCRATCH"] = "/tmp" analysisControl = AnalyserControl("127.0.0.1", "50000") occupancyCheckRun = OccupancyCheck(PrintStatus(), daqProgram, analysisControl) # I have no interest in running this in a separate thread (that's mostly for gui # stuff) so I'll just call the run method directly. If I wanted to start it in a # separate thread I'd call "start" instead. occupancyCheckRun.run() occupancies = analysisControl.occupancies() # The C++ code doesn't know which CBCs are connected. Dummy data is in the output files # for unconnected CBCs. I'll check which CBCs are connected and only print the data for # those. for cbcName in daqProgram.supervisor.connectedCBCNames(): try: occupancyArray = occupancies[cbcName] # First print some column headers
class GlibControlService: """ Class that invokes the Glib control methods in response to JSON RPC calls. There should be no logic pertaining to the Glib here - this should solely pass on any commands that you want externally visible to the correct method in the python control library. @author Mark Grimes ([email protected]) @date 11/Jan/2014 """ class _DataTakingStatusReceiver(object) : """ Simple class to receive the status notifications from the data taking thread. Sets parameters in the GlibControlService provided in the constructor, so intended to be created by GlibControlService passing "self". """ def __init__( self, parentControlService ) : self.parentControlService=parentControlService def currentStatus( self, fractionComplete, statusString ) : self.parentControlService.dataTakingFractionComplete=fractionComplete self.parentControlService.dataTakingStatusString=statusString def finished( self ) : self.parentControlService.dataTakingThread=None self.parentControlService.dataTakingFractionComplete=1 self.parentControlService.dataTakingStatusString="Not taking data" def __init__(self): self.boardAddress = "192.168.0.175" self.program = SimpleGlibProgram( os.path.join( INSTALLATION_PATH, "runcontrol", "GlibSuper.xml" ) ) # Need to specify the environment variables required to run XDAQ. To get them use the system # settings in runcontrol/environmentVariables.py. I can't get them from the current environment # because they might not be set for the current user (apache won't have any of them set). environmentVariables=getEnvironmentVariables() self.program.setEnvironmentVariables( environmentVariables ) self.program.initialiseCBCs() # Do the necessary initialisation to get information about the CBCs # Need to provide the full executable path because this might not be in the path for different users # When the analyser is spawned it takes on the environment of this script, so I'll modify that directly self.analysisControl = AnalyserControl( "127.0.0.1", "50000", True, environmentVariables ) self.analysisControl.reset() # Directory where the user can save their I2C files self.userI2cDirectory=INSTALLATION_PATH+"/runcontrol/user_i2c/" # The members below are for handling the thread that takes data self.dataTakingThread=None self.dataTakingFractionComplete=1 self.dataTakingStatusString="Not taking data" def getStates(self, msg): """ Returns the states of all the active XDAQ applications as an array. Each element is itself a two element array of the application name and the state. """ try: results = [] for context in self.program.contexts : for application in context.applications : results.append( [application.className,application.getState()] ) return results except Exception as error: return "Exception: "+str(error) def connectedCBCNames(self, msg): """ Returns the names of the connected CBCs. """ return self.program.supervisor.connectedCBCNames() def I2CRegisterValues(self, msg): return self.program.supervisor.I2CRegisterValues(msg) def setI2CRegisterValues(self, msg): # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") chipNames = msg.keys() registerNameValueTuple = msg[chipNames[0]] return self.program.supervisor.setI2c( registerNameValueTuple, chipNames ) def saveI2cRegisterValues(self, msg): self.program.supervisor.saveI2c( self.userI2cDirectory+msg ) return msg def loadI2cRegisterValues(self, msg): self.program.supervisor.loadI2c( self.userI2cDirectory+msg ) return msg def startProcesses(self, msg): """ Starts all of the XDAQ processes """ # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") try: self.program.startAllProcesses() return None except Exception as error: return "Exception: "+str(error) def killProcesses(self, msg): """ Kills all of the XDAQ processes """ # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") try: self.program.killAllProcesses() return None except Exception as error: return "Exception: "+str(error) def boardIsReachable( self, msg ): """ Pings the board to see if it is available """ # return true or false depending on whether the board can be pinged return testStandTools.ping( self.boardAddress ) def stopTakingData( self, msg ) : """ Tell the data taking thread to stop whatever it's doing. """ if self.dataTakingThread!=None : self.dataTakingThread.quit=True def startSCurveRun( self, msg ) : """ Starts a new thread taking s-curve data """ # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") self.dataTakingFractionComplete=0 self.dataTakingStatusString="Initiating s-curve run" thresholds=msg self.analysisControl.reset() self.dataTakingThread=SCurveRun( GlibControlService._DataTakingStatusReceiver(self), self.program, self.analysisControl, thresholds ) self.dataTakingThread.start() def startOccupancyCheck( self, msg ) : """ Starts a new thread with a short 100 event run to check the occupancies for the current settings. """ # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") self.dataTakingFractionComplete=0 self.dataTakingStatusString="Initiating occupancy check" self.analysisControl.reset() self.dataTakingThread=OccupancyCheck( GlibControlService._DataTakingStatusReceiver(self), self.program, self.analysisControl ) self.dataTakingThread.start() def startTrimCalibration( self, msg ) : """ Starts a new thread that tries to calibrate the channel trims. """ # Make sure I'm not currently taking data if self.dataTakingThread!=None : raise Exception("Currently taking data") self.dataTakingFractionComplete=0 self.dataTakingStatusString="Initiating trim calibration" self.analysisControl.reset() self.dataTakingThread=CalibrateChannelTrims( GlibControlService._DataTakingStatusReceiver(self), self.program, self.analysisControl, range(100,150), msg['midPointTarget'], maxLoops=msg['maxLoops'] ) self.dataTakingThread.start() def getDataTakingStatus( self, msg ) : return {"fractionComplete":self.dataTakingFractionComplete,"statusString":self.dataTakingStatusString} def getOccupancies( self, msg ) : returnValue={} #self.analysisControl.analyseFile( "/tmp/cbc2SCurveRun_OutputFile.dat" ) occupancies=self.analysisControl.occupancies() # The C++ code doesn't know which CBCs are connected. Dummy data is in the output files # for unconnected CBCs. I'll check which CBCs are connected and only return the data for # those. for cbcName in self.program.supervisor.connectedCBCNames() : try : returnValue[cbcName]=occupancies[cbcName] except KeyError : # No data for that CBC returnValue[cbcName]=None return returnValue def createHistogram( self, msg ) : self.analysisControl.saveHistogramPicture( INSTALLATION_PATH+"/gui/output/"+msg['outputFilename'], msg['cbcChannelRange'] ) def saveHistograms( self, msg ) : self.analysisControl.saveHistograms( msg )
if __name__ == "__main__": from pythonlib.SimpleGlibProgram import SimpleGlibProgram from pythonlib.AnalyserControl import AnalyserControl # Create an object to print the current status to the screen. This will # be passed to the SCurveRun instance which will call these methods. class PrintStatus(object): def currentStatus(self, fractionComplete, statusString): print "%3d%% - %s" % (int(fractionComplete * 100 + 0.5), statusString) def finished(self): print "Finished" daqProgram = SimpleGlibProgram("GlibSuper.xml") # Temporary hack. At the moment I can't get this to run as myself so I'll start # as the xtaldaq user daqProgram.contexts[0].forcedEnvironmentVariables["USER"] = "******" daqProgram.contexts[0].forcedEnvironmentVariables["SCRATCH"] = "/tmp" analysisControl = AnalyserControl("127.0.0.1", "50000") analysisControl.reset() # I might be connecting to an already running controller cbc2SCurveRun = SCurveRun(PrintStatus(), daqProgram, analysisControl, range(100, 150)) # I have no interest in running this in a separate thread (that's mostly for gui # stuff) so I'll just call the run method directly. If I wanted to start it in a # separate thread I'd call "start" instead. cbc2SCurveRun.run() analysisControl.saveHistograms("/tmp/histograms.root") print "Histograms saved to '/tmp/histograms.root'"