SND@LHC Software
Loading...
Searching...
No Matches
run_digiSND.py
Go to the documentation of this file.
1#!/usr/bin/env python
2import atexit
3firstEvent = 0
4
5def pyExit():
6 "nasty hack"
7 # This is needed to bypass seg violation with exiting cpp digitization
8 # Most likely related to file ownership.
9 os.system('kill '+str(os.getpid()))
10
11import resource
13 # Getting virtual memory size
14 pid = os.getpid()
15 with open(os.path.join("/proc", str(pid), "status")) as f:
16 lines = f.readlines()
17 _vmsize = [l for l in lines if l.startswith("VmSize")][0]
18 vmsize = int(_vmsize.split()[1])
19 #Getting physical memory size
20 pmsize = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
21 print("memory: virtuell = %5.2F MB physical = %5.2F MB"%(vmsize/1.0E3,pmsize/1.0E3))
22
23import ROOT,os,sys
24import shipRoot_conf
25import shipunit as u
26
28
29from argparse import ArgumentParser
30parser = ArgumentParser()
31parser.add_argument("-f", "--inputFile", dest="inputFile", help="single input file", required=True)
32parser.add_argument("-g", "--geoFile", dest="geoFile", help="geofile", required=True)
33parser.add_argument("-n", "--nEvents", dest="nEvents", type=int, help="number of events to process", default=100000)
34parser.add_argument("-ts", "--thresholdScifi", dest="ts", type=float, help="threshold energy for Scifi [p.e.]", default=3.5)
35parser.add_argument("-ss", "--saturationScifi", dest="ss", type=float, help="saturation energy for Scifi [p.e.]", default=104.)
36parser.add_argument("-tML", "--thresholdMufiL", dest="tml", type=float, help="threshold energy for Mufi large [p.e.]", default=0.0)
37parser.add_argument("-tMS", "--thresholdMufiS", dest="tms", type=float, help="threshold energy for Mufi small [p.e.]", default=0.0)
38parser.add_argument("-no-cls", "--noClusterScifi", action='store_true', help="do not make Scifi clusters")
39parser.add_argument("-cpp", "--digiCPP", action='store_true', dest="FairTask_digi", help="perform digitization using DigiTaskSND")
40parser.add_argument("-d", "--Debug", dest="debug", help="debug", default=False)
41parser.add_argument("--copy-emulsion-points", action='store_true', help="Copy emulsion points from input file (potentially large file size!).")
42
43options = parser.parse_args()
44# rephrase the no-cluster flag
45makeClusterScifi = not options.noClusterScifi
46# -----Timer-------------
47timer = ROOT.TStopwatch()
48timer.Start()
49
50# outfile should be in local directory
51tmp = options.inputFile.split('/')
52outFile = tmp[len(tmp)-1].replace('.root','_dig.root')
53if options.inputFile.find('/eos')==0:
54 if options.FairTask_digi:
55 options.inputFile = os.environ['EOSSHIP']+options.inputFile
56 else:
57 os.system('xrdcp '+os.environ['EOSSHIP']+options.inputFile+' '+outFile)
58else:
59 if not options.FairTask_digi:
60 os.system('cp '+options.inputFile+' '+outFile)
61
62# -----Create geometry----------------------------------------------
63import shipLHC_conf as sndDet_conf
64
65if options.geoFile.find('/eos')==0:
66 options.geoFile = os.environ['EOSSHIP']+options.geoFile
67import SndlhcGeo
68snd_geo = SndlhcGeo.GeoInterface(options.geoFile)
69
70# set digitization parameters for MuFilter
71lsOfGlobals = ROOT.gROOT.GetListOfGlobals()
72scifiDet = lsOfGlobals.FindObject('Scifi')
73mufiDet = lsOfGlobals.FindObject('MuFilter')
74scifiDet.SetConfPar("Scifi/nphe_min",options.ts) # threshold
75scifiDet.SetConfPar("Scifi/nphe_max",options.ss) # saturation
76
77
83better_update = False
84if scifiDet.GetConfParF("Scifi/signalSpeed")==0:
85 scifiDet.SetConfPar("Scifi/signalSpeed", 15*u.cm/u.nanosecond)
86 better_update = True
87# geofiles before March 2026 don't have the Veto 3 atten.length
88if mufiDet.GetConfParF("MuFilter/VTAttenuationLength")==0:
89 mufiDet.SetConfPar("MuFilter/VTAttenuationLength",999*u.cm)
90 better_update = True
91# old digi constants from before the MuFi response update
92if mufiDet.GetConfParF("MuFilter/VandUpAttenuationLength")==999*u.cm:
93 better_update = True
94# in very ancient MC productions it is possible some digitization params are missing
95# set them here values updated in March 2026.
96if mufiDet.GetConfParF("MuFilter/DsAttenuationLength")==0 or\
97 mufiDet.GetConfParF("MuFilter/VandUpPropSpeed")==0 :
98 mufiDet.SetConfPar("MuFilter/DsAttenuationLength",230*u.cm)
99 mufiDet.SetConfPar("MuFilter/DsTAttenuationLength",700*u.cm)
100 mufiDet.SetConfPar("MuFilter/VandUpAttenuationLength",210*u.cm)
101 mufiDet.SetConfPar("MuFilter/VTAttenuationLength",999*u.cm)
102 mufiDet.SetConfPar("MuFilter/DsSiPMcalibration",25.*1000.)
103 # 1.65 MeV = 41 qcd over 6 Large SiPMs(one side)
104 mufiDet.SetConfPar("MuFilter/VandUpSiPMcalibrationL",50.*1000.)
105 # no MIP signal for small SiPMs, delayed and compromised response in general
106 mufiDet.SetConfPar("MuFilter/VandUpSiPMcalibrationS",0.)
107 mufiDet.SetConfPar("MuFilter/VandUpPropSpeed",13.6*u.cm/u.nanosecond);
108 mufiDet.SetConfPar("MuFilter/DsPropSpeed",15.1*u.cm/u.nanosecond);
109 scifiDet.SetConfPar("Scifi/timeResol",150.*u.picosecond)
110 mufiDet.SetConfPar("MuFilter/timeResol",150.*u.picosecond) # time resolution in ps, first guess
111 better_update = True
112
113if better_update:
114 print("WARNING: Simulation file preceding the production cut change! Consider regenerating from scratch!")
115
116
117# Fair digitization task
118if options.FairTask_digi:
119 run = ROOT.FairRunAna()
120 ioman = ROOT.FairRootManager.Instance()
121 ioman.RegisterInputObject('Scifi', snd_geo.modules['Scifi'])
122 ioman.RegisterInputObject('MuFilter', snd_geo.modules['MuFilter'])
123 # Don't use FairRoot's default event header settings
124 run.SetEventHeaderPersistence(False)
125
126 # Set input
127 fileSource = ROOT.FairFileSource(options.inputFile)
128 run.SetSource(fileSource)
129 # Set output
130 outfile = ROOT.FairRootFileSink(outFile.replace('.root','CPP.root'))
131 run.SetSink(outfile)
132
133 # Set number of events to process
134 inRootFile = ROOT.TFile.Open(options.inputFile)
135 inTree = inRootFile.Get('cbmsim')
136 nEventsInFile = inTree.GetEntries()
137 nEvents = min(nEventsInFile, options.nEvents)
138
139 rtdb = run.GetRuntimeDb()
140 DigiTask = ROOT.DigiTaskSND()
141 DigiTask.withScifiClusters(makeClusterScifi)
142 DigiTask.set_copy_emulsion_points(options.copy_emulsion_points)
143 run.AddTask(DigiTask)
144 run.Init()
145 run.Run(firstEvent, nEvents)
146
147# Digitization using python code SndlhcDigi
148else:
149 if options.copy_emulsion_points:
150 print("ERROR: copying of emulsion points only configurable when using DigiTask")
151
152 # import digi task
153 import SndlhcDigi
154 Sndlhc = SndlhcDigi.SndlhcDigi(outFile,makeClusterScifi)
155 nEvents = min(Sndlhc.sTree.GetEntries(),options.nEvents)
156# main loop
157 for iEvent in range(firstEvent, nEvents):
158 if iEvent % 50000 == 0 or options.debug:
159 print('event ', iEvent, nEvents - firstEvent)
160 Sndlhc.iEvent = iEvent
161 rc = Sndlhc.sTree.GetEvent(iEvent)
162 Sndlhc.digitize()
163 if makeClusterScifi:
164 Sndlhc.clusterScifi()
165 # memory monitoring
166 # mem_monitor()
167
168 # end loop over events
169 Sndlhc.finish()
170
171timer.Stop()
172rtime = timer.RealTime()
173ctime = timer.CpuTime()
174print(' ')
175print("Real time ",rtime, " s, CPU time ",ctime,"s")
configure(darkphoton=None)