def Physics(self, frame): VEM = frame['IceTopLaputopSeededSelectedHLC'].apply(frame) VEM_2 = frame['IceTopLaputopSeededSelectedSLC'].apply(frame) waveforms = frame['IceTopVEMCalibratedWaveforms'] HLCWaveforms = dataclasses.I3WaveformSeriesMap() for i in VEM.keys(): HLCWaveforms[i] = waveforms[i] frame['LaputopHLCWaveforms'] = HLCWaveforms frame['LaputopHLCVEM'] = VEM frame['LaputopSLCVEM'] = VEM_2 self.PushFrame(frame)
rpsm = dataclasses.I3RecoPulseSeriesMap() rpsm[icetray.OMKey(1, 1)] = rps for key, pseries in rpsm: print(key) for pulse in pseries: print(pulse) #I3Waveform print('Testing I3Waveform') my_wf = dataclasses.I3Waveform() my_wf.time = 100.0 * icetray.I3Units.ns my_wf.bin_width = 3.3 * icetray.I3Units.ns awave = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] my_wf.waveform = awave my_wf.digitizer = dataclasses.I3Waveform.Source.FADC my_wf.hlc = True wv_series = dataclasses.I3WaveformSeries() wv_series.append(my_wf) for wv in wv_series: print(wv.time) wv_ser_map = dataclasses.I3WaveformSeriesMap() wv_ser_map[icetray.OMKey(2, 2)] = wv_series ENSURE(icetray.OMKey(2, 2) in wv_ser_map, 'I3Waveform not present in map!') ENSURE(icetray.OMKey(2, 3) not in wv_ser_map, 'mystery I3waveform in map!') print(my_wf)
def WaveformDerivatives(frame): frame["DoublePulseWaveforms"] = dataclasses.I3WaveformSeriesMap() frame["BinsToT1"] = dataclasses.I3VectorDouble( ) # bins with time over threshold (ToT) for the first pulse of a derivative waveform frame["BinsToT2"] = dataclasses.I3VectorDouble( ) # bins with time over threshold (ToT) for the second pulse of a derivative waveform frame["BinsTbT"] = dataclasses.I3VectorDouble( ) # bins with time below threshold (TbT) for the first trailing edge of a derivative waveform frame["Amp1"] = dataclasses.I3VectorDouble( ) # cumulative derivative amplitude of time over threshold (ToT) for the first pulse frame["Amp2"] = dataclasses.I3VectorDouble( ) # cumulative derivative amplitude of time over threshold (ToT) for the second pulse frame["AmpTrailing"] = dataclasses.I3VectorDouble( ) # cumulative derivative amplitude of time below threshold (ToT) for the trailing edge frame["DPWaveformQTot"] = dataclasses.I3VectorDouble() frame["DP_T1"] = dataclasses.I3VectorDouble() frame["DP_T2"] = dataclasses.I3VectorDouble() frame["DPWaveformPulse1Amp"] = dataclasses.I3VectorDouble() frame["DPWaveformPulse2Amp"] = dataclasses.I3VectorDouble() frame["DP_OMs"] = dataclasses.I3VectorOMKey() SDtag = False LCtag = False if frame.Has("CalibratedWaveformsHLCATWD"): wf_map = frame["CalibratedWaveformsHLCATWD"] dp_count = 0 #count number of dp waveforms from this event dp_om_keys = [] for om, wf_series in wf_map: for wf in wf_series: wf_vect = wf.waveform wf_status = wf.status wf_binwidth = wf.bin_width start_time = wf.time if wf_status == 0: wf_qtot = 0.0 for i in range(128): wf_vect[i] = wf_vect[ i] / I3Units.mV #transform wf unit to mV wf_qtot += wf_vect[ i] #individual wf integrated charge in mV #Calculate Sliding Time Window (STW) derivatives for waveforms stw_vect = [] stepsize = 2 for i in range(1, 127): stw_vect += [(wf_vect[i + 1] - wf_vect[i - 1]) / (wf_binwidth * stepsize)] der_wf_bins = len(stw_vect) der_flag = 0 for i in range(1, der_wf_bins - 6): # 3, 4, 5, 6 bins tried. With 6 bins required, all the manually-selected nice double pulse waveforms picked up by the algorithm. if (stw_vect[i - 1] > 0 and stw_vect[i] > 0 and stw_vect[i + 1] > 0 and stw_vect[i + 2] > 0 and stw_vect[i + 3] > 0 and stw_vect[i + 4] > 0): der_flag = i - 1 #Finding point where waveform first sees light. break #sum up the amplitude of the rising edge amp_rising = 0. for i1 in range(der_flag, der_flag + 6): amp_rising += stw_vect[i1] wf_diff = [] for i in range(der_flag, 128 - der_step, der_step): wf_diff += [(wf_vect[i + der_step] - wf_vect[i]) / (wf_binwidth * der_step)] diff_wf_bins = len(wf_diff) #search for the first and second pulses! pulse1 = False pulse2 = False trailing = False i_flag = 0 j_flag = 0 k_flag = 0 amp_p1 = 0 #amplitude of first rising edge in the derivative waveform amp_p2 = 0 #amplitude of second rising edge in the derivative waveform amp_trailing = 0 #amplitude of first trailing edge in the derivative waveform binsToT1 = 0 binsToT2 = 0 binsTbT = 0 j1_flag = 0 j2_flag = 0 j3_flag = 0 bins_p21 = 0 bins_p22 = 0 dp_t1 = 0 dp_t2 = 0 dp_amp1 = 0 # amplitude of first pulse dp_amp2 = 0 # amplitude of second pulse #first pulse search for i in range(diff_wf_bins - bins_p2 - bins_trailing): #if wf_diff[i]>0: #and wf_diff[i+1]>0: if np.prod([ True if wf_diff[n] > 0.0 else False for n in range(i, i + bins_p1) ]): pulse1 = True i_flag = i break #trailing edge search if pulse1: # firstly move the index out of the positive region for k in range(i_flag + bins_p1, diff_wf_bins - bins_trailing): # if np.prod([ True if wf_diff[n] < 0.0 else False for n in range(k, k + bins_trailing) ]): k_flag = k trailing = True l_flag = k_flag + bins_trailing break dp_t1 = start_time + der_flag * 422.4 / 128 #beginning time of the first pulse #second pulse search if pulse1 and trailing: for j in range(l_flag, (diff_wf_bins - bins_p2)): if np.prod([ True if wf_diff[n] > 0.0 else False for n in range(j, j + bins_p2) ]): pulse2 = True j_flag = j break for q in range( der_flag, der_flag + j_flag * der_step ): # transform the derivative waveform index back to the waveform vector basis dp_amp1 += wf_vect[ q] #calculate amplitude of first pulse #move the index out of the positive region, and do another round of big pulse search. #If the later pulse is bigger than the earlier one, point the index to the bigger one. #Having more than (including) two pulses with ToT of 3 derivetive waveform bins, which is #duration of 3*4*3.3 ns, is quite rare. Therefore, another round of searching should be sufficient enough. if j_flag and j_flag < (diff_wf_bins - bins_p2): for j1 in range(j_flag, (diff_wf_bins - bins_p2)): if wf_diff[j1] < 0: j1_flag = j1 break if j1_flag and j1_flag < (diff_wf_bins - bins_p2): for j2 in range(j1_flag, (diff_wf_bins - bins_p2)): if np.prod([ True if wf_diff[n] > 0.0 else False for n in range(j2, j2 + bins_p2) ]): j2_flag = j2 break #move the index out of the positive region if j2_flag and j2_flag < (diff_wf_bins - bins_p2): j3_flag = 0 for g in range(j2_flag + bins_p2, diff_wf_bins): if wf_diff[g] < 0: j3_flag = g break if j3_flag == 0: j3_flag = diff_wf_bins bins_p21 = j1_flag - j_flag bins_p22 = j3_flag - j2_flag pulse3 = True if bins_p22 > bins_p21: j_flag = j2_flag dp_t2 = start_time + ( der_flag + j_flag * der_step ) * 422.4 / 128 #starting time of second pulse for q in range( der_flag + j_flag * der_step, 128 ): # transform the derivative waveform index back to the waveform vector basis dp_amp2 += wf_vect[ q] #calculate amplitude of second pulse if pulse1 and trailing and pulse2: # calculate the cumulative derivative amplitude for potential first pulse for s in range(i_flag, k_flag): amp_p1 += wf_diff[s] binsToT1 = k_flag - i_flag #move the index out of the first trailing edge region r_flag = 0 for r in range(l_flag, (diff_wf_bins - bins_p2)): if wf_diff[r] > 0: r_flag = r break for q in range(k_flag, r_flag): amp_trailing += wf_diff[q] binsTbT = r_flag - k_flag # move the index out of the second positive region h_flag = 0 for h in range(j_flag + bins_p2, diff_wf_bins): if wf_diff[h] < 0: h_flag = h break if h_flag == 0: h_flag = diff_wf_bins # calculate the cumulative derivative amplitude for second pulse for t in range(j_flag, h_flag): amp_p2 += wf_diff[t] binsToT2 = h_flag - j_flag if wf_qtot > WfQtot and pulse1 and trailing and pulse2 and amp_p1 > Amp1LC and amp_p2 > Amp2LC and amp_trailing < AmpTrailingLC: # if this waveform has double peak feature. if amp_p1 > Amp1SD and amp_p2 > Amp2SD and amp_trailing < AmpTrailingSD and binsToT1 > 1: #if this waveform passes single dom double peak: SDtag = True dp_count += 1 dp_om_keys.append(om) frame["Amp1"].append(amp_p1) frame["Amp2"].append(amp_p2) frame["AmpTrailing"].append(amp_trailing) frame["BinsToT1"].append(binsToT1) frame["BinsTbT"].append(binsTbT) frame["BinsToT2"].append(binsToT2) frame["DPWaveformQTot"].append(wf_qtot) frame["DP_OMs"].append(om) frame["DoublePulseWaveforms"].update( {om: wf_series}) frame["DPWaveformPulse1Amp"].append(dp_amp1) frame["DPWaveformPulse2Amp"].append(dp_amp2) frame["DP_T1"].append(dp_t1) frame["DP_T2"].append(dp_t2) #end if #end for #end for #Finding waveforms that have neighboring DOMs that also see double pulses. If they do, use a lower threshold. for i in dp_om_keys: for j in dp_om_keys: if i[0] == j[0]: if 0 < np.abs(np.int(j[1]) - np.int(i[1])) < 3: LCtag = True break if LCtag: break frame["DPFlagSD"] = icetray.I3Int(SDtag) frame["DPFlagLC"] = icetray.I3Int(LCtag) else: return False #Keeping the double pulse events only if DiscardEvents: if LCtag or SDtag: return True return False
def RandomWaveforms(fr): calib = fr['I3Calibration'] status = fr['I3DetectorStatus'] pulsemap = dataclasses.I3RecoPulseSeriesMap() wfmap = dataclasses.I3WaveformSeriesMap() for om in calib.dom_cal.keys(): pulses = dataclasses.I3RecoPulseSeries() waveforms = dataclasses.I3WaveformSeries() fadc_templ = calib.dom_cal[om].fadc_pulse_template(False) atwd0_templ = calib.dom_cal[om].atwd_pulse_template(0, False) spe_charge = dataclasses.spe_mean(status.dom_status[om], calib.dom_cal[om]) if spe_charge < I3Units.pC: continue spe_charge *= calib.dom_cal[om].front_end_impedance for launch in range(0, random.randint(0, 4)): npulses = random.randint(0, 5) launchtime = launch * 10000 # Make 30% of SPE launches SLC slc = (npulses == 1 and random.uniform(0, 1) < 0.3) # ATWD Waveform atwd0_wf = dataclasses.I3Waveform() atwd0_wf.waveform = [ \ random.normalvariate(0, 0.3)*I3Units.mV for \ i in range(0, 128)] atwd0_wf.digitizer = dataclasses.I3Waveform.ATWD atwd0_wf.bin_width = 3.3 atwd0_wf.hlc = not slc atwd0_wf.time = launchtime # FADC Waveform if slc: fadc_nbins = 3 else: fadc_nbins = 256 fadc_wf = dataclasses.I3Waveform() fadc_wf.waveform = [ \ random.normalvariate(0, 0.1)*I3Units.mV for \ i in range(0, fadc_nbins)] fadc_wf.digitizer = dataclasses.I3Waveform.FADC fadc_wf.bin_width = 25 fadc_wf.hlc = not slc fadc_wf.time = launchtime for p in range(0, npulses): pulse = dataclasses.I3RecoPulse() pulse.charge = random.randint(1, 3) if not slc: pulse.time = launchtime + \ random.gammavariate(2.5, 80) pulse.flags = pulse.PulseFlags.LC else: pulse.time = launchtime + \ random.uniform(-25, 25) pulses.append(pulse) norm = spe_charge * pulse.charge for i in range(0, len(fadc_wf.waveform)): fadc_wf.waveform[i] += norm * \ fadc_templ((i+1)*fadc_wf.bin_width - \ (pulse.time - launchtime)) for i in range(0, len(atwd0_wf.waveform)): atwd0_wf.waveform[i] += norm * \ atwd0_templ((i+1)*atwd0_wf.bin_width - \ (pulse.time - launchtime)) waveforms.append(fadc_wf) if not slc: waveforms.append(atwd0_wf) wfmap[om] = waveforms pulsemap[om] = dataclasses.I3RecoPulseSeries( sorted(pulses, key=lambda pulse: pulse.time)) fr['RandomPulses'] = pulsemap fr['CalibratedWaveforms'] = wfmap fr['CalibratedWaveformRange'] = dataclasses.I3TimeWindow(0, 10000)