Skip to content
Snippets Groups Projects
Commit af5805db authored by Eric Torrence's avatar Eric Torrence
Browse files

Merge branch 'fasermc-dev' into 'master'

Consolodate s0010 script updates

See merge request faser/calypso!345
parents 2e1beb94 a81e5bd6
No related branches found
No related tags found
No related merge requests found
...@@ -44,6 +44,10 @@ def faser_pgparser(): ...@@ -44,6 +44,10 @@ def faser_pgparser():
help="Specify radius (in mm)") help="Specify radius (in mm)")
parser.add_argument("--angle", default=0.005, type=float_or_none, parser.add_argument("--angle", default=0.005, type=float_or_none,
help="Specify angular width (in Rad)") help="Specify angular width (in Rad)")
parser.add_argument("--xpos", default=None, type=float,
help="Specify x position of particles (in mm)")
parser.add_argument("--ypos", default=None, type=float,
help="Specify y position of particles (in mm)")
parser.add_argument("--zpos", default=None, type=float, parser.add_argument("--zpos", default=None, type=float,
help="Specify z position of particles (in mm) (helpful to avoid FASERnu)") help="Specify z position of particles (in mm) (helpful to avoid FASERnu)")
......
...@@ -148,9 +148,15 @@ if __name__ == '__main__': ...@@ -148,9 +148,15 @@ if __name__ == '__main__':
# -1000 is safely upstream of detector (to be checked) # -1000 is safely upstream of detector (to be checked)
# Note zpos is in mm! # Note zpos is in mm!
if args.zpos: if args.zpos != None:
sg_dict["z"] = args.zpos sg_dict["z"] = args.zpos
if args.xpos != None:
sg_dict["x"] = args.xpos
if args.ypos != None:
sg_dict["y"] = args.ypos
# Determine energy sampling # Determine energy sampling
if args.sampler == "lin": if args.sampler == "lin":
sg_dict["energy"] = PG.UniformSampler(args.minE*GeV, args.maxE*GeV) sg_dict["energy"] = PG.UniformSampler(args.minE*GeV, args.maxE*GeV)
...@@ -159,11 +165,28 @@ if __name__ == '__main__': ...@@ -159,11 +165,28 @@ if __name__ == '__main__':
elif args.sampler == "const": elif args.sampler == "const":
sg_dict["energy"] = PG.ConstSampler(args.maxE*GeV) sg_dict["energy"] = PG.ConstSampler(args.maxE*GeV)
elif args.sampler == "hist": elif args.sampler == "hist":
fname, hname = args.hist_name.split(":") nargs = len(args.hist_name.split(":"))
sg_dict["energy"] = PG.TH1Sampler(fname, hname) if nargs == 2:
fname, hname = args.hist_name.split(":")
sg_dict["energy"] = PG.TH1Sampler(fname, hname)
elif nargs == 3:
fname, hname, scale = args.hist_name.split(":")
sg_dict["energy"] = PG.TH1Sampler(fname, hname, scale)
else:
print(f"Can't parse histogram {args.hist_name}!")
sys.exit(1)
elif args.sampler == "hist2D": elif args.sampler == "hist2D":
fname, hname = args.hist_name.split(":") nargs = len(args.hist_name.split(":"))
sg_dict["energy"] = PG.TH2Sampler(fname, hname) if nargs == 2:
fname, hname = args.hist_name.split(":")
sg_dict["energy"] = PG.TH2Sampler(fname, hname)
elif nargs == 4:
fname, hname, scalex, scaley = args.hist_name.split(":")
sg_dict["energy"] = PG.TH2Sampler(fname, hname, scalex, scaley)
else:
print(f"Can't parse histogram {args.hist_name}!")
sys.exit(1)
else: else:
print(f"Sampler {args.sampler} not known!") print(f"Sampler {args.sampler} not known!")
sys.exit(1) sys.exit(1)
...@@ -255,8 +278,12 @@ if __name__ == '__main__': ...@@ -255,8 +278,12 @@ if __name__ == '__main__':
b = time.time() b = time.time()
log.info("Run G4FaserAlg in " + str(b-a) + " seconds") log.info("Run G4FaserAlg in " + str(b-a) + " seconds")
#
# Success should be 0 # Signal errors
# if sc.isSuccess():
sys.exit(not sc.isSuccess()) log.info("Execution succeeded")
sys.exit(0)
else:
log.info("Execution failed, return 1")
sys.exit(1)
...@@ -185,9 +185,12 @@ cd "${config_file_stem}-${seg_str}" ...@@ -185,9 +185,12 @@ cd "${config_file_stem}-${seg_str}"
# Run job # Run job
if [[ -z "$tag" ]]; then if [[ -z "$tag" ]]; then
faser_particlegun.py "--conf=$config_path" "--segment=$seg_str" faser_particlegun.py "--conf=$config_path" "--segment=$seg_str"
gen_code=$?
else else
faser_particlegun.py "--conf=$config_path" "--segment=$seg_str" "--tag=$tag" faser_particlegun.py "--conf=$config_path" "--segment=$seg_str" "--tag=$tag"
gen_code=$?
fi fi
echo "Return code: $gen_code"
# #
# Print out ending time # Print out ending time
date date
...@@ -198,25 +201,51 @@ export EOS_MGM_URL=root://eospublic.cern.ch ...@@ -198,25 +201,51 @@ export EOS_MGM_URL=root://eospublic.cern.ch
# #
if ! [ -z "$outdest" ] if ! [ -z "$outdest" ]
then then
echo "Output directory:"
ls -l ls -l
echo "copy *-HITS.root to $outdest" thefile=`ls *-HITS.root`
mkdir -p $outdest if [ $? -eq 0 ]; then
eos cp *-HITS.root ${outdest}/ || true echo "copy $thefile to $outdest"
eos mkdir -p $outdest
eos cp $thefile ${outdest}/${thefile} || true
# Check that it worked
eos ls ${outdest}/${thefile} > /dev/null
if [ $? -eq 0 ]; then
echo "file $thefile copied to $outdest"
copy_code=0
else
echo "didnt find $thefile in $outdest !"
copy_code=1
fi
else
echo "ls *-xAOD.root returned nothing!"
copy_code=1
fi
fi fi
# #
# Also copy log file # Also copy log file
if ! [ -z "$logdest" ] if ! [ -z "$logdest" ]
then then
cd .. cd ..
echo "Working directory:"
ls -l ls -l
echo "copy $logfile to $logdest" echo "copy $logfile to $logdest"
mkdir -p $logdest eos mkdir -p $logdest
eos cp $logfile $logdest/$logfile eos cp $logfile $logdest/$logfile
elif ! [ -z "$outdest" ] elif ! [ -z "$outdest" ]
then then
cd .. cd ..
ls -l ls -l
echo "copy $logfile to $outdest" echo "copy $logfile to $outdest"
mkdir -p $outdest eos mkdir -p $outdest
eos cp $logfile $outdest/$logfile eos cp $logfile $outdest/$logfile
fi fi
# Make sure to return an error is calypso failed
if [ $gen_code -ne 0 ] || [ $copy_code -ne 0 ]; then
exit 1
else
exit 0
fi
...@@ -14,6 +14,7 @@ def load_hist(*args): ...@@ -14,6 +14,7 @@ def load_hist(*args):
""" """
Load a histogram from a filename/TFile and histo name. If a single arg is Load a histogram from a filename/TFile and histo name. If a single arg is
provided, it has to be a histo object and will be cloned before return. provided, it has to be a histo object and will be cloned before return.
""" """
h = None h = None
if len(args) == 1 and issubclass(type(args[0]), ROOT.TH1): if len(args) == 1 and issubclass(type(args[0]), ROOT.TH1):
...@@ -25,6 +26,7 @@ def load_hist(*args): ...@@ -25,6 +26,7 @@ def load_hist(*args):
#f.Close() #f.Close()
elif type(args[0]) is ROOT.TFile and type(args[1]) is str: elif type(args[0]) is ROOT.TFile and type(args[1]) is str:
h = args[0].Get(args[1]).Clone() h = args[0].Get(args[1]).Clone()
if h is None: if h is None:
raise Exception("Error in histogram loading from " + args) raise Exception("Error in histogram loading from " + args)
else: else:
...@@ -77,7 +79,7 @@ def get_random_bin(globalbins, cheights): ...@@ -77,7 +79,7 @@ def get_random_bin(globalbins, cheights):
raise Exception("Sample fell outside range of cumulative distribution?!?!") raise Exception("Sample fell outside range of cumulative distribution?!?!")
def get_random_x(h, globalbins, cheights, globalbin_to_axisbin): def get_random_x(h, globalbins, cheights, globalbin_to_axisbin, scale=1.):
""" """
Choose a random bin via get_random_bin, then pick a uniform random x Choose a random bin via get_random_bin, then pick a uniform random x
point in that bin (without any attempt at estimating the in-bin distribution). point in that bin (without any attempt at estimating the in-bin distribution).
...@@ -86,10 +88,10 @@ def get_random_x(h, globalbins, cheights, globalbin_to_axisbin): ...@@ -86,10 +88,10 @@ def get_random_x(h, globalbins, cheights, globalbin_to_axisbin):
axisids = globalbin_to_axisbin.get(irand) axisids = globalbin_to_axisbin.get(irand)
assert axisids is not None assert axisids is not None
xrand = random.uniform(h.GetXaxis().GetBinLowEdge(axisids[0]), h.GetXaxis().GetBinUpEdge(axisids[0])) xrand = random.uniform(h.GetXaxis().GetBinLowEdge(axisids[0]), h.GetXaxis().GetBinUpEdge(axisids[0]))
return xrand return scale * xrand
def get_random_xy(h2, globalbins, cheights, globalbin_to_axisbin): def get_random_xy(h2, globalbins, cheights, globalbin_to_axisbin, xscale=1., yscale=1.):
""" """
Choose a random bin via get_random_bin, then pick a uniform random x,y Choose a random bin via get_random_bin, then pick a uniform random x,y
point in that bin (without any attempt at estimating the in-bin distribution). point in that bin (without any attempt at estimating the in-bin distribution).
...@@ -99,34 +101,71 @@ def get_random_xy(h2, globalbins, cheights, globalbin_to_axisbin): ...@@ -99,34 +101,71 @@ def get_random_xy(h2, globalbins, cheights, globalbin_to_axisbin):
assert axisids is not None assert axisids is not None
xrand = random.uniform(h2.GetXaxis().GetBinLowEdge(axisids[0]), h2.GetXaxis().GetBinUpEdge(axisids[0])) xrand = random.uniform(h2.GetXaxis().GetBinLowEdge(axisids[0]), h2.GetXaxis().GetBinUpEdge(axisids[0]))
yrand = random.uniform(h2.GetYaxis().GetBinLowEdge(axisids[1]), h2.GetYaxis().GetBinUpEdge(axisids[1])) yrand = random.uniform(h2.GetYaxis().GetBinLowEdge(axisids[1]), h2.GetYaxis().GetBinUpEdge(axisids[1]))
return xrand, yrand return (xscale*xrand), (yscale*yrand)
class TH1(object): class TH1(object):
"Minimal wrapper for ROOT TH1, for sampling consistency and easy loading" "Minimal wrapper for ROOT TH1, for sampling consistency and easy loading"
def __init__(self, *args): def __init__(self, *args):
self.th1 = load_hist(*args) """ Args can be variable length, but these are now kwargs, so order matters
fname - filename
hname - histogram name
xscale - scaling factor for x axis variable
"""
if len(args) > 2:
self.th1 = load_hist(*(args[0:2]))
else:
self.th1 = load_hist(*args)
self.globalbins, self.globalbin_to_axisbin, self.cheights = None, None, None self.globalbins, self.globalbin_to_axisbin, self.cheights = None, None, None
if len(args) >= 3:
self.xscale = float(args[2])
else:
self.xscale = 1.
def GetRandom(self): def GetRandom(self):
"A GetRandom that works for TH1s and uses Python random numbers" "A GetRandom that works for TH1s and uses Python random numbers"
if self.globalbins is None or self.globalbin_to_axisbin is None or self.cheights is None: if self.globalbins is None or self.globalbin_to_axisbin is None or self.cheights is None:
self.globalbins, self.globalbin_to_axisbin, self.cheights = get_sampling_vars(self.th1) self.globalbins, self.globalbin_to_axisbin, self.cheights = get_sampling_vars(self.th1)
return get_random_x(self.th1, self.globalbins, self.cheights, self.globalbin_to_axisbin) return get_random_x(self.th1, self.globalbins, self.cheights, self.globalbin_to_axisbin, self.xscale)
class TH2(object): class TH2(object):
"Minimal wrapper for ROOT TH2, for easy loading and to allow 2D sampling" "Minimal wrapper for ROOT TH2, for easy loading and to allow 2D sampling"
def __init__(self, *args): def __init__(self, *args):
self.th2 = load_hist(*args) """ Args can be variable length, but these are now kwargs, so order matters
fname - filename
hname - histogram name
xscale - scaling factor for x axis variable
yscale - scaling factor for y axis variable
"""
if len(args) > 2:
self.th2 = load_hist(*(args[0:2]))
else:
self.th2 = load_hist(*args)
self.globalbins, self.globalbin_to_axisbin, self.cheights = None, None, None self.globalbins, self.globalbin_to_axisbin, self.cheights = None, None, None
if len(args) >= 3:
self.xscale = float(args[2])
else:
self.xscale = 1.
if len(args) >= 4:
self.yscale = float(args[3])
else:
self.yscale = 1.
def GetRandom(self): def GetRandom(self):
"A GetRandom that works for TH2s" "A GetRandom that works for TH2s"
if self.globalbins is None or self.globalbin_to_axisbin is None or self.cheights is None: if self.globalbins is None or self.globalbin_to_axisbin is None or self.cheights is None:
self.globalbins, self.globalbin_to_axisbin, self.cheights = get_sampling_vars(self.th2) self.globalbins, self.globalbin_to_axisbin, self.cheights = get_sampling_vars(self.th2)
return get_random_xy(self.th2, self.globalbins, self.cheights, self.globalbin_to_axisbin) return get_random_xy(self.th2, self.globalbins, self.cheights, self.globalbin_to_axisbin, self.xscale, self.yscale)
...@@ -633,14 +633,23 @@ class EThetaMPhiSampler(MomSampler): ...@@ -633,14 +633,23 @@ class EThetaMPhiSampler(MomSampler):
pt = p sin(theta) pt = p sin(theta)
""" """
if self._theta is None:
e,theta = self.energy()
else:
e = self.energy()
theta = self.theta()
m = self.mass() m = self.mass()
p = math.sqrt( e**2 - m**2 )
count = 0
e = -1
while (e < m and count < 5):
count += 1
if self._theta is None:
e,theta = self.energy()
else:
e = self.energy()
theta = self.theta()
try:
p = math.sqrt( e**2 - m**2 )
except Exception:
raise Exception(f"Error generating E: {e} m: {m}!")
pz = p * math.cos(theta) pz = p * math.cos(theta)
pt = p * math.sin(theta) pt = p * math.sin(theta)
phi = self.phi() phi = self.phi()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment