package gen; import mmc.*; import tfa.*; import java.util.Random; import java.util.Vector; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.StringTokenizer; /** * This is the main lepton generator class. */ public class AtmFlux extends PhysicsModel{ public double D=1730; public double length, radius; private double R=400; private double tf[], af[], sF[], tF=0; private double nF=1, mF=0, xn=1; private double tT=1; private double t0=0; private long evt=0; private boolean OSC=true; private boolean GEN=false; private boolean PROP=false; private double R0=EarthModel.R0*1.e3; private int gens, lept=0; private double px, py, pz, th, phi; public double elost, eini, thini; public String Name; public EarthModel eM; private IntFlux iF[]; private NeutrinoTot nT; private Amanda mP, tP; private Integral I; private Random rand; private Vector I3hist; private boolean f2k=true; private double Ecut[], A[], G[], a[], g[]; private String tdir=""; private String dtct=""; private String name[] = {"mu-", "mu+", "nu_mu", "~nu_mu", "nu_e", "~nu_e", "nu_tau", "~nu_tau", "e-", "e+", "tau-", "tau+", "hadr"}; //----------------------------------------------------------------------------------------------------// /** * Class initializer, command-line option parser. Call with "-help" to list all options. */ public long initAtmFlux(String[] args, boolean f2k){ this.f2k=f2k; String param="AtmFlux"; int i; long num=10; double Emu=300; double Enm=100; double Ene=100; double Ent=100; double Amu=1, Anm=1, Ane=1; double Gmu=0, Gnm=0, Gne=0; double ant=0, anm=0, ane=0; double gnt=2, gnm=2, gne=2; double prompt=0; int w=1, f=0, m=-1; double h0=-114.8, z0=2.834, b0=0.024; int sM=0; double Efr=10; double gE=0, gD=0.2; long seed=0; boolean SEED=false; int bnum=0; String pbad=""; boolean pflag; for(i=0; i tau oscillations\n"+ " -nlow=[GeV] lowest neutrino energy\n"+ " -gen use as generator only\n"+ " -prop use as propagator only\n"+ " -seed=[integer] random number generator seed\n"+ "mmc help lines follow:"); new Amanda().setp(args); return -1; } else if(args[i].equals("-gen")){ GEN=true; } else if(args[i].equals("-prop")){ PROP=true; } else if(args[i].equals("-noosc")){ OSC=false; } else if(args[i].startsWith("-Emu=")){ try{ Emu=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Emu=600; } } else if(args[i].startsWith("-Enm=")){ try{ Enm=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Enm=600; } } else if(args[i].startsWith("-Ene=")){ try{ Ene=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Ene=600; } } else if(args[i].startsWith("-Ent=")){ try{ Ent=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Ent=600; } } else if(args[i].startsWith("-Amu=")){ try{ Amu=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Amu=1; } } else if(args[i].startsWith("-Anm=")){ try{ Anm=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Anm=1; } } else if(args[i].startsWith("-Ane=")){ try{ Ane=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Ane=1; } } else if(args[i].startsWith("-Gmu=")){ try{ Gmu=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Gmu=0; } } else if(args[i].startsWith("-Gnm=")){ try{ Gnm=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Gnm=0; } } else if(args[i].startsWith("-Gne=")){ try{ Gne=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Gne=0; } } else if(args[i].startsWith("-ant=")){ try{ ant=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ ant=0; } } else if(args[i].startsWith("-anm=")){ try{ anm=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ anm=0; } } else if(args[i].startsWith("-ane=")){ try{ ane=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ ane=0; } } else if(args[i].startsWith("-gnt=")){ try{ gnt=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ gnt=2; } } else if(args[i].startsWith("-gnm=")){ try{ gnm=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ gnm=2; } } else if(args[i].startsWith("-gne=")){ try{ gne=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ gne=2; } } else if(args[i].startsWith("-prompt=")){ try{ prompt=Double.parseDouble(args[i].substring(8)); }catch(Exception error){ prompt=0; } } else if(args[i].startsWith("-R=")){ try{ R=Double.parseDouble(args[i].substring(3)); }catch(Exception error){ R=10; } } else if(args[i].startsWith("-D=")){ try{ D=Double.parseDouble(args[i].substring(3)); }catch(Exception error){ D=0; } } else if(args[i].startsWith("-N=")){ try{ num=(long)Double.parseDouble(args[i].substring(3)); }catch(Exception error){ num=1; } } else if(args[i].startsWith("-f=")){ try{ f=(int)Double.parseDouble(args[i].substring(3)); }catch(Exception error){ f=0; } } else if(args[i].startsWith("-m=")){ try{ m=(int)Double.parseDouble(args[i].substring(3)); }catch(Exception error){ m=-1; } } else if(args[i].startsWith("-z0=")){ try{ z0=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ z0=0; } } else if(args[i].startsWith("-b0=")){ try{ b0=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ b0=0; } } else if(args[i].startsWith("-h0=")){ try{ h0=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ h0=-114.8; } } else if(args[i].startsWith("-nF=")){ try{ nF=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ nF=1; } } else if(args[i].startsWith("-mF=")){ try{ mF=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ mF=0; } } else if(args[i].startsWith("-sM=")){ try{ sM=(int)Double.parseDouble(args[i].substring(4)); }catch(Exception error){ sM=0; } } else if(args[i].startsWith("-Efr=")){ try{ Efr=Double.parseDouble(args[i].substring(5)); }catch(Exception error){ Efr=10; } } else if(args[i].startsWith("-gE=")){ try{ gE=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ gE=0; } } else if(args[i].startsWith("-gD=")){ try{ gD=Double.parseDouble(args[i].substring(4)); }catch(Exception error){ gD=0.2; } } else if(args[i].startsWith("-nlow=")){ try{ nlow=Double.parseDouble(args[i].substring(6))*1.e3; }catch(Exception error){ nlow=Me; } } else if(args[i].equals("-tau")){ args[i]="-ignore-tau"; } else if(args[i].startsWith("-seed=")){ try{ seed=Long.parseLong(args[i].substring(6)); }catch(Exception error){ seed=0; } SEED=true; } else if(args[i].startsWith("-tdir=")){ tdir=args[i].substring(6)+"/"; } else{ bnum++; pbad+=(bnum>1?",":"")+" \""+args[i]+"\""; pflag=false; } if(pflag) param+=" "+args[i]; } Output.err.println(Output.version); Output.err.println("Running \""+param+"\""); if(bnum>0){ param+=" (not used:"+pbad+")"; pbad=bnum==1?pbad+" is":"s"+pbad+" are"; Output.err.println("Warning: Parameter"+pbad+" not recognized"); } if(Emu1) f=0; if(m<-1 || m>3) m=-1; Output.err.println("Choosing f="+f+" m="+m+" z0="+Output.f(z0)+" km b0="+ Output.f(b0)+" km h0="+Output.f(h0)+" "+(h0>0?"km":"g/cm^2")); Output.err.println("Detector with radius R="+Output.f(R)+" m is at depth="+Output.f(D)+" m"); Output.err.println("Energy thresholds: Emu="+Output.f(Emu)+" GeV, Enm="+Output.f(Enm)+" GeV, Ene="+Output.f(Ene)+" GeV, Ent="+Output.f(Ent)+" GeV"); if(nF<=0) nF=1; if(nF>1) Output.err.println("Use nF>1 to speed up the calculation for energy thresholds << 10 TeV"); else if(nF<1) Output.err.println("Setting nF value to "+Output.f(nF)+" < 1. Your time would probably be much better spent elsewhere"); if(mF<1) mF=0; if(GEN || PROP) mF=0; if(mF>0) Output.err.println("Using re-weighting technique. This is an approximation! Only use mF>>1, e.g. mF=10"); if(sM<0) sM=0; if(PROP) sM=0; if(Efr<1) Efr=10; if(sM>0) Output.err.println("Solar modulation enabled with parameters: sM="+sM+", Efr="+Output.f(Efr)+" GeV"); if(gE<0) gE=0; if(gD<=0) gD=0.2; if(gE>0) Output.err.println("Geomagnetic cutoff enabled with parameters: gE="+Output.f(gE)+ " GeV, gD="+Output.f(gD)+(sM>0?"":", Efr="+Output.f(Efr)+" GeV")); Decay.flag=true; Output.RecDec=true; if(!GEN){ mP = new Amanda(); tP = new Amanda(); mP.dtct=dtct; tP.dtct=dtct; eM = new EarthModel(m<0?0:m, z0, b0, D*1.e-3); nT = new NeutrinoTot(); } rand = new Random(); R0+=z0*1.e3; if(f2k) Output.out.println("V 2000.1.2"); String ename=""; if(!GEN){ mP.setup(args); if(f2k) mP.history(); String argt[] = new String[args.length+1]; for(i=0; i0){ if(nlow!=Me) name+="_l"+Output.f(nlow); if(ebig!=bigEnergy) name+="_b"+Output.f(ebig); } if(sM>0) name+="_s"+sM+"-"+Output.f(Efr); if(gE>0) name+="_g"+Output.f(gE)+"-"+Output.f(gD); if(Output.raw) name+="_raw"; else name+="_ascii"; name+=".data"; boolean flag; do { if(Output.texi) return -1; flag=false; try{ Output.open(name); if(!GEN) eM.interpolate(); if(mF>0){ IntFlux.mF=mF; IntFlux.eM=eM; IntFlux.nT=nT; } if(sM>0){ IntFlux.sM=sM; IntFlux.Efr=Efr; } if(gE>0){ IntFlux.gEcut=gE; IntFlux.gD=gD; } if(!PROP && !(Amu==0 && Anm==0 && Ane==0)){ Output.err.print("Parameterizing intflX ... "); for(i=0; i<6; i++) iF[i].interpolate(Ecut[i]); Output.err.println("done"); interpolate(); Output.err.println("Finished parameterizations"); } Output.close(); }catch (mmcException error){ flag=true; Output.delete(name); } } while(flag); if(!PROP){ for(i=0; i<6; i++){ lept=i; tf[i]=A[i]*getTotFlux(1); af[i]=2*Pi*a[i]*Math.pow(Ecut[i<2?i+6:i], 1-g[i])/(g[i]-1); tF+=tf[i]+af[i]; sF[i]=tF; } for(i=0; i<6; i++) sF[i]/=tF; tT=nF/(tF*2.e4*Pi*R*R); } if(f2k){ Output.out.println("HI "+Output.version+"\nHI "+param); if(!PROP){ Output.out.println("HI Total Flux is "+Output.f(tF)+" cm^-2s^-1 ( "+Output.f(tf[0]+tf[1])+" "+Output.f(tf[2]+tf[3])+" "+ Output.f(tf[4]+tf[5])+" "+Output.f(af[0]+af[1])+" "+Output.f(af[2]+af[3])+" "+Output.f(af[4]+af[5])+" )"); Output.out.println("HI corresponds to the energy cutoffs of Emu="+ Output.f(Ecut[0])+" Enm="+Output.f(Ecut[2])+" Ene="+Output.f(Ecut[4])+" Ent="+Output.f(Ecut[6])+" GeV"); Output.out.println("HI Amu="+Output.f(A[0])+" Anm="+Output.f(A[2])+" Ane="+Output.f(A[4]) +" Gmu="+Output.f(G[0])+" Gnm="+Output.f(G[2])+" Gne="+Output.f(G[4])); Output.out.println("HI ant="+Output.f(a[0])+" anm="+Output.f(a[2])+" ane="+Output.f(a[4]) +" gnt="+Output.f(g[0])+" gnm="+Output.f(g[2])+" gne="+Output.f(g[4])); if(prompt>0) Output.out.println("HI ratio of prompt to pion muons is "+Output.f(prompt)); else if(prompt<0) Output.out.println("HI only prompt muons will be generated: "+Output.f(prompt)); } Output.out.println("HI Detector with radius R="+Output.f(R)+" m is at depth="+Output.f(D)+" m"); Output.out.println("HI Neutrino cross section multiplicative factors are nF="+Output.f(nF)+", mF="+Output.f(mF)); if(sM>0) Output.out.println("HI Solar modulation enabled with parameters: sM="+sM+", Efr="+Output.f(Efr)+" GeV"); if(gE>0) Output.out.println("HI Geomagnetic cutoff enabled with parameters: gE="+Output.f(gE)+ " GeV, gD="+Output.f(gD)+(sM>0?"":", Efr="+Output.f(Efr)+" GeV")); if(!PROP) Output.out.println("HI "+Output.f(num)+" showers correspond to the lifetime of "+Output.f(tT*num)+" seconds"); } if(SEED){ if(f2k) Output.out.println("HI random number generator seed is set at "+seed); rand.setSeed(seed); } return num; } //----------------------------------------------------------------------------------------------------// /** * begins the f2k stream. */ public void beginAtmFlux(){ if(!GEN) if(f2k){ mP.defUSER(); tP.defUSER(); Output.out.println("USER_DEF almc_e Name Eini Elost Theta"); mP.initBufs(); tP.initBufs(); } } //----------------------------------------------------------------------------------------------------// /** * concludes the f2k stream. */ public void endAtmFlux(){ if(GEN) Output.err.println("generated "+evt+" events"); else{ Output.err.println("generated "+evt+" events, "+mP.tracks+" muon tracks, "+tP.tracks+" tau tracks"); Output.err.println("average "+(mP.vertices+tP.vertices)/evt+" vertices, missed volume: "+(mP.missed+tP.missed)); } } //----------------------------------------------------------------------------------------------------// /** * F2k stream lepton generator. */ public static void main(String[] args){ AtmFlux A = new AtmFlux(); A.dtct=".atmflux"; long num=A.initAtmFlux(args, true); if(A.PROP){ A.mmcf2k(); } else if(num>=0){ A.beginAtmFlux(); Output.out.println("TBEGIN ? ? ?"); for(long i=0; i angle at the surface if(st==0){ s1=0; c1=ct; } else{ s1=st*(1-D/R0); c1=Math.sqrt(1-s1*s1); } x/=c1; fx=x*Math.cos(phi)-y*Math.sin(phi); fy=x*Math.sin(phi)+y*Math.cos(phi); if(rand.nextDouble()>0.5){ ct=-ct; th=Pi-th; } sa=st*c1-ct*s1; if(sa>1) sa=1; // angle difference between the two frames ca=ct*c1+st*s1; if(ca>1) ca=1; else if(ca<-1) ca=-1; cp=Math.cos(phi); sp=Math.sin(phi); axx=cp*cp*(ca-1)+1; // transformation matrix computation axy=cp*sp*(ca-1); axz=cp*sa; ayx=axy; ayy=sp*sp*(ca-1)+1; ayz=sp*sa; azx=-axz; azy=-ayz; azz=ca; rx=R0*sa*cp; // shift vector computation ry=R0*sa*sp; rz=R0*(ca-1)+D; // z is additionally shifted by depth x=axx*fx+axy*fy+rx; // coordinates on the tangent plane in the detector frame y=ayx*fx+ayy*fy+ry; z=azx*fx+azy*fy+rz; cp=Math.cos(phi); sp=Math.sin(phi); px=st*cp; // direction in the CORSIKA frame py=st*sp; pz=ct; b=x*px+y*py+(z+R0-D)*pz; c=x*x+y*y+(z+R0-D)*(z+R0-D)-R0*R0; r=b-Math.sqrt(b*b-c); // shift along (px,py,pz) to reach the surface from the tangent plane x-=px*r; // final coordinates in the detector frame y-=py*r; z-=pz*r; t=r/(C*1.e-11); th*=180/Pi; phi*=180/Pi; t0+=-Math.log(rand.nextDouble())*tT; tt=t0-(x*px+y*py+z*pz)/(C*1.e-2); tts=Math.floor(tt*1000)/1000; ttn=(tt-tts)*1.e9; if(f2k) Output.out.println("EM "+evt+" 1 1970 0 "+Output.f(tts)+" "+Output.f(ttn)); Name=name[lept]; eini=E; thini=th; if(GEN) putOut(lept, 0, x, y, z, t, -1, E, null); else{ eM.sett(-px, -py, -pz); if(mF>0 && (lept>=2 && lept<=5)){ xn=eM.X(eM.ti, eM.tf)*mF; boolean nu=(lept==2 || lept==4); double tI=(lept==5)?nT.dSdy(E):0; tI+=nT.dSdy(E, true, nu); tI+=nT.dSdy(E, false, nu); xn*=tI; if(xn>1) xn=1; } else xn=1; gens=0; elost=0; prop(lept, 0, E, x, y, z, t, eM.ti); } if(f2k){ if(!GEN){ mP.outUSER(); tP.outUSER(); Output.out.println("US almc_e "+Name+" "+Output.f(eini)+" "+ Output.f(elost)+" "+Output.f(thini)); } Output.out.println("EE"); } } //----------------------------------------------------------------------------------------------------// /** * general-purpose lepton propagator. */ public Particle[] propagate(Particle p){ if(f2k) return null; Particle[] I3p; I3hist.clear(); propagate(p.name, p.igen, p.gens, p.x*1.e-2, p.y*1.e-2, p.z*1.e-2, 180-p.theta, p.phi<180?p.phi+180:p.phi-180, p.r*1.e-2, p.e*1.e-3, p.t*1.e9); I3p = new Particle[I3hist.size()]; for(int i=0; igens) gens=igen; prnt=st.nextToken(); try{ ipar=Integer.parseInt(prnt); if(ipar>gens) gens=ipar; }catch(NumberFormatException error){ ipar=-1; } } else if("EE".equals(taux) || "END".equals(taux)){ mP.iniUSER(); tP.iniUSER(); for(i=0; ieM.tf){ putOut(lept, igen, x, y, z, t, 0, E, null); return; } if(lept>=2 && lept<=7) while(true){ if(EXt) nf=eM.tf; else{ nf=eM.t(); if(Math.abs(nf-eM.tf)<=Math.abs(eM.tf-eM.ti)*computerPrecision) nf=eM.tf; // computer precision control } l=(nf-ni)*1.e3; putOut(lept, igen, x, y, z, t, l, E, null); igen=gens; if(nf==eM.tf) break; x-=px*l; y-=py*l; z-=pz*l; t+=l/(C*1.e-11); if(OSC) if(!el) if(rand.nextDouble()1) aP.rho[aP.medianum-1]=eM.intRho(nf)/aP.srho[aP.medianum-1]; p=aP.propagate(pi); if(f2k) aP.recUSER(); elost+=aP.elost; putOut(lept, igen, x, y, z, t, pi.r*1.e-2, E, pi); igen=gens; for(int i=0; i=2 && lept<=7) if(insDet(xi, yi, zi)) elost-=ei; } else lptOut(p[i]); } } else{ putOut(lept, igen, x, y, z, t, 0, E, null); if(insDet(x, y, z)) elost+=E; } } //----------------------------------------------------------------------------------------------------// /** * Calculates if the coordinates are inside the detector */ boolean insDet(double x, double y, double z){ switch(mP.gdet){ case 1: return Math.abs(x)0?" "+igen+" ":" ? ")+name[lept]+" "+Output.f(x)+" "+Output.f(y)+" "+Output.f(z) +" "+Output.f(th)+" "+Output.f(phi)+" "+(l>=0?Output.f(l):"?")+" "+Output.f(E)+" "+Output.f(t)); else I3hist.add(new Particle(igen, gens, name[lept], x*1.e2, y*1.e2, z*1.e2, 180-th, phi<180?phi+180:phi-180, E*1.e3, t*1.e-9, l*1.e2, p)); } //----------------------------------------------------------------------------------------------------// /** * Copies the lepton into the output stream. */ private void lptOut(Particle p){ gens++; if(f2k) Output.out.println("TR "+p.gens+" "+p.igen+" "+p.name+" "+ Output.f(p.x*1.e-2)+" "+Output.f(p.y*1.e-2)+" "+Output.f(p.z*1.e-2)+" "+ Output.f(180-p.theta)+" "+Output.f(p.phi<180?p.phi+180:p.phi-180)+" "+ Output.f(p.r*1.e-2)+" "+Output.f(p.e*1.e-3)+" "+Output.f(p.t*1.e9)); else I3hist.add(p); } //----------------------------------------------------------------------------------------------------// private double getTotFlux(double x){ return getTotFlux(x, -1); } //----------------------------------------------------------------------------------------------------// private double getTotFlux(double x, double rnd){ if(rnd<0){ if(jt) return J[lept].interpolate(x); return I.integrateOpened(0, x, this); } else{ if(jt) return Math.min(Math.max(J[lept].findLimit(rnd*J[lept].interpolate(x)), 0), x); I.integrateOpened(0, x, this, rnd); return I.getUpperLimit(); } } //----------------------------------------------------------------------------------------------------// /** * Function for flux integration over zenith angles - interface to Integral. */ public double function(double x){ return 2*Pi*iF[lept].getIntFlux(Ecut[lept], x); } //----------------------------------------------------------------------------------------------------// /** * Parametrizes the integral of this class. */ public void interpolate(){ int g=4; // do not change these settings jt=false; Output.err.print("Parameterizing totflX ... "); J = new Interpolate[6]; for(int i=0; i<6; i++){ lept=i; J[i] = new Interpolate(num3, 0, 1, this, g, true, false, false, g, false, false, true); } jt=true; Output.err.println("done"); } //----------------------------------------------------------------------------------------------------// public Interpolate J[]; public boolean jt=false; /** * 1d parametrization - interface to Interpolate */ public double functionInt(double x){ return getTotFlux(x); } }