def getDetectorCalibration(verbose=False, fileName=''): if fileName == '': detCalib = aolUtil.struct({'path': 'detCalib', 'name': 'calib'}) # Get the latest detector callibration values from file if not os.path.exists(detCalib.path): os.makedirs(detCalib.path) if not os.path.exists(detCalib.path + '/' + detCalib.name + '0.txt'): np.savetxt(detCalib.path + '/' + detCalib.name + '0.txt', [1] * 16) detCalib.fileNumber = np.max([ int(f[len(detCalib.name):-4]) for f in os.listdir(detCalib.path) if len(f) > len(detCalib.name) and f[:len(detCalib.name)] == detCalib.name ]) else: detCalib = aolUtil.struct() splitPath = fileName.split('/') if len(splitPath) > 1: detCalib.path = '/'.join(splitPath[:-1]) else: detCalib.path = '.' detCalib.name = splitPath[-1] detCalib.fileNumber = np.nan if args.calibrate == -1: detCalib.factors = np.loadtxt( detCalib.path + '/' + detCalib.name + '{}.txt'.format(detCalib.fileNumber if np. isfinite(detCalib.fileNumber) else '')) else: detCalib.factors = np.ones(16) if verbose: print 'Detector factors =', detCalib.factors return detCalib
def getDetectorCalibration(verbose=False, fileName=''): if fileName == '': detCalib = aolUtil.struct({'path':'detCalib', 'name':'calib'}) # Get the latest detector callibration values from file if not os.path.exists(detCalib.path): os.makedirs(detCalib.path) if not os.path.exists(detCalib.path + '/' + detCalib.name + '0.txt'): np.savetxt(detCalib.path + '/' + detCalib.name + '0.txt', [1]*16) detCalib.fileNumber = np.max([int(f[len(detCalib.name):-4]) for f in os.listdir(detCalib.path) if len(f) > len(detCalib.name) and f[:len(detCalib.name)]==detCalib.name]) else: detCalib = aolUtil.struct() splitPath = fileName.split('/') if len(splitPath) > 1: detCalib.path = '/'.join(splitPath[:-1]) else: detCalib.path = '.' detCalib.name = splitPath[-1] detCalib.fileNumber = np.nan if args.calibrate == -1: detCalib.factors = np.loadtxt(detCalib.path + '/' + detCalib.name + '{}.txt'.format( detCalib.fileNumber if np.isfinite(detCalib.fileNumber) else '' ) ) else: detCalib.factors = np.ones(16) if verbose: print 'Detector factors =', detCalib.factors return detCalib
def masterLoopSetup(args, scales): # Master loop data collector masterLoop = aolUtil.struct() # Define the plot interval from the command line input masterLoop.tPlot = args.plotInterval # set up the buffer size to be able to handle twice the amoun of # data that is expected masterLoop.bufSize = int(np.round(120 * masterLoop.tPlot * 1.3)) # Make template of the array that should be sent between the ranks masterLoop.bufTemplate = np.empty((1, dSize), dtype=float) # Make empty queues. masterLoop.req = deque() masterLoop.buf = deque() # Initialize the stop time masterLoop.tStop = time.time() # Calibration if args.calibrate > -1: masterLoop.calibValues = [] return masterLoop
def eventDataContainer(args): # Set up some data containers event = aolUtil.struct() event.sender = [] event.fiducials = [] event.times = [] event.full = [] event.intRoi0 = [] event.intRoi0Bg = [] event.intRoi1 = [] event.pol = [] #event.positions = [] event.ebEnergyL3 = [] event.gasDet = [] if args.photonEnergy != 'no': event.energy = [] event.evrCodes = [] #event.deltaK = [] #event.deltaEnc = [] event.delayStage = [] event.fsTiming = [] event.ttTime = [] event.timeSignals_V = [] return event
def master_data_setup(args): # Container for the master data # This is mainly for the averaging buffers master_data = aolUtil.struct() #master_data.energyAmplitude = None #master_data.energyAmplitudeRoi0 = None #master_data.timeAmplitude = None #master_data.timeAmplitudeFiltered = None #master_data.timeAmplitudeRoi0 = None #master_data.timeAmplitudeRoi1 = None # Storage for the trace avareaging buffer master_data.time_trace_buffer = deque([], args.traceAverage) master_data.roi_0_buffer = deque([], args.roi0Average) master_data.energy_trace_buffer = deque([], args.traceAverage) # Storage for roi averaging master_data.roi_0_buffer = deque([], args.roi0Average) master_data.roi_1_buffer = deque([], args.roi1Average) # Buffers for the polarization averageing master_data.pol_degree_buffer = deque([], args.polAverage) master_data.pol_angle_buffer = deque([], args.polAverage) master_data.pol_amp_buffer = deque([], args.polAverage) master_data.pol_beta_buffer = deque([], args.polAverage) master_data.pol_roi0_buffer = deque([], args.polAverage) return master_data
def get_scales(env, cb, verbose=False): global dSize global dTraces global d_energy_trace # A struct object to hold the scale information scales = aolUtil.struct() # Assume that all the tofs have the same energy scale and use only the first # one. scales.energy_eV = cb.get_energy_scales_eV()[0] scales.energyRoi0_eV = cb.get_energy_scales_eV(roi=0)[0] scales.energyRoi0_slice = slice( scales.energy_eV.searchsorted(np.min(scales.energyRoi0_eV)), scales.energy_eV.searchsorted(np.max(scales.energyRoi0_eV), side='right')) # Get all the time scales scales.time_us = cb.get_time_scales_us() scales.timeRoi0_us = cb.get_time_scales_us(roi=0) scales.timeRoi0_slice = [ slice(full.searchsorted(np.min(part)), full.searchsorted(np.max(part), side='right')) for full, part in zip(scales.time_us, scales.timeRoi0_us) ] scales.timeRoi2_us = cb.get_time_scales_us(roi=2) scales.timeRoi1_us = cb.get_time_scales_us(roi=1) scales.timeRoi1_slice = [ slice(full.searchsorted(np.min(part)), full.searchsorted(np.max(part), side='right')) for full, part in zip(scales.time_us, scales.timeRoi1_us) ] for i, scale_list in enumerate( [scales.timeRoi0_us, scales.timeRoi1_us, scales.timeRoi2_us]): if np.any([len(s) == 0 for s in scale_list]): print ('ERROR: Roi {} is empty for at leas one of' + \ 'the detectors.').format(i) sys.exit(0) # Calculate the background factors scales.tRoi0BgFactors = np.array([ np.float(len(s)) / len(bg) for s, bg in zip(scales.timeRoi0_us, scales.timeRoi2_us) ]) # Get some angle vectors scales.angles = cb.getAngles('rad') scales.anglesFit = np.linspace(0, 2 * np.pi, 100) # Update the data size descriptions in the globals traces_size = 16 * np.max([len(t) for t in scales.time_us]) dTraces = slice(dSize, dSize + traces_size) dSize += traces_size energy_trace_size = len(scales.energy_eV) d_energy_trace = slice(dSize, dSize + energy_trace_size) dSize += energy_trace_size return scales
def get_scales(env, cb, verbose=False): global dSize global dTraces global d_energy_trace # A struct object to hold the scale information scales = aolUtil.struct() # Assume that all the tofs have the same energy scale and use only the first # one. scales.energy_eV = cb.get_energy_scales_eV()[0] scales.energyRoi0_eV = cb.get_energy_scales_eV(roi=0)[0] scales.energyRoi0_slice = slice( scales.energy_eV.searchsorted(np.min(scales.energyRoi0_eV)), scales.energy_eV.searchsorted(np.max(scales.energyRoi0_eV), side='right')) # Get all the time scales scales.time_us = cb.get_time_scales_us() scales.timeRoi0_us = cb.get_time_scales_us(roi=0) scales.timeRoi0_slice = [slice(full.searchsorted(np.min(part)), full.searchsorted(np.max(part), side='right')) for full, part in zip(scales.time_us, scales.timeRoi0_us)] scales.timeRoi2_us = cb.get_time_scales_us(roi=2) scales.timeRoi1_us = cb.get_time_scales_us(roi=1) scales.timeRoi1_slice = [slice(full.searchsorted(np.min(part)), full.searchsorted(np.max(part), side='right')) for full, part in zip(scales.time_us, scales.timeRoi1_us)] for i, scale_list in enumerate([scales.timeRoi0_us, scales.timeRoi1_us, scales.timeRoi2_us]): if np.any([len(s)==0 for s in scale_list]): print ('ERROR: Roi {} is empty for at leas one of' + \ 'the detectors.').format(i) sys.exit(0) # Calculate the background factors scales.tRoi0BgFactors = np.array( [np.float(len(s))/len(bg) for s,bg in zip(scales.timeRoi0_us, scales.timeRoi2_us)]) # Get some angle vectors scales.angles = cb.getAngles('rad') scales.anglesFit = np.linspace(0, 2*np.pi, 100) # Update the data size descriptions in the globals traces_size = 16 * np.max([len(t) for t in scales.time_us]) dTraces = slice(dSize, dSize + traces_size) dSize += traces_size energy_trace_size = len(scales.energy_eV) d_energy_trace = slice(dSize, dSize+energy_trace_size) dSize += energy_trace_size return scales
def master_loop_setup(args): # Master loop data collector master_loop = aolUtil.struct() # Define the plot interval from the command line input master_loop.tPlot = args.plotInterval # Make template of the array that should be sent between the ranks master_loop.buf_template = np.empty((dSize, ), dtype=float) # Initialize the stop time master_loop.tStop = time.time() # Calibration if args.calibrate > -1: master_loop.calibValues = [] return master_loop
def master_loop_setup(args): # Master loop data collector master_loop = aolUtil.struct() # Define the plot interval from the command line input master_loop.tPlot = args.plotInterval # Make template of the array that should be sent between the ranks master_loop.buf_template = np.empty((dSize,), dtype=float) # Initialize the stop time master_loop.tStop = time.time() # Calibration if args.calibrate > -1: master_loop.calibValues = [] return master_loop
def load_configuration_dict(file_name, default=None, verbose=False): if (not os.path.isfile(file_name)): if default is None: raise IOError(('The file {} could not be read' + ' and no default was given.').format(file_name)) return struct(default) with open(file_name, 'r') as fp: config_dict = json.load(fp) config_dict = convertToStrings(config_dict) if verbose: print 'Configuration file read:' print json.dumps(config_dict, sort_keys=True, indent=4) return config_dict
def getScales(env, config, verbose=False): global dSize global dTraces scales = aolUtil.struct() # Grab the relevant scales scales.energy_eV = (config.energyScaleBinLimits[:-1] + np.diff(config.energyScaleBinLimits) / 2) scales.eRoi0S = slice( scales.energy_eV.searchsorted(np.min(config.energyRoi0_eV_common)), scales.energy_eV.searchsorted(np.max(config.energyRoi0_eV_common))) scales.energyRoi0_eV = scales.energy_eV[scales.eRoi0S] tempTime = tof.getTimeScale_us(env, config.cbSourceString, verbose=verbose) scales.baselineSlice = slice(tempTime.searchsorted(config.baselineEnd_us)) scales.timeSlice = slice(tempTime.searchsorted(config.tMin_us), tempTime.searchsorted(config.tMax_us)) scales.time_us = tempTime[scales.timeSlice] scales.tRoi0S = cookieBox.sliceFromRange(scales.time_us, [config.timeRoi0_us_common] * 16) scales.tRoi0BgS = cookieBox.sliceFromRange( scales.time_us, [config.timeRoi0Bg_us_common] * 16) scales.tRoi0BgFactors = np.array([ np.float(s.stop - s.start) / (bg.stop - bg.start) for s, bg in zip(scales.tRoi0S, scales.tRoi0BgS) ]) scales.tRoi1S = cookieBox.sliceFromRange(scales.time_us, [config.timeRoi1_us_common] * 16) scales.timeRoi0_us = [scales.time_us[s] for s in scales.tRoi0S] scales.timeRoiBg0_us = [scales.time_us[s] for s in scales.tRoi0BgS] scales.timeRoi1_us = [scales.time_us[s] for s in scales.tRoi1S] scales.angles = cookieBox.phiRad scales.anglesFit = np.linspace(0, 2 * np.pi, 100) scales.scaling_VperCh, scales.offset_V = cookieBox.getSignalScaling( env, config.cbSourceString, verbose=verbose) dTraces = slice(dSize, dSize + 16 * len(scales.time_us)) dSize += 16 * len(scales.time_us) return scales
def getScales(env, config, verbose=False): global dSize global dTraces scales = aolUtil.struct() # Grab the relevant scales scales.energy_eV = (config.energyScaleBinLimits[:-1] + np.diff(config.energyScaleBinLimits)/2) scales.eRoi0S = slice( scales.energy_eV.searchsorted(np.min(config.energyRoi0_eV_common)), scales.energy_eV.searchsorted(np.max(config.energyRoi0_eV_common))) scales.energyRoi0_eV = scales.energy_eV[scales.eRoi0S] tempTime = tof.getTimeScale_us(env, config.cbSourceString, verbose=verbose) scales.baselineSlice = slice( tempTime.searchsorted(config.baselineEnd_us) ) scales.timeSlice = slice( tempTime.searchsorted(config.tMin_us), tempTime.searchsorted(config.tMax_us) ) scales.time_us = tempTime[ scales.timeSlice ] scales.tRoi0S = cookieBox.sliceFromRange(scales.time_us, [config.timeRoi0_us_common]*16) scales.tRoi0BgS = cookieBox.sliceFromRange(scales.time_us, [config.timeRoi0Bg_us_common]*16) scales.tRoi0BgFactors = np.array([np.float(s.stop-s.start)/(bg.stop-bg.start) for s,bg in zip(scales.tRoi0S, scales.tRoi0BgS)]) scales.tRoi1S = cookieBox.sliceFromRange(scales.time_us, [config.timeRoi1_us_common]*16) scales.timeRoi0_us = [scales.time_us[s] for s in scales.tRoi0S] scales.timeRoiBg0_us = [scales.time_us[s] for s in scales.tRoi0BgS] scales.timeRoi1_us = [scales.time_us[s] for s in scales.tRoi1S] scales.angles = cookieBox.phiRad scales.anglesFit = np.linspace(0, 2*np.pi, 100) scales.scaling_VperCh, scales.offset_V = cookieBox.getSignalScaling(env, config.cbSourceString, verbose=verbose) dTraces = slice(dSize, dSize + 16*len(scales.time_us)) dSize += 16*len(scales.time_us) return scales
def event_data_container(args, event=None): # Set up some data containers if event is None: event = aolUtil.struct() event.sender = [] event.fiducials = [] event.times = [] event.intRoi0 = [] event.intRoi0Bg = [] event.intRoi1 = [] event.pol = [] event.ebEnergyL3 = [] event.gasDet = [] if args.photonEnergy != 'no': event.energy = [] event.deltaK = [] event.deltaEnc = [] return event
"filterWinerResponse": 1, "filterAverageNumPoints": 4, "detectorSource": "DetInfo(AmoETOF.0:Acqiris.0)", "t_min_us": 0.20, #interval to cut from raw data "t_max_us": 0.26, "t_slice": True } lclsConfig = {'lcls_photonEnergyA': 1, 'lcls_photonEnergyB': 1} lclsConfig = aolUtil.struct(lclsConfig) retardationPV = 'AMO:R14:IOC:10:VHS0:CH0:VoltageMeasure' # Acqiris channel asignment acqiris_setup = { 0: ['ACQ4', 1], 1: ['ACQ4', 2], 2: ['ACQ4', 3], 3: ['ACQ4', 0], 4: ['ACQ1', 7], 5: ['ACQ1', 6], 6: ['ACQ1', 5], 7: ['ACQ1', 4], 8: ['ACQ1', 3], 9: ['ACQ1', 2],
def loadConfiguration(file_name, default=None, quiet=False): return struct(load_config_dict(file_name, default, ~quiet))
+ "amoh5215/psana/tofCalibs/tof_calib_0.json"), "filterMethod": "none", # wavelet, average, wienerDeconv "filterWaveletLevels": 10, "filterWinerSNR": 1, "filterWinerResponse":1, "filterAverageNumPoints":4, "detectorSource": "DetInfo(AmoETOF.0:Acqiris.0)", "t_min_us": 0.20, "t_max_us": 0.26, "t_slice": True } lclsConfig = { 'lcls_photonEnergyA':1, 'lcls_photonEnergyB':1} lclsConfig = aolUtil.struct(lclsConfig) retardationPV = 'AMO:R14:IOC:10:VHS0:CH0:VoltageMeasure' # Acqiris channel asignment acqiris_setup = { 0:['ACQ1', 4], 1:['ACQ1', 3], 2:['ACQ1', 2], 3:['ACQ1', 1], 4:['ACQ1', 0], 5:['ACQ1', 15], 6:['ACQ1', 14], 7:['ACQ1', 13], 8:['ACQ1', 12], 9:['ACQ1', 11],
def main(args, verbose=False): verbose=args.verbose try: # Import the configuration file config = importConfiguration(args, verbose=verbose) # Read the detector transmission calibrations detCalib = getDetectorCalibration(verbose=verbose, fileName=args.gainCalib) # Change the configuration fit masks according to the factors config.nanFitMask = config.nanFitMask.astype(float) config.nanFitMask[np.isnan(detCalib.factors)] = np.nan config.boolFitMask[np.isnan(detCalib.factors)] = False # Connect to the correct datasource ds = connectToDataSource(args, config, verbose=verbose) events = ds.events() # Get the epics store epics = ds.env().epicsStore() # Get the next event. The purpouse here is only to make sure the # datasource is initialized enough so that the env object is avaliable. evt = events.next() cookieBox.proj.setFitMask(config.boolFitMask) # Get the scales that we need scales = getScales(ds.env(), config) #print scales # The master have some extra things to do if rank == 0: # Set up the plotting in AMO from ZmqSender import zmqSender zmq = zmqSender() masterLoop = masterLoopSetup(args, scales) # Averaging factor for the augers augerAverage = aolUtil.struct() augerAverage.fNewRoi1 = args.roi1Average augerAverage.fOldRoi1 = 1. - augerAverage.fNewRoi1 augerAverage.plotRoi1 = None if args.saveData != 'no': saveFile = openSaveFile(args.saveData, not args.offline, config) else: # set an empty request req = None # The main loop that never ends... while 1: # An event data container eventData = eventDataContainer(args) # The master should set up the recive requests if rank == 0: masterDataSetup(eventData, args) setupRecives(masterLoop, verbose=verbose) # The master should do something usefull while waiting for the time # to pass while (time.time() < masterLoop.tStop) if rank==0 else 1 : # Get the next event evt = events.next() appendEventData(evt, eventData, config, scales, detCalib, masterLoop if rank==0 else None, args, verbose=verbose) appendEpicsData(epics, eventData) # Everyone but the master goes out of the loop here if rank > 0: break # Rank 0 stuff on timed loop exit if rank == 0: # Shift the stop time masterLoop.tStop += masterLoop.tPlot # Check how many arrived masterLoop.nArrived = \ [r.Get_status() for r in masterLoop.req].count(True) if verbose: print 'master recived data from', masterLoop.nArrived, \ 'events' print 'with its own events it makes up', \ masterLoop.nArrived + masterLoop.nProcessed if masterLoop.nArrived == 0 and masterLoop.nProcessed==0: continue # A temp buffer for the arrived data masterLoop.arrived = [b.reshape(-1) for i,b in enumerate(masterLoop.buf) if i < masterLoop.nArrived] mergeMasterAndWorkerData(eventData, masterLoop, args, verbose=False) # Send data for plotting zmqPlotting(eventData, augerAverage, scales, zmq) if args.saveData != 'no': writeDataToFile(saveFile, eventData, args.saveData) else: # The rest of the ranks come here after breaking out of the loop # the goal is to send data to the master core. req = packageAndSendData(eventData, req) except KeyboardInterrupt: print "Terminating program." if rank == 0 and args.calibrate > -1: if args.saveData != 'no': closeSaveFile(saveFile) saveDetectorCalibration(masterLoop, detCalib, config, verbose=verbose, beta = args.calibBeta)
def main(args, verbose=False): verbose = args.verbose try: # Import the configuration file config = importConfiguration(args, verbose=verbose) # Read the detector transmission calibrations detCalib = getDetectorCalibration(verbose=verbose, fileName=args.gainCalib) # Change the configuration fit masks according to the factors config.nanFitMask = config.nanFitMask.astype(float) config.nanFitMask[np.isnan(detCalib.factors)] = np.nan config.boolFitMask[np.isnan(detCalib.factors)] = False # Connect to the correct datasource ds = connectToDataSource(args, config, verbose=verbose) events = ds.events() # Get the epics store epics = ds.env().epicsStore() # Get the next event. The purpouse here is only to make sure the # datasource is initialized enough so that the env object is avaliable. evt = events.next() cookieBox.proj.setFitMask(config.boolFitMask) # Get the scales that we need scales = getScales(ds.env(), config) #print scales # The master have some extra things to do if rank == 0: # Set up the plotting in AMO from ZmqSender import zmqSender zmq = zmqSender() masterLoop = masterLoopSetup(args, scales) # Averaging factor for the augers augerAverage = aolUtil.struct() augerAverage.fNewRoi1 = args.roi1Average augerAverage.fOldRoi1 = 1. - augerAverage.fNewRoi1 augerAverage.plotRoi1 = None if args.saveData != 'no': saveFile = openSaveFile(args.saveData, not args.offline, config) else: # set an empty request req = None # The main loop that never ends... while 1: # An event data container eventData = eventDataContainer(args) # The master should set up the recive requests if rank == 0: masterDataSetup(eventData, args) setupRecives(masterLoop, verbose=verbose) # The master should do something usefull while waiting for the time # to pass while (time.time() < masterLoop.tStop) if rank == 0 else 1: # Get the next event evt = events.next() appendEventData(evt, eventData, config, scales, detCalib, masterLoop if rank == 0 else None, args, verbose=verbose) appendEpicsData(epics, eventData) # Everyone but the master goes out of the loop here if rank > 0: break # Rank 0 stuff on timed loop exit if rank == 0: # Shift the stop time masterLoop.tStop += masterLoop.tPlot # Check how many arrived masterLoop.nArrived = \ [r.Get_status() for r in masterLoop.req].count(True) if verbose: print 'master recived data from', masterLoop.nArrived, \ 'events' print 'with its own events it makes up', \ masterLoop.nArrived + masterLoop.nProcessed if masterLoop.nArrived == 0 and masterLoop.nProcessed == 0: continue # A temp buffer for the arrived data masterLoop.arrived = [ b.reshape(-1) for i, b in enumerate(masterLoop.buf) if i < masterLoop.nArrived ] mergeMasterAndWorkerData(eventData, masterLoop, args, verbose=False) # Send data for plotting zmqPlotting(eventData, augerAverage, scales, zmq) if args.saveData != 'no': writeDataToFile(saveFile, eventData, args.saveData) else: # The rest of the ranks come here after breaking out of the loop # the goal is to send data to the master core. req = packageAndSendData(eventData, req) except KeyboardInterrupt: print "Terminating program." if rank == 0 and args.calibrate > -1: if args.saveData != 'no': closeSaveFile(saveFile) saveDetectorCalibration(masterLoop, detCalib, config, verbose=verbose, beta=args.calibBeta)