File indexing completed on 2025-08-05 08:11:10
0001
0002 import pandas as pd
0003 import numpy as np
0004 import subprocess
0005 import argparse
0006 import os
0007 import shutil
0008
0009 parser = argparse.ArgumentParser()
0010 subparser = parser.add_subparsers(dest='command')
0011
0012 f4a = subparser.add_parser('f4a', help='Create condor submission directory.')
0013 status = subparser.add_parser('status', help='Get status of Condor.')
0014 gen = subparser.add_parser('gen', help='Generate run lists.')
0015
0016 f4a.add_argument('-i', '--hist-dir', type=str, help='Directory of histogram lists.', required=True)
0017 f4a.add_argument('-e', '--executable', type=str, default='scripts/genStatus.sh', help='Job script to execute. Default: scripts/genStatus.sh')
0018 f4a.add_argument('-m', '--macro', type=str, default='macros/genStatus.C', help='Analysis macro. Default: macros/genStatus.C')
0019 f4a.add_argument('-b', '--f4a', type=str, default='bin/genStatus', help='Analysis executable. Default: bin/genStatus')
0020 f4a.add_argument('-d', '--output', type=str, default='test', help='Output Directory. Default: ./test')
0021 f4a.add_argument('-s', '--memory', type=float, default=0.2, help='Memory (units of GB) to request per condor submission. Default: 0.2 GB.')
0022 f4a.add_argument('-l', '--log', type=str, default='/tmp/anarde/dump/job-$(ClusterId)-$(Process).log', help='Condor log file.')
0023 f4a.add_argument('-n', '--submissions', type=int, default=1, help='Number of submissions. Default: 1.')
0024
0025 gen.add_argument('-o', '--output', type=str, default='files', help='Output Directory. Default: files')
0026 gen.add_argument('-t', '--ana-tag', type=str, default='ana437', help='ana tag. Default: ana437')
0027 gen.add_argument('-s', '--script', type=str, default='scripts/getGoodRunList.py', help='Good run generation script. Default: scripts/getGoodRunList.py')
0028 gen.add_argument('-b', '--bad', type=str, default='files/bad-runs.list', help='List of known bad runs. Default: files/bad-runs.list')
0029
0030 args = parser.parse_args()
0031
0032 def create_f4a_jobs():
0033 hist_dir = os.path.realpath(args.hist_dir)
0034 executable = os.path.realpath(args.executable)
0035 macro = os.path.realpath(args.macro)
0036 f4a = os.path.realpath(args.f4a)
0037 output_dir = os.path.realpath(args.output)
0038 memory = args.memory
0039 log = args.log
0040 n = args.submissions
0041
0042 concurrency_limit = 2308032
0043
0044 print(f'Hist Dir: {hist_dir}')
0045 print(f'Fun4All : {macro}')
0046 print(f'Output Directory: {output_dir}')
0047 print(f'Bin: {f4a}')
0048 print(f'Executable: {executable}')
0049 print(f'Requested memory per job: {memory}GB')
0050 print(f'Condor log file: {log}')
0051 print(f'Submissions: {n}')
0052
0053
0054 os.makedirs(output_dir,exist_ok=True)
0055 shutil.copy(f4a, output_dir)
0056 shutil.copy(macro, output_dir)
0057 shutil.copy(executable, output_dir)
0058
0059 command = f'readlink -f {hist_dir}/* > jobs.list'
0060 subprocess.run(['bash','-c',command],cwd=output_dir)
0061
0062 os.makedirs(f'{output_dir}/stdout',exist_ok=True)
0063 os.makedirs(f'{output_dir}/error',exist_ok=True)
0064 os.makedirs(f'{output_dir}/output',exist_ok=True)
0065
0066 with open(f'{output_dir}/genStatus.sub', mode="w") as file:
0067 file.write(f'executable = {os.path.basename(executable)}\n')
0068 file.write(f'arguments = {output_dir}/{os.path.basename(f4a)} $(input_run) {output_dir}/output\n')
0069 file.write(f'log = {log}\n')
0070 file.write('output = stdout/job-$(Process).out\n')
0071 file.write('error = error/job-$(Process).err\n')
0072 file.write(f'request_memory = {memory}GB\n')
0073 file.write(f'queue input_run from jobs.list')
0074
0075 def get_condor_status():
0076 hosts = [f'sphnx{x:02}' for x in range(1,9)]
0077
0078
0079
0080 dt_all = []
0081 dt_user = []
0082
0083 for host in hosts:
0084 print(f'Progress: {host}')
0085
0086 a = subprocess.run(['bash','-c',f'ssh {host} "condor_q | tail -n 3 | head -n 2"'], capture_output=True, encoding="utf-8")
0087 total = int(a.stdout.split('\n')[-3].split('jobs')[0].split(':')[1])
0088 idle = int(a.stdout.split('\n')[-3].split('idle')[0].split(',')[-1])
0089 running = int(a.stdout.split('\n')[-3].split('running')[0].split(',')[-1])
0090 held = int(a.stdout.split('\n')[-3].split('held')[0].split(',')[-1])
0091
0092 dt_user.append({'host': host, 'total': total, 'idle': idle, 'running': running, 'held': held})
0093
0094 total = int(a.stdout.split('\n')[-2].split('jobs')[0].split(':')[1])
0095 idle = int(a.stdout.split('\n')[-2].split('idle')[0].split(',')[-1])
0096 running = int(a.stdout.split('\n')[-2].split('running')[0].split(',')[-1])
0097 held = int(a.stdout.split('\n')[-2].split('held')[0].split(',')[-1])
0098
0099 dt_all.append({'host': host, 'total': total, 'idle': idle, 'running': running, 'held': held})
0100
0101 print('All')
0102 print(pd.DataFrame(dt_all).to_string(index=False))
0103
0104 print('User')
0105 print(pd.DataFrame(dt_user).to_string(index=False))
0106
0107 def create_run_lists():
0108 ana_tag = args.ana_tag
0109 output = os.path.realpath(args.output)+'/'+ana_tag
0110 gen_runs = os.path.realpath(args.script)
0111 bad_runs = os.path.realpath(args.bad)
0112 dst_tag = 'DST_CALOFITTING_run2pp'
0113
0114 print(f'Tag: {ana_tag}')
0115 print(f'DST: {dst_tag}')
0116 print(f'Output: {output}')
0117 print(f'Good Runs Script: {gen_runs}')
0118 print(f'Known Bad Runs: {bad_runs}')
0119
0120 os.makedirs(output,exist_ok=True)
0121
0122 print('Generating Good Run List')
0123 subprocess.run(f'{gen_runs}'.split(),cwd=output)
0124
0125 print('Generating Bad Tower Maps Run List')
0126 subprocess.run(['bash','-c','find /cvmfs/sphenix.sdcc.bnl.gov/calibrations/sphnxpro/cdb/CEMC_BadTowerMap -name "*p0*" | cut -d \'-\' -f2 | cut -d c -f1 | sort | uniq > runs-hot-maps.list'],cwd=output)
0127
0128 print(f'Generating {ana_tag} 2024p007 Run List')
0129 subprocess.run(['bash','-c',f'CreateDstList.pl --build {ana_tag} --cdb 2024p007 {dst_tag} --printruns > runs-{ana_tag}.list'],cwd=output)
0130
0131 print('Generating Runs with MBD NS >= 1 and Jet X GeV triggers enabled')
0132 subprocess.run(['bash','-c',f'psql -h sphnxdaqdbreplica -p 5432 -U phnxro daq -c \'select runnumber from gl1_scaledown where runnumber > 46619 and scaledown10 != -1 and scaledown21 != -1 and scaledown22 != -1 and scaledown23 != -1 order by runnumber;\' -At > runs-trigger-all.list'],cwd=output)
0133 subprocess.run(['bash','-c',f'psql -h sphnxdaqdbreplica -p 5432 -U phnxro daq -c \'select runnumber from gl1_scaledown where runnumber > 46619 and scaledown10 != -1 and (scaledown21 != -1 or scaledown22 != -1 or scaledown23 != -1) order by runnumber;\' -At > runs-trigger-any.list'],cwd=output)
0134
0135 print(f'Generating Good {ana_tag} 2024p007 Run List')
0136 subprocess.run(['bash','-c',f'comm -12 runList.txt runs-{ana_tag}.list > runs-{ana_tag}-good.list'],cwd=output)
0137
0138 print(f'Generating Good {ana_tag} 2024p007 with Bad Tower Maps Run List')
0139 subprocess.run(['bash','-c',f'comm -12 runs-{ana_tag}-good.list runs-hot-maps.list > runs-{ana_tag}-good-maps.list'],cwd=output)
0140
0141 print(f'Generating Good {ana_tag} 2024p007 with triggers')
0142 subprocess.run(['bash','-c',f'comm -12 runs-{ana_tag}-good-maps.list runs-trigger-all.list > runs-{ana_tag}-good-maps-trigger-all.list'],cwd=output)
0143 subprocess.run(['bash','-c',f'comm -12 runs-{ana_tag}-good-maps.list runs-trigger-any.list > runs-{ana_tag}-good-maps-trigger-any.list'],cwd=output)
0144
0145 print('Remove any known bad runs')
0146 subprocess.run(['bash','-c',f'comm -23 runs-{ana_tag}-good-maps-trigger-all.list {bad_runs} > runs-{ana_tag}-good-maps-trigger-all-clean.list'],cwd=output)
0147 subprocess.run(['bash','-c',f'comm -23 runs-{ana_tag}-good-maps-trigger-any.list {bad_runs} > runs-{ana_tag}-good-maps-trigger-any-clean.list'],cwd=output)
0148
0149 print('Run Stats')
0150 subprocess.run(['bash','-c','wc -l *'],cwd=output)
0151
0152 if __name__ == '__main__':
0153 if(args.command == 'f4a'):
0154 create_f4a_jobs()
0155 if(args.command == 'status'):
0156 get_condor_status()
0157 if(args.command == 'gen'):
0158 create_run_lists()