def LatePulseCleaning(frame, Pulses, Residual=3e3 * I3Units.ns): pulses = dataclasses.I3RecoPulseSeriesMap.from_frame(frame, Pulses) mask = dataclasses.I3RecoPulseSeriesMapMask(frame, Pulses) counter, charge = 0, 0 qtot = 0 times = dataclasses.I3TimeWindowSeriesMap() for omkey, ps in pulses.iteritems(): if len(ps) < 2: if len(ps) == 1: qtot += ps[0].charge continue ts = numpy.asarray([p.time for p in ps]) cs = numpy.asarray([p.charge for p in ps]) median = weighted_median(ts, cs) qtot += cs.sum() for p in ps: if p.time >= (median + Residual): if not times.has_key(omkey): ts = dataclasses.I3TimeWindowSeries() ts.append( dataclasses.I3TimeWindow(median + Residual, numpy.inf) ) # this defines the **excluded** time window times[omkey] = ts mask.set(omkey, p, False) counter += 1 charge += p.charge frame[nominalPulsesName + "LatePulseCleaned"] = mask frame[nominalPulsesName + "LatePulseCleanedTimeWindows"] = times frame[nominalPulsesName + "LatePulseCleanedTimeRange"] = copy.deepcopy( frame[Pulses + "TimeRange"])
def shift_timerange(frame, Input): if frame.Has(Input) and frame.Has('TimeShift'): range = frame[Input] shift = frame['TimeShift'] range_new = dataclasses.I3TimeWindow(range.start - shift.value, range.stop - shift.value) frame.Delete(Input) frame.Put(Input, range_new)
def pulse_pruner(frame, Input): '''A simple re-implementation of the I3Pruner that works on pulses Uses only InIce readout_settings for readout windows ''' triggers = frame["I3Triggers"] dstatus = frame["I3DetectorStatus"] readoutStart = float('inf') readoutStop = -float('inf') #looping through all triggers to find #the global start and stop time of the readout for trig in triggers: ts = dstatus.trigger_status[trig.key] #For now we only care about InIce rs = ts.readout_settings[ts.INICE] rminus = rs.readout_time_minus rplus = rs.readout_time_plus triggerStart = trig.time triggerStop = trig.time + trig.length curr_readoutStart = triggerStart - rminus curr_readoutStop = triggerStop + rplus if(readoutStart > curr_readoutStart): readoutStart = curr_readoutStart if(readoutStop < curr_readoutStop): readoutStop = curr_readoutStop pulses = dataclasses.I3RecoPulseSeriesMapMask(frame, Input, lambda om, idx, pulse: pulse.time >= readoutStart and pulse.time < readoutStop).apply(frame) del frame[Input] frame[Input] = pulses frame[Input+'TimeRange'] = dataclasses.I3TimeWindow(readoutStart,readoutStop)
def Physics(self, frame): """Modifies pulses as specified in modification. Parameters ---------- frame : I3Frame Current i3 frame. """ # get pulses pulses = frame[self._pulse_key] if isinstance(pulses, dataclasses.I3RecoPulseSeriesMapMask) or \ isinstance(pulses, dataclasses.I3RecoPulseSeriesMapUnion): pulses = pulses.apply(frame) # make copy of pulses pulses = copy.copy(dataclasses.I3RecoPulseSeriesMap(pulses)) # get modification function modification_func = getattr(pulse_modification_functions, self._modification) # apply modification to pulses modified_pulses = modification_func( self, pulses, dom_noise_rate_dict=self._dom_noise_rate, frame=frame, **self._modification_settings) # write to frame if self._out_key is None: frame[self._pulse_key + '_mod'] = modified_pulses frame[self._pulse_key + '_modTimeRange'] = dataclasses.I3TimeWindow( frame[self._pulse_key + 'TimeRange']) else: frame[self._out_key] = copy.copy(modified_pulses) if self._pulse_key + 'TimeRange' in frame.keys(): frame[self._out_key + '_modTimeRange'] = dataclasses.I3TimeWindow( frame[self._pulse_key + 'TimeRange']) # push frame self.PushFrame(frame)
def FindDetectorVolumeIntersections(frame, TrackName="", OutputTimeWindow=None, TimePadding=0.): if TrackName in frame: if OutputTimeWindow is not None: twName = OutputTimeWindow else: twName = TrackName + "TimeRange" theTrack = frame[TrackName] geometry = frame["I3Geometry"] times = _FindDetectorVolumeIntersections(frame, theTrack, geometry) if len(times) == 0: #raise RuntimeError("track does not intersect the detector volume") frame[twName] = dataclasses.I3TimeWindow() elif len(times) == 1: raise RuntimeError("tracks with only one intersection are not supported") else: tWindow = dataclasses.I3TimeWindow(times[0]-TimePadding, times[-1]+TimePadding) frame[twName] = tWindow
def Physics(self, frame): time_pulses = [] pulses = dataclasses.I3RecoPulseSeriesMap.from_frame( frame, self.inputPulses) maxTime = -1.e100 minTime = 1.e100 for item in pulses: for pulse in item[1]: if pulse.time < minTime: minTime = pulse.time if pulse.time > maxTime: maxTime = pulse.time if maxTime < minTime: frame.Put(self.output, dataclasses.I3TimeWindow(-self.offset, self.offset)) else: frame.Put( self.output, dataclasses.I3TimeWindow(minTime - self.offset, maxTime + self.offset)) self.PushFrame(frame)
def FramePacket(self, frames): mctree = dataclasses.I3MCTree() mask = dataclasses.I3RecoPulseSeriesMapMask( frames[0], self.pulseSourceName, dataclasses.I3RecoPulseSeriesMap()) for frame in frames: if (frame.Stop == icetray.I3Frame.Physics): if (frame["I3EventHeader"].sub_event_stream == self.splitName): smallmctree = dataclasses.I3MCTree() #need to have the time range if (not frame.Has(self.recoMapName + "TimeRange")): time_pulses = [] pulses = dataclasses.I3RecoPulseSeriesMap.from_frame( frame, self.recoMapName) for item in pulses: for pulse in item[1]: time_pulses.append(pulse.time) time_pulses = numpy.array(time_pulses) frame.Put( self.recoMapName + "TimeRange", dataclasses.I3TimeWindow(time_pulses.min(), time_pulses.max())) #now do the composition work tr = frame[self.recoMapName + "TimeRange"] part = frame[self.fitName] primary = deepcopy(frame[self.fitName]) inparticle = deepcopy(frame[self.fitName]) outparticle = deepcopy(frame[self.fitName]) #primary.pos = part.shift_along_track((tr.start-part.time)*part.speed) primary.type = dataclasses.I3Particle.NuMuBar #NuMuBar primary.shape = dataclasses.I3Particle.Primary #InfiniteTrack #ContainedTrack #StoppingTrack #primary.time = tr.start primary.energy = 1 #primary.length = part.speed*(tr.start-tr.stop) mctree.add_primary(primary) smallmctree.add_primary(primary) inparticle.type = dataclasses.I3Particle.MuMinus inparticle.shape = dataclasses.I3Particle.ContainedTrack inparticle.energy = 1 inparticle.length = part.speed * (tr.start - tr.stop) inparticle.time = tr.start #inparticle.pos = part.shift_along_track((tr.start-part.time)*part.speed) mctree.append_child(primary, inparticle) smallmctree.append_child(primary, inparticle) mask = mask | frame[self.recoMapName] frame.Put("smallTree" + self.fitName, smallmctree) frames[0].Put("coll" + self.recoMapName, mask) frames[0].Put("coll" + self.fitName, mctree) for frame in frames: self.PushFrame(frame)
def DAQ(self, fr): fr[self.Pulses + 'TimeRange'] = dataclasses.I3TimeWindow( fr[self.TimeRange].start - 25. * icetray.I3Units.ns, fr[self.TimeRange].stop) self.PushFrame(fr)
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 add_timerange(frame, pulses): time_range = frame['CalibratedWaveformRange'] frame[pulses + 'TimeRange'] = dataclasses.I3TimeWindow( time_range.start - 25. * I3Units.ns, time_range.stop) return True