Skip to content

Commit 50391b1

Browse files
committed
feat: qtl xcharge for charge and clock analyses
1 parent d65540e commit 50391b1

7 files changed

Lines changed: 177 additions & 22 deletions

File tree

bin/qtl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ usage() {
1818
physics Generate and analyze physics QA timelines (Step 2)
1919
error Scan for errors in Slurm logs (for Step 1)
2020
reheat Reproduce a data file, e.g., to rerun postprocessing
21+
xcharge Cross check and analyze FC charge
2122
xtrain Cross check run list from trains and DSTs
2223
2324
OPTIONS: Each command has its own set of options; run a command with no
@@ -42,6 +43,7 @@ case $cmd in
4243
ph*) exec $TIMELINESRC/bin/qtl-physics "$@" ;;
4344
er*) exec $TIMELINESRC/bin/qtl-error "$@" ;;
4445
re*) exec $TIMELINESRC/bin/qtl-reheat "$@" ;;
46+
xc*) exec $TIMELINESRC/bin/qtl-xcharge "$@" ;;
4547
xt*) exec $TIMELINESRC/bin/qtl-xtrain "$@" ;;
4648
-v|--version)
4749
echo $(mvn -q help:evaluate -Dexpression=project.version -DforceStdout -f $TIMELINESRC/pom.xml || echo "UNKNOWN")

bin/qtl-xcharge

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
source $(dirname $0)/../libexec/environ.sh
5+
6+
# constants ############################################################
7+
# methods: name -> description
8+
declare -A METHODS=(
9+
[charge]="run charge analysis (from Bhawani)"
10+
[clock]="plot the clock vs timestamp"
11+
)
12+
########################################################################
13+
14+
# usage
15+
suffix=''
16+
sep="================================================================"
17+
usage() {
18+
echo """
19+
Take a closer look at the FC charge
20+
NOTE: chefs should not typically need to run this
21+
22+
$sep
23+
USAGE: qtl xcharge [OPTIONS]
24+
$sep
25+
26+
REQUIRED OPTIONS:
27+
-i [INPUT_FILE] input HIPO file
28+
-o [OUTPUT_DIR] output directory
29+
-m [METHOD] which analysis method, one of:
30+
$(for key in "${!METHODS[@]}"; do printf "%24s %-11s %-s\n" "" "$key" "${METHODS[$key]}"; done)
31+
32+
OPTIONAL OPTIONS:
33+
-s [SUFFIX] a suffix to append to output files
34+
default: $suffix
35+
""" >&2
36+
}
37+
if [ $# -lt 1 ]; then
38+
usage
39+
exit 101
40+
fi
41+
42+
# parse options
43+
inputFile=""
44+
outputDir=""
45+
mtd=""
46+
while getopts "i:o:m:s:h-:" opt; do
47+
case $opt in
48+
i) inputFile=$OPTARG ;;
49+
o) outputDir=$OPTARG ;;
50+
m)
51+
[ -z "${METHODS[$OPTARG]-}" ] && printError "unknown command '$OPTARG'" && exit 100
52+
mtd=$OPTARG
53+
;;
54+
s) suffix=$OPTARG ;;
55+
h)
56+
usage
57+
exit 101
58+
;;
59+
*) exit 100 ;;
60+
esac
61+
done
62+
63+
# check arguments
64+
[ -z "$inputFile" ] && printError "missing input directory argument" && exit 100
65+
[ -z "$outputDir" ] && printError "missing output directory argument" && exit 100
66+
[ -z "$mtd" ] && printError "missing method argument" && exit 100
67+
68+
# make output directory
69+
mkdir -p $outputDir
70+
71+
# run the script
72+
case $mtd in
73+
charge)
74+
$TIMELINESRC/qa-physics/charge_analysis/analyze_charge.py $inputFile $outputDir $suffix
75+
;;
76+
clock)
77+
$TIMELINESRC/libexec/run-groovy-timeline.sh $TIMELINESRC/qa-physics/charge_analysis/analyze_clock.groovy $inputFile $outputDir $suffix
78+
root -b -q $TIMELINESRC/qa-physics/charge_analysis/plot_clock.C'("'$outputDir'", "'$suffix'")'
79+
;;
80+
*)
81+
echo "ERROR: unknown method '$mtd'" >&2
82+
exit 100
83+
;;
84+
esac
85+
echo "Done, see files in '$outputDir' with suffix '$suffix'"
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1+
These scripts are called by `qtl xcharge`
2+
13
# Charge Analysis
24

