1"""! Tools that can be used in HPSMC jobs."""
9from subprocess
import PIPE
17 Run the SLIC Geant4 simulation.
19 Optional parameters are: **nevents**, **macros**, **run_number**, **disable_particle_table** \n
20 Required parameters are: **detector** \n
21 Required configurations are: **slic_dir**, **detector_dir**
36 Component.__init__(self,
44 Setup command arguments.
45 @return list of arguments
48 raise Exception(
"No inputs given for SLIC.")
59 args.extend([
"-m",
"run_number.mac"])
63 if os.path.exists(tbl):
64 args.extend([
"-P", tbl])
66 raise Exception(
'SLIC particle.tbl does not exist: %s' % tbl)
71 if macro ==
"run_number.mac":
72 raise Exception(
"Macro name '%s' is not allowed." % macro)
73 if not os.path.isabs(macro):
74 raise Exception(
"Macro '%s' is not an absolute path." % macro)
75 args.extend([
"-m", macro])
82 """! Return path to detector file."""
86 """! Return path to particle table."""
87 return os.path.join(self.
slic_dir,
"share",
"particle.tbl")
90 """! Configure SLIC component."""
96 raise Exception(
'Failed to find valid detector_dir')
100 """! Setup SLIC component."""
101 if not os.path.exists(self.
slic_dir):
102 raise Exception(
"slic_dir does not exist: %s" % self.
slic_dir)
106 raise Exception(
'SLIC setup script does not exist: %s' % self.
namename)
109 run_number_cmd =
"/lcio/runNumber %d" % self.
run_number
110 run_number_mac = open(
"run_number.mac",
'w')
111 run_number_mac.write(run_number_cmd)
112 run_number_mac.close()
116 Return list of optional parameters.
118 Optional parameters are: **nevents**, **macros**, **run_number**
119 @return list of optional parameters
121 return [
'nevents',
'macros',
'run_number',
'disable_particle_table']
125 Return list of required parameters.
127 Required parameters are: **detector**
128 @return list of required parameters
134 Return list of required configurations.
136 Required configurations are: **slic_dir**, **detector_dir**
137 @return list of required configurations
139 return [
'slic_dir',
'detector_dir']
143 Execute SLIC component.
145 Component is executed by creating command line input
146 from command and command arguments.
147 @return return code of process
153 proc = subprocess.Popen(cl, shell=
True, stdout=log_out, stderr=log_err)
157 return proc.returncode
162 Run the hps-java JobManager class.
164 Input files have slcio format.
166 Required parameters are: **steering_files** \n
167 Optional parameters are: **detector**, **run_number**, **defs**
199 if 'overlay_file' in kwargs:
204 Component.__init__(self,
207 description=
'HPS Java Job Manager',
217 """! Configure JobManager component."""
221 if os.getenv(
'HPS_JAVA_BIN_JAR',
None)
is not None:
225 raise Exception(
'hps_java_bin_jar not set in environment or config file!')
227 if os.getenv(
"CONDITIONS_URL",
None)
is not None:
233 Return list of required configurations.
235 Required configurations are: **hps_java_bin_jar**
236 @retun list of required configurations.
238 return [
'hps_java_bin_jar']
241 """! Setup JobManager component."""
243 raise Exception(
"No inputs provided to hps-java.")
251 Setup command arguments.
252 @return list of arguments
257 self.
logger.debug(
'Setting java_args from config: %s' % self.
java_args)
272 self.
logger.debug(
'Setting conditions_password from config (not shown)')
296 args.append(
"outputFile=" + os.path.splitext(self.
output_files()[0])[0])
299 for k, v
in self.
defs.items():
301 args.append(k +
"=" + str(v))
305 self.
logger.debug(
"Steering does not exist at '%s' so assuming it is a resource." % self.
steering_file)
308 raise Exception(
'Steering looks like a file but is not an abs path: %s' % self.
steering_file)
317 args.append(input_file)
321 args.append(
"overlayFile=" + os.path.splitext(self.
overlay_file)[0])
327 Return list of required parameters.
329 Required parameters are: **steering_files**
330 @return list of required parameters
332 return [
'steering_files']
336 Return list of optional parameters.
338 Optional parameters are: **detector**, **run_number**, **defs**
339 @return list of optional parameters
341 return [
'detector',
'run_number',
'defs',
'nevents']
346 Run the hpstr analysis tool.
348 Required parameters are: **config_files** \n
349 Optional parameters are: **year**, **is_data**, **nevents** \n
350 Required configs are: **hpstr_install_dir**, **hpstr_base**
353 def __init__(self, cfg=None, is_data=0, year=None, tracking=None, **kwargs):
366 Component.__init__(self,
372 """! Setup HPSTR component."""
381 if len(os.path.dirname(config_file)):
383 if os.path.isabs(config_file):
387 raise Exception(
'The config has a directory but is not an abs path: %s' % self.
cfg)
394 if os.path.splitext(self.
input_files()[0])[1] ==
'.root':
400 Return list of required parameters.
402 Required parameters are: **config_files**
403 @return list of required parameters
405 return [
'config_files']
409 Return list of optional parameters.
411 Optional parameters are: **year**, **is_data**, **nevents**
412 @return list of optional parameters
414 return [
'year',
'is_data',
'nevents',
'tracking']
418 Return list of required configs.
420 Required configs are: **hpstr_install_dir**, **hpstr_base**
421 @return list of required configs
423 return [
'hpstr_install_dir',
'hpstr_base']
427 Setup command arguments.
428 @return list of arguments
436 if self.
year is not None:
437 args.extend([
"-y", str(self.
year)])
439 args.extend([
"-w", str(self.
tracking)])
443 """! Adjust names of output files."""
446 return [
'%s.root' % f]
453 """! Execute HPSTR component."""
459 proc = subprocess.Popen(cl, shell=
True, stdout=log_out, stderr=log_err)
463 return proc.returncode
470 Generic class for StdHep tools.
474 seed_names = [
'beam_coords',
477 'lhe_tridents_displacetime',
478 'lhe_tridents_displaceuni',
485 Component.__init__(self,
487 command=
"stdhep_" + name,
492 Setup command arguments.
493 @return list of arguments
497 if self.
name in StdHepTool.seed_names:
503 raise Exception(
"Too many outputs specified for StdHepTool.")
505 raise Exception(
"No outputs specified for StdHepTool.")
508 for i
in self.
inputs[::-1]:
511 raise Exception(
"No inputs specified for StdHepTool.")
518 Transform StdHep events into beam coordinates.
520 Optional parameters are: **beam_sigma_x**, **beam_sigma_y**, **beam_rot_x**,
521 **beam_rot_y**, **beam_rot_z**, **target_x**, **target_y**, **target_z**
543 StdHepTool.__init__(self,
550 Setup command arguments.
551 @return list of arguments
553 args = StdHepTool.cmd_args(self)
568 args.extend([
'-X', str(self.
target_x)])
570 args.extend([
'-Y', str(self.
target_y)])
572 args.extend([
'-Z', str(self.
target_z)])
578 Return list of optional parameters.
580 Optional parameters are: **beam_sigma_x**, **beam_sigma_y**, **beam_rot_x**,
581 **beam_rot_y**, **beam_rot_z**, **target_x**, **target_y**, **target_z**
582 @return list of optional parameters
584 return [
'beam_sigma_x',
'beam_sigma_y',
'beam_rot_x',
585 'beam_rot_y',
'beam_rot_z',
586 'target_x',
'target_y',
'target_z']
591 Randomly sample StdHep events into a new file.
593 Optional parameters are: **nevents**, **mu**
597 StdHepTool.__init__(self,
598 name=
'random_sample',
599 append_tok=
'sampled',
606 Setup command arguments.
607 @return list of arguments
611 if self.
name in StdHepTool.seed_names:
614 args.extend([
"-N", str(1)])
619 if self.
mu is not None:
620 args.extend([
"-m", str(self.
mu)])
624 args.insert(0, os.path.splitext(self.
output_files()[0])[0])
626 raise Exception(
"Too many outputs specified for RandomSample.")
628 raise Exception(
"No outputs specified for RandomSample.")
631 for i
in self.
inputs[::-1]:
634 raise Exception(
"No inputs were provided.")
640 Return list of optional parameters.
642 Optional parameters are: **nevents**, **mu**
643 @return list of optional parameters
645 return [
'nevents',
'mu']
648 """! Execute RandomSample component"""
649 returncode = Component.execute(self, log_out, log_err)
652 src =
'%s_1.stdhep' % os.path.splitext(self.
output_files()[0])[0]
653 dest =
'%s.stdhep' % os.path.splitext(self.
output_files()[0])[0]
654 self.
logger.debug(
"Moving '%s' to '%s'" % (src, dest))
655 shutil.move(src, dest)
662 Convert LHE files to StdHep, displacing the time by given ctau.
664 Optional parameters are: **ctau**
670 StdHepTool.__init__(self,
671 name=
'lhe_tridents_displacetime',
672 output_ext=
'.stdhep',
677 Setup command arguments.
678 @return list of arguments
680 args = StdHepTool.cmd_args(self)
681 if self.
ctau is not None:
682 args.extend([
"-l", str(self.
ctau)])
687 Return list of optional parameters.
689 Optional parameters are: **ctau**
690 @return list of optional parameters
697 Convert LHE files to StdHep, displacing the time by given ctau.
699 Optional parameters are: **ctau**
705 StdHepTool.__init__(self,
706 name=
'lhe_tridents_displaceuni',
707 output_ext=
'.stdhep',
712 Setup command arguments.
713 @return list of arguments
715 args = StdHepTool.cmd_args(self)
716 if self.
ctau is not None:
717 args.extend([
"-l", str(self.
ctau)])
722 Return list of optional parameters.
724 Optional parameters are: **ctau**
725 @return list of optional parameters
732 Add mother particles for physics samples.
736 StdHepTool.__init__(self,
743 """! Add full truth mother particles for physics samples"""
746 StdHepTool.__init__(self,
747 'add_mother_full_truth',
748 append_tok=
'mom_full_truth',
751 raise Exception(
"Must have 2 input files: a stdhep file and a lhe file in order")
755 raise Exception(
"The first input file must be a stdhep file")
759 raise Exception(
"The second input file must be a lhe file")
763 Setup command arguments.
764 @return list of arguments
771 Merge StdHep files, applying poisson sampling.
773 Required parameters are: **target_thickness**, **num_electrons**
784 StdHepTool.__init__(self,
785 name=
'merge_poisson',
786 append_tok=
'sampled',
790 """! Setup MergePoisson component."""
794 raise Exception(
"Cross section is missing.")
795 self.
logger.info(
"mu is %f", self.
mu)
799 Return list of required parameters.
801 Required parameters are: **target_thickness**, **num_electrons**
802 @return list of required parameters
804 return [
'target_thickness',
'num_electrons']
808 Setup command arguments.
809 @return list of arguments
812 if self.
name in StdHepTool.seed_names:
819 args.insert(0, os.path.splitext(self.
output_files()[0])[0])
821 raise Exception(
"Too many outputs specified for MergePoisson.")
823 raise Exception(
"No outputs specified for MergePoisson.")
826 for i
in self.
inputs[::-1]:
829 raise Exception(
"No inputs were provided.")
834 """! Execute MergePoisson component."""
835 returncode = Component.execute(self, log_out, log_err)
838 src =
'%s_1.stdhep' % os.path.splitext(self.
output_files()[0])[0]
839 dest =
'%s.stdhep' % os.path.splitext(self.
output_files()[0])[0]
840 self.
logger.debug(
"Moving '%s' to '%s'" % (src, dest))
841 shutil.move(src, dest)
850 Optional parameters are: none \n
851 Required parameters are: none
855 StdHepTool.__init__(self,
861 Return list of optional parameters.
863 Optional parameters are: none
864 @return list of optional parameters
870 Return list of required parameters.
872 Required parameters are: none
873 @return list of required parameters
880 Count number of events in a StdHep file.
884 Component.__init__(self,
886 command=
'stdhep_count.sh',
891 Setup command arguments.
892 @return list of arguments
898 """! Execute StdHepCount component."""
901 proc = subprocess.Popen(cl, stdout=PIPE)
902 (output, err) = proc.communicate()
904 nevents = int(output.split()[1])
905 print(
"StdHep file '%s' has %d events." % (self.
input_files()[0], nevents))
907 return proc.returncode
912 Generic base class for Java based tools.
922 Component.__init__(self,
929 Return list of required config.
931 Required config are: **hps_java_bin_jar**
932 @return list of required config
934 return [
'hps_java_bin_jar']
938 Setup command arguments.
939 @return list of arguments
943 self.
logger.debug(
"Setting java_args from config: %s" + self.
java_args)
959 Convert EVIO events to LCIO using the hps-java EvioToLcio command line tool.
961 Input files have evio format (format used by DAQ system).
963 Required parameters are: **detector**, **steering_files** \n
964 Optional parameters are: **run_number**, **skip_events**, **nevents**, **event_print_interval**
979 JavaTool.__init__(self,
981 java_class=
'org.hps.evio.EvioToLcio',
987 Return list of required parameters.
989 Required parameters are: **detector**, **steering_files**
990 @return list of required parameters
992 return [
'detector',
'steering_files']
996 Return list of optional parameters.
998 Optional parameters are: **run_number**, **skip_events**, **nevents**, **event_print_interval**
999 @return list of optional parameters
1001 return [
'run_number',
'skip_events',
'nevents',
'event_print_interval']
1004 """! Setup EvioToLcio component."""
1012 Setup command arguments.
1013 @return list of arguments
1015 args = JavaTool.cmd_args(self)
1017 raise Exception(
'No output files were provided.')
1019 args.append(
'-DoutputFile=%s' % os.path.splitext(output_file)[0])
1028 self.
logger.debug(
"Steering does not exist at '%s' so assuming it is a resource." % self.
steering_file)
1031 raise Exception(
"Steering looks like a file but is not an abs path: %s" % self.
steering_file)
1040 args.append(inputfile)
1050 Space MC events and apply energy filters to process before readout.
1052 Optional parameters are: **filter_ecal_hit_ecut**, **filter_event_interval**,
1053 **filter_nevents_read**, **filter_nevents_write**, **filter_no_cuts** \n
1054 Required config are: **hps_java_bin_jar**
1058 if 'filter_no_cuts' in kwargs:
1064 if 'filter_ecal_pairs' in kwargs:
1069 if 'filter_ecal_hit_ecut' in kwargs:
1076 if 'filter_event_interval' in kwargs:
1082 if 'filter_nevents_read' in kwargs:
1088 if 'filter_nevents_write' in kwargs:
1096 JavaTool.__init__(self,
1097 name=
'filter_bunches',
1098 java_class=
'org.hps.util.FilterMCBunches',
1103 """! Configure FilterBunches component."""
1106 if os.getenv(
'HPS_JAVA_BIN_JAR',
None)
is not None:
1112 Setup command arguments.
1113 @return list of arguments
1115 args = JavaTool.cmd_args(self)
1138 Return list of optional parameters.
1140 Optional parameters are: **filter_ecal_hit_ecut**, **filter_event_interval**,
1141 **filter_nevents_read**, **filter_nevents_write**, **filter_no_cuts** \n
1142 @return list of optional parameters
1144 return [
'filter_ecal_hit_ecut',
1145 'filter_event_interval',
1146 'filter_nevents_read',
1147 'filter_nevents_write',
1152 Return list of required config.
1154 Required config are: **hps_java_bin_jar**
1155 @return list of required config
1157 return [
'hps_java_bin_jar']
1162 Apply hodo-hit filter and space MC events to process before readout.
1164 The nevents parameter is not settable from JSON in this class. It should
1165 be supplied as an init argument in the job script if it needs to be
1166 customized (the default nevents and event_interval used to apply spacing
1167 should usually not need to be changed by the user). \n
1169 Optional parameters are: **num_hodo_hits**, **event_interval**
1173 if "num_hodo_hits" in kwargs:
1178 if "event_interval" in kwargs:
1183 JavaTool.__init__(self,
1184 name=
'filter_events',
1185 java_class=
'org.hps.util.ExtractEventsWithHitAtHodoEcal',
1191 Setup command arguments.
1192 @return list of arguments
1194 args = JavaTool.cmd_args(self)
1210 Return list of optional parameters.
1212 Optional parameters are: **num_hodo_hits**, **event_interval**
1213 @return list of optional parameters
1215 return [
'num_hodo_hits',
'event_interval']
1220 Unzip the input files to outputs.
1224 Component.__init__(self,
1230 """! Return list of output files."""
1233 return [os.path.splitext(i)[0]
for i
in self.
input_files()]
1236 """! Execute Unzip component."""
1240 with gzip.open(inputfile,
'rb')
as in_file, open(outputfile,
'wb')
as out_file:
1241 shutil.copyfileobj(in_file, out_file)
1242 self.
logger.debug(
"Unzipped '%s' to '%s'" % (inputfile, outputfile))
1248 Dump LCIO event information.
1250 Required parameters are: none \n
1251 Required config are: **lcio_dir**
1257 Component.__init__(self,
1258 name=
'lcio_dump_event',
1259 command=
'dumpevent',
1262 if "event_num" in kwargs:
1268 """! Configure LCIODumpEvent component."""
1274 """! Setup LCIODumpEvent component."""
1279 Setup command arguments.
1280 @return list of arguments
1283 raise Exception(
"Missing required inputs for LCIODumpEvent.")
1291 Return list of required config.
1293 Required config are: **lcio_dir**
1294 @return list of required config
1300 Return list of required parameters.
1302 Required parameters are: none
1303 @return list of required parameters
1310 Count events in an LHE file.
1313 def __init__(self, minevents=0, fail_on_underflow=False, **kwargs):
1315 Component.__init__(self,
1320 """! Setup LHECount component."""
1322 raise Exception(
"Missing at least one input file.")
1326 Check if command exists.
1327 @return True if command exists
1332 """! Execute LHECount component."""
1334 with gzip.open(i,
'rb')
as in_file:
1335 lines = in_file.readlines()
1339 if "<event>" in line:
1342 print(
"LHE file '%s' has %d events." % (i, nevents))
1345 msg =
"LHE file '%s' does not contain the minimum %d events." % (i, nevents)
1346 if self.fail_on_underflow:
1347 raise Exception(msg)
1355 Tar files into an archive.
1359 Component.__init__(self,
1365 Check if command exists.
1366 @return True if command exists
1371 """! Execute TarFiles component."""
1372 self.
logger.debug(
"Opening '%s' for writing ..." % self.
outputs[0])
1373 tar = tarfile.open(self.
outputs[0],
"w")
1375 self.
logger.debug(
"Adding '%s' to archive" % i)
1384 Move input files to new locations.
1388 Component.__init__(self,
1394 Check if command exists.
1395 @return True if command exists
1400 """! Execute TarFiles component."""
1402 raise Exception(
"Input and output lists are not the same length!")
1406 self.
logger.info(
"Moving %s -> %s" % (src, dest))
1407 shutil.move(src, dest)
1413 Generic component for LCIO tools.
1415 Required parameters are: none \n
1416 Required config are: **lcio_bin_jar**
1422 Component.__init__(self,
1428 """! Configure LCIOTool component."""
1435 Setup command arguments.
1436 @return list of arguments
1439 raise Exception(
"Name required to write cmd args for LCIOTool.")
1444 Return list of required config.
1446 Required config are: **lcio_bin_jar**
1447 @return list of required config
1449 return [
'lcio_bin_jar']
1453 Return list of required parameters.
1455 Required parameters are: none
1456 @return list of required parameters
1463 Concatenate LCIO files together.
1467 LCIOTool.__init__(self,
1473 Setup command arguments.
1474 @return list of arguments
1476 args = LCIOTool.cmd_args(self)
1478 raise Exception(
"Missing at least one input file.")
1480 raise Exception(
"Missing an output file.")
1482 args.extend([
"-f", i])
1483 args.extend([
"-o", self.
outputs[0]])
1489 Count events in LCIO files.
1491 Required parameters are: none \n
1492 Optional parameters are: none
1496 LCIOTool.__init__(self,
1502 Setup command arguments.
1503 @return list of arguments
1505 args = LCIOTool.cmd_args(self)
1507 raise Exception(
"Missing an input file.")
1513 Return list of required parameters.
1515 Required parameters are: none
1516 @return list of required parameters
1522 Return list of optional parameters.
1524 Optional parameters are: none
1525 @return list of optional parameters
1536 LCIOTool.__init__(self,
1542 Setup command arguments.
1543 @return list of arguments
1545 args = LCIOTool.cmd_args(self)
1547 raise Exception(
"Missing at least one input file.")
1549 raise Exception(
"Missing an output file.")
1551 args.extend([
"-f", i])
1552 args.extend([
"-o", self.
outputs[0]])
Base class for components in a job.
output_files(self)
Return a list of output files created by this component.
config_from_environ(self)
Configure component from environment variables which are just upper case versions of the required con...
cmd_args(self)
Return the command arguments of this component.
input_files(self)
Get a list of input files for this component.
Miscellaneous math functions.