#!/usr/bin/env python from __future__ import print_function """ This example is a complete analysis, computing the effective area from both neutrino and anti-neutrino event files. The output is automatically written to a web-page, which has both plots and tables. """ # This script shows how to use the event weights to compute event rates # for a given flux, and the neutrino effective area. from math import * import ROOT, aa aa.i() ROOT.gStyle.SetOptStat(0) ROOT.gROOT.SetBatch(True) ROOT.gStyle.SetTitleOffset(1.5, "xyz") from util.aautil import table www = aa.WebFile("effective area", "./aeff_webdir" ) copy_cmd = "scp -r aeff_webdir t61@login.nikhef.nl:~/public_html" # change if you're not t61 www.add( """ This is the effective area of one KM3NeT building block (there will be two building blocks, so multiply by 2). This is at "trigger level" (which means that all detected neutrinos contribute, and no cuts are applied to remove backgrounds. (so it's optimistic).

the cos(zenith) is defined such that -1 is a down-going neutrino, while +1 is an upgoing neutrino (through the Earth -- note earth absorption is accounted for and the effect visiable at high E and cos(zenith)=1).

The tables refer to the average affective area ( = (Anu+Anubar)/2 ). This average can be multiiplied with the total (nu+nubar) flux, if the flux consists of an equal amount of nu and nubar.