35
From Bhawani Singh
46

5-
`./analyze.py` Produces PNG files comparing the DAQ-gated FC charge determined from
7+
`./analyze_charge.py` Produces PNG files comparing the DAQ-gated FC charge determined from
68
- the `RUN::scaler` bank directly
79
- the livetime and ungated charge, by multiplication
810

9-
### Example
10-
11-
Suppose we have reheated (`qtl reheat`) a skim file on `/cache` and
12-
stored it at `/volatile/reheat/`. To compare results:
13-
14-
```bash
15-
./analyze.py /cache/...../skim.hipo before_reheat
16-
./analyze.py /volatile/reheat/skim.hipo after_reheat
17-
ls -t *.png
18-
```
11+
# Clock analysis
12+
- `analyze_clock.groovy`: gets the clock for each timestamp
13+
- `plot_clock.C`: plots the clock vs. timestamp

qa-physics/charge_analysis/analyze.py renamed to qa-physics/charge_analysis/analyze_charge.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,18 @@
2222

2323
def main():
2424

25-
if len(sys.argv) != 3:
25+
if len(sys.argv) != 4:
2626
print(f'''
27-
USAGE: {sys.argv[0]} [INPUT_HIPO_FILE] [OUTPUT_FILE_SUFFIX]
27+
USAGE: {sys.argv[0]} [INPUT_HIPO_FILE] [OUTPUT_DIR] [OUTPUT_FILE_SUFFIX]
2828
INPUT_HIPO_FILE input HIPO file
2929
OUTPUT_FILE_SUFFIX append this string to the output
3030
file name; useful if you are comparing
3131
output files before and after reheating
3232
''')
3333
exit(2)
34-
hipo_file = sys.argv[1]
35-
output_suffix = sys.argv[2]
34+
hipo_file = sys.argv[1]
35+
output_dir = sys.argv[2]
36+
output_suffix = sys.argv[3]
3637

3738
hipo_prefix = os.getenv('HIPO')
3839
if hipo_prefix == None:
@@ -109,7 +110,7 @@ def main():
109110
ax.tick_params(axis='both', labelsize=9)
110111

111112
fig1.tight_layout(rect=[0, 0.03, 1, 0.95])
112-
fig1.savefig(f'fcup_vs_timestamp_{run_number}_{output_suffix}.png', bbox_inches='tight', dpi=300)
113+
fig1.savefig(f'{output_dir}/fcup_vs_timestamp_{run_number}_{output_suffix}.png', bbox_inches='tight', dpi=300)
113114
plt.close(fig1)
114115
# ---------- Compute Chunked FCUP Gated with neighbor handling ----------
115116
chunk_size = 2000
@@ -296,7 +297,7 @@ def main():
296297
ax_ltdist.tick_params(axis='both', labelsize=10)
297298

298299
fig2.tight_layout(rect=[0, 0.03, 1, 0.95])
299-
fig2.savefig(f'chunked_fcupgated_comparison_{run_number}_{output_suffix}.png', bbox_inches='tight', dpi=300)
300+
fig2.savefig(f'{output_dir}/chunked_fcupgated_comparison_{run_number}_{output_suffix}.png', bbox_inches='tight', dpi=300)
300301
plt.close(fig2)
301302

