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 print "Occupancies for " + cbcName print " ", # Padding to account for row names for index in range(0, 16): print "CHx%X" % index, row = 0 print "\nCH%Xx" % row, for index in range(0, len(occupancyArray)): print "%4d" % occupancyArray[index],
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 )