def RecoSuccess(frame): it_combo_count = 0 ii_combo_count = 0 it_count = 0 ii_count = 0 ii_counts = 0 if (('IT_mpeLLH_itSEED' in frame) and (int(frame['IT_mpeLLH_itSEED'].fit_status) == 0)): it_combo_count = 1 if (('II_speLLH_mpeSEED' in frame) and (int(frame['II_speLLH_mpeSEED'].fit_status) == 0)): ii_combo_count = 1 if (('Laputop' in frame) and (int(frame['Laputop'].fit_status) == 0)): it_count = 1 if (('CoincMuonReco_SPEFit2' in frame) and (int(frame['CoincMuonReco_SPEFit2'].fit_status) == 0)): ii_counts = 1 if (('CoincMuonReco_MPEFit' in frame) and (int(frame['CoincMuonReco_MPEFit'].fit_status) == 0)): ii_count = 1 frame['Good_COMBO_IT'] = dataclasses.I3Double(it_combo_count) frame['Good_COMBO_II'] = dataclasses.I3Double(ii_combo_count) frame['Good_Laputop'] = dataclasses.I3Double(it_count) frame['Good_MPE'] = dataclasses.I3Double(ii_count) frame['Good_SPE'] = dataclasses.I3Double(ii_counts)
def initialize(self): """Initialize empty data fields. """ # data fields that can be used as input into the network during # inference. if self.config['is_str_dom_format']: self.x_dom = np.zeros( [self.batch_size, 86, 60, self.config['num_bins']]) self.x_dom_exclusions = np.ones( [self.batch_size, 86, 60, self.config['num_bins']], dtype=bool) else: self.x_ic78 = np.zeros( [self.batch_size, 10, 10, 60, self.config['num_bins']]) self.x_deepcore = np.zeros( [self.batch_size, 8, 60, self.config['num_bins']]) self.x_ic78_exclusions = np.ones( [self.batch_size, 10, 10, 60, self.config['num_bins']], dtype=bool) self.x_deepcore_exclusions = np.ones( [self.batch_size, 8, 60, self.config['num_bins']], dtype=bool) self.global_time_offset_batch = np.zeros([self.batch_size]) self.runtime_batch = np.zeros([self.batch_size]) # data fields to hold I3Data to be written to frame # (This does not require batching because values are properly # written to the frame for each event by the DNNContainerHandler.) self.bin_exclusions = dataclasses.I3MapKeyVectorInt() self.bin_indices = dataclasses.I3MapKeyVectorInt() self.bin_values = dataclasses.I3MapKeyVectorDouble() self.global_time_offset = dataclasses.I3Double() self.runtime = dataclasses.I3Double()
def Physics(self, frame): q_tot = NaN n_channels = 0 n_hits = 0 max_qfrac = NaN pulse_map = dataclasses.I3RecoPulseSeriesMap.from_frame( frame, self.pulses) charge_list = [] for omkey, pulses in pulse_map: # Throw out Deep Core strings (want homogenized total charge) if (omkey.string < 79) and (omkey.om >= self.min_DOM) and ( omkey.om <= self.max_DOM): n_channels += 1 for pulse in pulses: charge_list += [pulse.charge] # Check to see if DOMs with signal are in the min_DOM to # max_DOM range if n_channels == 0: q_tot = NaN max_qfrac = NaN else: q_tot = np.sum(charge_list) n_hits = len(charge_list) max_qfrac = np.max(charge_list) / q_tot frame.Put('InIce_charge_{}_{}'.format(self.min_DOM, self.max_DOM), dataclasses.I3Double(q_tot)) frame.Put('NChannels_{}_{}'.format(self.min_DOM, self.max_DOM), icetray.I3Int(n_channels)) frame.Put('NHits_{}_{}'.format(self.min_DOM, self.max_DOM), icetray.I3Int(n_hits)) frame.Put('max_qfrac_{}_{}'.format(self.min_DOM, self.max_DOM), dataclasses.I3Double(max_qfrac)) self.PushFrame(frame)
def CleanTH(frame, Pulses, TrackNames): lists = [] fitnames = [] for fitname in TrackNames: if frame.Has(fitname): p = 0 q = 0 for k in frame.keys(): if ("TrackHits_{0}_{1}".format(fitname, Pulses) in k) and ("coincObsQsList" in k): Ps = frame[k] for om, charges in Ps: if not len(charges) == 0: p = p + 1 q = q + sum(charges) del frame[k] elif ("TrackHits_{0}_{1}".format(fitname, Pulses) in k): del frame[k] lists.append([p, q, fitname]) ps = sorted(lists, key=itemgetter(0), reverse=True) qs = sorted(lists, key=itemgetter(1), reverse=True) frame["TrackHits_MaxCompHits"] = dataclasses.I3Double(ps[0][0]) frame["TrackHits_MaxCompCharge"] = dataclasses.I3Double(qs[0][1]) print "TrackHits_MaxCompHits = {0:.3f}".format(ps[0][0]) print "TrackHits_MaxCompCharge = {0:.3f}".format(qs[0][1])
def GetCore(frame): # global omKey3Vec_, omKey4Vec_, omKey5Vec_, omKey6Vec_ # omKey3Vec_ = [] # omKey4Vec_ = [] # omKey5Vec_ = [] # omKey6Vec_ = [] if (frame.Has("OfflinePulses_sRT")): srtMask = frame["OfflinePulses_sRT"] srtPulse = srtMask.apply(frame) pulseList = [] firstStrings = [] #Store srtPulse information in a list of tuples with time variable first for omKey, series in srtPulse: pulseTup = series[0].time, omKey.string, omKey, geometry_.omgeo[ omKey].position[2] pulseList.append(pulseTup) #Get number of hits on each string stringList = [i[1] for i in sorted(pulseList)] stringCount = [stringList.count(j) for j in stringList] #Make pulseList sorted in Time pulseList.sort() frame["ThreePosX"] = dataclasses.I3Double(geometry_.omgeo[[ i for i, j in srtPulse ][stringCount.index(min([i for i in stringCount if i > 2]))]].position[0]) frame["ThreePosY"] = dataclasses.I3Double(geometry_.omgeo[[ i for i, j in srtPulse ][stringCount.index(min([i for i in stringCount if i > 2]))]].position[1]) frame["ThreePosZ"] = dataclasses.I3Double(geometry_.omgeo[[ i for i, j in srtPulse ][stringCount.index(min([i for i in stringCount if i > 2]))]].position[2])
def ComputeChargeWeightedDist(frame, Pulses, Track): if(not frame.Stop==icetray.I3Frame.Physics): return if(not frame.Has(Pulses)): return if(not frame.Has(Track)): return pulses=getRecoPulses(frame,Pulses) track=frame[Track] if(track.__class__==dataclasses.I3String): Track=track.value if(not frame.Has(Track)): return track=frame[Track] geo=frame.Get('I3Geometry') omgeo=geo.omgeo Qtot=0 AvgDistQ=0 for dom in pulses: DomPosition=omgeo[dom[0]].position Dist=phys_services.I3Calculator.closest_approach_distance(track,DomPosition) Qdom=0 for pulse in dom[1]: Qdom+=pulse.charge Qtot+=Qdom AvgDistQ+=Dist*Qdom if(Qtot==0): AvgDistQ=NaN else: AvgDistQ/=Qtot if not frame.Has(Track+'_AvgDistQ'): frame.Put(Track+"_AvgDistQ",dataclasses.I3Double(AvgDistQ)) if not frame.Has(Pulses+"_Qtot"): frame.Put(Pulses+"_Qtot",dataclasses.I3Double(Qtot))
def Contained(frame): if "I3Geometry" in frame: geo = frame["I3Geometry"] calculator = phys_services.I3ScaleCalculator(geo, icconfig, itconfig) frame['True_IT_Cont'] = dataclasses.I3Double( calculator.scale_icetop(frame["MCPrimary"])) frame['True_II_Cont'] = dataclasses.I3Double( calculator.scale_inice(frame["MCPrimary"]))
def Physics(self, frame): if 'MCPrimary' in frame: frame.Put('InIce_FractionContainment', dc.I3Double(self.scaling.scale_inice(frame['MCPrimary']))) frame.Put('IceTop_FractionContainment', dc.I3Double(self.scaling.scale_icetop(frame['MCPrimary']))) self.PushFrame(frame)
def charge_localization( frame, pulses='' ): # the algorithm that computes the reconstructed muon track. Can be used in this form as a module in icetray script. pulse_series = dataclasses.I3RecoPulseSeriesMap.from_frame(frame, pulses) DOMcharge = [] ## getting the charge deposited in each DOM for omkey, pulses in pulse_series: DOMcharge.append( np.array([omkey.string, omkey.om, sum([p.charge for p in pulses])])) DOMcharge = np.asarray(DOMcharge) localized_charge, total_event_charge = localize( DOMcharge ) ## returns [string, om, % total event charge], total charge of the event brightest_dom_coord = DOMcoord[ int(localized_charge[0][0]), int(localized_charge[0][1])] ## coordintates of the brightest DOM brightest_dom_charge = localized_charge[0][2] second_brightest_dom_charge = 0 for dom in localized_charge: if int(localized_charge[0][0]) != int( dom[0] ): # if the second brightest DOM is on the same string as the brightest, add its charge to the brightest, move on to next brightest DOM second_brightest_dom_coord = DOMcoord[int(dom[0]), int(dom[1])] second_brightest_dom_charge = dom[2] break else: second_brightest_dom_coord = DOMcoord[int(dom[0]), int(dom[1])] brightest_dom_charge = +dom[2] brightest_dom_distance = np.linalg.norm( brightest_dom_coord - second_brightest_dom_coord ) ## distance betweeen the two brightest DOMs, called the lever arm if brightest_dom_coord[2] > second_brightest_dom_coord[2]: charge_localization_vector = ( brightest_dom_coord - second_brightest_dom_coord) / brightest_dom_distance else: charge_localization_vector = ( second_brightest_dom_coord - brightest_dom_coord) / brightest_dom_distance localization_zenith, localization_azimuth = angles( charge_localization_vector) particle = dataclasses.I3Particle( ) # creating an I3Particle object containing direction and length information particle.dir = dataclasses.I3Direction(-charge_localization_vector[0], -charge_localization_vector[1], -charge_localization_vector[2]) particle.pos = dataclasses.I3Position(brightest_dom_coord[0], brightest_dom_coord[1], brightest_dom_coord[2]) frame[ 'localization_line'] = particle # writing I3Particle object to the I3File particle.length = brightest_dom_distance frame['brightest_dom_charge'] = dataclasses.I3Double( brightest_dom_charge ) # writing brightest and second brightest DOM charge to I3File frame['second_brightest_dom_charge'] = dataclasses.I3Double( second_brightest_dom_charge)
def add_fraction_containment(frame, track): scaling = phys_services.I3ScaleCalculator(frame['I3Geometry']) icetop_containment = scaling.scale_icetop(frame[track]) frame['FractionContainment_{}_IceTop'.format( track)] = dataclasses.I3Double(icetop_containment) inice_containment = scaling.scale_inice(frame[track]) frame['FractionContainment_{}_InIce'.format(track)] = dataclasses.I3Double( inice_containment)
def Physics(self, frame): if self.recoPulses not in frame: self.PushFrame(frame) return tank_map = frame[self.recoPulses] if tank_map.__class__ == dc.I3RecoPulseSeriesMapMask: tank_map = tank_map.apply(frame) # Build list of charges and corresponding om's charge_map = [] for om, pulses in tank_map: for wave in pulses: # If nan, use charge in other tank as best approximation if wave.charge != wave.charge: # Get neighboring charge omList = [om1 for om1, pulses in tank_map if om1 != om] stringList = [om1.string for om1 in omList] try: index = stringList.index(om.string) except ValueError: # pulse cleaning removed one tank continue om_neighbor = omList[index] pulses = tank_map[om_neighbor] charge = pulses[0].charge else: charge = wave.charge charge_map.append((charge, om)) if len(charge_map) < 1: self.PushFrame(frame) return charge_map = sorted(charge_map, reverse=True) q1 = charge_map[0][0] q1_dom = charge_map[0][1] # Get charge in neighbor to largest pulse (Q1b) omList = [om1 for om1, pulses in tank_map if om1 != q1_dom] stringList = [om1.string for om1 in omList] if q1_dom.string in stringList: index = stringList.index(q1_dom.string) q1b_dom = omList[index] q1b = tank_map[q1b_dom][0].charge frame['Q1b'] = dc.I3Double(q1b) # Write charges to frame bookedN = 0 while (bookedN < self.nPulses) and (bookedN < charge_map.__len__()): name = 'Q%i' % (bookedN + 1) frame[name] = dc.I3Double(charge_map[bookedN][0]) bookedN += 1 self.PushFrame(frame)
def Physics(self, frame): track = frame[self.track] pulse_map = dataclasses.I3RecoPulseSeriesMap.from_frame( frame, self.pulses) dists, charges = [], [] for omkey, pulses in pulse_map: # Throw out Deep Core strings (want homogenized total charge) if (omkey.string < 79) and (omkey.om >= self.min_DOM) and ( omkey.om <= self.max_DOM): # Get distance of clostest approach to DOM from track dist = self.get_dist(track, self.geomap[omkey].position) dists.append(dist) # Get charge recorded in DOM charge = np.sum([pulse.charge for pulse in pulses]) charges.append(charge) # Ensure that both dists and charges have non-zero size if dists and charges: frame['inice_dom_dists_{}_{}'.format( self.min_DOM, self.max_DOM)] = dataclasses.I3VectorDouble(dists) frame['inice_dom_charges_{}_{}'.format( self.min_DOM, self.max_DOM)] = dataclasses.I3VectorDouble(charges) dists = np.asarray(dists) charges = np.asarray(charges) avg_dist = np.average(dists) median_dist = np.median(dists) std_dists = np.std(dists) one_std_mask = (dists > avg_dist + std_dists) | ( dists < avg_dist - std_dists) half_std_mask = (dists > avg_dist + 2 * std_dists) | ( dists < avg_dist - 2 * std_dists) frac_outside_one_std = dists[one_std_mask].shape[0] / dists.shape[0] frac_outside_two_std = dists[half_std_mask].shape[0] / dists.shape[ 0] # Add variables to frame frame['avg_inice_radius'] = dataclasses.I3Double(avg_dist) frame['median_inice_radius'] = dataclasses.I3Double(median_dist) frame['std_inice_radius'] = dataclasses.I3Double(std_dists) frame['frac_outside_one_std_inice_radius'] = dataclasses.I3Double( frac_outside_one_std) frame['frac_outside_two_std_inice_radius'] = dataclasses.I3Double( frac_outside_two_std) # frame['qweighted_inice_radius_{}_{}'.format(self.min_DOM, self.max_DOM)] = dataclasses.I3Double(np.average(dists, weights=charges)) # # frame['invqweighted_inice_radius_{}_{}'.format(self.min_DOM, self.max_DOM)] = dataclasses.I3Double(np.average(dists, weights=1/charges)) self.PushFrame(frame)
def Physics(self, frame): if self.pulses not in frame: self.PushFrame(frame) return vem = frame[self.pulses] if vem.__class__ == dc.I3RecoPulseSeriesMapMask: vem = vem.apply(frame) loudPulse, loudStaCharge, avStaCharge = 0, 0, 0 loudStation1, loudStation2, loudStation3 = 0, 0, 0 prevSta, staCharge = 0, 0 sat_stations = [] for key, series in vem: for tank in series: # will be one waveform anyway # if NaN : rely on waveform in other tank, so skip if tank.charge != tank.charge: continue # Keep track of largest single pulse if tank.charge > loudPulse: loudPulse = tank.charge loudStation1 = key.string # Calculate total station charge if key.string != prevSta: staCharge = tank.charge else: staCharge += tank.charge if staCharge > loudStaCharge: loudStaCharge = staCharge loudStation2 = key.string prevSta = key.string # LG saturaton bookkeeping : if tank.charge > self.saturation: sat_stations.append(key.string) # Write to frame frame['StationWithLoudestPulse'] = dc.I3Double(loudStation1) frame['LoudestStation'] = dc.I3Double(loudStation2) # Option for writing saturated stations if self.outputName != '': sat_stations = set(sat_stations) sta_list = dc.I3VectorInt() for sta in sat_stations: sta_list.append(sta) frame[self.outputName] = sta_list self.PushFrame(frame)
def effective_area(frame, model, generator): mctree = frame["I3MCTree"] primary = mctree.primaries[0] muon = mctree.get_daughters(primary)[0] bundle = MuonGun.BundleConfiguration([MuonGun.BundleEntry(0, muon.energy)]) area = 1 / generator.generated_events(primary, bundle) frame["MCMuon"] = muon frame["MuonEffectiveArea"] = dataclasses.I3Double(area) weighter = MuonGun.WeightCalculator(model, generator) weight = weighter(primary, bundle) frame["MuonWeight"] = dataclasses.I3Double(weight) return True
def Physics(self, frame): # print('Working on Physics frame') # print('track = {}'.format(self.track)) # print('keys = {}'.format(frame.keys())) icetop_containment = self.scaling.scale_icetop(frame[self.track]) frame['FractionContainment_{}_IceTop'.format( self.track)] = dataclasses.I3Double(icetop_containment) inice_containment = self.scaling.scale_inice(frame[self.track]) frame['FractionContainment_{}_InIce'.format( self.track)] = dataclasses.I3Double(inice_containment) self.PushFrame(frame)
def get_reco_losses_inside(p_frame): if "MillipedeStarting2ndPass" not in p_frame: p_frame["MillipedeStarting2ndPass_totalRecoLossesInside"] = dataclasses.I3Double(numpy.nan) p_frame["MillipedeStarting2ndPass_totalRecoLossesTotal"] = dataclasses.I3Double(numpy.nan) return recoParticle = p_frame["MillipedeStarting2ndPass"] if "MillipedeStarting2ndPassParams" not in p_frame: p_frame["MillipedeStarting2ndPass_totalRecoLossesInside"] = dataclasses.I3Double(numpy.nan) p_frame["MillipedeStarting2ndPass_totalRecoLossesTotal"] = dataclasses.I3Double(numpy.nan) return def getRecoLosses(vecParticles): losses = [] for p in vecParticles: if not p.is_cascade: continue if p.energy==0.: continue losses.append([p.time, p.energy]) return losses recoLosses = getRecoLosses(p_frame["MillipedeStarting2ndPassParams"]) intersectionPoints = VHESelfVeto.IntersectionsWithInstrumentedVolume(p_frame["I3Geometry"], recoParticle) intersectionTimes = [] for intersectionPoint in intersectionPoints: vecX = intersectionPoint.x - recoParticle.pos.x vecY = intersectionPoint.y - recoParticle.pos.y vecZ = intersectionPoint.z - recoParticle.pos.z prod = vecX*recoParticle.dir.x + vecY*recoParticle.dir.y + vecZ*recoParticle.dir.z dist = numpy.sqrt(vecX**2 + vecY**2 + vecZ**2) if prod < 0.: dist *= -1. intersectionTimes.append(dist/dataclasses.I3Constants.c + recoParticle.time) entryTime = None exitTime = None intersectionTimes = sorted(intersectionTimes) if len(intersectionTimes)==0: p_frame["MillipedeStarting2ndPass_totalRecoLossesInside"] = dataclasses.I3Double(0.) totalRecoLosses = 0. for entry in recoLosses: totalRecoLosses += entry[1] p_frame["MillipedeStarting2ndPass_totalRecoLossesTotal"] = dataclasses.I3Double(totalRecoLosses) return entryTime = intersectionTimes[0]-60.*I3Units.m/dataclasses.I3Constants.c intersectionTimes = intersectionTimes[1:] exitTime = intersectionTimes[-1]+60.*I3Units.m/dataclasses.I3Constants.c intersectionTimes = intersectionTimes[:-1] totalRecoLosses = 0. totalRecoLossesInside = 0. for entry in recoLosses: totalRecoLosses += entry[1] if entryTime is not None and entry[0] < entryTime: continue if exitTime is not None and entry[0] > exitTime: continue totalRecoLossesInside += entry[1] p_frame["MillipedeStarting2ndPass_totalRecoLossesInside"] = dataclasses.I3Double(totalRecoLossesInside) p_frame["MillipedeStarting2ndPass_totalRecoLossesTotal"] = dataclasses.I3Double(totalRecoLosses)