302303

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import org.jlab.detector.scalers.DaqScalers;
2+
import org.jlab.detector.scalers.DaqScalersSequence;
3+
import org.jlab.detector.calib.utils.ConstantsManager;
4+
import org.jlab.jnp.hipo4.io.HipoReader;
5+
import org.jlab.jnp.hipo4.data.Event;
6+
import org.jlab.jnp.hipo4.data.Bank;
7+
import org.jlab.jnp.hipo4.data.SchemaFactory;
8+
import java.util.List;
9+
import java.util.ArrayList;
10+
11+
if(args.length<3) {
12+
System.err.println """
13+
USAGE: groovy ${this.class.getSimpleName()}.groovy [HIPO file] [output directory] [suffix]
14+
"""
15+
System.exit(101)
16+
}
17+
def in_file = args[0]
18+
def out_dir = args[1]
19+
def suffix = args[2]
20+
21+
List<String> filenames = new ArrayList<>();
22+
filenames.add(in_file);
23+
24+
ConstantsManager consts = new ConstantsManager();
25+
consts.init("/runcontrol/fcup","/runcontrol/slm","/runcontrol/helicity","/daq/config/scalers/dsc1","/runcontrol/hwp");
26+
DaqScalersSequence seq = DaqScalersSequence.rebuildSequence(1, consts, filenames);
27+
28+
// seq.fixClockRollover();
29+
30+
def out_file_name = "${out_dir}/clock_${suffix}.dat";
31+
def out_file = new File(out_file_name);
32+
def out_file_writer = out_file.newWriter(false);
33+
34+
out_file_writer << [ "timestamp/L", "clock_gated/L", "clock_ungated/L" ].join(':') << '\n';
35+
36+
for(String filename : filenames) {
37+
HipoReader reader = new HipoReader();
38+
reader.setTags(1);
39+
reader.open(filename);
40+
SchemaFactory schema = reader.getSchemaFactory();
41+
42+
while(reader.hasNext()) {
43+
Bank rcfgBank = new Bank(schema.getSchema("RUN::config"));
44+
Event event = new Event();
45+
reader.nextEvent(event);
46+
event.read(rcfgBank);
47+
long timestamp = -1;
48+
if (rcfgBank.getRows()>0)
49+
timestamp = rcfgBank.getLong("timestamp",0);
50+
DaqScalers ds=seq.get(timestamp);
51+
if (ds!=null) {
52+
out_file_writer << [ds.getTimestamp(), ds.dsc2.gatedClock, ds.dsc2.clock].join(' ') << '\n';
53+
}
54+
}
55+
56+
reader.close();
57+
}
58+
59+
out_file_writer.flush();
60+
out_file_writer.close();
61+
System.out.println("WROTE $out_file_name");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
void plot_clock(TString out_dir, TString suffix) {
2+
TString basename = out_dir + "/clock_" + suffix;
3+
TFile* o = new TFile(basename+".root", "RECREATE");
4+
TTree* tr = new TTree("tr", "tr");
5+
tr->ReadFile(basename+".dat");
6+
tr->Write();
7+
o->Close();
8+
std::cout << "WROTE " << basename << ".root\n";
9+
std::cout << "Recommended plot commands:" << std::endl;
10+
std::cout << " tr->Draw(\"clock_ungated:timestamp\")" << std::endl;
11+
std::cout << " tr->Draw(\"clock_gated:timestamp\")" << std::endl;
12+
}

qadb/notes/rga_sp18.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,15 @@ bin/qtl reheat -m rollover -c 13.3.0 -d rga_sp18_6.4GeV_outbending_lo_nSidis -o
8080
bin/qtl reheat -m rollover -c 13.3.0 -d rga_sp18_6.4GeV_inbending_lo_nSidis -o /volatile/clas12/users/$LOGNAME/reheat/rga_sp18_6.4GeV_inbending_lo_nSidis -i /cache/clas12/rg-a/production/recon/spring2018/6.42gev/torus-0.75/pass1/dst/train/nSidis
8181
```
8282

83-
3. check the results on some runs; see [`qa-physics/charge_analysis/README.md`](/qa-physics/charge_analysis/README.md); for example:
83+
3. check the results on some runs; for example:
8484
```bash
85-
cd qa-physics/charge_analysis
86-
8785
# before reheat
88-
for f in /cache/clas12/rg-a/production/recon/spring2018/6.42gev/torus+1/pass1/dst/train/nSidis/*.hipo; do ./analyze.py $f original; done
86+
for f in /cache/clas12/rg-a/production/recon/spring2018/6.42gev/torus+1/pass1/dst/train/nSidis/*.hipo; do bin/qtl xcharge -m charge -i $f -o test_charge -s original; done
8987

9088
# after reheat
91-
for f in ~/v/reheat/rga_sp18_6.4GeV_outbending_nSidis/*.hipo; do ./analyze.py $f reheated; done
89+
for f in ~/v/reheat/rga_sp18_6.4GeV_outbending_nSidis/*.hipo; do bin/qtl xcharge -m charge -i $f -o test_charge -s original; done
9290
```
91+
then see files in `test_charge/`.
9392

9493
## Run monitoring
9594

0 commit comments

Comments
 (0)