def remove(mctree, track, parent, detector): r"""Remove children from MC tree. Remove the children of the given parent particle from the given MC tree that are outside of the given detector volume. Parameters ---------- mctree : I3MCTree MC tree track : MMCTrack MMC Track to retrieve entry/exit time parent : I3Particle Parent particle detector : SamplingSurface Detector volume Returns ------- I3MCTree Cleaned MC tree """ cleanedtree = dataclasses.I3MCTree(mctree) daughters = mctree.get_daughters(parent) for daughter in daughters: #intersections = detector.intersection(daughter.pos, parent.dir) #if intersections.first * intersections.second > 0.: if daughter.time < track.ti or daughter.time > track.tf: cleanedtree.erase(daughter) return cleanedtree
def DAQ(self, frame): """ Check if we need to move on to the next injector, and check then if we've reached the end of the file. """ while self.event_no>=len(self.datafile[self.keys[self.keyno]]['final_1']): self.keyno+=1 self.event_no=0 if self.keyno >= len(self.keys): print("Requesting Suspension") self.RequestSuspension() return else: print("Moving to key {}".format(self.keys[self.keyno])) active = self.datafile[self.keys[self.keyno]] frame['I3MCTree'] = dataclasses.I3MCTree() dataclasses.I3MCTree.add_primary( frame['I3MCTree'], make_i3_particle( active['initial'][self.event_no])) dataclasses.I3MCTree.append_child( frame['I3MCTree'], frame['I3MCTree'][0].id, make_i3_particle( active['final_1'][self.event_no])) dataclasses.I3MCTree.append_child( frame['I3MCTree'], frame['I3MCTree'][0].id, make_i3_particle( active['final_2'][self.event_no])) frame['I3EventHeader'] = dataclasses.I3EventHeader() frame['EventProperties'] = get_prop_dict(active['properties'][self.event_no], 'Ranged' in self.keys[self.keyno]) self.event_no += 1 self.PushFrame(frame)
def Process(self): if self.counter % 20 == 0: sframe = icetray.I3Frame('S') info = simclasses.I3CorsikaInfo() sframe['I3CorsikaInfo'] = info self.PushFrame(sframe) qframe = icetray.I3Frame('Q') eh = dataclasses.I3EventHeader() eh.run_id = 1 eh.event_id = self.counter qframe['I3EventHeader'] = eh tree = dataclasses.I3MCTree() p1 = dataclasses.I3Particle() tree.insert(p1) if self.counter % 2 == 0: qframe['I3MCTree'] = tree qframe['I3MCPrimary'] = p1 self.PushFrame(qframe) self.counter += 1 if self.counter >= 100: self.RequestSuspension()
def export_frame(frame, frame_list, mctree_name, keys_to_export, rename_dict): """Export frames and append them to the provided frame list. Parameters ---------- frame : I3Frame The current I3Frame. frame_list : list The list to which to append the exported frames. mctree_name : str The name of the I3MCTree key. keys_to_export : list of str The keys to extract save to the exported frame rename_dict : dict A dictionary that defines the renaming of the keys. Signature: rename_dict[old_name] = new_name """ # create a new DAQ frame fr = icetray.I3Frame(icetray.I3Frame.DAQ) # extract I3MCTree fr[mctree_name] = dataclasses.I3MCTree(frame[mctree_name]) # extract specified keys for key in keys_to_export: if key in frame: new_name = rename_dict.get(key, key) fr[new_name] = frame[key] # append frame to list frame_list.append(fr)
def DAQ(self, frame): daughter = dataclasses.I3Particle() daughter.type = self.particleType daughter.energy = self.energy daughter.pos = dataclasses.I3Position(self.xCoord, self.yCoord, self.zCoord) daughter.dir = dataclasses.I3Direction(0., 0., -1.) daughter.time = 0. daughter.location_type = dataclasses.I3Particle.LocationType.InIce primary = dataclasses.I3Particle() primary.type = dataclasses.I3Particle.ParticleType.NuE primary.energy = self.energy primary.pos = dataclasses.I3Position(self.xCoord, self.yCoord, self.zCoord) primary.dir = dataclasses.I3Direction(0., 0., -1.) primary.time = 0. primary.location_type = dataclasses.I3Particle.LocationType.Anywhere mctree = dataclasses.I3MCTree() mctree.add_primary(primary) mctree.append_child(primary, daughter) frame["I3MCTree"] = mctree self.PushFrame(frame) self.eventCounter += 1 if self.eventCounter == self.nEvents: self.RequestSuspension()
def Generator(frame, FromEnergy=1 * I3Units.TeV, ToEnergy=1 * I3Units.TeV): p = dataclasses.I3Particle() p.energy = random.uniform(FromEnergy, ToEnergy) p.pos = dataclasses.I3Position(0, 0, 0) # sample on a cylinder theta = random.uniform(0., 2 * pi) r = sqrt(random.uniform(0, 300 * I3Units.m * 300 * I3Units.m)) x = r * sin(theta) y = r * cos(theta) z = random.uniform(-300 * I3Units.m, 300 * I3Units.m) zenith = random.uniform(0., pi) azimuth = random.uniform(0., 2 * pi) p.dir = dataclasses.I3Direction(zenith, azimuth) p.length = 500 * I3Units.m p.type = dataclasses.I3Particle.ParticleType.EMinus p.location_type = dataclasses.I3Particle.LocationType.InIce p.time = 0. * I3Units.ns tree = dataclasses.I3MCTree() tree.add_primary(p) frame["I3MCTree"] = tree
def DAQ(self, frame): """Inject casacdes into I3MCtree. Parameters ---------- frame : icetray.I3Frame.DAQ An I3 q-frame. """ trees = [frame[t] for t in self.mctree_keys] # oversampling for i in range(self.oversampling_factor): if i > 0: # create a new frame frame = icetray.I3Frame(frame) del frame['oversampling'] for key, tree in zip(self.mctree_keys, trees): del frame[key] frame[key] = dataclasses.I3MCTree(tree) if self.oversampling_factor > 1: frame['oversampling'] = dataclasses.I3MapStringInt({ 'event_num_in_run': self.events_done, 'oversampling_num': i, }) self.PushFrame(frame) self.events_done += 1
def muon_injector(frame): zenith = randomService.uniform(ZenithMin, ZenithMax) azimuth = randomService.uniform(0, 360 * I3Units.degree) x = CylinderRadius * math.cos(azimuth) y = CylinderRadius * math.sin(azimuth) z = CylinderRadius * math.cos(zenith) global mu_type if mu_type == dataclasses.I3Particle.MuMinus: mu_type = dataclasses.I3Particle.MuPlus else: mu_type = dataclasses.I3Particle.MuMinus mu = dataclasses.I3Particle() mu.type = mu_type mu.pos = dataclasses.I3Position(x, y, z) mu.dir = dataclasses.I3Direction(zenith, azimuth) mu.energy = MuonEnergy mu.time = 0 * I3Units.ns mu.length = NaN mu.location_type = dataclasses.I3Particle.InIce mctree = dataclasses.I3MCTree() mctree.add_primary(mu) frame["I3MCTree_preMuonProp"] = mctree
def _create_mc_tree(self, inj_pos, inj_time, inj_dir): """Inject accompanying muon in provided I3MCTree Parameters ---------- inj_pos : I3Position The position at which to inject the muon. inj_time : double The time at which to inject the muon. inj_dir : I3Direction The direction of the injected muon. Returns ------- I3MCTree The modified I3MCTree with the injected Muon. I3MapStringDouble Information on the injected muon. """ mc_tree = dataclasses.I3MCTree() muon_primary = dataclasses.I3Particle() muon_primary.shape = dataclasses.I3Particle.ParticleShape.Primary muon_primary.dir = dataclasses.I3Direction(inj_dir) muon_primary.pos = dataclasses.I3Position(inj_pos) muon_primary.time = inj_time muon = dataclasses.I3Particle() muon.dir = dataclasses.I3Direction(inj_dir) muon.pos = dataclasses.I3Position(inj_pos) muon.time = inj_time muon.location_type = dataclasses.I3Particle.LocationType.InIce # sample type: MuPlus or MuMinus u = self.random_service.uniform(0., 1.) if u > 0.5: pdg_encoding = 13 else: pdg_encoding = -13 muon.pdg_encoding = pdg_encoding # sample energy muon.energy = self._sample_energy() # add muon primary to I3MCTree mc_tree.add_primary(muon_primary) # add muon as new child mc_tree.append_child(muon_primary, muon) # add info injection_info = dataclasses.I3MapStringDouble({ 'muon_energy': muon.energy, 'muon_pdg_encoding': muon.pdg_encoding, }) return mc_tree, injection_info
def make_mctree(frame): mctree = dataclasses.I3MCTree() primary = make_particle() primary.location_type = primary.Anywhere primary.type = primary.unknown muon = make_particle() mctree.add_root(primary) mctree.append_child(primary, muon) frame['I3MCTree'] = mctree
def make_mctree(frame, linearized=True): tree = dataclasses.I3MCTree() p1 = dataclasses.I3Particle() tree.insert(p1) p2 = dataclasses.I3Particle() tree.append_child(p1, p2) if linearized: tree = dataclasses.I3LinearizedMCTree(tree) frame['I3MCTree'] = tree
def particle(f): p = dataclasses.I3Particle(dataclasses.I3Position(0, 0, 0), dataclasses.I3Direction(0, 0, 1), 0, dataclasses.I3Particle.Cascade, 0) p.type = dataclasses.I3Particle.ParticleType.EMinus p.location_type = dataclasses.I3Particle.LocationType.InIce p.energy = 1.e5 * I3Units.GeV t = dataclasses.I3MCTree() t.add_primary(p) f["particle"] = t
def DAQ(self, frame): """Inject casacdes into I3MCtree. Parameters ---------- frame : icetray.I3Frame.DAQ An I3 q-frame. """ pre_tree = frame['I3MCTree_preMuonProp'] frame['I3MCTree'] = dataclasses.I3MCTree(pre_tree) self.PushFrame(frame)
def DAQ(self, frame): # Fill primary into an MCTree mctree = dataclasses.I3MCTree() mctree.add_primary(self.primary) frame["I3MCTree_preMuonProp"] = mctree self.PushFrame(frame) self.events_done += 1 if self.events_done >= self.num_events: self.RequestSuspension()
def test_get_most_energetic_primary(self): primary1 = dc.I3Particle() primary1.energy = 10 * I3Units.TeV primary2 = dc.I3Particle() primary2.energy = 1 * I3Units.TeV tree = dc.I3MCTree() tree.insert(primary1) tree.insert(primary2) mep = get_most_energetic_primary(tree) self.assertTrue(mep, "got no particles, but there are primaries.") self.assertEqual(mep.id, primary1.id, "got the wrong particle.")
def Process(self): frame = icetray.I3Frame(icetray.I3Frame.DAQ) mctree = dataclasses.I3MCTree() cascade = dataclasses.I3Particle(dataclasses.I3Particle.Primary, dataclasses.I3Particle.EPlus) muon = dataclasses.I3Particle(dataclasses.I3Particle.Primary, dataclasses.I3Particle.MuPlus) mctree.add_primary(cascade) mctree.add_primary(muon) frame["I3MCTree"] = mctree self.PushFrame(frame)
def DAQ(self, frame): primary = frame[self.primary_name] self.generator.StartShower(primary, frame) tree = dataclasses.I3MCTree(primary) more = True while more: secondary = dataclasses.I3Particle() more = self.generator.NextParticle(secondary) if more: tree.append_child(primary, secondary) frame["I3MCTree"] = tree self.generator.EndEvent(frame) self.PushFrame(frame)
def Generator(frame, FromEnergy=1 * I3Units.TeV, ToEnergy=1 * I3Units.TeV): p = dataclasses.I3Particle() p.energy = random.uniform(FromEnergy, ToEnergy) p.pos = dataclasses.I3Position(0, 0, 0) zenith = random.uniform(0., pi) azimuth = random.uniform(0., 2 * pi) p.dir = dataclasses.I3Direction(zenith, azimuth) p.length = 500 * I3Units.m p.type = dataclasses.I3Particle.ParticleType.MuMinus p.location_type = dataclasses.I3Particle.LocationType.InIce p.time = 0. * I3Units.ns tree = dataclasses.I3MCTree() tree.add_primary(p) frame["I3MCTree_preMuonProp"] = tree
def PruneTree(self, mctree, hitseries_map): keep = {} for omkey, hitseries in hitseries_map.items(): for hit in hitseries: if hit.hit_source != dataclasses.I3MCHit.SPE: continue parent = mctree.get_particle_from_hit(hit) if parent: primary = mctree.get_primary(parent) keep[(primary.major_id, primary.minor_id)] = primary newtree = dataclasses.I3MCTree() for key, primary in keep.items(): newtree.add_primary(primary) BuildSubTree(newtree, mctree, primary) return newtree
def DAQ(self, frame): azi = self.rs.uniform(self.azimuthMin, self.azimuthMax) cos_zen_low = math.cos(self.zenithMin / I3Units.radian) cos_zen_high = math.cos(self.zenithMax / I3Units.radian) zen = math.acos(self.rs.uniform(cos_zen_low, cos_zen_high)) r = self.ConstructPerpVector(zen, azi) * math.sqrt( self.rs.uniform(0, self.diskRadius**2)) diskCenter = self.sphereRadius * numpy.array([math.sin(zen) * math.cos(azi),\ math.sin(zen) * math.sin(azi), math.cos(zen)]) pos = diskCenter + r # set the particle's energy energy = self.rs.uniform(self.energyMin, self.energyMax) * I3Units.GeV daughter = dataclasses.I3Particle() daughter.type = self.particleType daughter.energy = energy daughter.pos = dataclasses.I3Position(pos[0], pos[1], pos[2]) daughter.dir = dataclasses.I3Direction(zen, azi) daughter.time = 0. daughter.location_type = dataclasses.I3Particle.LocationType.InIce primary = dataclasses.I3Particle() primary.type = dataclasses.I3Particle.ParticleType.NuMu primary.energy = energy primary.pos = dataclasses.I3Position(pos[0], pos[1], pos[2]) primary.dir = dataclasses.I3Direction(zen, azi) primary.time = 0. primary.location_type = dataclasses.I3Particle.LocationType.Anywhere mctree = dataclasses.I3MCTree() mctree.add_primary(primary) mctree.append_child(primary, daughter) frame["I3MCTree_preMuonProp"] = mctree self.PushFrame(frame)
def CombineSignal(frame, signal_name='SignalI3MCTree', bg_name='BackgroundI3MCTree'): signal_tree = frame[signal_name] combined_tree = dataclasses.I3MCTree(frame[bg_name]) polyplopia.MergeMCTrees(combined_tree, signal_tree, 0) frame["I3MCTree"] = combined_tree signal_mmc = None if 'MMCTrackList' in frame and 'SignalMMCTrackList' in frame: combined_mmc = frame['MMCTrackList'] signal_mmc = frame['SignalMMCTrackList'] polyplopia.MergeMMCInfo(combined_mmc, signal_mmc, 0) del frame['MMCTrackList'] frame['MMCTrackList'] = combined_mmc elif 'SignalMMCTrackList' in frame: signal_mmc = frame['SignalMMCTrackList'] frame['MMCTrackList'] = signal_mmc
def DAQ(self, frame): azi = self.rs.uniform(self.azimuthMin, self.azimuthMax) cos_zen_low = math.cos(self.zenithMin / I3Units.radian) cos_zen_high = math.cos(self.zenithMax / I3Units.radian) zen = math.acos(self.rs.uniform(cos_zen_low, cos_zen_high)) while True: posX = self.rs.uniform(-self.cylinderRadius, self.cylinderRadius) posY = self.rs.uniform(-self.cylinderRadius, self.cylinderRadius) if posX**2 + posY**2 < self.cylinderRadius**2: break posZ = self.rs.uniform(-self.cylinderHeight / 2., self.cylinderHeight / 2.) # set the particle's energy energy = self.rs.uniform(self.energyMin, self.energyMax) * I3Units.GeV daughter = dataclasses.I3Particle() daughter.type = self.particleType daughter.energy = energy daughter.pos = dataclasses.I3Position(posX, posY, posZ) daughter.dir = dataclasses.I3Direction(zen, azi) daughter.time = 0. daughter.location_type = dataclasses.I3Particle.LocationType.InIce primary = dataclasses.I3Particle() primary.type = dataclasses.I3Particle.ParticleType.NuMu primary.energy = energy primary.pos = dataclasses.I3Position(posX, posY, posZ) primary.dir = dataclasses.I3Direction(zen, azi) primary.time = 0. primary.location_type = dataclasses.I3Particle.LocationType.Anywhere mctree = dataclasses.I3MCTree() mctree.add_primary(primary) mctree.append_child(primary, daughter) frame["I3MCTree_preMuonProp"] = mctree self.PushFrame(frame)
def Physics(self, frame): if 'I3MCTreeThin' in frame: icetray.logging.log_fatal( 'File already contains the thinned I3MCTree') mctree = frame.Get('I3MCTree') # get the I3MCTree primary = mctree.primaries[0] # make a thinned mctree which only contains relevant energy depositions thin_mctree = dataclasses.I3MCTree() thin_mctree.add_primary(primary) num_particles = len(mctree) # get number of particles in the mctree if num_particles == 1: # catch the case where there was no interaction and just return outright icetray.logging.log_info("There are no children of the primary") else: # otherwise, loop through the mctree and look for energy depositions for particle in mctree: # skip the primary if particle == primary: continue # don't worry about this particle if it's energy is below the threshold if particle.energy < self._energy_cut: continue # and only add cascades cascades ("energy depositions") to the thin_mctree # includes EPlus, EMinus, Brems, DeltaE, PairProd, NuclInt, Hadrons, PiPlus or PiMinus # see https://docs.icecube.aq/combo/trunk/projects/dataclasses/particle.html is_cascade function if particle.is_cascade: thin_mctree.append_child(primary, particle) frame.Put("I3MCTreeThin", thin_mctree) self.PushFrame(frame)
def DAQ(self, frame): sample = sampleFromMap(self.the_map, self.random_state, ptype=self.particle_type, pos_sigma=self.pos_sigma) primary = dataclasses.I3Particle() daughter = dataclasses.I3Particle() primary.time = sample['time'] * I3Units.ns primary.dir = dataclasses.I3Direction(sample['zenith'], sample['azimuth']) primary.energy = sample['energy'] * I3Units.GeV primary.pos = dataclasses.I3Position(sample['posX'] * I3Units.m, sample['posY'] * I3Units.m, sample['posZ'] * I3Units.m) primary.speed = dataclasses.I3Constants.c primary.location_type = dataclasses.I3Particle.LocationType.Anywhere if self.particle_type == 'numu': primary.type = dataclasses.I3Particle.ParticleType.NuMu daughter.type = dataclasses.I3Particle.ParticleType.MuMinus elif self.particle_type == 'nutau': primary.type = dataclasses.I3Particle.ParticleType.NuTau daughter.type = dataclasses.I3Particle.ParticleType.TauMinus elif self.particle_type == 'nue': primary.type = dataclasses.I3Particle.ParticleType.NuE daughter.type = dataclasses.I3Particle.ParticleType.EMinus else: raise ValueError(('particle_type {} not known or not ' + 'implemented'.format(self.particle_type))) # Load xsec tables # Draw muon energy from xsec base_path = os.path.join('$I3_DATA', 'neutrino-generator', 'cross_section_data', 'csms_differential_v1.0') base_path = os.path.expandvars(base_path) cross_section = sim_services.I3CrossSection( os.path.join(base_path, 'dsdxdy_nu_CC_iso.fits'), os.path.join(base_path, 'sigma_nu_CC_iso.fits')) final_state_record = cross_section.sample_final_state( primary.energy, primary.type, self.random_service) daughter.energy = primary.energy * (1 - final_state_record.y) daughter.time = primary.time daughter.dir = primary.dir daughter.speed = primary.speed daughter.pos = dataclasses.I3Position(primary.pos.x, primary.pos.y, primary.pos.z) daughter.location_type = dataclasses.I3Particle.LocationType.InIce daughter.shape = dataclasses.I3Particle.InfiniteTrack # ################################################ # Add hadrons to the mctree with E_h = E_nu * y # # ################################################ hadrons = dataclasses.I3Particle() hadrons.energy = primary.energy - daughter.energy hadrons.pos = dataclasses.I3Position(primary.pos.x, primary.pos.y, primary.pos.z) hadrons.time = daughter.time hadrons.dir = daughter.dir hadrons.speed = daughter.speed hadrons.type = dataclasses.I3Particle.ParticleType.Hadrons hadrons.location_type = daughter.location_type hadrons.shape = dataclasses.I3Particle.Cascade # Fill primary and daughter particles into a MCTree mctree = dataclasses.I3MCTree() mctree.add_primary(primary) mctree.append_child(primary, daughter) mctree.append_child(primary, hadrons) frame["I3MCTree"] = mctree self.PushFrame(frame) self.events_done += 1 if self.events_done >= self.num_events: self.RequestSuspension()
def DAQ(self, frame): print 'starting physics stuff...' mctree = dataclasses.I3MCTree() ### # Read a line from the file ### line = self.f.readline() ### # If an empty line is returned this means the end of the file is reached # In that case I3Module::RequestSuspension is called to stop the IceTray flow. ### if len(line) == 0: self.RequestSuspension() return # ignore possible lines starting with # while line[0] == '#': line = self.f.readline() ### # First line of an event is event number and number of particles ### eventNumber = int(line.split()[0]) numberParticles = int(line.split()[1]) ### #Hadronic sum, if required ### hadsum = HepEvtParticle() hadsum.idhep = 99 nhadorigin = 0 firsthadind = -1 firstleptonind = -1 ### # The list that will hold all the HepEvtParticles ### particlelist = [] ### # The list that will hold all the primary particles to be saved ### primI3PartList = [] ### # The list of indices to the primary particles ### ind_prims_added = [] ### # Read in numberParticles lines, get HEPEVtPartile and add to the list # If primary particle, add them to the mctree, depending on requested # readout scheme ### for ip in range(numberParticles): firstlepton = False firsthadron = False islepton = False line = self.f.readline() hep = HepEvtParticle() hep.ReadLine(line) # hep.Print() particlelist.append(hep) if hep.isthep == 0: # save the index of the first lepton if (abs(hep.idhep) > 10 and abs(hep.idhep) < 17): islepton = True if firstleptonind < 0: firstleptonind = ip firstlepton = True # save the index of the first non-leptonic particle else: if firsthadind < 0: firsthadind = ip firsthadron = True ### # Add the primaries and save them in a list # This depends on the options for how to attach the final state # particles to the primaries ### addparticle = False # # if everything has to be attached to the lepton, only add this # to primary list if it is the first found lepton if self.attachtolepton: if firstlepton: addparticle = True # # if hadronic particles are to be added, save all leptons # + first hadronic particle elif self.addhadronic: if islepton or firsthadron: addparticle = True # # in other cases just add all the particles else: print 'addparticle=True' addparticle = True if addparticle: ind_prims_added.append(ip) i3part = hep.GetI3Particle() primI3PartList.append(i3part) mctree.add_primary(i3part) ### # Now find all the final state particles ### print 'Now find all the final state particles...' for ind in range(len(particlelist)): heppart = particlelist[ind] # only consider final state particles if heppart.isthep != 1 or heppart.jmohep1 == -1: continue # ignore slow final state particles ptot = heppart.phepx * heppart.phepx ptot += (heppart.phepy * heppart.phepy) ptot += (heppart.phepz * heppart.phepz) ptot = sqrt(ptot) if ptot < self.pthres: continue # find primary mother particle misthep = 1 mind = ind nstep = 0 while misthep != 0: mind = particlelist[mind].jmohep1 try: misthep = particlelist[mind].isthep except IndexError: print "Warning: Index out of particlelist range" break nstep += 1 # just a check when ending up in an infinite loop if nstep > 20: print "Warning: more than 20 steps in finding primary mother particle" break #print "prim mother index ",mind, " with pdg id ", particlelist[mind].idhep if misthep != 0: print "Did not find mother of final state particle, will not be added to the tree!" continue # if the particle doesn't come from a lepton, it is said to be from hadronic # origin and will be added to the hadronic particle (shower) if requested hadronicOrigin = False if (abs(particlelist[mind].idhep)<10 or \ abs(particlelist[mind].idhep)>17): hadronicOrigin = True nhadorigin += 1 if self.addhadronic and hadronicOrigin: # add particle momenta & energy to hadsum hadsum.phepx += heppart.phepx hadsum.phepy += heppart.phepy hadsum.phepz += heppart.phepz hadsum.phepe += heppart.phepe # this will result in the vertex and time set from the last particle hadsum.vhepx = heppart.vhepx hadsum.vhepy = heppart.vhepy hadsum.vhepz = heppart.vhepz hadsum.vhept = heppart.vhept #skip adding the particle to the tree, it will be done after the loop continue # get the index in the list that holds the indices of the primary particles # It will depend on the requested manner of attaching the final state # particles to their parent # # if all particle have to be attached to the lepton, the index will be of # the first lepton in the primary particle list # the case where hadronic particle are summed does not reach this step # the one remaining case just keeps the previous found value for mind if self.attachtolepton: if firstleptonind < 0: print "Requested to add all particles to the primary lepton " \ "but did not found one! Particle will be attached to " \ "the original primary" else: mind = firstleptonind # find the index in the primary i3particle list of the mother particle prind = -1 try: prind = ind_prims_added.index(mind) except ValueError: print "Primary with index ", mind, " not found in primary particle list" continue fsI3Part = heppart.GetI3Particle() mctree.append_child(primI3PartList[prind], fsI3Part) # Add sum of hadronic particle if requested, and if particles where added if self.addhadronic and nhadorigin > 0: hadsum.phepm = hadsum.phepe**2 hadsum.phepm -= hadsum.phepx**2 hadsum.phepm -= hadsum.phepy**2 hadsum.phepm -= hadsum.phepz**2 if hadsum.phepm < 0: hadsum.phepm = 0 hadsum.phepm = sqrt(hadsum.phepm) hadsum.phepe = sqrt(hadsum.phepx**2 + hadsum.phepy**2 + hadsum.phepz**2) fsI3parthadsum = hadsum.GetI3Particle() mind = -1 if self.attachtolepton: if firstleptonind < 0: print "Requested to add summed hadronic particles to the primary "\ "lepton but did not found one! Particle will be attached " \ "to the first hadronic primary" else: mind = firstleptonind if mind < 0: if firsthadind < 0: print "Did not find first hadronic primary!" else: mind = firsthadind # find the index in the primary i3particle list of the mother particle prind = -1 try: prind = ind_prims_added.index(mind) except ValueError: if mind < 0: print " Did not find primary particle " else: print "Primary with index ",mind," not found in primary " \ "particle list" print "Summed hadronic system will not be added to the MC tree" if prind >= 0: mctree.append_child(primI3PartList[prind], fsI3parthadsum) #sim_services.I3GeoShifter.ShiftTree(frame,mctree) frame['I3MCTree'] = mctree # #add event id to the eventheader # #(AttributeError: *** The dynamism of this class has been disabled # #*** Attribute (EventID) does not exist in class I3EventHeader) # evthdr = frame.Get('I3EventHeader') # evthdr.EventID=eventNumber self.PushFrame(frame)
def DAQ(self, frame): """Inject casacdes into I3MCtree. Parameters ---------- frame : icetray.I3Frame.DAQ An I3 q-frame. Raises ------ ValueError If interaction type is unknown. """ # -------------- # sample cascade # -------------- # vertex if 'vertex' in self.constant_vars: vertex = self.vertex else: vertex = self._sample_vertex() if 'time' in self.constant_vars: vertex_time = self.vertex_time else: vertex_time = \ self.random_service.uniform(*self.time_range)*I3Units.ns # direction if 'azimuth' in self.constant_vars: azimuth = self.azimuth else: azimuth = \ self.random_service.uniform(*self.azimuth_range)*I3Units.deg if 'zenith' in self.constant_vars: zenith = self.zenith else: if self.sample_in_cos: zenith = np.rad2deg( np.arccos( self.random_service.uniform(*self.cos_zenith_range))) else: zenith = self.random_service.uniform(*self.zenith_range) zenith = zenith * I3Units.deg # energy if 'primary_energy' in self.constant_vars: log_primary_energy = self.log_primary_energy else: log_primary_energy = self.random_service.uniform( *self.log_primary_energy_range) * I3Units.GeV primary_energy = 10**log_primary_energy if 'fractional_energy_in_hadrons' in self.constant_vars: fraction = self.fraction else: fraction = self.random_service.uniform( *self.fractional_energy_in_hadrons_range) hadron_energy = primary_energy * fraction daughter_energy = primary_energy - hadron_energy # flavor and interaction if 'flavor' in self.constant_vars: flavor = self.flavor else: flavor = \ self.flavors[self.random_service.integer(self.num_flavors)] if 'interaction_type' in self.constant_vars: interaction_type = self.interaction_type else: interaction_type = self.interaction_types[ self.random_service.integer(self.num_interaction_types)] # create pseduo I3MCWeightDict mc_dict = {} if interaction_type == 'cc': # Charged Current Interaction: 1 mc_dict['InteractionType'] = 1 else: # Neutral Current Interaction: 2 mc_dict['InteractionType'] = 2 frame['I3MCWeightDict'] = dataclasses.I3MapStringDouble(mc_dict) # create particle primary = dataclasses.I3Particle() daughter = dataclasses.I3Particle() primary.time = vertex_time * I3Units.ns primary.dir = dataclasses.I3Direction(zenith, azimuth) primary.energy = primary_energy * I3Units.GeV primary.pos = vertex primary.speed = dataclasses.I3Constants.c # Assume the vertex position in range is in ice, so the primary is the # in ice neutrino that interacts primary.location_type = dataclasses.I3Particle.LocationType.InIce daughter.location_type = dataclasses.I3Particle.LocationType.InIce daughter.time = primary.time daughter.dir = primary.dir daughter.speed = primary.speed daughter.pos = primary.pos daughter.energy = daughter_energy * I3Units.GeV if interaction_type == 'cc' and flavor == 'numu': daughter.shape = dataclasses.I3Particle.InfiniteTrack else: daughter.shape = dataclasses.I3Particle.Cascade if flavor == 'numu': primary.type = dataclasses.I3Particle.ParticleType.NuMu if interaction_type == 'cc': daughter.type = dataclasses.I3Particle.ParticleType.MuMinus elif interaction_type == 'nc': daughter.type = dataclasses.I3Particle.ParticleType.NuMu elif flavor == 'nutau': primary.type = dataclasses.I3Particle.ParticleType.NuTau if interaction_type == 'cc': daughter.type = dataclasses.I3Particle.ParticleType.TauMinus elif interaction_type == 'nc': daughter.type = dataclasses.I3Particle.ParticleType.NuTau elif flavor == 'nue': primary.type = dataclasses.I3Particle.ParticleType.NuE if interaction_type == 'cc': daughter.type = dataclasses.I3Particle.ParticleType.EMinus elif interaction_type == 'nc': daughter.type = dataclasses.I3Particle.ParticleType.NuE else: raise ValueError(('particle_type {!r} not known or not ' + 'implemented'.format(self.particle_type))) # add hadrons hadrons = dataclasses.I3Particle() hadrons.energy = hadron_energy * I3Units.GeV hadrons.pos = daughter.pos hadrons.time = daughter.time hadrons.dir = daughter.dir hadrons.speed = daughter.speed hadrons.type = dataclasses.I3Particle.ParticleType.Hadrons hadrons.location_type = daughter.location_type hadrons.shape = dataclasses.I3Particle.Cascade # oversampling for i in range(self.oversampling_factor): if i > 0: # create a new frame frame = icetray.I3Frame(frame) del frame['I3MCTree_preMuonProp'] del frame['oversampling'] # Fill primary and daughter particles into a MCTree primary_copy = dataclasses.I3Particle(primary) mctree = dataclasses.I3MCTree() mctree.add_primary(primary_copy) mctree.append_child(primary_copy, dataclasses.I3Particle(daughter)) mctree.append_child(primary_copy, dataclasses.I3Particle(hadrons)) frame['I3MCTree_preMuonProp'] = mctree if self.oversampling_factor > 1: frame['oversampling'] = dataclasses.I3MapStringInt({ 'event_num_in_run': self.events_done, 'oversampling_num': i, }) self.PushFrame(frame) self.events_done += 1 if self.events_done >= self.num_events: self.RequestSuspension()
def stash(frame): frame['RemadeMCTree'] = dataclasses.I3MCTree(frame['I3MCTree'])
def testTypes(self): #try to access all keys of the params WimpParams = self.frame[self.WimpParamsName] self.assert_( isinstance(WimpParams, simclasses.I3WimpParams) and WimpParams != simclasses.I3WimpParams(), "WimpParams exists and not the default constructor") self.assert_( isinstance(WimpParams.mass, float) and WimpParams.mass != 0., "WimpParams.mass exists and is set") self.assert_( isinstance(WimpParams.channel, simclasses.I3WimpParams.DecayChannel) and WimpParams.channel != simclasses.I3WimpParams.DecayChannel.unknown, "WimpParams.channel exists and is set") self.assert_( isinstance(WimpParams.source, simclasses.I3WimpParams.SourceType) and WimpParams.source != simclasses.I3WimpParams.SourceType.UNKNOWN, "WimpParams.time exists and is set") self.assert_( isinstance(WimpParams.nu_weight, float) and WimpParams.nu_weight != 0., "WimpParams.nu_weight exists and is set") self.assert_( isinstance(WimpParams.lep_weight, float) and WimpParams.lep_weight != 0., "WimpParams.lep_weight exists and is set") self.assert_( isinstance(WimpParams.had_weight, float) and WimpParams.had_weight != 0., "WimpParams.had_weight exists and is set") self.assert_( isinstance(WimpParams.vgen, float) and WimpParams.vgen != 0., "WimpParams.vgen exists and is set") self.assert_(isinstance(WimpParams.time, dataclasses.I3Time), "WimpParams.time exists") #try to access all the particles in the mctree WimpMCTree = self.frame[self.WimpMCTreeName] self.assert_( isinstance(WimpMCTree, dataclasses.I3MCTree) and WimpMCTree != dataclasses.I3MCTree(), "WimpMCTree exists and is not the default constructor") #try to access all set parameters in the I3EventHeader EventHeader = self.frame[self.EventHeaderName] self.assert_( isinstance(EventHeader, dataclasses.I3EventHeader) and EventHeader != dataclasses.I3EventHeader(), "EventHeader exists and is not the default constructor") #try to access all set parameters in the I3EventHeader #test values self.assert_(WimpParams.mass == 1000, "The wimpMass is correctly 1000") self.assert_(WimpParams.channel == 5, "WIMPs have corectly annihilated trough the 5(w) channel" ) #simclasses.I3WimpParams.w self.assert_(WimpParams.source == simclasses.I3WimpParams.EARTH, "it is the EARTH") #test the values: MCTree self.assert_( len(WimpMCTree.primaries) == 1, "found exactly one primary") self.assert_( len(WimpMCTree.get_daughters(WimpMCTree.primaries[0])) == 2, "found my two daughter particles and they are asserted") #test the values EentHeader: self.assert_(EventHeader.start_time != dataclasses.I3Time(), "EventHeader.start_time is set") self.assert_(EventHeader.run_id == 0, "EventHeader.run_id is correctly set") self.assert_(EventHeader.event_id == self.count_up, "EventHeader.event_id is correctly set") self.count_up += 1
def I3SimpleProtonDecayGenerator(frame, posZRange=(-327.*I3Units.m,-502.*I3Units.m), radius=50.*I3Units.m, randomService=None, centerX=0.*I3Units.m, centerY=0.*I3Units.m): if randomService is None: raise RuntimeError("No random number generator!") massProton = 938.271996*I3Units.MeV massPi0 = 134.9766*I3Units.MeV massPositron = 0.510998910*I3Units.MeV # 2-body decay in proton rest-frame from 4-momentum conservation (TODO: check) ETotPi0 = (massProton**2. + massPi0**2. - massPositron**2.)/(2.*massProton) ETotPositron = (massProton**2. + massPositron**2. - massPi0**2.)/(2.*massProton) EKinPi0 = ETotPi0-massPi0 EKinPositron = ETotPositron-massPositron posZ = randomService.uniform(posZRange[0], posZRange[1]) while True: posX = randomService.uniform(-radius, radius) posY = randomService.uniform(-radius, radius) posR = math.sqrt(posX**2. + posY**2.) if posR <= radius: break dirZenith = math.acos(randomService.uniform(-1.,1.)) dirAzimuth = randomService.uniform(0., 2.*math.pi) #posZ = (posZRange[0]+posZRange[1])/2. #posX = 0. #posY = 0. #dirZenith = 90.*I3Units.deg posX += centerX posY += centerY # remove existing I3MCTree if "I3MCTree" in frame: del frame["I3MCTree"] mcTree = dataclasses.I3MCTree() # clsim interprets I3Particle.Get/SetEnergy() as the kinetic energy primaryProton = dataclasses.I3Particle() primaryProton.location_type = dataclasses.I3Particle.LocationType.Anywhere # not InIce! primaryProton.shape = dataclasses.I3Particle.ParticleShape.Primary primaryProton.type = dataclasses.I3Particle.ParticleType.PPlus primaryProton.speed = 0. primaryProton.energy = 0.*I3Units.GeV primaryProton.time = 10.*I3Units.ns primaryProton.pos = dataclasses.I3Position(posX, posY, posZ) primaryProton.dir = dataclasses.I3Direction(dirZenith, dirAzimuth) mcTree.add_primary(primaryProton) childPiZero = dataclasses.I3Particle() childPiZero.location_type = dataclasses.I3Particle.LocationType.InIce childPiZero.shape = dataclasses.I3Particle.ParticleShape.Cascade childPiZero.type = dataclasses.I3Particle.ParticleType.Pi0 childPiZero.energy = EKinPi0 # kinetic energy childPiZero.time = primaryProton.time childPiZero.pos = dataclasses.I3Position(posX, posY, posZ) childPiZero.dir = primaryProton.dir mcTree.append_child(primaryProton, childPiZero) childPositron = dataclasses.I3Particle() childPositron.location_type = dataclasses.I3Particle.LocationType.InIce childPositron.shape = dataclasses.I3Particle.ParticleShape.Cascade childPositron.type = dataclasses.I3Particle.ParticleType.EPlus #childPositron.type = dataclasses.I3Particle.ParticleType.MuPlus childPositron.energy = EKinPositron # kinetic energy childPositron.time = primaryProton.time childPositron.pos = dataclasses.I3Position(posX, posY, posZ) childPositron.dir = dataclasses.I3Direction(-primaryProton.dir.x, -primaryProton.dir.y, -primaryProton.dir.z) mcTree.append_child(primaryProton, childPositron) frame["I3MCTree"] = mcTree
def generator(frame): frame["tree"] = dataclasses.I3MCTree()