def TabulatePhotonsFromSource(tray, name, PhotonSource="cascade", Zenith=0. * I3Units.degree, Azimuth=0. * I3Units.degree, ZCoordinate=0. * I3Units.m, Energy=1. * I3Units.GeV, FlasherWidth=127, FlasherBrightness=127, Seed=12345, NEvents=100, IceModel='spice_mie', DisableTilt=False, Filename="", TabulateImpactAngle=False, PhotonPrescale=1, Axes=None, Directions=None, Sensor='DOM', RecordErrors=False): """ Tabulate the distribution of photoelectron yields on IceCube DOMs from various light sources. The light profiles of the sources are computed from the same parameterizations used in PPC, but like in the direct propagation mode can be computed using GEANT4 instead. The mode of tabulation is controlled primarily by the **PhotonSource** parameter. - *'cascade'* will simulate an electromagnetic cascade of **Energy** GeV at (0, 0, **ZCoordinate**), oriented according to **Zenith** and **Azimuth**. The default coordinate system is spherical and centered the given vertex, with 200 quadratically spaced bins in radius, 36 linear bins in azimuthal angle (only from 0 to 180 degrees by default), 100 linear bins in the cosine of the polar angle, and 105 quadratic bins in time residual w.r.t the direct path from (0, 0, **ZCoordinate**). - *'flasher'* will simulate a 405 nm LED flasher pulse with the given **FlasherWidth** and **FlasherBrightness** settings. The source position and coordinate system are the same as for the 'cascade' case. - *'infinite-muon'* will simulate a "bare" muon of infinite length. The coordinate system is cylindrical and centered on the axis of the muon. Since the muon's position is degenerate with time, the usual parallel distance is replaced by the z coordinate of the closest approach to the detection position, and the starting positions of the simulated muons are sampled randomly (**ZCoordinate** is ignored). There are 100 quadratic bins in perpendicular distance to the source axis, 36 linear bins in azimuthal angle (0 to :math:`\pi` radians), 100 linear bins in z coordinate of closest approach, and 105 quadratic bins in time residual w.r.t. the earliest possible Cherenkov photon. :param PhotonSource: the type of photon source ('cascade', 'flasher', or 'infinite-muon'). :param Zenith: the orientation of the source :param ZCoordinate: the depth of the source :param Energy: the energy of the source (only for cascade tables) :param FlasherWidth: the width of the flasher pulse (only for flasher tables) :param FlasherBrightness: the brightness of the flasher pulse (only for flasher tables) :param Seed: the seed for the random number service :param NEvents: the number of events to simulate :param RecordErrors: record the squares of weights as well (useful for error bars) :param IceModel: the path to an ice model in $I3_SRC/clsim/resources/ice. Likely values include: 'spice_mie' ppc-style SPICE-Mie parametrization 'photonics_spice_1/Ice_table.spice.i3coords.cos080.10feb2010.txt' Photonics-style SPICE1 table 'photonics_wham/Ice_table.wham.i3coords.cos094.11jul2011.txt' Photonics-style WHAM! table :param DisableTilt: if true, disable tilt in ice model :param Filename: the name of the FITS file to write :param TabulateImpactAngle: if True, tabulate the impact position of the photon on the DOM instead of weighting by the DOM's angular acceptance :param Axes: a subclass of :cpp:class:`clsim::tabulator::Axes` that defines the coordinate system. If None, an appropriate default will be chosen based on **PhotonSource**. :param Directions: a set of directions to allow table generation for multiple sources. If None, only one direction given by **Zenith** and **Azimuth** is used. """ # check sanity of args PhotonSource = PhotonSource.lower() if PhotonSource not in ['cascade', 'flasher', 'infinite-muon']: raise ValueError( "photon source %s is unknown. Please specify either 'cascade', 'flasher', or 'infinite-muon'" % PhotonSource) from icecube import icetray, dataclasses, dataio, phys_services, sim_services, clsim from os.path import expandvars # a random number generator randomService = phys_services.I3GSLRandomService(Seed) tray.AddModule("I3InfiniteSource", name + "streams", Stream=icetray.I3Frame.DAQ) tray.AddModule("I3MCEventHeaderGenerator", name + "gen_header", Year=2009, DAQTime=158100000000000000, RunNumber=1, EventID=1, IncrementEventID=True) if Directions is None: Directions = numpy.asarray([(Zenith, Azimuth)]) if PhotonSource in ('cascade', 'flasher', 'muon-segment'): if PhotonSource == 'muon-segment': ptype = I3Particle.ParticleType.MuMinus else: ptype = I3Particle.ParticleType.EMinus def reference_source(zenith, azimuth, scale): source = I3Particle() source.type = ptype source.energy = Energy * scale source.pos = I3Position(0., 0., ZCoordinate) source.dir = I3Direction(zenith, azimuth) source.time = 0. if PhotonSource == 'muon-segment': source.length = 3. else: source.length = 0. source.location_type = I3Particle.LocationType.InIce return source elif PhotonSource == 'infinite-muon': from icecube import MuonGun # pad depth to ensure that the track appears effectively infinite surface = MuonGun.Cylinder(1800, 800) # account for zenith-dependent distribution of track lengths length_scale = surface.area(dataclasses.I3Direction( 0, 0)) / surface.area(dataclasses.I3Direction(Zenith, 0)) ptype = I3Particle.ParticleType.MuMinus def reference_source(zenith, azimuth, scale): source = I3Particle() source.type = ptype source.energy = Energy * scale source.dir = I3Direction(zenith, azimuth) source.pos = surface.sample_impact_position( source.dir, randomService) crossings = surface.intersection(source.pos, source.dir) source.length = crossings.second - crossings.first source.time = 0. source.location_type = I3Particle.LocationType.InIce return source import copy class MakeParticle(icetray.I3Module): def __init__(self, ctx): super(MakeParticle, self).__init__(ctx) self.AddOutBox("OutBox") self.AddParameter("SourceFunction", "", lambda: None) self.AddParameter("NEvents", "", 100) def Configure(self): self.reference_source = self.GetParameter("SourceFunction") self.nevents = self.GetParameter("NEvents") self.emittedEvents = 0 def DAQ(self, frame): if PhotonSource != "flasher": primary = I3Particle() mctree = I3MCTree() mctree.add_primary(primary) for zenith, azimuth in Directions: source = self.reference_source(zenith, azimuth, 1. / len(Directions)) mctree.append_child(primary, source) frame["I3MCTree"] = mctree # use the emitting particle as a geometrical reference frame["ReferenceParticle"] = source else: pulseseries = I3CLSimFlasherPulseSeries() for zenith, azimuth in Directions: pulse = makeFlasherPulse(0, 0, ZCoordinate, zenith, azimuth, FlasherWidth, FlasherBrightness, 1. / len(Directions)) pulseseries.append(pulse) frame["I3FlasherPulseSeriesMap"] = pulseseries frame["ReferenceParticle"] = self.reference_source( Zenith, Azimuth, 1.) self.PushFrame(frame) self.emittedEvents += 1 if self.emittedEvents >= self.nevents: self.RequestSuspension() tray.AddModule(MakeParticle, SourceFunction=reference_source, NEvents=NEvents) if PhotonSource == "flasher": flasherpulse = "I3FlasherPulseSeriesMap" mctree = None else: flasherpulse = None mctree = "I3MCTree" header = dict(FITSTable.empty_header) header['zenith'] = Zenith / I3Units.degree header['azimuth'] = Azimuth / I3Units.degree header['z'] = ZCoordinate header['energy'] = Energy header['type'] = int(ptype) header['efficiency'] = Efficiency.RECEIVER | Efficiency.WAVELENGTH if PhotonSource == 'infinite-muon': header['n_events'] = length_scale * NEvents / float(PhotonPrescale) if Axes is None: if PhotonSource != "infinite-muon": dims = [ clsim.tabulator.PowerAxis(0, 580, 200, 2), clsim.tabulator.LinearAxis(0, 180, 36), clsim.tabulator.LinearAxis(-1, 1, 100), clsim.tabulator.PowerAxis(0, 7e3, 105, 2), ] geo = clsim.tabulator.SphericalAxes else: dims = [ clsim.tabulator.PowerAxis(0, 580, 100, 2), clsim.tabulator.LinearAxis(0, numpy.pi, 36), clsim.tabulator.LinearAxis(-8e2, 8e2, 80), clsim.tabulator.PowerAxis(0, 7e3, 105, 2), ] geo = clsim.tabulator.CylindricalAxes # Add a dimension for the impact angle if TabulateImpactAngle: dims.append(clsim.tabulator.LinearAxis(-1, 1, 20)) Axes = geo(dims) if PhotonSource == "flasher": header['flasherwidth'] = FlasherWidth header['flasherbrightness'] = FlasherBrightness # some constants DOMRadius = 0.16510 * icetray.I3Units.m # 13" diameter referenceArea = dataclasses.I3Constants.pi * DOMRadius**2 # NB: GetIceCubeDOMAcceptance() calculates the quantum efficiency by # dividing the geometric area (a circle of radius domRadius) by the # tabulated effective area. Scaling that radius by *sqrt(prescale)* # _reduces_ the effective quantum efficiency by a factor *prescale*. # Since we draw photons directly from the QE-weighted Cherenkov # spectrum, this causes *prescale* fewer photons to be progagated per # light source. We compensate by dividing the number of events by # *prescale* in the header above. # to be propagated per light source. domAcceptance = clsim.GetIceCubeDOMAcceptance( domRadius=math.sqrt(PhotonPrescale) * DOMRadius) if Sensor.lower() == 'dom': angularAcceptance = clsim.GetIceCubeDOMAngularSensitivity(holeIce=True) elif Sensor.lower() == 'degg': referenceArea = dataclasses.I3Constants.pi * (300. * I3Units.mm / 2)**2 angularAcceptance = Gen2Sensors.GetDEggAngularSensitivity(pmt='both') domAcceptance = Gen2Sensors.GetDEggAcceptance(active_fraction=1. / PhotonPrescale) elif Sensor.lower() == 'wom': # outer diameter of the pressure vessel is 11.4 cm, walls are 9 mm thick referenceArea = (11 - 2 * 0.9) * 90 * icetray.I3Units.cm2 angularAcceptance = Gen2Sensors.GetWOMAngularSensitivity() domAcceptance = Gen2Sensors.GetWOMAcceptance(active_fraction=1. / PhotonPrescale) else: raise ValueError("Don't know how to simulate %ds yet" % (sensor)) tray.AddSegment( I3CLSimTabulatePhotons, name + "makeCLSimPhotons", MCTreeName= mctree, # if source is a cascade this will point to the I3MCTree FlasherPulseSeriesName= flasherpulse, # if source is a flasher this will point to the I3CLSimFlasherPulseSeries MMCTrackListName=None, # do NOT use MMC ParallelEvents= 1, # only work at one event at a time (it'll take long enough) RandomService=randomService, # UnWeightedPhotons=True, UseGPUs= False, # table-making is not a workload particularly suited to GPUs UseCPUs=True, # it should work fine on CPUs, though Area=referenceArea, WavelengthAcceptance=domAcceptance, AngularAcceptance=angularAcceptance, DoNotParallelize=True, # no multithreading UseGeant4=False, OverrideApproximateNumberOfWorkItems= 1, # if you *would* use multi-threading, this would be the maximum number of jobs to run in parallel (OpenCL is free to split them) ExtraArgumentsToI3CLSimModule=dict(Filename=Filename, TableHeader=header, Axes=Axes, PhotonsPerBunch=200, EntriesPerPhoton=5000, RecordErrors=RecordErrors), MediumProperties=parseIceModel( expandvars("$I3_SRC/clsim/resources/ice/" + IceModel), disableTilt=DisableTilt), )
'$I3_TESTDATA/GCD/GeoCalibDetectorStatus_IC86.55697_corrected_V2.i3.gz' )) parser.add_argument("outfile", help="save plot to file") args = parser.parse_args() from icecube import icetray, dataclasses, dataio from icecube import phys_services, simclasses, MuonGun from I3Tray import I3Tray from os.path import expandvars tray = I3Tray() tray.context['I3RandomService'] = phys_services.I3GSLRandomService(1337) from icecube.MuonGun.segments import GenerateBundles outer = MuonGun.Cylinder(1600, 800) inner = MuonGun.Cylinder(300, 150, dataclasses.I3Position(0, 0, -350)) spectrum = MuonGun.OffsetPowerLaw(5, 1e3, 1e1, 1e4) model = MuonGun.load_model('GaisserH4a_atmod12_SIBYLL') generator = MuonGun.EnergyDependentSurfaceInjector( outer, model.flux, spectrum, model.radius, MuonGun.ConstantSurfaceScalingFunction(inner)) tray.AddSegment( GenerateBundles, 'BundleGen', NEvents=1000, Generator=generator, GCDFile=expandvars( '$I3_TESTDATA/GCD/GeoCalibDetectorStatus_IC86.55697_corrected_V2.i3.gz' ))
""" from argparse import ArgumentParser from os.path import expandvars parser = ArgumentParser() parser.add_argument("outfile", help="save plot to file") args = parser.parse_args() import matplotlib matplotlib.use('agg') import pylab, numpy from icecube import dataclasses, MuonGun surface = MuonGun.Cylinder(1600, 800) area = numpy.pi**2 * surface.radius * (surface.radius + surface.length) # 1 file of E^-2.6 5-component 3e4-1e9 GeV (3:2:1:1:1) soft = 4e5 * MuonGun.corsika_genprob('CascadeOptimized5Comp') # 1 file of E^-2 5-component 6e2-1e11 GeV (10:5:3:2:1) hard = 2.5e6 * MuonGun.corsika_genprob('Standard5Comp') # In order to compare to "unweighted" CORSIKA, turn the Hoerandel flux # into a probability (since we happen to know the integral) areanorm = 0.131475115 * area # 1 file of natural-spectrum ("unweighted") CORSIKA unweighted = (2.5e7 / areanorm) * MuonGun.corsika_genprob('Hoerandel5') model = MuonGun.load_model('GaisserH4a_atmod12_SIBYLL') model.flux.min_multiplicity = 1 model.flux.max_multiplicity = 1
def GenerateAtmosphericNeutrinos(tray, name, Files, GCDFile="", AutoExtendMuonVolume=False, EnergyBiasPower=1, FlavorBias=[30, 1, 1], CylinderRadius=600 * I3Units.m, CylinderHeight=1200 * I3Units.m, CrossSections='csms', NEvents=-1, MakeNeutrino=True): r""" Read CORSIKA showers containing neutrinos, and force exactly one neutrino to interact. NB: this segment is deprecated. Use GenerateAirShowers, SelectNeutrino, and PropagateMuons instead. :param Files: a list of CORSIKA files to read :param GCDFile: I3 file with GCD information to read in before the CORSIKA files :param AutoExtendMuonVolume: allow :math:`\nu_{\mu}` to interact far before they reach the detector :param EnergyBiasPower: select a neutrino from the bundle with probability proportional to E^power :param FlavorBias: scale selection probability for :math:`\nu_{e}/\nu_{\mu}/\nu_{\tau}` by these factors. The default value is appropriate for equal sampling of conventional atmospheric :math:`\nu_{e}/\nu_{\mu}`. :param CylinderRadius: radius of upright-cylinder target volume :param CylinderHeight: full height of simulation volume :param CrossSections: cross-section tables to use ('cteq5', 'css', or 'csms') """ import warnings warnings.warn( 'GenerateAtmosphericNeutrinos is deprecated. Use GenerateAirShowers, SelectNeutrino, and PropagateMuons instead' ) from operator import add from icecube import neutrino_generator, sim_services, MuonGun from icecube.sim_services.propagation import get_propagators icetray.load('corsika-reader', False) random = tray.context['I3RandomService'] surface = MuonGun.Cylinder(CylinderHeight, CylinderRadius) tray.Add('I3CORSIKAReader', 'reader', filenamelist=Files, NEvents=NEvents, CylinderHeight=surface.length, CylinderRadius=surface.radius, Prefix=GCDFile) # Drop showers where no particles reach the observation level tray.Add(lambda frame: len(frame['I3MCTree']) > 1, Streams=[icetray.I3Frame.DAQ]) # Remove low-energy muons that can't reach the detector tray.Add('I3InIceCORSIKATrimmer') tray.Add(SelectNeutrino, AutoExtendMuonVolume=AutoExtendMuonVolume, EnergyBiasPower=EnergyBiasPower, FlavorBias=FlavorBias, CylinderRadius=CylinderRadius, CylinderHeight=CylinderHeight, CrossSections=CrossSections) base_propagators = get_propagators() propagators = tray.context['I3ParticleTypePropagatorServiceMap'] for k in base_propagators.keys(): propagators[k] = base_propagators[k] tray.Add('Rename', Keys=['I3MCTree', 'I3MCTree_preMuonProp']) tray.Add('I3PropagatorModule', PropagatorServices=propagators, InputMCTreeName="I3MCTree_preMuonProp", OutputMCTreeName="I3MCTree", RandomService='I3RandomService')
#!/usr/bin/env python """ Use muon flux weights to calculate an effective livetime for combined CORSIKA samples as a function of energy. """ import pylab, numpy from icecube import MuonGun, icetray, dataclasses from icecube.icetray import I3Units outer = MuonGun.Cylinder(1600, 800) #inner = MuonGun.Cylinder(1600, 800) inner = MuonGun.Cylinder(500, 150, dataclasses.I3Position(46.3, -34.9, -300)) #inner = MuonGun.Cylinder(700, 125, dataclasses.I3Position(29.3,52.6,-150)) #inner = outer #Most tested spectrum #spectrum = MuonGun.OffsetPowerLaw(5.0, 7e2, 0, 1e5) spectrum = MuonGun.OffsetPowerLaw(5.0, 7e2, 500, 1e5) #Limited spectrum range #spectrum = MuonGun.OffsetPowerLaw(5.2, 7e2, 150, 1e4) #spectrum = MuonGun.OffsetPowerLaw(2, 1*I3Units.TeV, 1*I3Units.TeV, 1*I3Units.PeV) #Good spectrum producing ~1 day with 10k evts above 200 GeV #spectrum = MuonGun.OffsetPowerLaw(5.2, 7e2, 200, 1e6) #Jackob's spectrum #spectrum = MuonGun.OffsetPowerLaw(5.0, 5e2, 200, 1e6) #Good spectrum producing ~1 day with 5000 evts above 400 GeV #spectrum = MuonGun.OffsetPowerLaw(5.25, 1000, 1, 1e6) model = MuonGun.load_model( '/home/mamday/icesim/build/MuonGun/resources/tables/GaisserH4a_atmod12_SIBYLL' )
def main(cfg, run_number, scratch): with open(cfg, 'r') as stream: cfg = yaml.load(stream, Loader=yaml.Loader) cfg['run_number'] = run_number cfg['run_folder'] = get_run_folder(run_number) infile = cfg['infile_pattern'].format(**cfg) infile = infile.replace(' ', '0') if scratch: outfile = cfg['scratchfile_pattern'].format(**cfg) else: outfile = cfg['outfile_pattern'].format(**cfg) outfile = outfile.replace(' ', '0') tray = I3Tray() """The main script""" tray.AddModule('I3Reader', 'i3 reader', FilenameList=[cfg['gcd'], infile]) detectorsurface = MuonGun.Cylinder( length=1600.*icetray.I3Units.m, radius=800.*icetray.I3Units.m, center=dataclasses.I3Position(0.*icetray.I3Units.m, 0.*icetray.I3Units.m, 0.*icetray.I3Units.m,)) # filter secondaries that are not in detector volume tray.AddModule(MuonRemoveChildren, 'MuonRemoveChildren', Detector=detectorsurface, Output='I3MCTree') #-------------------------------------------------- # Add MC Labels mirco trained his DNN on #-------------------------------------------------- add_cascade_labels = False if add_cascade_labels: tray.AddModule(modules.MCLabelsCascades, 'MCLabelsCascade', PulseMapString='InIcePulses', PrimaryKey='MCPrimary1', OutputKey='LabelsDeepLearning') else: tray.AddModule(modules.MCLabelsDeepLearning, 'MCLabelsDeepLearning', PulseMapString='InIcePulses', PrimaryKey='MCPrimary1', MCPESeriesMapName=cfg['mcpe_series_map'], OutputKey='LabelsDeepLearning', IsMuonGun=True) tray.AddModule("I3Writer", "EventWriter", filename=outfile, Streams=[icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.TrayInfo, icetray.I3Frame.Simulation], DropOrphanStreams=[icetray.I3Frame.DAQ]) tray.Execute() del tray
def PolyplopiaSegment( tray, name, mctype='CORSIKA', RandomService=None, mctree_name="I3MCTree_preMuonProp", separate_coincident_mctree_name="", # leave empty to combine bgfile=None, timewindow=40. * I3Units.microsecond, rate=float('nan'), If=lambda f: True): """ There are three scenarios for polyplopia: 1. bgfile: We are reading background MC from a separate file and injecting events to signal (or weighted background) based on a Poisson distribution within the given time window. 2. we are generating MuonGun bundles and injecting events to signal (or weighted background) based on a Poisson distribution within the given time window. """ from icecube import polyplopia, MuonGun #tray.AddModule("ParticleMapper","mapprimary") if bgfile: # merge bg into signal background = polyplopia.CoincidentI3ReaderService(bgfile) else: # Use MuonGun # Default: use Hoerandel as a template for generating muons. model = MuonGun.load_model("Hoerandel5_atmod12_SIBYLL") #model = MuonGun.load_model('GaisserH4a_atmod12_SIBYLL') # Generate bundles (even if not 100 percent accurate). model.flux.max_multiplicity = 100 gamma_index = 2.6 energy_offset = 700. energy_min = 1e4 energy_max = 1e7 cylinder_length = 1600. cylinder_radius = 800. cylinder_x = 0. cylinder_y = 0. cylinder_z = 0. # Default: cylinder aligned with z-axis at detector center as injection # surface. outsurface_center = dataclasses.I3Position(cylinder_x * I3Units.m, cylinder_y * I3Units.m, cylinder_z * I3Units.m) outsurface = MuonGun.Cylinder(length=cylinder_length * I3Units.m, radius=cylinder_radius * I3Units.m, center=outsurface_center) generator = MuonGun.NaturalRateInjector(outsurface, model.flux, model.energy) background = polyplopia.MuonGunBackgroundService() background.set_generator(generator) background.set_rng(RandomService) background.set_rate(rate) background.set_mctree_name(mctree_name) tray.AddModule("PoissonMerger", "merge", CoincidentEventService=background, PrimaryType=mctype, MCTreeName=mctree_name, Rate=rate, SeparateMCTree=separate_coincident_mctree_name, TimeWindow=timewindow) return tray
def SelectNeutrino( tray, name, Propagators=None, AutoExtendMuonVolume=False, EnergyBiasPower=1, FlavorBias=[30, 1, 1], CylinderRadius=600 * I3Units.m, CylinderHeight=1200 * I3Units.m, CrossSections='csms', ): """ Select a neutrino to interact, and add neutrino propagators to the context. :param AutoExtendMuonVolume: allow :math:`\nu_{\mu}` to interact far before they reach the detector :param EnergyBiasPower: select a neutrino from the bundle with probability proportional to E^power :param FlavorBias: scale selection probability for :math:`\nu_{e}/\nu_{\mu}/\nu_{\tau}` by these factors. The default value is appropriate for equal sampling of conventional atmospheric :math:`\nu_{e}/\nu_{\mu}`. :param CylinderRadius: radius of upright-cylinder target volume :param CylinderHeight: full height of simulation volume :param CrossSections: cross-section tables to use ('cteq5', 'css', or 'csms') """ from operator import add from icecube import neutrino_generator, sim_services, MuonGun # Set up NeutrinoGenerator internals random = tray.context['I3RandomService'] surface = MuonGun.Cylinder(CylinderHeight, CylinderRadius) config = neutrino_generator.Steering() config.detection_surface = surface config.do_muon_range_extension = AutoExtendMuonVolume interactions = neutrino_generator.I3NuGInteractionInfo( random, config, CrossSections) interactions.initialize() # I3NuGSourceSelector needs this in its context tray.context['NuGSteer'] = config # Remove all but one neutrino tray.Add('I3NuGSourceSelector', EnergyBiasPowerIndex=EnergyBiasPower, ParticleBiases=reduce(add, [[b] * 2 for b in FlavorBias]), KeepDarkNeutrinos=False) # Store propagators in the context if not 'I3ParticleTypePropagatorServiceMap' in tray.context: tray.context[ 'I3ParticleTypePropagatorServiceMap'] = sim_services.I3ParticleTypePropagatorServiceMap( ) Propagators = tray.context['I3ParticleTypePropagatorServiceMap'] # Use NeutrinoPropagator for neutrinos prop = neutrino_generator.I3NeutrinoPropagator(random, config, interactions) # ensure that all nu_e and nu_mu reach the detector prop.prop_mode = neutrino_generator.PropagationMode.ncgrweighted tau_prop = neutrino_generator.I3NeutrinoPropagator(random, config, interactions) # un-weighted propagation for nu_tau to allow for tau regeneration tau_prop.prop_mode = neutrino_generator.PropagationMode.nopropweight for flavor in 'E', 'Mu', 'Tau': for ptype in '', 'Bar': Propagators[getattr(dataclasses.I3Particle.ParticleType, 'Nu' + flavor + ptype)] = tau_prop if flavor == 'Tau' else prop
def GenerateNeutrinos( tray, name, RandomService=None, NumEvents=100, SimMode='Full', VTXGenMode='NuGen', # currently only NuGen is supported InjectionMode='Surface', CylinderParams=[ 0, 0, 0, 0, 0 ], # CIRCLE[radius, active_height_before, active_height_after] SURFACE[radius, length, center_x, center_y, center_z] AutoExtendMuonVolume=True, Flavor="NuMu", GammaIndex=2.0, FromEnergy=1. * I3Units.TeV, ToEnergy=10. * I3Units.PeV, ZenithRange=[0, 180 * I3Units.degree], AzimuthRange=[0, 360 * I3Units.degree], CrossSections='csms', CrossSectionsPath=None, ParamsMap=dict()): from I3Tray import I3Units from icecube import icetray, dataclasses, dataio, phys_services, sim_services from icecube import neutrino_generator, MuonGun earthModelService = name + "_earthmodel" steering = name + "_steering" injector = name + "_injector" interactions = name + "_interactions" #----------------------------- # make ParamMap's key lowercase and # check multiple definitions. #----------------------------- params = dict() for key in ParamsMap: keylower = key.lower() if keylower in params: raise Exception('param %s is set twice!' % (keylower)) params[keylower] = ParamsMap[key] #----------------------------- # configure earthmodel service #----------------------------- earthModelServiceArgs = dict() if "earthmodels" in params: if not isinstance(params["earthmodels"], (list, tuple)): raise Exception('EarthModels must be a list of strings') earthModelServiceArgs['EarthModels'] = params["earthmodels"] if "materialmodels" in params: if not isinstance(params["materialmodels"], (list, tuple)): raise Exception('MaterialModels must be a list of strings') earthModelServiceArgs['MaterialModels'] = params["materialmodels"] if "earthparamspath" in params: if not isinstance(params["earthparamspath"], (str, unicode)): raise Exception('EarthParamsPath must be a strings') earthModelServiceArgs['PathToDataFileDir'] = params["earthparamspath"] if "icecaptype" in params: if not isinstance(params["icecaptype"], (str, unicode)): raise Exception('IceCapType must be a strings') earthModelServiceArgs['IceCapType'] = params["icecaptype"] if "icecapsimpleangle" in params: if not isinstance(params["icecapsimpleangle"], float): raise Exception('IceCapType must be a float') earthModelServiceArgs['IceCapSimpleAngle'] = params[ "icecapsimpleangle"] if "detectordepth" in params: if not isinstance(params["detectordepth"], float): raise Exception('DetectorDepth must be a float') earthModelServiceArgs['DetectorDepth'] = params["detectordepth"] tray.AddService("I3EarthModelServiceFactory", earthModelService, **earthModelServiceArgs) #----------------------------- # configure steering factory #----------------------------- # this is default cylinder. If you want to change cylinder size # and cylinder center, set positive value to CylinderParams. surface = MuonGun.Cylinder(1900 * I3Units.m, 950 * I3Units.m) steeringServiceArgs = dict() steeringServiceArgs['NEvents'] = NumEvents steeringServiceArgs['SimMode'] = SimMode steeringServiceArgs['VTXGenMode'] = VTXGenMode steeringServiceArgs['InjectionMode'] = InjectionMode steeringServiceArgs['DetectionSurface'] = surface steeringServiceArgs['CylinderParams'] = CylinderParams steeringServiceArgs['DoMuonRangeExtension'] = AutoExtendMuonVolume if "globalxsecscalefactor" in params: if not isinstance(params["globalxsecscalefactor"], (list, tuple)): raise Exception('GlobalXsecScaleFactor must be a list of float') steeringServiceArgs['GlobalXsecScaleFactor'] = params[ "globalxsecscalefactor"] tray.AddService("I3NuGSteeringFactory", steering, EarthModelName=earthModelService, **steeringServiceArgs) #----------------------------- # configure injector #----------------------------- EnergyLogRange = [ math.log10(FromEnergy / I3Units.GeV), math.log10(ToEnergy / I3Units.GeV) ] injectorServiceArgs = dict() injectorServiceArgs['NuFlavor'] = Flavor injectorServiceArgs['GammaIndex'] = GammaIndex injectorServiceArgs['ZenithMin'] = ZenithRange[0] injectorServiceArgs['ZenithMax'] = ZenithRange[1] injectorServiceArgs['AzimuthMin'] = AzimuthRange[0] injectorServiceArgs['AzimuthMax'] = AzimuthRange[1] injectorServiceArgs['EnergyMinLog'] = EnergyLogRange[0] injectorServiceArgs['EnergyMaxLog'] = EnergyLogRange[1] if "zenithweightparam" in params: if not isinstance(params["zenithweightparam"], float): raise Exception('ZenithWeightParam must be a float') injectorServiceArgs['ZenithWeightParam'] = params["zenithweightparam"] tray.AddService("I3NuGInjectorFactory", injector, SteeringName=steering, **injectorServiceArgs) #----------------------------- # configure interaction service #----------------------------- interactionServiceArgs = dict() if CrossSectionsPath is not None: interactionServiceArgs['TablesDir'] = CrossSectionsPath interactionServiceArgs['CrossSectionModel'] = CrossSections tray.AddService("I3NuGInteractionInfoFactory", interactions, SteeringName=steering, **interactionServiceArgs) #----------------------------- # configure neutrino generator #----------------------------- nugenArgs = dict() nugenArgs['MCTreeName'] = 'I3MCTree_preMuonProp' if "primarynuname" in params: if not isinstance(params["primarynuname"], (str, unicode)): raise Exception('PrimaryNuName must be a strings') nugenArgs['PrimaryNuName'] = params["primarynuname"] if "interactionweight" in params: if not isinstance(params["interactionweight"], (list, tuple)): raise Exception('InteractionWeight must be a list of float') nugenArgs['InteractionCCFactor'] = params["interactionweight"][0] nugenArgs['InteractionNCFactor'] = params["interactionweight"][1] nugenArgs['InteractionGRFactor'] = params["interactionweight"][2] if "propagationweightmode" in params: if not isinstance(params["propagationweightmode"], (str, unicode)): raise Exception('PropagationWeightMode must be a string') propmode = neutrino_generator.to_propagation_mode( params["propagationweightmode"]) nugenArgs['PropagationWeightMode'] = propmode tray.AddModule("I3NeutrinoGenerator", name + "_neutrino", SteeringName=steering, InjectorName=injector, InteractionInfoName=interactions, **nugenArgs)
def main(cfg, run_number, scratch): with open(cfg, 'r') as stream: if int(yaml.__version__[0]) < 5: # backwards compatibility for yaml versions before version 5 cfg = yaml.load(stream) else: cfg = yaml.full_load(stream) cfg['run_number'] = run_number cfg['run_folder'] = get_run_folder(run_number) tray = I3Tray() random_services, _ = create_random_services( dataset_number=cfg['dataset_number'], run_number=cfg['run_number'], seed=cfg['seed'], n_services=2) random_service, random_service_prop = random_services tray.context['I3RandomService'] = random_service model = MuonGun.load_model(cfg['muongun_model']) model.flux.min_multiplicity = cfg['muongun_min_multiplicity'] model.flux.max_multiplicity = cfg['muongun_max_multiplicity'] spectrum = MuonGun.OffsetPowerLaw(cfg['gamma'], cfg['e_min'] * icetray.I3Units.GeV, cfg['e_min'] * icetray.I3Units.GeV, cfg['e_max'] * icetray.I3Units.GeV) surface = MuonGun.Cylinder(1600, 800, dataclasses.I3Position(31.25, 19.64, 0)) if cfg['muongun_generator'] == 'energy': scale = MuonGun.BasicSurfaceScalingFunction() scale.SetSideScaling(4., 17266, 3.41, 1.74) scale.SetCapScaling(4., 23710, 3.40, 1.88) generator = MuonGun.EnergyDependentSurfaceInjector( surface, model.flux, spectrum, model.radius, scale) elif cfg['muongun_generator'] == 'static': generator = MuonGun.StaticSurfaceInjector(surface, model.flux, spectrum, model.radius) elif cfg['muongun_generator'] == 'floodlight': generator = MuonGun.Floodlight( surface=surface, energyGenerator=spectrum, cosMin=cfg['muongun_floodlight_min_cos'], cosMax=cfg['muongun_floodlight_max_cos'], ) else: err_msg = 'MuonGun generator {} is not known.' err_msg += " Must be 'energy','static' or 'floodlight" raise ValueError(err_msg.format(cfg['muongun_generator'])) tray.Add(MuonGun.segments.GenerateBundles, 'MuonGenerator', Generator=generator, NEvents=cfg['n_events_per_run'], GCDFile=cfg['gcd']) tray.Add("Rename", keys=["I3MCTree", "I3MCTree_preMuonProp"]) tray.AddSegment(segments.PropagateMuons, "PropagateMuons", RandomService=random_service_prop, **cfg['muon_propagation_config']) if scratch: outfile = cfg['scratchfile_pattern'].format(**cfg) else: outfile = cfg['outfile_pattern'].format(**cfg) outfile = outfile.replace(' ', '0') if cfg['distance_splits'] is not None: click.echo('SplittingDistance: {}'.format(cfg['distance_splits'])) distance_splits = np.atleast_1d(cfg['distance_splits']) dom_limits = np.atleast_1d(cfg['threshold_doms']) if len(dom_limits) == 1: dom_limits = np.ones_like(distance_splits) * cfg['threshold_doms'] oversize_factors = np.atleast_1d(cfg['oversize_factors']) order = np.argsort(distance_splits) distance_splits = distance_splits[order] dom_limits = dom_limits[order] oversize_factors = oversize_factors[order] stream_objects = generate_stream_object(distance_splits, dom_limits, oversize_factors) tray.AddModule(OversizeSplitterNSplits, "OversizeSplitterNSplits", thresholds=distance_splits, thresholds_doms=dom_limits, oversize_factors=oversize_factors) for stream_i in stream_objects: outfile_i = stream_i.transform_filepath(outfile) tray.AddModule("I3Writer", "writer_{}".format(stream_i.stream_name), Filename=outfile_i, Streams=[ icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.Stream('S'), icetray.I3Frame.Stream('M') ], If=stream_i) click.echo('Output ({}): {}'.format(stream_i.stream_name, outfile_i)) else: click.echo('Output: {}'.format(outfile)) tray.AddModule("I3Writer", "writer", Filename=outfile, Streams=[ icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.Stream('S'), icetray.I3Frame.Stream('M') ]) click.echo('Scratch: {}'.format(scratch)) tray.AddModule("TrashCan", "the can") tray.Execute() tray.Finish()
def main(cfg, run_number, scratch): with open(cfg, 'r') as stream: cfg = yaml.load(stream) cfg['run_number'] = run_number cfg['run_folder'] = get_run_folder(run_number) tray = I3Tray() random_service, random_service_prop, _ = create_random_services( dataset_number=cfg['dataset_number'], run_number=cfg['run_number'], seed=cfg['seed']) tray.context['I3RandomService'] = random_service model = MuonGun.load_model(cfg['muongun_model']) model.flux.min_multiplicity = cfg['muongun_min_multiplicity'] model.flux.max_multiplicity = cfg['muongun_max_multiplicity'] spectrum = MuonGun.OffsetPowerLaw( cfg['gamma'], cfg['e_min']*icetray.I3Units.TeV, cfg['e_min']*icetray.I3Units.TeV, cfg['e_max']*icetray.I3Units.TeV) surface = MuonGun.Cylinder(1600, 800, dataclasses.I3Position(31.25, 19.64, 0)) if cfg['muongun_generator'] == 'energy': scale = MuonGun.BasicSurfaceScalingFunction() scale.SetSideScaling(4., 17266, 3.41, 1.74) scale.SetCapScaling(4., 23710, 3.40, 1.88) generator = MuonGun.EnergyDependentSurfaceInjector(surface, model.flux, spectrum, model.radius, scale) elif cfg['muongun_generator'] == 'static': generator = MuonGun.StaticSurfaceInjector(surface, model.flux, spectrum, model.radius) elif cfg['muongun_generator'] =='floodlight': generator = MuonGun.Floodlight(surface = surface, energyGenerator=spectrum, cosMin=cfg['muongun_floodlight_min_cos'], cosMax=cfg['muongun_floodlight_max_cos'], ) else: err_msg = 'MuonGun generator {} is not known.' err_msg += " Must be 'energy','static' or 'floodlight" raise ValueError(err_msg.format(cfg['muongun_generator'])) tray.Add(MuonGun.segments.GenerateBundles, 'MuonGenerator', Generator=generator, NEvents=cfg['n_events_per_run'], GCDFile=cfg['gcd']) tray.Add("Rename", keys=["I3MCTree", "I3MCTree_preMuonProp"]) tray.AddSegment( segments.PropagateMuons, "PropagateMuons", RandomService=random_service_prop) if scratch: outfile = cfg['scratchfile_pattern'].format(**cfg) else: outfile = cfg['outfile_pattern'].format(**cfg) outfile = outfile.replace(' ', '0') outfile = outfile.replace('.bz2', '') tray.AddModule("I3Writer", "writer", Filename=outfile, Streams=[icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.Stream('S'), icetray.I3Frame.Stream('M')]) tray.AddModule("TrashCan", "the can") tray.Execute() tray.Finish()
def main(cfg, run_number, scratch): with open(cfg, 'r') as stream: cfg = yaml.load(stream, Loader=yaml.Loader) cfg['run_number'] = run_number cfg['run_folder'] = get_run_folder(run_number) if scratch: outfile = cfg['scratchfile_pattern'].format(**cfg) else: outfile = cfg['outfile_pattern'].format(**cfg) outfile = outfile.replace(' ', '0') if cfg['distance_splits'] is not None: click.echo('SplittingDistances: {}'.format(cfg['distance_splits'])) click.echo('Oversizefactors: {}'.format(cfg['oversize_factors'])) click.echo('NEvents: {}'.format(cfg['n_events_per_run'])) click.echo('EMin: {}'.format(cfg['e_min'])) click.echo('EMax: {}'.format(cfg['e_max'])) click.echo('EBreak: {}'.format(cfg['muongun_e_break'])) click.echo('Gamma: {}'.format(cfg['gamma'])) click.echo('ZenithMin: {}'.format(cfg['zenith_min'])) click.echo('ZenithMax: {}'.format(cfg['zenith_max'])) # create convex hull if 'use_convex_hull' in cfg and cfg['use_convex_hull']: # hardcode icecube corner points # ToDo: read from geometry file points = [ [-570.90002441, -125.13999939, 501], # string 31 [-256.14001465, -521.08001709, 501], # string 1 [361., -422.82998657, 501], # string 6 [576.36999512, 170.91999817, 501], # string 50 [338.44000244, 463.72000122, 501], # string 74 [101.04000092, 412.79000854, 501], # string 72 [22.11000061, 509.5, 501], # string 78 [-347.88000488, 451.51998901, 501], # string 75 [-570.90002441, -125.13999939, -502], # string 31 [-256.14001465, -521.08001709, -502], # string 1 [361., -422.82998657, -502], # string 6 [576.36999512, 170.91999817, -502], # string 50 [338.44000244, 463.72000122, -502], # string 74 [101.04000092, 412.79000854, -502], # string 72 [22.11000061, 509.5, -502], # string 78 [-347.88000488, 451.51998901, -502], # string 75 ] convex_hull = ConvexHull(points) else: convex_hull = None if 'extend_past_hull' not in cfg: cfg['extend_past_hull'] = 0.0 random_services, _ = create_random_services( dataset_number=cfg['dataset_number'], run_number=cfg['run_number'], seed=cfg['seed'], n_services=2) random_service, random_service_prop = random_services # create muon muon = create_muon( azimuth_range=[cfg['azimuth_min'], cfg['azimuth_max']], zenith_range=[cfg['zenith_min'], cfg['zenith_max']], energy_range=[cfg['e_min'], cfg['e_max']], anchor_time_range=cfg['anchor_time_range'], anchor_x_range=cfg['anchor_x_range'], anchor_y_range=cfg['anchor_y_range'], anchor_z_range=cfg['anchor_z_range'], length_to_go_back=cfg['length_to_go_back'], convex_hull=convex_hull, extend_past_hull=cfg['extend_past_hull'], random_service=random_services[0], ) tray = I3Tray() tray.context['I3RandomService'] = random_service tray.AddModule("I3InfiniteSource", "TheSource", Prefix=cfg['gcd'], Stream=icetray.I3Frame.DAQ) if cfg['MuonGenerator'] == 'MuonGunSinglemuons': tray.AddSegment(segments.GenerateSingleMuons, "GenerateCosmicRayMuons", NumEvents=cfg['n_events_per_run'], FromEnergy=cfg['e_min'] * icetray.I3Units.GeV, ToEnergy=cfg['e_max'] * icetray.I3Units.GeV, BreakEnergy=cfg['muongun_e_break'] * icetray.I3Units.GeV, GammaIndex=cfg['gamma'], ZenithRange=[ cfg['zenith_min'] * icetray.I3Units.deg, cfg['zenith_max'] * icetray.I3Units.deg ]) elif cfg['MuonGenerator'] == 'MuonGunGeneral': model = MuonGun.load_model(cfg['muongun_model']) model.flux.min_multiplicity = cfg['muongun_min_multiplicity'] model.flux.max_multiplicity = cfg['muongun_max_multiplicity'] spectrum = MuonGun.OffsetPowerLaw(cfg['gamma'], cfg['e_min'] * icetray.I3Units.GeV, cfg['e_min'] * icetray.I3Units.GeV, cfg['e_max'] * icetray.I3Units.GeV) surface = MuonGun.Cylinder(1600, 800, dataclasses.I3Position(31.25, 19.64, 0)) if cfg['muongun_generator'] == 'energy': scale = MuonGun.BasicSurfaceScalingFunction() scale.SetSideScaling(4., 17266, 3.41, 1.74) scale.SetCapScaling(4., 23710, 3.40, 1.88) generator = MuonGun.EnergyDependentSurfaceInjector( surface, model.flux, spectrum, model.radius, scale) elif cfg['muongun_generator'] == 'static': generator = MuonGun.StaticSurfaceInjector(surface, model.flux, spectrum, model.radius) elif cfg['muongun_generator'] == 'floodlight': generator = MuonGun.Floodlight( surface=surface, energyGenerator=spectrum, cosMin=cfg['muongun_floodlight_min_cos'], cosMax=cfg['muongun_floodlight_max_cos'], ) else: err_msg = 'MuonGun generator {} is not known.' err_msg += " Must be 'energy','static' or 'floodlight" raise ValueError(err_msg.format(cfg['muongun_generator'])) tray.Add(MuonGun.segments.GenerateBundles, 'MuonGenerator', Generator=generator, NEvents=cfg['n_events_per_run'], GCDFile=cfg['gcd']) tray.Add("Rename", keys=["I3MCTree", "I3MCTree_preMuonProp"]) elif cfg['MuonGenerator'] == 'MuonResimulation': tray.AddModule(ParticleMultiplier, 'make_particles', num_events=cfg['n_events_per_run'], primary=muon) else: err_msg = 'MuonGenerator {} is not known.' err_msg += " Must be 'MuonGunSinglemuons','MuonGunGeneral' or 'MuonResimulation" raise ValueError(err_msg.format(cfg['MuonGenerator'])) # -------------------------------------- # Propagate Muons # -------------------------------------- tray.AddSegment(segments.PropagateMuons, "PropagateMuons", RandomService=random_service_prop, **cfg['muon_propagation_config']) # -------------------------------------- # Distance Splits # -------------------------------------- if cfg['distance_splits'] is not None: click.echo('SplittingDistance: {}'.format(cfg['distance_splits'])) distance_splits = np.atleast_1d(cfg['distance_splits']) dom_limits = np.atleast_1d(cfg['threshold_doms']) if len(dom_limits) == 1: dom_limits = np.ones_like(distance_splits) * cfg['threshold_doms'] oversize_factors = np.atleast_1d(cfg['oversize_factors']) order = np.argsort(distance_splits) distance_splits = distance_splits[order] dom_limits = dom_limits[order] oversize_factors = oversize_factors[order] stream_objects = generate_stream_object(distance_splits, dom_limits, oversize_factors) tray.AddModule(OversizeSplitterNSplits, "OversizeSplitterNSplits", thresholds=distance_splits, thresholds_doms=dom_limits, oversize_factors=oversize_factors) for stream_i in stream_objects: outfile_i = stream_i.transform_filepath(outfile) tray.AddModule("I3Writer", "writer_{}".format(stream_i.stream_name), Filename=outfile_i, Streams=[ icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.Stream('S'), icetray.I3Frame.Stream('M') ], If=stream_i) click.echo('Output ({}): {}'.format(stream_i.stream_name, outfile_i)) else: click.echo('Output: {}'.format(outfile)) tray.AddModule("I3Writer", "writer", Filename=outfile, Streams=[ icetray.I3Frame.DAQ, icetray.I3Frame.Physics, icetray.I3Frame.Stream('S'), icetray.I3Frame.Stream('M') ]) click.echo('Scratch: {}'.format(scratch)) tray.Execute() del tray