""" ) def fill_histograms() : "this functions produces histograms of the Aeff from MC input files" dr = "/sps/km3net/repo/mc/atm_neutrino/KM3NeT_-00000001_20171212/v5.1/reco/mcv5.1.genhen_numuCC.sirene.jte.jchain.aashower.NNN.root" infiles_nu = [ dr.replace("NNN",str(i)) for i in range(1,4) ] infiles_anu = [ n.replace("numu","anumu") for n in infiles_nu ] def fillhist( infiles , name = "h"): h = ROOT.TH2D( name, name ,28,1,8,20,-1,1) ngen_tot = 0 for infile in infiles : f = ROOT.EventFile( infile ) ngen_tot += header.ngen() for evt in f : #require at least one reconstructed track if evt.trks.size() == 0 : continue # add other quality cuts / upgoing etc here. nu = evt.mc_trks[0] h.Fill( log10(nu.E), nu.dir.z , evt.w[1]/nu.E ) h.Scale( 1.0/ngen_tot) print (" ngen tot = " , ngen_tot ) return h h_nu = fillhist( infiles_nu, "h_nu" ) h_anu = fillhist( infiles_anu, "h_anu" ) fout = ROOT.TFile("aeff.root","RECREATE" ) h_nu.Write() h_anu.Write() del fout import os, sys if 'gen' in sys.argv or os.path.exists("aeff.root") == False : fill_histograms() def sindecl_vs_coszenith( lattitude = ( 36 + 16 / 60.0 ) * pi / 180 ): # ARCA: 36deg 16 sec "return a histogram of sin(declination) vs cos(zenith)" sindecl_vs_coszenith = ROOT.TH2D("sindecl_vs_coszenith","sindecl_vs_coszenith;cos(theta);sin(decl)", 20, -1,1, 20, -1,1) for idz in range( 1, sindecl_vs_coszenith.GetNbinsX()+1 ) : dz = sindecl_vs_coszenith.GetXaxis().GetBinCenter( idz ) for az in aa.frange( 0, pi, 0.001 ): el = pi/2 - acos( dz ) eq = ROOT.sla.dh2e( az, el , lattitude ) sindecl_vs_coszenith.Fill( dz , sin(eq.DEC) ) # normalize the dz slice -- in a very painful way c =0 for idecl in range ( 1, sindecl_vs_coszenith.GetNbinsY()+1 ) : bin = sindecl_vs_coszenith.GetBin( idz, idecl ) c += sindecl_vs_coszenith.GetBinContent( bin ) for idecl in range ( 1, sindecl_vs_coszenith.GetNbinsY()+1 ) : bin = sindecl_vs_coszenith.GetBin( idz, idecl ) sindecl_vs_coszenith.SetBinContent( bin , sindecl_vs_coszenith.GetBinContent( bin) / c ) return sindecl_vs_coszenith def to_eq( h , name = "decl" , lattitude = ( 36 + 16 / 60.0 ) * pi / 180 ): "turn a histogram with cos(zenith) on the y-axis into one with sin(decl)" r = h.Clone( name ) r.Scale(0) for ix in range( 1, h.GetNbinsX()+1 ) : x = h.GetXaxis().GetBinCenter( ix ) for iy in range( 1, h.GetNbinsY()+1 ) : dz = h.GetYaxis().GetBinCenter( iy ) b = h.GetBin( ix, iy ) N = 1000 for i in range (N): az = 2*pi*i/N el = pi/2 - acos( dz ) eq = ROOT.sla.dh2e( az, -el , lattitude ) cc = h.GetBinContent(b) r.Fill( x, sin( eq.DEC) , cc /N ) return r def scale ( h ): "normalize the effective area histograms" binsize_e = h.GetXaxis().GetBinWidth(1) binsize_ang = h.GetYaxis().GetBinWidth(1) omega = 2*pi *binsize_ang # each bin covers this solid angle # ngen scaling has already been applied. S = 1 / ( log(10) * binsize_e * 3600.0 * 24 * 365 * omega ) h.Scale(S) f = ROOT.TFile("aeff.root") h_nu = f.Get("h_nu") h_anu = f.Get("h_anu") scale(h_nu) scale(h_anu) for h in [h_nu, h_anu] : h.SetXTitle("logE") h.SetYTitle("cos(zenith)") h_nu_decl = to_eq ( h_nu, "h_nu_decl" ) h_anu_decl = to_eq ( h_anu, "h_anu_decl" ) h_nu_decl.SetTitle("h_nu_decl") h_anu_decl.SetTitle("h_anu_decl") h_nu_decl.SetYTitle("sin(decl)") h_anu_decl.SetYTitle("sin(decl)") h_ave = h_nu.Clone("h_ave") h_ave.Add( h_anu ) h_ave_decl = h_nu.Clone("h_ave_decl") h_ave_decl.Add( h_anu_decl ) h_ave.SetTitle("average nu+nubar/2 vs cos(zenith)") h_ave_decl.SetTitle("average nu+nubar/2 vs sin(decl)") if True : from ROOT import gPad, TCanvas c = TCanvas("c","c",800,800) c.Divide(2,3) opt = "lego2" c.cd(1) gPad.SetLogz() h_nu.UseCurrentStyle() h_nu.Draw(opt) c.cd(2) gPad.SetLogz() h_anu.UseCurrentStyle() h_anu.Draw(opt) c.cd(3) gPad.SetLogz() h_nu_decl.UseCurrentStyle() h_nu_decl.Draw(opt) c.cd(4) gPad.SetLogz() h_anu_decl.UseCurrentStyle() h_anu_decl.Draw(opt) c.cd(5) gPad.SetLogz() h_ave.UseCurrentStyle() h_ave.Draw(opt) c.cd(6) gPad.SetLogz() h_ave_decl.UseCurrentStyle() h_ave_decl.Draw(opt) www.add( c) def to_table( h2 ): T = table( ["binnr", h2.GetXaxis().GetTitle()+"-min", h2.GetXaxis().GetTitle()+"-max", h2.GetYaxis().GetTitle()+"-min", h2.GetYaxis().GetTitle()+"-max", "Aeff(m2)"] ) for ix in range( 1, h2.GetNbinsX()+1 ) : for iy in range ( 1, h2.GetNbinsY()+1 ) : b = h2.GetBin( ix, iy ) T.append( [ b, h2.GetXaxis().GetBinLowEdge( ix ), h2.GetXaxis().GetBinUpEdge( ix ), h2.GetYaxis().GetBinLowEdge( iy ), h2.GetYaxis().GetBinUpEdge( iy ), "%.4f" % (h2.GetBinContent(b),) ] ) return T s = to_table( h_ave ).sprint_ascii() www.add( "
"+ s + "
" ) www.add( "
"+ to_table( h_ave_decl ).sprint_ascii() + "
" ) def get_slice ( h , yval1, yval2 ): "return a x-slice of the 2d-histogrma h, for y-values between yval1 and yval2 " bin1 = h.GetYaxis().FindBin( yval1 ) bin2 = h.GetYaxis().FindBin( yval2 ) r = h.ProjectionX( h.GetName()+str(bin1)+str(bin2), bin1, bin2 ) r.Scale( 1.0 / (1+bin2-bin1) ) return r to_table( h_ave ) c2 = TCanvas("c2","c2",800,800) c2.Divide(2,2) c2.cd(1) gPad.SetLogy() h__0 = get_slice( h_ave, -.99, -.8 ) h__0.Draw("l hist") h__1 = get_slice( h_ave, -0.1, 0.1 ) h__1.Draw("l hist") h__2 = get_slice( h_ave, .8, .99 ) h__2.Draw("l hist same") gPad.Update() c2.cd(2) gPad.SetLogy() hd__0 = get_slice( h_ave_decl, -.99, -.8 ) hd__0.Draw("l hist") hd__1 = get_slice( h_ave_decl, -0.1, 0.1 ) hd__1.Draw("l hist") hd__2 = get_slice( h_ave_decl, .8, .99 ) hd__2.Draw("l hist same") gPad.Update() www.add( c2 ) del www if copy_cmd : os.system( copy_cmd ) print ('bye!')