File indexing completed on 2025-01-18 10:17:19
0001
0002
0003
0004
0005
0006 import argparse
0007 import numpy as np
0008 import matplotlib.pyplot as plt
0009 from scipy.stats import gumbel_r
0010 import pandas as pd
0011
0012 parser = argparse.ArgumentParser()
0013 parser.add_argument('-sr', '--sampleRate', metavar='SAMPLERATE', type=int, nargs=1, required=True,
0014 help='sampling rate in MHz of SAMPA chips -> [5], [10], or [20]')
0015 parser.add_argument('-nc', '--numChans', metavar='NUMCHANS', type=int, nargs=1, required=True,
0016 help='number of channels to simulate')
0017 parser.add_argument('-ne', '--numEvents', metavar='NUMEVENTS', type=int, nargs=1, required=True,
0018 help='number of events to simulate')
0019 parser.add_argument('-spec', '--spectra', metavar='SPECTRA', type=str, nargs=1, required=True,
0020 help='ADC spectra to simulate -> [gumbel] or [sampa]')
0021 parser.add_argument('-m', '--mode', metavar='MODE', type=str, nargs=1,
0022 help='SAMPA DAQ mode to simulate -> [das] or [dsp]')
0023 args = parser.parse_args()
0024
0025 sampleRate = args.sampleRate[0]
0026 numChans = args.numChans[0]
0027 numEvents = args.numEvents[0]
0028 specMode = args.spectra[0]
0029 if args.mode : adcMode = args.mode[0]
0030
0031 def sampaHitFunc(sample, peak, startTime, decayTime, baseLine):
0032 adcSample = np.piecewise(sample, [sample < startTime, sample >= startTime], [lambda sample: baseLine,
0033 lambda sample: (peak * np.power(((sample - startTime) / decayTime), 4) *
0034 np.exp((-4) * ((sample - startTime) / decayTime)) + baseLine)])
0035 return adcSample
0036
0037 class DataStream:
0038
0039 def __init__(self, sampleRate, numEvents):
0040
0041 self.sampleRate, self.numEvents = sampleRate, numEvents
0042
0043 self.numSamples = 1024
0044
0045 self.windowWidth = (1.0 / self.sampleRate) * self.numSamples
0046
0047 self.runTime = self.numEvents * self.windowWidth
0048
0049 self.initTime = 0.0
0050
0051
0052 def simTimeSamples(self, windowStart, windowEnd):
0053 self.timeSamples = np.linspace(windowStart, windowEnd, int(self.numSamples))
0054 self.initTime = self.timeSamples[-1]
0055 self.randTimeIndex = np.random.randint(int(len(self.timeSamples) * 0.25),
0056 high=int(len(self.timeSamples) * 0.75))
0057
0058
0059
0060 def gumbelAdcSignals(self):
0061 self.baseLine = np.random.rand(int(self.numSamples)) * 1.0e-2
0062 self.hitJudge = np.random.random()
0063 if (self.hitJudge < 0.5):
0064 self.adcSamples = self.baseLine
0065 elif (self.hitJudge >= 0.5):
0066 self.gumbelMean = np.random.random()
0067 self.gumbelBeta = np.random.random()
0068 self.gumbelPpf = np.linspace(gumbel_r.ppf(0.001, loc=self.gumbelMean, scale=self.gumbelBeta),
0069 gumbel_r.ppf(0.999, loc=self.gumbelMean, scale=self.gumbelBeta), 100)
0070 self.gumbelPdf = gumbel_r.pdf(self.gumbelPpf, loc=self.gumbelMean, scale=self.gumbelBeta)
0071 self.adcSamples = np.insert(self.baseLine, self.randTimeIndex, self.gumbelPdf)[:int(self.numSamples)]
0072
0073
0074 def sampaAdcSignals(self):
0075 self.baseLine = np.random.randint(60, 81, size=self.numSamples)
0076 self.hitJudge = np.random.randint(0, 2, size=1)[0]
0077 if (self.hitJudge == 0):
0078 self.adcSamples = self.baseLine
0079 elif (self.hitJudge == 1):
0080 self.peak = np.random.randint(5000, 50001, size=1)[0]
0081 self.baseLine = np.random.randint(60, 81, size=self.numSamples)
0082 self.startTime = np.random.randint(4, 7, size=1)[0]
0083 self.decayTime = np.random.randint(2, 5, size=1)[0]
0084 self.numHitSamples = np.random.randint(10, 16, size=1)[0]
0085 self.samples = np.arange(0, self.numHitSamples + 11)
0086 self.hitSamples = sampaHitFunc(self.samples, self.peak, self.startTime, self.decayTime, np.average(self.baseLine))
0087 self.adcSamples = np.insert(self.baseLine, self.randTimeIndex, self.hitSamples)[:int(self.numSamples)]
0088
0089 def __iter__(self):
0090 return self
0091
0092 def __next__(self):
0093 if (self.initTime == 0.0):
0094
0095 self.simTimeSamples(self.initTime, self.windowWidth)
0096 if specMode == 'gumbel': self.gumbelAdcSignals()
0097 if specMode == 'sampa': self.sampaAdcSignals()
0098 elif (self.initTime > 0.0 and self.initTime < self.runTime):
0099
0100 self.simTimeSamples(self.initTime, self.initTime + self.windowWidth)
0101 if specMode == 'gumbel': self.gumbelAdcSignals()
0102 if specMode == 'sampa': self.sampaAdcSignals()
0103 elif (self.initTime >= self.runTime):
0104 raise StopIteration
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 if specMode == 'gumbel' :
0122 datFile = open('run-%d-mhz-%d-chan-%d-ev.dat' % (sampleRate, numChans, numEvents), 'w+')
0123 for ievent in range(1, numEvents + 1):
0124 datFile.write('@ event = %d\n' % ievent)
0125 for chan in range(1, numChans + 1):
0126 datFile.write('# channel = %d\n' % chan)
0127 dataObj = DataStream(sampleRate * 1.0e+6, 1)
0128 for event in dataObj:
0129 if len(dataObj.timeSamples) != len(dataObj.adcSamples): print("!!!Something terrible is amiss!!!")
0130 np.savetxt(datFile, (np.add(dataObj.timeSamples, dataObj.windowWidth * (ievent - 1)), dataObj.adcSamples), fmt='%.9f')
0131
0132
0133
0134
0135
0136 datFile.close()
0137
0138 if specMode == 'sampa' :
0139 datFile = open('run-%d-mhz-%d-chan-%d-ev.dat' % (sampleRate, numChans, numEvents), 'w+')
0140 dfl = []; esl = []
0141 for ievent in range(1, numEvents + 1):
0142 csl = []
0143 for chan in range(1, numChans + 1):
0144 dataObj = DataStream(sampleRate * 1.0e+6, 1)
0145 for event in dataObj:
0146 if len(dataObj.timeSamples) != len(dataObj.adcSamples): print("!!!Something terrible is amiss!!!")
0147 csl.append(pd.Series(dataObj.adcSamples, name = 'chan_%d' % chan))
0148 esl.append(csl)
0149 dfl.append(pd.concat(esl[ievent-1], axis = 1))
0150 df = pd.concat(dfl, ignore_index=True)
0151 np.savetxt(datFile, df.values, fmt='%04d')
0152
0153
0154
0155
0156
0157 datFile.close()