def _add_mc_pulses(self, frame, mcpe_series_map): '''Create MC reco pulses from I3MCPESeriesMap This is a dirty hack, so that other modules can be used without changing them. However, this will use up unecessary space, because I3RecoPulses have more data fields, which are not required by an MC hit (width, ATWD, ...) . Parameters ---------- frame : I3Frame The I3Frame to which the MC Pulses will be added to. mcpe_series_map : I3MCPESeriesMap The I3MCPESeriesMap which will be converted. ''' mc_pulse_map = dataclasses.I3RecoPulseSeriesMap() for omkey, mcpe_series in mcpe_series_map.items(): mc_pulses = [] for mcpe in mcpe_series: # create I3RecoPulse with corresponding time and 'charge' # The charge is set to the number of photo electrons (npe) mc_pulse = dataclasses.I3RecoPulse() mc_pulse.time = mcpe.time mc_pulse.charge = mcpe.npe # append pulse mc_pulses.append(mc_pulse) mc_pulse_map[omkey] = dataclasses.vector_I3RecoPulse(mc_pulses) # write to frame frame[self._output_key] = mc_pulse_map
def make_rpsmap(): rpsmap = dataclasses.I3RecoPulseSeriesMap() for omkey in doms: rpsmap[omkey] = dataclasses.I3RecoPulseSeries() # time, width, and charge rp_properties = [(1650, 100, 0), (1850, 100, 1), (0, 100, 2), (550, 0, 3), (800, 0, 4), (3500, 100, 5), (3500, 100, 6), (3500, 100, 7), (3500, 100, 8), (8000, 3000, 9), (9000, 100, 10), (9500, 100, 11)] rp_list = [dataclasses.I3RecoPulse() for i in range(len(rp_properties))] for idx, prop in enumerate(rp_properties): rp_list[idx].time = prop[0] rp_list[idx].width = prop[1] rp_list[idx].charge = prop[2] rpsmap[doms[0]].append(rp_list[0]) rpsmap[doms[0]].append(rp_list[1]) rpsmap[doms[0]].append(rp_list[2]) rpsmap[doms[1]].append(rp_list[3]) rpsmap[doms[2]].append(rp_list[4]) rpsmap[doms[2]].append(rp_list[5]) rpsmap[doms[3]].append(rp_list[6]) rpsmap[doms[3]].append(rp_list[7]) rpsmap[doms[4]].append(rp_list[8]) rpsmap[doms[4]].append(rp_list[9]) rpsmap[doms[4]].append(rp_list[10]) rpsmap[doms[4]].append(rp_list[11]) return rpsmap
def setUp(self): self.frame = icetray.I3Frame(icetray.I3Frame.Physics) pulses = dataclasses.I3RecoPulseSeriesMap() key1 = icetray.OMKey(42, 7) vec = dataclasses.I3RecoPulseSeries() pulse = dataclasses.I3RecoPulse() pulse.time = 1.0 pulse.charge = 2.3 vec.append(pulse) pulse.time = 2.0 vec.append(pulse) pulse.time = 15.0 vec.append(pulse) pulses[key1] = vec key2 = icetray.OMKey(7, 7) vec = dataclasses.I3RecoPulseSeries() pulse.time = 1.0 pulse.charge = 2.3 vec.append(pulse) pulse.time = 2.0 vec.append(pulse) pulse.time = 15.0 vec.append(pulse) pulses[key2] = vec self.frame['Pulses'] = pulses mask1 = dataclasses.I3RecoPulseSeriesMapMask(self.frame, 'Pulses') mask1.set(key1, 1, False) self.frame['Mask1'] = mask1 mask2 = dataclasses.I3RecoPulseSeriesMapMask(self.frame, 'Pulses') mask2.set(key2, 1, False) self.frame['Mask2'] = mask2
def Process(self): if not self.geometry: self.geometry = True geometry = dc.I3Geometry() for string in self.strings: for dom in self.doms: omkey= icetray.OMKey(string,dom) geometry.omgeo[omkey] = dc.I3OMGeo() x=random.uniform(-500,500) y=random.uniform(-500,500) z=random.uniform(-300,300) geometry.omgeo[omkey].position = dc.I3Position(x,y,z) frame = icetray.I3Frame(icetray.I3Frame.Geometry); frame.Put('I3Geometry',geometry) self.PushFrame(frame) pulsesmap= dc.I3RecoPulseSeriesMap() for string in self.strings: for dom in self.doms: omkey= icetray.OMKey(string,dom) pulse= dc.I3RecoPulse() pulse.charge= random.uniform(0.3,6.)#pulses are not used in the algorithm of this module, #just put a single pulse with any value of the charge pulsesmap[omkey]= dc.I3RecoPulseSeries([pulse]) frame = icetray.I3Frame(icetray.I3Frame.Physics); frame.Put("TestPulseSeriesMap",pulsesmap) self.PushFrame(frame)
def gaussian_smear_pulse_times(self, pulses, scale, *args, **kwargs): """Smear the pulse times with a Gaussian centered at the original value. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. scale : float The scale parameter of the Gaussian that is used to smear the pulse times. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ assert scale >= 0, 'scale {!r} must be >= zero'.format(scale) modified_pulses = {} for key, dom_pulses in pulses.items(): # smear times times = self._random_generator.normal(loc=[p.time for p in dom_pulses], scale=scale) charges = np.array([p.charge for p in dom_pulses]) widths = np.array([p.width for p in dom_pulses]) flags = np.array([p.flags for p in dom_pulses]) # sort pulses in time sorted_indices = np.argsort(times) charges = charges[sorted_indices] times = times[sorted_indices] widths = widths[sorted_indices] flags = flags[sorted_indices] modified_dom_pulses = [] for charge, time, flag, width in zip(charges, times, flags, widths): # create pulse modified_pulse = dataclasses.I3RecoPulse() modified_pulse.charge = charge modified_pulse.time = time modified_pulse.flags = int(flag) modified_pulse.width = width # append pulse modified_dom_pulses.append(modified_pulse) modified_pulses[key] = dataclasses.vector_I3RecoPulse( fix_time_overlap(modified_dom_pulses)) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
def Create_PulseSeriesMap(frame): pulsesmap = dc.I3RecoPulseSeriesMap() p1 = dc.I3RecoPulse() p1.charge = 2.3 p1.time = 5.1 p2 = dc.I3RecoPulse() p2.charge = 1.5 p2.time = 9.1 pulsesmap[icetray.OMKey(10, 4)] = dc.I3RecoPulseSeries([p1, p2]) p1 = dc.I3RecoPulse() p1.charge = 4.5 p1.time = 43.1 p2 = dc.I3RecoPulse() p2.charge = 0.9 p2.time = 1.2 pulsesmap[icetray.OMKey(25, 13)] = dc.I3RecoPulseSeries([p1, p2]) frame.Put("TestRecoPulseSeriesMap", pulsesmap)
def Physics(self, frame): rpsmap = dataclasses.I3RecoPulseSeriesMap() doms = [icetray.OMKey(0, i) for i in range(4)] for omkey, time in zip(doms, self.times): rp = dataclasses.I3RecoPulse() rp.time = time rps = dataclasses.I3RecoPulseSeries() rps.append(rp) rpsmap[omkey] = rps frame[self.output_map_name] = rpsmap self.PushFrame(frame)
def I3MapKeyVectorDouble_to_I3RecoPulseSeriesMap(f): i3MapKeyVectorDouble = f['splittedDOMMap'] i3RecoPulseSeriesMap = dataclasses.I3RecoPulseSeriesMap() for (k, l) in i3MapKeyVectorDouble.items(): pulses = dataclasses.I3RecoPulseSeries() for d in l: p = dataclasses.I3RecoPulse() p.time = d pulses.append(p) i3RecoPulseSeriesMap[k] = pulses f['splittedDOMMap_pulses'] = i3RecoPulseSeriesMap
def shift_pulses(self, pulses, charge_shift=None, time_shift=None, first_k_pulses=float('inf'), *args, **kwargs): """Shift the charges and times of the provided pulses. There is an option to ony shift the first k number of pulses by providing a value to first_k_pulses. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. charge_shift : float, optional The amount to shift the pulse charges. time_shift : float, optional The amount to shift the pulse times. first_k_pulses : int, optional If specified, only shift the first_k_pulses of a DOM. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ modified_pulses = {} for key, dom_pulses in pulses.items(): modified_dom_pulses = [] pulse_counter = 0 for pulse in dom_pulses: modified_pulse = dataclasses.I3RecoPulse(pulse) pulse_counter += 1 # modify pulse if pulse_counter <= first_k_pulses: if time_shift is not None: modified_pulse.time += time_shift if charge_shift is not None: modified_pulse.charge = np.clip( modified_pulse.charge + charge_shift, 0., float('inf')) # append pulse modified_dom_pulses.append(modified_pulse) modified_pulses[key] = \ dataclasses.vector_I3RecoPulse(modified_dom_pulses) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
def Process(self): """ deliver frames QP with only a bit of rudamentary information """ #make a Q-frame Qframe = icetray.I3Frame(icetray.I3Frame.DAQ) Qeh = dataclasses.I3EventHeader() Qeh.start_time = (dataclasses.I3Time(2011, 0)) Qeh.end_time = (dataclasses.I3Time(2011, 2)) Qeh.run_id = 1 Qeh.event_id = 1 Qframe.Put("I3EventHeader", Qeh) Qrecomap = dataclasses.I3RecoPulseSeriesMap() recopulse1 = dataclasses.I3RecoPulse() recopulse1.time = 0 recopulse1.charge = 1 recopulse2 = dataclasses.I3RecoPulse() recopulse2.time = 1 recopulse2.charge = 2 Qrecomap[icetray.OMKey(1,1)] = [recopulse1] Qrecomap[icetray.OMKey(2,2)] = [recopulse2] Qframe.Put(OrgPulses, Qrecomap) Qframe.Put(SplitName+"SplitCount", icetray.I3Int(1)) self.PushFrame(Qframe) #now make the first p-frame containing one I3RecoPulse P1frame = icetray.I3Frame(icetray.I3Frame.Physics) P1eh = dataclasses.I3EventHeader() P1eh.start_time = (dataclasses.I3Time(2011, 0)) P1eh.end_time = (dataclasses.I3Time(2011, 1)) P1eh.run_id = 1 P1eh.event_id = 1 P1eh.sub_event_stream = "split" P1eh.sub_event_id = 0 P1frame.Put("I3EventHeader", P1eh) P1recomap = dataclasses.I3RecoPulseSeriesMap() P1recomap[icetray.OMKey(1,1)] = [recopulse1] P1recomask = dataclasses.I3RecoPulseSeriesMapMask(Qframe, OrgPulses, Qrecomap) P1frame.Put(SplitPulses, P1recomask) self.PushFrame(P1frame) self.RequestSuspension()
def fakeit(frame): header = dataclasses.I3EventHeader() frame['I3EventHeader'] = header pulsemap = dataclasses.I3RecoPulseSeriesMap() pulses = dataclasses.I3RecoPulseSeries() pulse = dataclasses.I3RecoPulse() pulses.append(pulse) pulsemap[icetray.OMKey(7,42)] = pulses pulsemap[icetray.OMKey(9,42)] = pulses frame['Pulses'] = pulsemap mask = dataclasses.I3RecoPulseSeriesMapMask(frame, 'Pulses') frame['PulseMask'] = mask
def Create_PulseSeriesMap(frame): pulsesmap= dc.I3RecoPulseSeriesMap() p1=dc.I3RecoPulse() p1.charge=2.3 p1.time=1.0*icetray.I3Units.ns p1.width=.0*icetray.I3Units.ns p2=dc.I3RecoPulse() p2.charge=1.5 p2.time=2.*icetray.I3Units.ns p2.width=.0*icetray.I3Units.ns pulsesmap[icetray.OMKey(10,4)]= dc.I3RecoPulseSeries([p1,p2]) p1=dc.I3RecoPulse() p1.charge=4.5 p1.time=3.0*icetray.I3Units.ns p1.width=.0*icetray.I3Units.ns p2=dc.I3RecoPulse() p2.charge=0.9 p2.time=802.*icetray.I3Units.ns #will find two pulses (in OMKey(10,4)) that are not in the window of 800 ns p2.width=.0*icetray.I3Units.ns pulsesmap[icetray.OMKey(10,5)]= dc.I3RecoPulseSeries([p1,p2]) frame.Put("TestRecoPulseSeriesMap",pulsesmap)
def Physics(self, frame): pulse_map = dataclasses.I3RecoPulseSeriesMap() for string in range(1, n_strings + 1): for om in range(1, n_doms + 1): om_key = icetray.OMKey(string, om) n_hits = np.random.poisson(lam=self.lambda_poisson) times = (np.random.random(n_hits) * self.event_length).round(1) pulse_series = dataclasses.I3RecoPulseSeries() for time in sorted(times): pulse = dataclasses.I3RecoPulse() pulse.time = time pulse.charge = 1.0 pulse_series.append(pulse) pulse_map[om_key] = pulse_series frame["SLOPPOZELA_Pulses"] = pulse_map self.PushFrame(frame)
def setUp(self): super(I3RecoPulseSeriesMapMaskTest2, self).setUp() # create a pulse series map with a known bad # 0 width case. only two pulses. self.pulses = dataclasses.I3RecoPulseSeriesMap() key1 = icetray.OMKey(42, 7) vec = dataclasses.I3RecoPulseSeries() pulse = dataclasses.I3RecoPulse() pulse.time = 10226.6 pulse.charge = 28.1466 pulse.width = 0.833585 vec.append(pulse) pulse.time = 10227.4 pulse.charge = 18.5683 pulse.width = 0.833585 vec.append(pulse) self.pulses[key1] = vec
def discard_random_pulses(self, pulses, discard_probability, *args, **kwargs): """Discard pulses randomly based on the discard_probability. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. discard_probability : float The probabilty a pulse is discarded. Must be a value between 0 and 1. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ assert discard_probability >= 0 and discard_probability <= 1, \ 'discard_probability {!r} not in [0, 1]'.format(discard_probability) modified_pulses = {} for key, dom_pulses in pulses.items(): modified_dom_pulses = [] for pulse in dom_pulses: modified_pulse = dataclasses.I3RecoPulse(pulse) # draw random variable and decide if pulse is discarded discard_pulse = \ self._random_generator.uniform() < discard_probability # append pulse if not discard_pulse: modified_dom_pulses.append(modified_pulse) if modified_dom_pulses: modified_pulses[key] = \ dataclasses.vector_I3RecoPulse(modified_dom_pulses) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
def mcpulse_to_recopulse(frame, mapname = "I3MCPulseSeriesMap", outputmap = "I3RecoPulseSeriesMap"): ''' A module that does a direct conversion of I3MCPulses to I3RecoPulses. It is intended to be used with PMTResponseSimulator output when one wants to avoid the DOM simulation for some reason (no DOM electronic simulation. ie no launches but PMT effects such as saturation is present). ''' recopulsemap = dataclasses.I3RecoPulseSeriesMap() mcpulsemap = frame[mapname] for omkey, pulses in mcpulsemap: recopulsemap[omkey] = dataclasses.I3RecoPulseSeries() for pulse in pulses: rpulse = dataclasses.I3RecoPulse() rpulse.time = pulse.time rpulse.charge = pulse.charge rpulse.flags = dataclasses.I3RecoPulse.PulseFlags.LC recopulsemap[omkey].append(rpulse) frame[outputmap] = recopulsemap
def Physics(self, frame): pulse_map = dataclasses.I3RecoPulseSeriesMap() for string in range(51, 60): track_time = self.event_length / 9 * (string - 50) for om in range(40, 45): om_key = icetray.OMKey(string, om) n_hits = np.random.poisson(lam=3) times = (np.random.random(n_hits) * 50000 - 25000 + track_time).round(1) pulse_series = dataclasses.I3RecoPulseSeries() for time in sorted(times): pulse = dataclasses.I3RecoPulse() pulse.time = time pulse.charge = 1.0 pulse.flags = 7 pulse_series.append(pulse) pulse_map[om_key] = pulse_series frame["SLOPPORATOR_Pulses"] = pulse_map self.PushFrame(frame)
def scramble_charges(self, pulses, *args, **kwargs): """Scramble the charges of the pulses. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ modified_pulses = {} for key, dom_pulses in pulses.items(): charges = [p.charge for p in dom_pulses] # scramble pulse charges self._random_generator.shuffle(charges) modified_dom_pulses = [] for pulse, charge in zip(dom_pulses, charges): modified_pulse = dataclasses.I3RecoPulse(pulse) # modify pulse modified_pulse.charge = charge # append pulse modified_dom_pulses.append(modified_pulse) modified_pulses[key] = \ dataclasses.vector_I3RecoPulse(modified_dom_pulses) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
def effective_domsim(frame, mapname = "I3MCPulseSeriesMap", outputmap = "I3RecoPulseSeriesMap"): ''' A module similar to mcpulse_to_recopulse above. It does an effective DOM electronics simulation by adding jitter to the time and charge to the pulse while converting the MCPulse to a reco pulse. The values for the spread of the gaussian jitter were found by studying the spread of 1PE extracted pulses. The module is intended to be use with the PMTResponseSimulator output in situations when one wants to avoid the actual DOM simulation for some reason. ''' from icecube.icetray import I3Units recopulsemap = dataclasses.I3RecoPulseSeriesMap() mcpulsemap = frame[mapname] for omkey, pulses in mcpulsemap: recopulsemap[omkey] = dataclasses.I3RecoPulseSeries() for pulse in pulses: rpulse = dataclasses.I3RecoPulse() rpulse.time = random_service.gaus(pulse.time,2.0*I3Units.ns) rpulse.charge = random_service.gaus(pulse.charge,0.012)#PE rpulse.flags = dataclasses.I3RecoPulse.PulseFlags.LC recopulsemap[omkey].append(rpulse) frame[outputmap] = recopulsemap
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)
def test_PulseChargeShifting(self): frame = icetray.I3Frame() omkey = icetray.OMKey(1, 1) # create a calibration object calibration = dataclasses.I3Calibration() calibration.dom_cal[omkey] = dataclasses.I3DOMCalibration() calibration.dom_cal[omkey].mean_atwd_charge = 1.2 calibration.dom_cal[omkey].mean_fadc_charge = 1.8 frame["I3Calibration"] = calibration # create some pulses on our fake DOM pulse1 = dataclasses.I3RecoPulse() pulse1.flags = dataclasses.I3RecoPulse.PulseFlags.ATWD pulse1.time = 1. * I3Units.nanosecond pulse1.charge = 10. pulse1.width = 1. pulse2 = dataclasses.I3RecoPulse() pulse2.flags = dataclasses.I3RecoPulse.PulseFlags.FADC pulse2.time = 10. * I3Units.nanosecond pulse2.charge = 5. pulse2.width = 1. pulse_series = dataclasses.I3RecoPulseSeriesMap() pulse_series[omkey] = dataclasses.I3RecoPulseSeries() pulse_series[omkey].append(pulse1) pulse_series[omkey].append(pulse2) # add these pulses to our new frame frame["UnshiftedPulses"] = pulse_series # create a shifter object frame[ "ShiftedPulses"] = dataclasses.I3RecoPulseSeriesMapApplySPECorrection( pulses_key="UnshiftedPulses", calibration_key="I3Calibration") # retrieve the shifted pulses shifted_pulses = dataclasses.I3RecoPulseSeriesMap.from_frame( frame, "ShiftedPulses") # make sure everything is as expected self.assertEqual(pulse_series[omkey][0].time, shifted_pulses[omkey][0].time, "these should be the same.") self.assertEqual(pulse_series[omkey][0].width, shifted_pulses[omkey][0].width, "these should be the same.") self.assertEqual(pulse_series[omkey][0].flags, shifted_pulses[omkey][0].flags, "these should be the same.") self.assertAlmostEqual(pulse_series[omkey][0].charge / calibration.dom_cal[omkey].mean_atwd_charge, shifted_pulses[omkey][0].charge, places=4, msg="these should be the same.") self.assertEqual(pulse_series[omkey][1].time, shifted_pulses[omkey][1].time, "these should be the same.") self.assertEqual(pulse_series[omkey][1].width, shifted_pulses[omkey][1].width, "these should be the same.") self.assertEqual(pulse_series[omkey][1].flags, shifted_pulses[omkey][1].flags, "these should be the same.") self.assertAlmostEqual(pulse_series[omkey][1].charge / calibration.dom_cal[omkey].mean_fadc_charge, shifted_pulses[omkey][1].charge, places=4, msg="these should be the same.")
def Process(self): gcd = dataio.I3File(self.gcdfile, 'R') while (gcd.more()): frame = gcd.pop_frame() self.PushFrame(frame) gcd.close() #now deliver artificial testcase #make a Q-frame Qframe = icetray.I3Frame(icetray.I3Frame.DAQ) Qeh = dataclasses.I3EventHeader() Qeh.start_time = (dataclasses.I3Time(2011, 0)) Qeh.end_time = (dataclasses.I3Time(2011, 2)) Qeh.run_id = 1 Qeh.event_id = 1 Qframe.Put("I3EventHeader", Qeh) Qrecomap = dataclasses.I3RecoPulseSeriesMap() recopulse1 = dataclasses.I3RecoPulse() recopulse1.time = 0 recopulse1.charge = 1 recopulse2 = dataclasses.I3RecoPulse() recopulse2.time = 1 recopulse2.charge = 2 Qrecomap[icetray.OMKey(1,1)] = [recopulse1] Qrecomap[icetray.OMKey(2,2)] = [recopulse2] Qframe.Put(OrgPulses, Qrecomap) Qframe.Put(SplitName+"SplitCount", icetray.I3Int(2)) Qframe.Put(SplitName+"ReducedCount", icetray.I3Int(0)) self.PushFrame(Qframe) #now make the first p-frame containing one I3RecoPulse P1frame = icetray.I3Frame(icetray.I3Frame.Physics) P1eh = dataclasses.I3EventHeader() P1eh.start_time = (dataclasses.I3Time(2011, 0)) P1eh.end_time = (dataclasses.I3Time(2011, 1)) P1eh.run_id = 1 P1eh.event_id = 1 P1eh.sub_event_stream = "split" P1eh.sub_event_id = 0 P1frame.Put("I3EventHeader", P1eh) P1recomap = dataclasses.I3RecoPulseSeriesMap() P1recomap[icetray.OMKey(1,1)] = [recopulse1] P1recomask = dataclasses.I3RecoPulseSeriesMapMask(Qframe, OrgPulses, Qrecomap) P1frame.Put(SplitPulses, P1recomask) P1fit = dataclasses.I3Particle() P1fit.pos= dataclasses.I3Position(0.,0., CriticalDistance) P1fit.dir= dataclasses.I3Direction(0., CriticalAngle) P1fit.fit_status = dataclasses.I3Particle.OK P1frame.Put("Fit", P1fit) self.PushFrame(P1frame) #now make the second p-frame containing one I3RecoPulse P2frame = icetray.I3Frame(icetray.I3Frame.Physics) P2eh = dataclasses.I3EventHeader() P2eh.start_time = (dataclasses.I3Time(2011, 1)) P2eh.end_time = (dataclasses.I3Time(2011, 2)) P2eh.run_id = 1 P2eh.event_id = 1 P2eh.sub_event_stream = "split" P2eh.sub_event_id = 1 P2frame.Put("I3EventHeader", P2eh) P2recomap = dataclasses.I3RecoPulseSeriesMap() P2recomap[icetray.OMKey(2,2)] = [recopulse2] P2recomask = dataclasses.I3RecoPulseSeriesMapMask(Qframe, OrgPulses, P2recomap) P2frame.Put(SplitPulses, P2recomask) P2fit = dataclasses.I3Particle() P2fit.pos= dataclasses.I3Position(0.,0., CriticalDistance) P2fit.dir= dataclasses.I3Direction(0., -CriticalAngle) P2fit.fit_status = dataclasses.I3Particle.OK P2frame.Put("Fit", P2fit) self.PushFrame(P2frame) Hframe = icetray.I3Frame(icetray.I3Frame.Physics) Heh = dataclasses.I3EventHeader() Heh.start_time = (dataclasses.I3Time(2011, 0)) Heh.end_time = (dataclasses.I3Time(2011, 2)) Heh.run_id = 1 Heh.event_id = 1 Heh.sub_event_stream = HypoName Heh.sub_event_id = 0 Hframe.Put("I3EventHeader", Heh) Hrecomap = dataclasses.I3RecoPulseSeriesMap() Hrecomap[icetray.OMKey(1,1)] = [recopulse1] Hrecomap[icetray.OMKey(2,2)] = [recopulse2] Hrecomask = dataclasses.I3RecoPulseSeriesMapMask(Qframe, OrgPulses, Hrecomap) Hframe.Put(SplitPulses, Hrecomask) Hcf = dataclasses.I3MapStringVectorDouble() Hcf["split"]=[0,1] Hframe.Put("CS_CreatedFrom", Hcf) Hfit = dataclasses.I3Particle() Hfit.time= 0 Hfit.pos= dataclasses.I3Position(0.,0.,0.) Hfit.dir= dataclasses.I3Direction(0., 0.) Hfit.fit_status = dataclasses.I3Particle.OK Hframe.Put("HFit", Hfit) self.PushFrame(Hframe) self.RequestSuspension()
def Process(self): gcd = dataio.I3File(self.gcdfile, 'R') while (gcd.more()): frame = gcd.pop_frame() self.PushFrame(frame) gcd.close() #now deliver artificial testcase #make a Q-frame#make a Q-frame Qframe = icetray.I3Frame(icetray.I3Frame.DAQ) Qeh = dataclasses.I3EventHeader() Qeh.start_time = (dataclasses.I3Time(2011, 0)) Qeh.end_time = (dataclasses.I3Time(2011, 2)) Qeh.run_id = 1 Qeh.event_id = 1 Qframe.Put("I3EventHeader", Qeh) Qrecomap = dataclasses.I3RecoPulseSeriesMap() recopulse1 = dataclasses.I3RecoPulse() recopulse1.time = 0 recopulse1.charge = 1 recopulse2 = dataclasses.I3RecoPulse() recopulse2.time = 1 recopulse2.charge = 2 Qrecomap[icetray.OMKey(1, 1)] = [recopulse1] Qrecomap[icetray.OMKey(2, 2)] = [recopulse2] Qframe.Put(OrgPulses, Qrecomap) Qframe.Put(SplitName + "SplitCount", icetray.I3Int(2)) Qframe.Put(SplitName + "ReducedCount", icetray.I3Int(0)) self.PushFrame(Qframe) #now make the first p-frame containing one I3RecoPulse P1frame = icetray.I3Frame(icetray.I3Frame.Physics) P1eh = dataclasses.I3EventHeader() P1eh.start_time = (dataclasses.I3Time(2011, 0)) P1eh.end_time = (dataclasses.I3Time(2011, 1)) P1eh.run_id = 1 P1eh.event_id = 1 P1eh.sub_event_stream = SplitName P1eh.sub_event_id = 0 P1frame.Put("I3EventHeader", P1eh) P1recomap = dataclasses.I3RecoPulseSeriesMap() P1recomap[icetray.OMKey(1, 1)] = [recopulse1] P1recomask = dataclasses.I3RecoPulseSeriesMapMask( Qframe, OrgPulses, Qrecomap) P1frame.Put(SplitPulses, P1recomask) self.PushFrame(P1frame) #now make the second p-frame containing one I3RecoPulse P2frame = icetray.I3Frame(icetray.I3Frame.Physics) P2eh = dataclasses.I3EventHeader() P2eh.start_time = (dataclasses.I3Time(2011, 1)) P2eh.end_time = (dataclasses.I3Time(2011, 2)) P2eh.run_id = 1 P2eh.event_id = 1 P2eh.sub_event_stream = SplitName P2eh.sub_event_id = 1 P2frame.Put("I3EventHeader", P2eh) P2recomap = dataclasses.I3RecoPulseSeriesMap() P2recomap[icetray.OMKey(2, 2)] = [recopulse2] P2recomask = dataclasses.I3RecoPulseSeriesMapMask( Qframe, OrgPulses, P2recomap) P2frame.Put(SplitPulses, P2recomask) self.PushFrame(P2frame) self.RequestSuspension()
def add_white_noise(self, pulses, charge_range, time_range, noise_rate_factor, dom_noise_rate_dict, frame, *args, **kwargs): """Add white noise to DOMs. Pulses are drawn uniformly from the ranges specificied in charge_range and time_range. The noise rate at each DOM is taken from calibration data and then scaled by the noise_rate_factor. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. charge_range : [float, float] The charge range in which the pulse charges are uniformly sampled. time_range : [float, float] The time range in which the pulse times are uniformly sampled. noise_rate_factor : float The poisson mean for the added white noise will be the DOM noise rate multiplied by the noise_rate_factor, e.g. noise_rate_factor=100 will add white noise to DOMs that corresponds to 100 times the normal rate. dom_noise_rate_dict : dict A dictionary {omkey: noise rate} that contains the noise rate for each DOM. frame : I3Frame The current I3Frame. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ assert time_range[1] > time_range[0], '{!r} !< {!r}'.format(*time_range) time_window = time_range[1] - time_range[0] modified_pulses = {} for key, rate in dom_noise_rate_dict.items(): # Do not incldude DOMs if they do not belong to the # detector configuration, e.g. if they are marked as bad DOMs. if (key in frame['BadDomsList'] or key in frame['BadDomsListSLC']): continue # sample random pulses that are to be added num_pulses = self._random_generator.poisson( time_window * rate * noise_rate_factor) charges_new = self._random_generator.uniform( low=charge_range[0], high=charge_range[1], size=num_pulses) times_new = self._random_generator.uniform( low=time_range[0], high=time_range[1], size=num_pulses) # set LC, ATWD, and FADC flag flags_new = [7] * num_pulses # set width to 2 ns (most common in pulses) widths_new = [2] * num_pulses if key in pulses: dom_pulses = pulses[key] else: dom_pulses = [] charges = np.concatenate(([p.charge for p in dom_pulses], charges_new)) times = np.concatenate(([p.time for p in dom_pulses], times_new)) widths = np.concatenate(([p.width for p in dom_pulses], widths_new)) flags = np.concatenate(([p.flags for p in dom_pulses], flags_new)) if len(charges) > 0: # sort pulses in time sorted_indices = np.argsort(times) charges = charges[sorted_indices] times = times[sorted_indices] widths = widths[sorted_indices] flags = flags[sorted_indices] modified_dom_pulses = [] for charge, time, flag, width in zip(charges, times, flags, widths): # create pulse modified_pulse = dataclasses.I3RecoPulse() modified_pulse.charge = charge modified_pulse.time = time modified_pulse.flags = int(flag) modified_pulse.width = width # append pulse modified_dom_pulses.append(modified_pulse) modified_pulses[key] = dataclasses.vector_I3RecoPulse( fix_time_overlap(modified_dom_pulses)) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
def add_random_pulses(self, pulses, mean_dom_pulses, time_range, charge_shape=1.8, *args, **kwargs): """Add pulses randomly to hit DOMs based on poisson expectation mean_dom_pulses and the provided time_range. Note: this does NOT add random pulses to all DOMs - just to hit ones. Parameters ---------- pulses : I3RecoPulseSeriesMap Pulses to modify. mean_dom_pulses : float The poisson expectation of how many pulses to add per DOM. charge_shape : float The expectation of the charge for each added pulse. The charge is sampled from a gamma distribution with the charge_shape set as shape. time_range : [float, float] The time range in which the pulse times are uniformly sampled. *args Variable length argument list. **kwargs Arbitrary keyword arguments. Returns ------- I3RecoPulseSeriesMap The modified pulses. """ modified_pulses = {} for key, dom_pulses in pulses.items(): # sample random pulses that are to be added num_pulses = self._random_generator.poisson(lam=mean_dom_pulses) if charge_shape is None or charge_shape in ['none', '', 'None']: charges_new = np.ones(shape=num_pulses) else: charges_new = self._random_generator.gamma(shape=charge_shape, size=num_pulses) times_new = self._random_generator.uniform(low=time_range[0], high=time_range[1], size=num_pulses) # set LC, ATWD, and FADC flag flags_new = [7] * num_pulses # set width to 2 ns (most common in pulses) widths_new = [2] * num_pulses charges = np.concatenate(([p.charge for p in dom_pulses], charges_new)) times = np.concatenate(([p.time for p in dom_pulses], times_new)) widths = np.concatenate(([p.width for p in dom_pulses], widths_new)) flags = np.concatenate(([p.flags for p in dom_pulses], flags_new)) # sort pulses in time sorted_indices = np.argsort(times) charges = charges[sorted_indices] times = times[sorted_indices] widths = widths[sorted_indices] flags = flags[sorted_indices] modified_dom_pulses = [] for charge, time, flag, width in zip(charges, times, flags, widths): # create pulse modified_pulse = dataclasses.I3RecoPulse() modified_pulse.charge = charge modified_pulse.time = time modified_pulse.flags = int(flag) modified_pulse.width = width # append pulse modified_dom_pulses.append(modified_pulse) modified_pulses[key] = dataclasses.vector_I3RecoPulse( fix_time_overlap(modified_dom_pulses)) return dataclasses.I3RecoPulseSeriesMap(modified_pulses)
# everything but the minor ID should be the same # we could really use a compare clone method assert (my_other_particle != mypart) print(mypart) print(my_other_particle) mypartvec = dataclasses.I3VectorI3Particle() mypartvec.append(mypart) for party in mypartvec: print(party) #I3RecoPulse print('Testing I3RecoPulse') rp = dataclasses.I3RecoPulse() rp.charge = 1.5 ## PEs rp.time = 100.0 * icetray.I3Units.ns rp.flags = dataclasses.I3RecoPulse.PulseFlags.ATWD print(rp) trigger_vect = dataclasses.I3VectorI3Trigger() trigger_vect.append(dataclasses.I3Trigger()) print(trigger_vect) rps = dataclasses.I3RecoPulseSeries() rps.append(rp) for pulse in rps: print(pulse)
def Process(self): gcd = dataio.I3File(self.gcdfile, 'R') while (gcd.more()): frame = gcd.pop_frame() if (frame.Stop == icetray.I3Frame.Geometry): geo = frame["I3Geometry"] self.PushFrame(frame) gcd.close() #now deliver artificial testcase #make a Q-frame Qrecomap = dataclasses.I3RecoPulseSeriesMap() recopulse1 = dataclasses.I3RecoPulse() recopulse1.time = 0. recopulse1.charge = 1. recopulse2 = dataclasses.I3RecoPulse() recopulse2.time = 1000. / I3Constants.c #=3335.ns recopulse2.charge = 2. Qrecomap[icetray.OMKey(26, 1)] = [recopulse1] Qrecomap[icetray.OMKey(27, 1)] = [recopulse1] Qrecomap[icetray.OMKey(35, 1)] = [recopulse1] Qrecomap[icetray.OMKey(37, 1)] = [recopulse1] Qrecomap[icetray.OMKey(45, 1)] = [recopulse1] Qrecomap[icetray.OMKey(46, 1)] = [recopulse1] Qrecomap[icetray.OMKey(26, 60)] = [recopulse2] Qrecomap[icetray.OMKey(27, 60)] = [recopulse2] Qrecomap[icetray.OMKey(35, 60)] = [recopulse2] Qrecomap[icetray.OMKey(37, 60)] = [recopulse2] Qrecomap[icetray.OMKey(45, 60)] = [recopulse2] Qrecomap[icetray.OMKey(46, 60)] = [recopulse2] Qframe = icetray.I3Frame(icetray.I3Frame.DAQ) Qeh = dataclasses.I3EventHeader() Qeh.start_time = (dataclasses.I3Time(2011, 0)) Qeh.end_time = (dataclasses.I3Time(2011, 2)) Qeh.run_id = 1 Qeh.event_id = 1 Qframe.Put("I3EventHeader", Qeh) Qframe.Put(OrgPulses, Qrecomap) Qframe.Put(SplitName + "SplitCount", icetray.I3Int(2)) Qframe.Put(SplitName + "ReducedCount", icetray.I3Int(0)) self.PushFrame(Qframe) #now make the first p-frame containing one I3RecoPulse P1frame = icetray.I3Frame(icetray.I3Frame.Physics) P1eh = dataclasses.I3EventHeader() P1eh.start_time = (dataclasses.I3Time(2011, 0)) P1eh.end_time = (dataclasses.I3Time(2011, 1)) P1eh.run_id = 1 P1eh.event_id = 1 P1eh.sub_event_stream = "split" P1eh.sub_event_id = 0 P1frame.Put("I3EventHeader", P1eh) P1recomap = dataclasses.I3RecoPulseSeriesMap() P1recomap[icetray.OMKey(26, 1)] = [recopulse1] P1recomap[icetray.OMKey(27, 1)] = [recopulse1] P1recomap[icetray.OMKey(35, 1)] = [recopulse1] P1recomap[icetray.OMKey(37, 1)] = [recopulse1] P1recomap[icetray.OMKey(45, 1)] = [recopulse1] P1recomap[icetray.OMKey(46, 1)] = [recopulse1] P1recomask = dataclasses.I3RecoPulseSeriesMapMask( Qframe, OrgPulses, P1recomap) P1frame.Put(SplitPulses, P1recomask) P1fit = dataclasses.I3Particle( dataclasses.I3Particle.ParticleShape.InfiniteTrack) P1fit.time = -455. * I3Units.ns P1fit.pos = geo.omgeo[icetray.OMKey(36, 1)].position P1fit.dir = dataclasses.I3Direction(0., 0.) #straight down P1fit.fit_status = dataclasses.I3Particle.OK P1frame.Put("Fit", P1fit) self.PushFrame(P1frame) #now make the second p-frame containing one I3RecoPulse P2frame = icetray.I3Frame(icetray.I3Frame.Physics) P2eh = dataclasses.I3EventHeader() P2eh.start_time = (dataclasses.I3Time(2011, 1)) P2eh.end_time = (dataclasses.I3Time(2011, 2)) P2eh.run_id = 1 P2eh.event_id = 1 P2eh.sub_event_stream = SplitName P2eh.sub_event_id = 1 P2frame.Put("I3EventHeader", P2eh) P2recomap = dataclasses.I3RecoPulseSeriesMap() P2recomap[icetray.OMKey(26, 60)] = [recopulse2] P2recomap[icetray.OMKey(27, 60)] = [recopulse2] P2recomap[icetray.OMKey(35, 60)] = [recopulse2] P2recomap[icetray.OMKey(37, 60)] = [recopulse2] P2recomap[icetray.OMKey(45, 60)] = [recopulse2] P2recomap[icetray.OMKey(46, 60)] = [recopulse2] P2recomask = dataclasses.I3RecoPulseSeriesMapMask( Qframe, OrgPulses, P2recomap) P2frame.Put(SplitPulses, P2recomask) P2fit = dataclasses.I3Particle( dataclasses.I3Particle.ParticleShape.InfiniteTrack) P2fit.time = 1000. / I3Constants.c - 454. * I3Units.ns P2fit.pos = geo.omgeo[icetray.OMKey(36, 60)].position P2fit.dir = dataclasses.I3Direction(0, 0.) #straight up P2fit.fit_status = dataclasses.I3Particle.OK P2frame.Put("Fit", P2fit) self.PushFrame(P2frame) Hframe = icetray.I3Frame(icetray.I3Frame.Physics) Heh = dataclasses.I3EventHeader() Heh.start_time = (dataclasses.I3Time(2011, 0)) Heh.end_time = (dataclasses.I3Time(2011, 2)) Heh.run_id = 1 Heh.event_id = 1 Heh.sub_event_stream = HypoName Heh.sub_event_id = 0 Hframe.Put("I3EventHeader", Heh) Hrecomap = dataclasses.I3RecoPulseSeriesMap() Hrecomap[icetray.OMKey(26, 1)] = [recopulse1] #ring top Hrecomap[icetray.OMKey(27, 1)] = [recopulse1] Hrecomap[icetray.OMKey(35, 1)] = [recopulse1] Hrecomap[icetray.OMKey(37, 1)] = [recopulse1] Hrecomap[icetray.OMKey(45, 1)] = [recopulse1] Hrecomap[icetray.OMKey(46, 1)] = [recopulse1] Hrecomap[icetray.OMKey(26, 60)] = [recopulse2] #ring bottom Hrecomap[icetray.OMKey(27, 60)] = [recopulse2] Hrecomap[icetray.OMKey(35, 60)] = [recopulse2] Hrecomap[icetray.OMKey(37, 60)] = [recopulse2] Hrecomap[icetray.OMKey(45, 60)] = [recopulse2] Hrecomap[icetray.OMKey(46, 60)] = [recopulse2] Hrecomask = dataclasses.I3RecoPulseSeriesMapMask( Qframe, OrgPulses, Hrecomap) Hframe.Put(SplitPulses, Hrecomask) Hcf = dataclasses.I3MapStringVectorDouble() Hcf["split"] = [0, 1] Hframe.Put("CS_CreatedFrom", Hcf) Hfit = dataclasses.I3Particle( dataclasses.I3Particle.ParticleShape.InfiniteTrack) Hfit.time = -454. * I3Units.ns Hfit.pos = geo.omgeo[icetray.OMKey(36, 1)].position Hfit.dir = dataclasses.I3Direction(0., 0.) Hfit.fit_status = dataclasses.I3Particle.OK Hframe.Put("HFit", Hfit) self.PushFrame(Hframe) self.RequestSuspension()
def Physics(self, frame): a = 4.823 * 10.0**(-4.0) #ns/m^2 b = 19.41 #ns sigma = 83.5 #m t_cog = frame['ShowerCOG'].time zenith_core = frame['Laputop'].dir.zenith azimuth_core = frame['Laputop'].dir.azimuth unit_core = np.array([ np.sin(zenith_core) * np.cos(azimuth_core), np.sin(zenith_core) * np.sin(azimuth_core), np.cos(zenith_core) ]) output_map = dataclasses.I3RecoPulseSeriesMap() Laputop = frame['Laputop'] x_core = np.array([Laputop.pos.x, Laputop.pos.y, Laputop.pos.z]) t_core = Laputop.time theta = Laputop.dir.theta phi = Laputop.dir.phi n = np.array([ np.sin(theta) * np.cos(phi), np.sin(theta) * np.sin(phi), np.cos(theta) ]) radius = dataclasses.I3MapKeyVectorDouble() radius_old = dataclasses.I3MapKeyVectorDouble() m = dataclasses.I3MapKeyVectorDouble() s = dataclasses.I3MapKeyVectorDouble() chi2 = dataclasses.I3MapKeyVectorDouble() sigma_m = dataclasses.I3MapKeyVectorDouble() sigma_s = dataclasses.I3MapKeyVectorDouble() for i in frame['LaputopHLCVEM'].keys(): output_map[i] = dataclasses.I3RecoPulseSeries() pulse = dataclasses.I3RecoPulse() vec = [] vec_old = [] vec_m = [] vec_s = [] vec_chi2 = [] vec_sigma_m = [] vec_sigma_s = [] for j in frame['LaputopHLCVEM'][i]: pulse.charge = j.charge time = j.time position_dom = frame['I3Geometry'].omgeo[i].position x_dom = np.array( [position_dom.x, position_dom.y, position_dom.z]) Radius = np.dot(x_dom - x_core, x_dom - x_core)**0.5 unit_dom = (x_dom - x_core) / Radius true_radius = np.dot(unit_dom - unit_core, x_dom - x_core) time_signal = time vec.append(true_radius) vec_old.append(Radius) key = str(i) pulse.time = frame['LaputopHLCVEM'][i][0].time vec_m.append(frame['WaveformInfo'][key]['m']) vec_s.append(frame['WaveformInfo'][key]['s']) vec_chi2.append(frame['WaveformInfo'][key]['chi2']) vec_sigma_m.append(frame['WaveformInfo'][key]['sigma_m']) vec_sigma_s.append(frame['WaveformInfo'][key]['sigma_s']) output_map[i].append(pulse) radius[i] = np.array(vec) radius_old[i] = np.array(vec_old) m[i] = np.array(vec_m) s[i] = np.array(vec_s) chi2[i] = np.array(vec_chi2) sigma_m[i] = np.array(vec_sigma_m) sigma_s[i] = np.array(vec_sigma_s) frame['All_radius'] = radius frame['All_radius_old'] = radius_old frame['All_pulses'] = output_map frame['m'] = m frame['s'] = s frame['chi2'] = chi2 frame['sigma_m'] = sigma_m frame['sigma_s'] = sigma_s self.PushFrame(frame)