def GetWaveDataR(configFileName, directoryName, fileNum=1, getZeroCrossingIntegral=True): startTime = time.time() print("Running GetWaveData!") print("Starting at " + time.strftime('%H:%M:%S')) config = configparser.ConfigParser() config.read(configFileName) # Setup data info # Directories data_directory = directoryName # New data_file_name = config['Directories']['data_file_name'] #pywaves_directory = config['Directories']['pywaves_directory'] # Digitizer dataFormatStr = config['Digitizer']['dataFormat'] nSamples = int(config['Digitizer']['samples_per_waveform']) ns_per_sample = int(config['Digitizer']['ns_per_sample']) number_of_bits = int(config['Digitizer']['number_of_bits']) dynamic_range_volts = float(config['Digitizer']['dynamic_range_volts']) polarity0 = int( config['Digitizer']['polarity0']) # Polarity of first several channels p0ch = int(config['Digitizer'] ['p0ch']) # Number of channels to apply first polarity to polarity1 = int( config['Digitizer']['polarity1']) # Polarity of remaining channels baselineOffset = int(config['Digitizer']['baseline_offset']) nBaselineSamples = int(config['Digitizer']['baseline_samples']) nCh = int(config['Digitizer']['number_of_channels']) # nWavesPerLoad = int(config['Data Management']['waves_per_load']) nWavesPerLoad = 10000 # Chosen pretty arbitrarily # nWaves = int(config['Data Management']['waves_per_folder']) # per folder nWaves = 1000000 # Large number # Let's just do all of the folders! startFolder = int(config['Data Management']['start_folder']) nFolders = fileNum # nFolders = int(config['Data Management']['number_of_folders']) unevenFactor = int(config['Data Management']['uneven_factor']) cfdFraction = float(config['Pulse Processing']['cfd_fraction']) integralEnd = int(config['Pulse Processing']['integral_end']) totalIntegralStart = int( config['Pulse Processing']['total_integral_start']) tailIntegralStart = int(config['Pulse Processing']['tail_integral_start']) applyCRRC4 = bool(int(config['Pulse Processing']['apply_crrc4'])) CRRC4Tau = float(config['Pulse Processing']['crrc4_shaping_time']) # Load pywaves # sys.path.extend([pywaves_directory]) from dataloader import DataLoader from waveform import Waveform # Pre-calc if dataFormatStr == 'DPP_MIXED': dataFormat = DataLoader.DAFCA_DPP_MIXED elif dataFormatStr == 'STANDARD': dataFormat = DataLoader.DAFCA_STD if platform.system() is 'Windows': directory_separator = '\\' else: directory_separator = '/' # Initialize data arrays dataFile1 = data_directory + directory_separator + str( 1) + directory_separator + data_file_name datloader1 = DataLoader(dataFile1, dataFormat, nSamples) nWavesIn1 = datloader1.GetNumberOfWavesInFile() # print(str(nWavesIn1)) nLoads = int(nWavesIn1 / nWavesPerLoad) if nLoads < 1: nLoads = 1 chBufferSize = int(nFolders * nWavesIn1 * unevenFactor / nCh) VperLSB = dynamic_range_volts / (2**number_of_bits) fileTimeGap = 2**43 # Note: no more than 3 hours per measurement! # Setup channel queues ph = np.zeros((nCh, chBufferSize)) amp = np.zeros((nCh, chBufferSize)) tailInt = np.zeros((nCh, chBufferSize)) totalInt = np.zeros((nCh, chBufferSize)) rms = np.zeros((nCh, chBufferSize)) ttt = np.zeros((nCh, chBufferSize), dtype=np.uint32) extras = np.zeros((nCh, chBufferSize), dtype=np.uint32) fullTime = np.zeros((nCh, chBufferSize), dtype=np.uint64) cfd = np.zeros((nCh, chBufferSize)) chCount = np.zeros(nCh, dtype=np.uint32) flags = np.zeros((nCh, chBufferSize), dtype=np.uint32) # Setup data loader waveform = Waveform(np.zeros(nSamples), polarity0, baselineOffset, nBaselineSamples) print('polarity0 =' + str(polarity0)) print('p0ch = ' + str(p0ch)) print('polarity1 =' + str(polarity1)) # Queue up waves for f in range(startFolder, startFolder + nFolders): print('Folder {}:'.format(f)) fullDFileName = data_directory + directory_separator + str( f) + directory_separator + data_file_name datloader = DataLoader(fullDFileName, dataFormat, nSamples) nWavesInFile = datloader.GetNumberOfWavesInFile() nWaves = nWavesInFile + 1 if (nWavesInFile < nWaves): print('Warning: requested more waves than exists in file!') loadsInFile = int(np.ceil(nWavesInFile / nWavesPerLoad)) print('Loading all {} waves instead...'.format(nWavesInFile)) lastLoad = nWavesInFile - (loadsInFile - 1) * nWavesPerLoad else: loadsInFile = nLoads lastLoad = nWavesPerLoad if nWavesInFile % 2 == 0 or nWavesInFile % 2 == 1 or int(nCh) == 2: for load in range(loadsInFile): if (load == loadsInFile - 1): wavesThisLoad = lastLoad else: wavesThisLoad = nWavesPerLoad waves = datloader.LoadWaves(wavesThisLoad) for w in range(wavesThisLoad): ch = waves[w]['Channel'] waveform.SetSamples(waves[w]['Samples']) if (ch >= p0ch): waveform.Polarize(polarity1) else: waveform.Polarize(polarity0) #print(str( waveform.polarity)) if applyCRRC4: waveform.ApplyCRRC4(ns_per_sample, CRRC4Tau) if getZeroCrossingIntegral: ph[ch][ chCount[ch]] = waveform.GetIntegralToZeroCrossing( ) * VperLSB * ns_per_sample amp[ch][chCount[ch]] = waveform.GetMax() tailInt[ch][chCount[ch]] = waveform.GetIntegralFromPeak( tailIntegralStart, integralEnd) * VperLSB * ns_per_sample totalInt[ch][chCount[ch]] = waveform.GetIntegralFromPeak( totalIntegralStart, integralEnd) * VperLSB * ns_per_sample cfd[ch][chCount[ch]] = waveform.GetCFDTime( cfdFraction) * ns_per_sample ttt[ch][chCount[ch]] = waves[w]['TimeTag'] rms[ch][chCount[ch]] = waveform.GetRMSbls(nBaselineSamples) if dataFormatStr == 'DPP_MIXED': extras[ch][chCount[ch]] = waves[w]['Extras'] # fullTime[ch][chCount[ch]] = ((waves[w]['TimeTag'] + # ((waves[w]['Extras'] & 0xFFFF0000) # << 15)))*ns_per_sample fullTime[ch][chCount[ch]] = ( (waves[w]['TimeTag'] + ((waves[w]['Extras'] & 0xFFFF0000) << 15)) + fileTimeGap * f) * ns_per_sample chCount[ch] += 1 endTime = time.time() runTime = endTime - startTime print("GetWaveDataR took {} s".format(runTime)) return chCount, ph, amp, tailInt, totalInt, cfd, ttt, extras, fullTime, flags, rms
def GetWaveData(configFileName, getZeroCrossingIntegral=True, getWaves=True, loud=False, getTail=False, getTot=False, getPH=False, getAmp=False, getRMS=False, getExtras=False, getFullTime=False, getCFD=False, getflags=False): # --------------------------------------------------------------------------------------------------------------------- # # Configuration # --------------------------------------------------------------------------------------------------------------------- # config = configparser.ConfigParser() config.read(configFileName) # Setup data info # Directories data_directory = config['Directories']['data_directory'] data_file_name = config['Directories']['data_file_name'] goodInd = False if 'goodind_file_name' in config['Directories']: goodInd = True goodind_file_name = config['Directories']['goodind_file_name'] pywaves_directory = config['Directories']['pywaves_directory'] # Load pywaves sys.path.extend([pywaves_directory]) from dataloader import DataLoader from waveform import Waveform # Digitizer global dataFormatStr global nSamples global ns_per_sample global number_of_bits global dynamic_range_volts global polarity global baselineOffset global nBaselineSamples global nCh global nWavesPerLoad global nWaves global startFolder global nFolders global unevenFactor global cfdFraction global integralEnd global totalIntegralStart global tailIntegralStart global applyCRRC4 global CRRC4Tau dataFormatStr = config['Digitizer']['dataFormat'] nSamples = int(config['Digitizer']['samples_per_waveform']) ns_per_sample = int(config['Digitizer']['ns_per_sample']) number_of_bits = int(config['Digitizer']['number_of_bits']) dynamic_range_volts = float(config['Digitizer']['dynamic_range_volts']) polarity = int(config['Digitizer']['polarity']) baselineOffset = int(config['Digitizer']['baseline_offset']) nBaselineSamples = int(config['Digitizer']['baseline_samples']) nCh = int(config['Digitizer']['number_of_channels']) nWavesPerLoad = int(config['Data Management']['waves_per_load']) nWaves = int(config['Data Management']['waves_per_folder']) # per folder startFolder = int(config['Data Management']['start_folder']) nFolders = int(config['Data Management']['number_of_folders']) unevenFactor = int(config['Data Management']['uneven_factor']) cfdFraction = float(config['Pulse Processing']['cfd_fraction']) integralEnd = int(config['Pulse Processing']['integral_end']) totalIntegralStart = int( config['Pulse Processing']['total_integral_start']) tailIntegralStart = int(config['Pulse Processing']['tail_integral_start']) applyCRRC4 = bool(int(config['Pulse Processing']['apply_crrc4'])) CRRC4Tau = float(config['Pulse Processing']['crrc4_shaping_time']) # Pre-calc if dataFormatStr == 'DPP_MIXED': dataFormat = DataLoader.DAFCA_DPP_MIXED elif dataFormatStr == 'STANDARD': dataFormat = DataLoader.DAFCA_STD if platform.system() is 'Windows': directory_separator = '\\' else: directory_separator = '/' nLoads = int(nWaves / nWavesPerLoad) chBufferSize = int(nFolders * nWaves * unevenFactor / nCh) VperLSB = dynamic_range_volts / (2**number_of_bits) fileTimeGap = 2**43 # Note: no more than 3 hours per measurement! # --------------------------------------------------------------------------------------------------------------------- # # Data structure setup # --------------------------------------------------------------------------------------------------------------------- # dataGetter = {} dataStorage = {} if getTail == True: dataGetter['tail'] = getWaveTail dataStorage['tail'] = np.zeros((nCh, chBufferSize)) if getTot == True: dataGetter['total'] = getWaveTot dataStorage['total'] = np.zeros((nCh, chBufferSize)) if getPH == True: dataGetter['ph'] = getWavePH dataStorage['ph'] = np.zeros((nCh, chBufferSize)) if getCFD == True: dataGetter['cfd'] = getWaveCFD dataStorage['cfd'] = np.zeros((nCh, chBufferSize)) if getRMS == True: dataGetter['rms'] = getWaveRMS dataStorage['rms'] = np.zeros((nCh, chBufferSize)) if getAmp == True: dataGetter['amp'] = getWaveAmp dataSotage['amp'] = np.zeros((nCh, chBufferSize)) if getExtras == True and dataFormatStr == 'DPP_MIXED': dataSotage['extra'] = np.zeros((nCh, chBufferSize), dtype=np.uint32) if getFullTime == True and dataFormatStr == 'DPP_MIXED': dataSotage['fulltime'] = np.zeros((nCh, chBufferSize), dtype=np.uint64) # Setup mandatory channel queues ttt = np.zeros((nCh, chBufferSize), dtype=np.uint32) chCount = np.zeros(nCh, dtype=np.uint32) flags = np.zeros((nCh, chBufferSize), dtype=np.uint32) # --------------------------------------------------------------------------------------------------------------------- # # Data aquisition # --------------------------------------------------------------------------------------------------------------------- # startTime = time.time() print("Running GetWaveData!") print("Starting at " + time.strftime('%H:%M:%S')) # Setup data loader waveform = Waveform(np.zeros(nSamples), polarity, baselineOffset, nBaselineSamples) pulses = [] # Queue up waves for f in range(startFolder, startFolder + nFolders): print('\n Folder {}:'.format(f)) fullDFileName = data_directory + directory_separator + str( f) + directory_separator + data_file_name print(fullDFileName) datloader = DataLoader(fullDFileName, dataFormat, nSamples) nWavesInFile = datloader.GetNumberOfWavesInFile() if (nWavesInFile < nWaves): print('Warning: requested more waves than exists in file!') loadsInFile = int(np.ceil(nWavesInFile / nWavesPerLoad)) print('Loading all {} waves instead...'.format(nWavesInFile)) lastLoad = nWavesInFile - (loadsInFile - 1) * nWavesPerLoad else: loadsInFile = nLoads lastLoad = nWavesPerLoad if goodInd == True: goodIndFileName = data_directory + directory_separator + str( f) + directory_separator + goodind_file_name goodIndices = [] with open(goodIndFileName, "r") as goodfi: good_lines = goodfi.readlines() for line in good_lines: goodIndices.append(int(line) - 1) goodIndices = np.array(goodIndices) else: goodIndices = np.arange(0, nWavesInFile - 1) waveNum = 0 printProgressBar(0, loadsInFile, prefix='Progress: ', suffix='Complete') for load in range(loadsInFile): if (load == loadsInFile - 1): wavesThisLoad = lastLoad else: wavesThisLoad = nWavesPerLoad waves = datloader.LoadWaves(wavesThisLoad) for w in range(0, wavesThisLoad): if waveNum == goodIndices[0]: goodIndices = goodIndices[1:] ch = waves[w]['Channel'] chCount[ch] += 1 # set up waveform structure waveform = Waveform(waves[w]['Samples'], polarity, baselineOffset, nBaselineSamples, ch=waves[w]['Channel'], time=waves[w]['TimeTag']) waveform.BaselineSubtract() # CCR4 if applyCRRC4: waveform.ApplyCRRC4(ns_per_sample, CRRC4Tau) # add timing data to mandatory channel structure ttt[ch][chCount[ch]] = waves[w]['TimeTag'] # populate data structure for optional for key, value in dataGetter.items(): dataStorage[key][ch][chCount[ch]] = getGetter[key]( waveform) ttt[ch][chCount[ch]] = waves[w]['TimeTag'] # get the whole wave if getWaves == True: pulses.append(waveform) waveNum += 1 # increment the wave counter in the current load # end iteration over waves in load - end load # update progress bar following new load printProgressBar(load + 1, loadsInFile, prefix='Progress: ', suffix='Complete') endTime = time.time() runTime = endTime - startTime print("\nGetWaveData took {} s".format(runTime)) if getWaves == False: return chCount, ttt, dataStorage else: return chCount, ttt, dataStorage, pulses
def Analyzing_Waves(): print("\n") print("Data file to be analyzed: " + str(Data_File)) print("\n") files = os.listdir(Path_to_Data) #if not os.mkdir(Output_Data_Path): # os.mkdir(Output_Data_Path) if not os.path.exists(Output_Data_Path): os.makedirs(Output_Data_Path) for f in files: Data = DataLoader(Path_to_Data + str(f) + "/dataFile0.dat", DataLoader.DAFCA_DPP_MIXED, Num_Samples) print("Reading in Folder: " + str(f)) print("Number of waves: " + str(Data.GetNumberOfWavesInFile())) print("\n") Number_of_Waves = Data.GetNumberOfWavesInFile() Waves = Data.LoadWaves(Number_of_Waves) ############################################## ############### Data Structure ############### ############################################## ### ('Channel',(np.int16,1)) ### ('PH',(np.float64,1)) ### ('PI',(np.float64,1)) ### ('DCFD',(np.float64,1)) ### ('Timetag',(np.int32,1)) ### ('Extras',(np.int32,1)) ### ('Tail',(np.float64,1)) ### ('Total',(np.float64,1)) ############################################## ############################################## Data_Out = np.zeros((len(Waves), 9)) for wave in np.arange(0, len(Waves), 1): #print(Waves[wave]['EventSize']) #print(Waves[wave]['Format']) #print(Waves[wave]['Channel']) #print(Waves[wave]['Baseline']) #print(Waves[wave]['ShortGate']) #print(Waves[wave]['LongGate']) #print(Waves[wave]['TimeTag']) #print(Waves[wave]['Extras']) #print(Waves[wave]['Samples']) #print("\n") Data_Out[wave][0] = Waves[wave]['Channel'] Channel_Val = int(Waves[wave]['Channel']) Subtracted_Wave = BaselineSubtract(Waves[wave]['Samples'], nBaselineSamples) if Waves[wave]['Channel'] in Negative_Waves: #x = np.arange(0,Num_Samples,1) #plt.plot(x, Subtracted_Wave) #plt.show() #plt.close() Subtracted_Wave = Subtracted_Wave * (-1.0) #plt.plot(x, Subtracted_Wave) #plt.show() #plt.close() #print(Channel_Val) #print(tail_integral_start[Channel_Val]) Max_index = np.argmax(Subtracted_Wave) #print(Max_index) #x = np.arange(0,Num_Samples,1) #plt.plot(x, Waves[wave]['Samples']) #plt.scatter(x[Max_index+tail_integral_start[Channel_Val]:Max_index+integral_end[Channel_Val]], Subtracted_Wave[Max_index+tail_integral_start[Channel_Val]:Max_index+integral_end[Channel_Val]]) #plt.scatter(x[Max_index+total_integral_start[Channel_Val]:Max_index+integral_end[Channel_Val]], Subtracted_Wave[Max_index+total_integral_start[Channel_Val]:Max_index+integral_end[Channel_Val]]) #plt.show() #plt.close() ph = np.max(Subtracted_Wave) * VperLSB PI = np.sum(Subtracted_Wave) * VperLSB * ns_per_sample Data_Out[wave][1] = ph Data_Out[wave][2] = PI DCFD = CFD(Subtracted_Wave, F) Data_Out[wave][3] = DCFD Data_Out[wave][4] = Waves[wave]['TimeTag'] Data_Out[wave][5] = Waves[wave]['Extras'] Tail = np.sum( Subtracted_Wave[Max_index + tail_integral_start[Channel_Val]:Max_index + integral_end[Channel_Val]]) Total = np.sum( Subtracted_Wave[Max_index + total_integral_start[Channel_Val]:Max_index + integral_end[Channel_Val]]) Data_Out[wave][6] = Tail Data_Out[wave][7] = Total Writing_Data(Data_Out, f)
def Using_DataLoader(): ''' ############################################## Step #2: Three variables are required to run DataLoader. Variable #1, Data_File_Path: A path and data file must be specified. Variable #2, dataType: CAEN digitizers will output data in one of three formats: DAFCA_STD, DAFCA_DPP_MIXED, or DAFCA_DPP_LIST. This defines the data structure for how data is pulled in. We will go through DAFCA_DPP_MIXED thoroughly. Variable #3, Num_Samples: This is the number of samples in a waveform, not the number of waves ############################################## ''' ############################################## Data_File_Path = "C:/Users/Giha/Documents/N3Glass/X1/1/dataFile0.dat" dataType = DataLoader.DAFCA_DPP_MIXED Num_Samples = 500 ############################################## Data = DataLoader(Data_File_Path, dataType, Num_Samples) print("DataLoader has two useful functions to new users.") print("\n") print( "The first useful function will tell you how many waves are in the specified file." ) print("\n") time.sleep(3) Number_of_data_structures = Data.GetNumberOfWavesInFile() print("In : " + str(Data_File_Path) + " , there are " + str(Number_of_data_structures) + " pulses, or more specifically, that many data structures.") print("\n") time.sleep(1) print( "The second useful function will load in a specified number of waves or data structures." ) print("\n") time.sleep(1) var = input( "Lets read in one wave and break down what we are reading in. Sound good? (Y/N): " ) if var == "Y": Waves = Data.LoadWaves(1) print("\n") time.sleep(1) print("This one wave has the following structure:") print("\n") print('EventSize is the event size in number of bytes: ' + str(Waves['EventSize'][0])) print('Format is referring to the CAEN datatype: ' + str(Waves['Format'][0])) print('Channel is referring to the input channel on the digitizer: ' + str(Waves['Channel'][0])) print('Baseline is the baseline of the pulse: ' + str(Waves['Baseline'][0])) print('ShortGate is the tail integral of the pulse: ' + str(Waves['ShortGate'][0])) print('LongGate is the total integral of the pulse: ' + str(Waves['LongGate'][0])) print( 'TimeTag is a course absolute time for when a pulse begins (ns): ' + str(Waves['TimeTag'][0])) print( 'Extras can be thought of as a finer time that can be combined with TimeTag: ' + str(Waves['Extras'][0])) print('Samples are the actual wave samples: ' + str(Waves['Samples'][0])) print("\n") time.sleep(1) print( "Baseline, ShortGate, and LongGate have generally not been used because they do not necessarily accuratley represent what they claim to." ) print( "For more infomration (especially when using Extras), please read the UM2580 DPP PSD User Manual found on CAEN's website." ) print("\n") time.sleep(1) print( "Now let's plot this pulse. When you are happy with looking at the pulse, close the figure." ) x = np.arange(0, Num_Samples * 2, 2) y = Waves['Samples'][0] plt.plot(x, y) plt.xlabel("Time (ns)") plt.xlabel("Digitizer Units") plt.show() plt.close() print("\n") time.sleep(1) print( "From this pulse, we can attain useful information, but first we must subtract the baseline." ) print("\n") print( "In DAFCA, the user can specify how much data of the pulse they want before the rising edge. This way a sufficient amount of data can be acquired to determine the baseline." ) print( "Generally, the baseline is determined by averaging the first 50 samples of the pulse." ) time.sleep(1) Baseline = np.average(Waves['Samples'][0][0:50]) print("\n") print("In this case, the baseline of the pulse is: " + str(Baseline)) print("\n") print("We can now subtract this baseline and plot the pulse.") print("\n") Baseline_Subtracted_Wave = Waves['Samples'][0] - Baseline x = np.arange(0, Num_Samples * 2, 2) y = Baseline_Subtracted_Wave plt.plot(x, y) plt.xlabel("Time (ns)") plt.xlabel("Digitizer Units") plt.show() plt.close() print("We can now attain some useful information about the pulse:") print("\n") Pulse_Height = np.max(Baseline_Subtracted_Wave) Max_Index = np.argmax(Baseline_Subtracted_Wave) negativeSamples = np.nonzero( Baseline_Subtracted_Wave[Max_Index:] < 0)[0] Pulse_Integral = np.sum( Baseline_Subtracted_Wave[:Max_Index + negativeSamples[0]]) * 2 dynamic_range_volts = 0.5 number_of_bits = 15 VperLSB = dynamic_range_volts / (2**number_of_bits) F = 0.2 Start_Time = CFD(Baseline_Subtracted_Wave, F) print("Pulse Height (Digitizer Units): " + str(Pulse_Height)) print("Pulse Integral (Digitizer Units-ns): " + str(Pulse_Integral)) print("Start Time (ns): " + str(Start_Time)) print("\n") print( "To convert from Digitizer Units to Votlage, it is necessary to multiply by the dynamic range of the digitizer and divide by 2^(number of bits). In this case the conversion is 0.5/2^14. This yields:" ) print("\n") Pulse_Height = np.max(Baseline_Subtracted_Wave) * VperLSB Pulse_Integral = np.sum( Baseline_Subtracted_Wave[:Max_Index + negativeSamples[0]]) * 2 * VperLSB print("Pulse Height (mV): " + str(Pulse_Height)) print("Pulse Integral (mV-ns): " + str(Pulse_Integral)) print("\n") print("The next code, GetWaveData, does these calculations for us.") print("\n") x = np.arange(0, Num_Samples * 2, 2) y = Baseline_Subtracted_Wave plt.plot(x, y) plt.xlabel("Time (ns)") plt.xlabel("Digitizer Units") plt.show() plt.close() else: print("Fine.")