From b300555d66179ffe020ac4b9cc904918f8645c18 Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Wed, 19 Jul 2023 21:58:04 -0500 Subject: [PATCH 1/3] add scripts for the test --- scripts/subdetector_tests/ff_det_names.json | 31 +++ .../subdetector_tests/ff_performance_test.py | 219 ++++++++++++++++++ scripts/subdetector_tests/gen_particles.py | 113 +++++++++ scripts/subdetector_tests/material_scan.py | 38 ++- 4 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 scripts/subdetector_tests/ff_det_names.json create mode 100644 scripts/subdetector_tests/ff_performance_test.py create mode 100644 scripts/subdetector_tests/gen_particles.py diff --git a/scripts/subdetector_tests/ff_det_names.json b/scripts/subdetector_tests/ff_det_names.json new file mode 100644 index 000000000..43f7649c9 --- /dev/null +++ b/scripts/subdetector_tests/ff_det_names.json @@ -0,0 +1,31 @@ +{ + "B0APF_BeamlineMagnet": "Beamline (ion)", + "B0ECal": "B0 Detector", + "B0PF_BeamlineMagnet": "Beamline (ion)", + "B0Tracker": "B0 Detector", + "B0TrackerCompanion": "B0 Detector", + "B1APF_BeamlineMagnet": "Beamline (ion)", + "B1PF_BeamlineMagnet": "Beamline (ion)", + "B2PF_BeamlineMagnet": "Beamline (ion)", + "BeamPipeB0": "B0 Detector", + "ForwardOffMTracker_station_1": "Off-M Tracker", + "ForwardOffMTracker_station_2": "Off-M Tracker", + "ForwardOffMTracker_station_3": "Off-M Tracker", + "ForwardOffMTracker_station_4": "Off-M Tracker", + "ForwardRomanPot_Station_1": "Roman Pot", + "ForwardRomanPot_Station_2": "Roman Pot", + "Pipe_cen_to_pos": "Beamline ($e^-$)", + "Q0EF": "Beamline ($e^-$)", + "Q0EF_vac": "Beamline ($e^-$)", + "Q1APF_BeamlineMagnet": "Beamline (ion)", + "Q1BPF_BeamlineMagnet": "Beamline (ion)", + "Q1EF": "Beamline ($e^-$)", + "Q1EF_vac": "Beamline ($e^-$)", + "Q2PF_BeamlineMagnet": "Beamline (ion)", + "VacuumMagnetElement": "Vacuum Magnet Element", + "ZDC_1stSilicon": "ZDC", + "ZDC_Crystal": "ZDC", + "ZDC_PbSci": "ZDC", + "ZDC_PbSi": "ZDC", + "ZDC_WSi": "ZDC" +} diff --git a/scripts/subdetector_tests/ff_performance_test.py b/scripts/subdetector_tests/ff_performance_test.py new file mode 100644 index 000000000..a4be2575b --- /dev/null +++ b/scripts/subdetector_tests/ff_performance_test.py @@ -0,0 +1,219 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2023 Chao Peng +''' + A python script to benchmark the performance of far forward detectors with high energy proton/nuclei + It tests each far forward detector (see FF_MOTHER and FF_COMP) and reads the process time at the end of the simulation + + Author: Chao Peng (ANL) + Date: 07/19/2023 +''' +import os +import re +import sys +import subprocess +import argparse +import shutil +import numpy as np +from matplotlib import pyplot as plt +from matplotlib import colors as mcolors + + +# script directory +SDIR = os.path.dirname(os.path.realpath(__file__)) +# event generation script (particle gun is not working in this method, subprocess.run won't go through) +GEN_SCRIPT = os.path.join(SDIR, 'gen_particles.py') + + +def mrad2deg(th): + return th/1000./np.pi*180. + + +def deg2mrad(ang): + return ang/180.*np.pi*1000. + + +# the ff xml file that is used by the top-level xml file +# this script will modify the file so try to use a copy of the original file +FF_MOTHER = 'compact/far_forward_test.xml' +# ff components +# this list will be tested one-by-one (by modifying the mother xml file +FF_COMP = np.array([ + ('Beamline (Ion)', 'far_forward/ion_beamline.xml'), + ('Beamline ($e^-$)', 'far_forward/electron_beamline.xml'), + ('B0 Beampipe', 'far_forward/beampipe_hadron_B0.xml'), + ('B0 Tracker', 'far_forward/B0_tracker.xml'), + ('B0 ECal', 'far_forward/B0_ECal.xml'), + ('Off-M Tracker', 'offM_tracker.xml'), + ('ZDC', 'far_forward/ZDC.xml'), + ('Roman Pots', 'far_forward/roman_pots_eRD24_design.xml'), +]) + + +# kwargs are used by gen_cmd and sim_cmd +def sim_performance_test(**kwargs): + gen_file = 'ff_test_gen.hepmc' + # generate particles + gen_cmd = [ + 'python', GEN_SCRIPT, gen_file, + '-n={nev}', + '--angmin={angle_min}', + '--angmax={angle_max}', + '--pmin={p_min}', + '--pmax={p_max}', + '--phmin={phi_min}', + '--phmax={phi_max}', + '--particles={particles}', + ] + gen_cmd = [c.format(**kwargs) for c in gen_cmd] + print(' '.join(gen_cmd)) + subprocess.run(gen_cmd, check=True) + + # simulation + sim_cmd = [ + 'ddsim', + '--runType=batch', + '--part.minimalKineticEnergy=1*TeV', + '--filter.tracker=edep0', + # '-v=WARNING', + '--numberOfEvents={nev}', + # '--physics.list {physics_list}', + # '--enableGun', + # '--gun.particle=proton', '--gun.energy=275*GeV', + # '--gun.position=\"0.0 0.0 0.0*cm\"', + # '--gun.phiMin=0.', '--gun.phiMax=2.*pi', + # '--gun.thetaMin=0.003', '--gun.thetaMax=0.004', + # '--gun.distribution=uniform', + '--inputFiles={}'.format(gen_file), + '--outputFile={sim_file}', + '--compact={compact}', + ] + sim_cmd = [c.format(**kwargs) for c in sim_cmd] + print(' '.join(sim_cmd)) + p = subprocess.run(sim_cmd, stdout=subprocess.PIPE) + lines = p.stdout.decode('utf-8').split('\n')[-4:] + + pat = re.compile('Event Processing:\s+([-+]?(?:\d*\.*\d+))\s+s') + r = pat.search('\n'.join(lines), re.MULTILINE) + if not r: + print('Cannot find event processing time in:') + print('\n'.join(lines)) + return None + return float(r.group(1)) + + +if __name__ == '__main__': + # argument parser + parser = argparse.ArgumentParser() + + parser.add_argument('compact', + help='A Top-level XML file of the detector discription.' + ) + parser.add_argument('--ff-compact', + default=FF_MOTHER, + help='The XML file for far-forward detectors, used by the top-level XML file. It will be modified by the script.' + ) + parser.add_argument('--nev', + default=100, type=int, + help='Number of events.' + ) + parser.add_argument('--particles', + default='proton', + help='Type of particles.' + ) + parser.add_argument('--sim-file', + default='ff_test.edm4hep.root', + help='Temporary output root file.' + ) + parser.add_argument('--theta-min', + default=3, type=float, + help='Min. polar angle (mrad).' + ) + parser.add_argument('--theta-max', + default=3.5, type=float, + help='Max. polar angle (mrad).' + ) + parser.add_argument('--p-min', + default=275, type=float, + help='Min. momentum of the particles (GeV).' + ) + parser.add_argument('--p-max', + default=275, type=float, + help='Max. momentum of the particles (GeV).' + ) + parser.add_argument('--phi-min', + default=0, type=float, + help='Min. phi angle of the particles (degree).' + ) + parser.add_argument('--phi-max', + default=360, type=float, + help='Max. phi angle of the particles (degree).' + ) + + args = parser.parse_args() + kwargs = vars(args) + # convert mrad to angle + kwargs['angle_min'] = mrad2deg(args.theta_min) + kwargs['angle_max'] = mrad2deg(args.theta_max) + + # all ff components + t = sim_performance_test(**kwargs) + result = [('All FF', t)] + + # read ff-compact + file1 = open(args.ff_compact, 'r') + lines = file1.readlines() + file1.close() + + for comp1, xml1 in FF_COMP: + print('Running test for ff component: {}'.format(comp1)) + new_lines = [] + for nl in lines: + is_needed = True + for comp2, xml2 in FF_COMP: + if xml2 in nl and comp2 != comp1: + is_needed = False + if is_needed: + new_lines.append(nl) + file2 = open(args.ff_compact, 'w') + file2.writelines(new_lines) + file2.close() + + # print(comp1) + # print(''.join(lines)) + # print(''.join(new_lines)) + + t = sim_performance_test(**vars(args)) + result.append((comp1, t)) + print('{}: {:.2f} s for {:d} events'.format(comp1, t, 100)) + + # restore it back + file2 = open(args.ff_compact, 'w') + file2.writelines(lines) + file2.close() + + + # Build the plot + result = np.array(result) + p = (args.p_min + args.p_max)/2. # GeV + theta = (args.theta_min + args.theta_max)/2. # mrad + nev = float(args.nev) + + prop_cycle = plt.rcParams['axes.prop_cycle'] + colors = prop_cycle.by_key()['color'] + + fig, ax = plt.subplots(figsize=(8, 6), dpi=160, gridspec_kw=dict(top=0.95, bottom=0.25, left=0.15, right=0.98)) + x_pos = np.arange(len(result)) + for i, (x, d, e) in enumerate(zip(x_pos, result.T[1].astype(float)/nev, result.T[1].astype(float)/np.sqrt(nev)/nev)): + ic = colors[i % len(colors)] + ax.bar(x, d, yerr=e, align='center', color=mcolors.to_rgba(ic, alpha=0.5), ec=ic, ecolor='black', capsize=10) + ax.set_ylabel('Process Time (s / event)', fontsize=16) + ax.set_xticks(x_pos) + ax.set_xticklabels(result.T[0], rotation=45, ha='right', fontsize=14) + ax.set_title('{:.0f} GeV/c {} @ ~{:.1f} mrad'.format(p, args.particles, theta), fontsize=16) + ax.yaxis.grid(ls=':') + ax.tick_params(labelsize=16) + ax.set_axisbelow(True) + + # Save the figure + # fig.tight_layout() + fig.savefig('ff_test_{:.0f}_{}_{:.0f}_mrad.png'.format(p, args.particles, theta)) diff --git a/scripts/subdetector_tests/gen_particles.py b/scripts/subdetector_tests/gen_particles.py new file mode 100644 index 000000000..aaba51b88 --- /dev/null +++ b/scripts/subdetector_tests/gen_particles.py @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2023 Chao Peng +''' + A simple script to generate single particles in HEPMC3 format + + Author: Chao Peng (ANL) + Date: 07/19/2023 +''' +import os +import sys +from pyHepMC3 import HepMC3 as hm +import numpy as np +import argparse + + +PARTICLES = { + "pion0": (111, 0.1349766), # pi0 + "pion+": (211, 0.13957018), # pi+ + "pion-": (-211, 0.13957018), # pi- + "kaon0": (311, 0.497648), # K0 + "kaon+": (321, 0.493677), # K+ + "kaon-": (-321, 0.493677), # K- + "proton": (2212, 0.938272), # proton + "neutron": (2112, 0.939565), # neutron + "electron": (11, 0.51099895e-3), # electron + "positron": (-11, 0.51099895e-3),# positron + "photon": (22, 0), # photon + "muon": (13, 105.6583755), # muon +} + + +def gen_event(p, theta, phi, pid, mass): + evt = hm.GenEvent(hm.Units.MomentumUnit.GEV, hm.Units.LengthUnit.MM) + # final state + state = 1 + e0 = np.sqrt(p*p + mass*mass) + px = np.cos(phi)*np.sin(theta) + py = np.sin(phi)*np.sin(theta) + pz = np.cos(theta) + + # beam + pbeam = hm.GenParticle(hm.FourVector(0, 0, 0, 0.938272), 2212, 4) + ebeam = hm.GenParticle(hm.FourVector(0, 0, e0, np.sqrt(e0*e0 + 0.511e-3*0.511e-3)), 11, 4) + + # out particle + hout = hm.GenParticle(hm.FourVector(px*p, py*p, pz*p, e0), pid, state) + + # vertex + vert = hm.GenVertex() + vert.add_particle_in(ebeam) + vert.add_particle_in(pbeam) + vert.add_particle_out(hout) + evt.add_vertex(vert) + return evt + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('output', help='path to the output file') + parser.add_argument('-n', type=int, default=1000, dest='nev', help='number of events to generate') + parser.add_argument('-s', type=int, default=-1, dest='seed', help='seed for random generator') + parser.add_argument('--parray', type=str, default="", dest='parray', + help='an array of momenta in GeV, separated by \",\"') + parser.add_argument('--pmin', type=float, default=8.0, dest='pmin', help='minimum momentum in GeV') + parser.add_argument('--pmax', type=float, default=100.0, dest='pmax', help='maximum momentum in GeV') + parser.add_argument('--angmin', type=float, default=0.0, dest='angmin', help='minimum angle in degree') + parser.add_argument('--angmax', type=float, default=20.0, dest='angmax', help='maximum angle in degree') + parser.add_argument('--phmin', type=float, default=0.0, dest='phmin', help='minimum angle in degree') + parser.add_argument('--phmax', type=float, default=360.0, dest='phmax', help='maximum angle in degree') + parser.add_argument('--particles', type=str, default='electron', dest='particles', + help='particle names, support {}'.format(list(PARTICLES.keys()))) + + args = parser.parse_args() + + # random seed (< 0 will get it from enviroment variable 'SEED', or a system random number) + if args.seed < 0: + args.seed = os.environ.get('SEED', int.from_bytes(os.urandom(4), byteorder='big', signed=False)) + print("Random seed is {}".format(args.seed)) + np.random.seed(args.seed) + + output = hm.WriterAscii(args.output); + if output.failed(): + print("Cannot open file \"{}\"".format(args.output)) + sys.exit(2) + + # build particle info + parts = [] + for pid in args.particles.split(','): + pid = pid.strip() + if pid not in PARTICLES.keys(): + print('pid {:d} not found in dictionary, ignored.'.format(pid)) + continue + parts.append(PARTICLES[pid]) + + # p values + pvals = np.random.uniform(args.pmin, args.pmax, args.nev) if not args.parray else \ + np.random.choice([float(p.strip()) for p in args.parray.split(',')], args.nev) + thvals = np.random.uniform(args.angmin, args.angmax, args.nev)/180.*np.pi + phivals = np.random.uniform(args.phmin, args.phmax, args.nev)/180.*np.pi + partvals = [parts[i] for i in np.random.choice(len(parts), args.nev)] + + count = 0 + for p, theta, phi, (pid, mass) in zip(pvals, thvals, phivals, partvals): + if (count % 1000 == 0): + print("Generated {} events".format(count), end='\r') + evt = gen_event(p, theta, phi, pid, mass) + output.write_event(evt) + evt.clear() + count += 1 + + print("Generated {} events".format(args.nev)) + output.close() diff --git a/scripts/subdetector_tests/material_scan.py b/scripts/subdetector_tests/material_scan.py index dd1afe3ee..97c612a6e 100644 --- a/scripts/subdetector_tests/material_scan.py +++ b/scripts/subdetector_tests/material_scan.py @@ -10,11 +10,8 @@ ''' import os -import math import json -import fnmatch import argparse -import subprocess import pandas as pd import numpy as np from io import StringIO @@ -195,6 +192,14 @@ def material_scan(desc, start, end, epsilon, int_dets=None, thickness_corrector= default='EcalBarrelScFi,EcalEndcapN,EcalEndcapP,SolenoidBarrel,HcalBarrel,HcalEndcapN,HcalEndcapP', help='Names of the interested detectors, separated by \",\". Use \"all\" for all detectors.' ) + # detector name map + # convert detector names in compact file {xml_name_1: det_name_1, ...} + # it can also group several xml components into one name {xml_name_1: det_name_1, xml_name_2: det_name_1, ...} + parser.add_argument( + '--dname-map', + default=None, + help='A json file that contains the detector name map.' + ) args = parser.parse_args() if not os.path.exists(args.compact): @@ -246,13 +251,27 @@ def material_scan(desc, start, end, epsilon, int_dets=None, thickness_corrector= th_corr.scan_missing_thickness(desc, start_point, np.array(start_point) + np.array([100., 50., 0.]), dz=0.0001, epsilon=args.epsilon) + + # detector name map + DNAME_MAP = dict() + if args.dname_map is not None: + with open(args.dname_map) as f: + dnames = json.load(f) + DNAME_MAP.update(dnames) + # array for detailed data # number of materials cannot be pre-determined, so just assign a large number to be safe - vals = np.zeros(shape=(len(etas), len(dets) + 1, 50)) - dets2 = dets + [OTHERS_NAME] + dn_map = {dn: dn for dn in np.unique(dets)} + dn_map.update(DNAME_MAP) + print('Detector Name Map:') + print(json.dumps(dn_map, sort_keys=True, indent=4)) + dets2 = pd.Series(dets).map(dn_map).unique() + if OTHERS_NAME not in dets2: + dets2 = np.append(dets2, [OTHERS_NAME]) det_mats = {d: [] for d in dets2} vt = ALLOWED_VALUE_TYPES[args.value_type] + vals = np.zeros(shape=(len(etas), len(dets2), 50)) for i, eta in enumerate(etas): if i % PROGRESS_STEP == 0: print('Scanned {:d}/{:d} for {:.2f} <= eta <= {:.2f}'.format(i, len(etas), etas[0], etas[-1]), @@ -263,13 +282,16 @@ def material_scan(desc, start, end, epsilon, int_dets=None, thickness_corrector= end_z = path_r*np.sinh(eta) # print('({:.2f}, {:.2f}, {:.2f})'.format(end_x, end_y, end_z)) dfr = material_scan(desc, start_point, (end_x, end_y, end_z), epsilon=args.epsilon, int_dets=dets, thickness_corrector=th_corr) + dn_map = {dn: dn for dn in dfr['detector'].unique()} + dn_map.update(DNAME_MAP) + dfr['det_name'] = dfr['detector'].map(dn_map) # aggregated values for detectors - x0_vals = dfr.groupby('detector')[vt[0]].sum().to_dict() + x0_vals = dfr.groupby('det_name')[vt[0]].sum().to_dict() for j, det in enumerate(dets2): vals[i, j, 0] = x0_vals.get(det, 0.) # update material dict - dfd = dfr[dfr['detector'] == det] + dfd = dfr[dfr['det_name'] == det] x0_mats = dfd.groupby('material')[vt[0]].sum() for mat in x0_mats.index: if mat not in det_mats[det]: @@ -331,7 +353,7 @@ def material_scan(desc, start, end, epsilon, int_dets=None, thickness_corrector= plt.close(fig) # detailed plot for each detector - for j, det in enumerate(dets): + for j, det in enumerate(dets2): dmats = det_mats[det] dfa = pd.DataFrame(data=vals[:, j, 1:len(dmats)+1], columns=dmats, index=etas) if not len(dmats): From 4c563735b91b3c52e579b044aa59a491495cd54a Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Sun, 17 Sep 2023 20:44:53 -0500 Subject: [PATCH 2/3] add the steering file --- scripts/subdetector_tests/ff_steering.py | 303 +++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 scripts/subdetector_tests/ff_steering.py diff --git a/scripts/subdetector_tests/ff_steering.py b/scripts/subdetector_tests/ff_steering.py new file mode 100644 index 000000000..ec0a3cb30 --- /dev/null +++ b/scripts/subdetector_tests/ff_steering.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python +""" +DD4hep simulation with some argument parsing +Based on M. Frank and F. Gaede runSim.py + @author A.Sailer + @version 0.1 +Modified with standard EIC EPIC requirements. +""" +from __future__ import absolute_import, unicode_literals +import logging +import sys +import math + +#from DDSim import SystemOfUnits +from DDSim.DD4hepSimulation import DD4hepSimulation +from g4units import mm, GeV, MeV, radian + +SIM = DD4hepSimulation() +################################################################ +# The compact XML file +# This defines the geometry version to use --> +# If making changes, you NEED to compile a local version +# of the ePIC repo! +# +# +# FIXME: You MUST source the right setup file is you compile +# ePIC locally! +# +# source epic/install/setup.sh +# +# +# The default magnetic field settings are for 18x275 GeV +################################################################# + +#SIM.compactFile = "/epic_ip6.xml" +## Lorentz boost for the crossing angle, in radian! + +############################################################# +# Particle Gun simulations use these options +# --> comment out if using MC input +############################################################# + +#SIM.enableDetailedShowerMode = False +SIM.enableG4GPS = False +SIM.enableG4Gun = False +SIM.enableGun = True +#SIM.gun.direction = (math.sin(-0.025*radian), 0, math.cos(-0.025*radian)) +SIM.crossingAngleBoost = -0.025*radian + + +## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .hepmc, .pairs files are supported +SIM.inputFiles = [] +## Macro file to execute for runType 'run' or 'vis' +SIM.macroFile = "" +## number of events to simulate, used in batch mode +SIM.numberOfEvents = 5000 +## Outputfile from the simulation,only lcio output is supported +SIM.outputFile = "RP_protons_testing_275_GeV_5k_events_8_29_2023_0.edm4hep.root" +## Physics list to use in simulation +#SIM.physicsList = None +## Verbosity use integers from 1(most) to 7(least) verbose +## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS +#SIM.printLevel = "VERBOSE" +## The type of action to do in this invocation +## batch: just simulate some events, needs numberOfEvents, and input file or gun +## vis: enable visualisation, run the macroFile if it is set +## run: run the macroFile and exit +## shell: enable interactive session +SIM.runType = "run" +## Skip first N events when reading a file +SIM.skipNEvents = 0 +## Steering file to change default behaviour +#SIM.steeringFile = None +## FourVector of translation for the Smearing of the Vertex position: x y z t +SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] +## FourVector of the Sigma for the Smearing of the Vertex position: x y z t +SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] + + +################################################################################ +## Action holding sensitive detector actions +## The default tracker and calorimeter actions can be set with +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) +## >>> SIM.action.calo = "Geant4CalorimeterAction" +## +## for specific subdetectors specific sensitive detectors can be set based on pattern matching +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" +## +## and additional parameters for the sensitive detectors can be set when the map is given a tuple +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) +## +## +################################################################################ + +## set the default calorimeter action +##SIM.action.calo = "Geant4ScintillatorCalorimeterAction" + +## create a map of patterns and actions to be applied to sensitive detectors +## example: SIM.action.mapActions['tpc'] = "TPCSDAction" +##SIM.action.mapActions = {} + +##SIM.action.mapActions['tpc'] = "TPCSDAction" + +## set the default tracker action +##SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) + + +################################################################################ +## Configuration for the magnetic field (stepper) +################################################################################ +SIM.field.delta_chord = 1e-03 +SIM.field.delta_intersection = 1e-03 +SIM.field.delta_one_step = .5e-01*mm +SIM.field.eps_max = 1e-03 +SIM.field.eps_min = 1e-04 +#SIM.field.equation = "Mag_UsualEqRhs" +SIM.field.largest_step = 100.0*mm +SIM.field.min_chord_step = 1.e-2*mm +SIM.field.stepper = "HelixSimpleRunge" + + +################################################################################ +## Configuration for sensitive detector filters +## +## Set the default filter for tracker or caliromter +## >>> SIM.filter.tracker = "edep1kev" +## >>> SIM.filter.calo = "" +## +## Assign a filter to a sensitive detector via pattern matching +## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" +## +## Or more than one filter: +## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] +## +## Don't use the default filter or anything else: +## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] +## +## Create a custom filter. The dictionary is used to instantiate the filter later on +## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) +## +## +################################################################################ + +## default filter for calorimeter sensitive detectors; this is applied if no other filter is used for a calorimeter +##SIM.filter.calo = "edep0" + +## list of filter objects: map between name and parameter dictionary +#SIM.filter.filters[ 'edep100MeV' ] = dict( name="EnergyDepositMinimumCut/100MeV", parameter={"Cut" : 1000*MeV} ) +#SIM.filter.filters = {'alexEDep': {'parameter': {'Cut': 100.0}, 'name': 'EnergyDepositMinimumCut/cut0'}} + +#SIM.filter.calo = "edep100MeV" +#SIM.filter.mapDetFilter['ForwardRomanPot_Station_1'] = "edep100MeV" +#SIM.filter.mapDetFilter['ForwardRomanPot_Station_2'] = "edep100MeV" +#SIM.part.minimalKineticEnergy = 100*MeV + +## a map between patterns and filter objects, using patterns to attach filters to sensitive detector +##SIM.filter.mapDetFilter = {} + +##SIM.filter.mapDetFilter['TPC'] = "edep0" + +## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker +##SIM.filter.tracker = "edep1kev" + + +################################################################################ +## Configuration for the GuineaPig InputFiles +################################################################################ + +## Set the number of pair particles to simulate per event. +## Only used if inputFile ends with ".pairs" +## If "-1" all particles will be simulated in a single event +## +#SIM.guineapig.particlesPerEvent = "1" + + +################################################################################ +## Configuration for the DDG4 ParticleGun +################################################################################ + +## direction of the particle gun, 3 vector +## shoot in the barrel region +#SIM.gun.direction = (0, 1, 0) + +## choose the distribution of the random direction for theta +## +## Options for random distributions: +## +## 'uniform' is the default distribution, flat in theta +## 'cos(theta)' is flat in cos(theta) +## 'eta', or 'pseudorapidity' is flat in pseudorapity +## 'ffbar' is distributed according to 1+cos^2(theta) +## +## Setting a distribution will set isotrop = True +## +SIM.gun.distribution = 'uniform' +SIM.gun.energy = 275.0*GeV ## default energy value is MeV +#SIM.gun.momentumMin = 80*GeV +#SIM.gun.momentumMax = 100*GeV + +## isotropic distribution for the particle gun +## +## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions +## if one of these options is not None the random distribution will be set to True and cannot be turned off! +## +SIM.gun.isotrop = True +#SIM.gun.multiplicity = 1 +SIM.gun.particle = "proton" +##SIM.gun.phiMax = pi + +## Minimal azimuthal angle for random distribution +##SIM.gun.phiMin = 0 + +## position of the particle gun, 3 vector. unit mm +##SIM.gun.position = (0, 0, 0) +SIM.gun.thetaMin = 0.002*radian +SIM.gun.thetaMax = 0.004*radian + + +################################################################################ +## Configuration for the output levels of DDG4 components +################################################################################ + +## Output level for input sources +SIM.output.inputStage = 3 + +## Output level for Geant4 kernel +SIM.output.kernel = 3 + +## Output level for ParticleHandler +SIM.output.part = 3 + +## Output level for Random Number Generator setup +SIM.output.random = 6 + + +################################################################################ +## Configuration for the Particle Handler/ MCTruth treatment +################################################################################ + +## Enable lots of printout on simulated hits and MC-truth information +SIM.part.enableDetailedHitsAndParticleInfo = False + +## Keep all created particles +SIM.part.keepAllParticles = True + +## Minimal distance between particle vertex and endpoint of parent after +## which the vertexIsNotEndpointOfParent flag is set +## +SIM.part.minDistToParentVertex = 2.2e-14 + +## MinimalKineticEnergy to store particles created in the tracking region +#SIM.part.minimalKineticEnergy = 1*MeV + +## Printout at End of Tracking +SIM.part.printEndTracking = False + +## Printout at Start of Tracking +SIM.part.printStartTracking = False + +## List of processes to save, on command line give as whitespace separated string in quotation marks +SIM.part.saveProcesses = ['Decay'] + + +################################################################################ +## Configuration for the PhysicsList +################################################################################ +SIM.physics.decays = True +SIM.physics.list = "FTFP_BERT" # "FTFP_BERT" + +## location of particle.tbl file containing extra particles and their lifetime information +## + + +## The global geant4 rangecut for secondary production +## +## Default is 0.7 mm as is the case in geant4 10 +## +## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" +## +## Set printlevel to DEBUG to see a printout of all range cuts, +## but this only works if range cut is not "None" +## +#SIM.physics.rangecut = 10.0*mm + + +################################################################################ +## Properties for the random number generator +################################################################################ + +## If True, calculate random seed for each event based on eventID and runID +## allows reproducibility even when SkippingEvents +SIM.random.enableEventSeed = False +SIM.random.file = None +SIM.random.luxury = 1 +SIM.random.replace_gRandom = True +SIM.random.seed = None +SIM.random.type = None From 162af7409a6272931108f0daa4f5f696e66c9635 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 01:45:01 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/subdetector_tests/ff_steering.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/subdetector_tests/ff_steering.py b/scripts/subdetector_tests/ff_steering.py index ec0a3cb30..eae7afa9f 100644 --- a/scripts/subdetector_tests/ff_steering.py +++ b/scripts/subdetector_tests/ff_steering.py @@ -23,7 +23,7 @@ # of the ePIC repo! # # -# FIXME: You MUST source the right setup file is you compile +# FIXME: You MUST source the right setup file is you compile # ePIC locally! # # source epic/install/setup.sh @@ -157,7 +157,7 @@ #SIM.filter.calo = "edep100MeV" #SIM.filter.mapDetFilter['ForwardRomanPot_Station_1'] = "edep100MeV" #SIM.filter.mapDetFilter['ForwardRomanPot_Station_2'] = "edep100MeV" -#SIM.part.minimalKineticEnergy = 100*MeV +#SIM.part.minimalKineticEnergy = 100*MeV ## a map between patterns and filter objects, using patterns to attach filters to sensitive detector ##SIM.filter.mapDetFilter = {} @@ -300,4 +300,4 @@ SIM.random.luxury = 1 SIM.random.replace_gRandom = True SIM.random.seed = None -SIM.random.type = None +SIM.random.type = None