Back to home page

EIC code displayed by LXR

 
 

    


Warning, /snippets/Tracking/svt_rate_per_source/README.md is written in an unsupported language. File is not indexed.

0001 # SVT reconstructed-hit rates by source
0002 Original implemented by Shujie Li, Oct 2026. 
0003 Refactored by Chatgpt. 
0004 
0005 Read EICrecon `events` trees, assign each SVT reconstructed hit to its MC source,
0006 and produce surface maps and rate tables. Copy this entire folder anywhere;
0007 it needs no files or imports from the parent analysis project, ROOT bindings,
0008 PODIO bindings, or detector installation. Input data and Python packages are
0009 the only external requirements.
0010 
0011 | File | Purpose |
0012 | --- | --- |
0013 | `plot_hit_rate_per_source.py` | Command-line workflow: chunked input → counts → rates → PDFs/CSV. |
0014 | `svt_sources.py` | Explicit SVT windows, relation names, source mapping, and ancestry tracing. |
0015 | `requirements.txt` | Four required Python packages; Python 3.9 or newer. |
0016 | `test_svt_rate.py` | Offline numerical, relation, chunking, and output checks. |
0017 
0018 ## Start here
0019 
0020 Use an existing analysis environment, or create one from this folder:
0021 
0022 ```bash
0023 python3 -m venv .venv
0024 source .venv/bin/activate
0025 python -m pip install -r requirements.txt
0026 # Only for root:// inputs; omit when using local files:
0027 python -m pip install XRootD
0028 python plot_hit_rate_per_source.py --help
0029 ```
0030 
0031 A short check on a local file, followed by a full run:
0032 
0033 ```bash
0034 python -u plot_hit_rate_per_source.py \
0035   --input-files /path/to/sample.eicrecon.edm4eic.root \
0036   --label check --entry-stop 10 --chunk-size 5
0037 
0038 python -u plot_hit_rate_per_source.py \
0039   --input-files /path/to/sample.eicrecon.edm4eic.root \
0040   --label full --chunk-size 50
0041 ```
0042 
0043 Outputs default to `outputs/LABEL/` beside the script. Use a new label for
0044 each run; nonempty output folders are protected from overwriting. Save your
0045 production command in a shell script before running it.
0046 
0047 ## Several files or remote input
0048 
0049 Pass several paths after `--input-files`, or use `--file-list inputs.txt`.
0050 The text list contains one local path or full URL per line; blank lines and
0051 lines beginning with `#` are ignored. Local paths in a list are relative to
0052 the list's directory; command-line paths are relative to your working directory.
0053 Both forms accept an optional `:events` suffix. Duplicate inputs are rejected.
0054 
0055 JLab's current XRootD layout is:
0056 
0057 ```text
0058 root://dtn2304.jlab.org:8443//jlab-osdf-ro/eic/EPIC/volatile/RECO/<campaign>/<dataset>/<file>.root
0059 ```
0060 
0061 Use an actual file URL from the [EIC production file catalog/access guide](https://eic.github.io/software/production_file.html);
0062 availability depends on the campaign. BNL and other full URLs are accepted
0063 unchanged. This release opens exactly the supplied locations; it does not
0064 switch servers automatically.
0065 
0066 ```bash
0067 python -u plot_hit_rate_per_source.py \
0068   --file-list inputs.txt --label production --chunk-size 50
0069 
0070 # Same inputs and normalization, finer spatial bins:
0071 python -u plot_hit_rate_per_source.py \
0072   --file-list inputs.txt --label production_tile --chunk-size 50 --tile
0073 ```
0074 
0075 | Option | Interpretation |
0076 | --- | --- |
0077 | `--entry-start A --entry-stop B` | Process `[A, B)` separately in every file; stop is clipped to its length. |
0078 | `--max-files N` | First N listed files; convenient for a quick check. |
0079 | `--chunk-size N` | Memory/IO control only; default 10 events. Reduce for busy background frames. |
0080 | `--frame-us T` | Duration of each equal-weight frame; default 2 µs. Controls rate normalization. |
0081 | `--tile` | 3.5 × 9.8 mm bins; default is 20 × 20 mm, called RSU here. |
0082 | `--min-surface-hits N` | Omit sparse PDF pages; preserves all counts and CSV rows. Default 1. |
0083 | `--output-dir DIR` | Write under `DIR/LABEL/`. |
0084 
0085 ## Physics conventions — read before interpreting rates
0086 
0087 Each selected event must represent the same physical duration and have equal
0088 statistical weight. Zero-hit frames count in the denominator. Files are pooled
0089 by event count, not averaged with equal weight per file.
0090 
0091 ```text
0092 N = total number of selected event frames across all files
0093 T = duration per frame in µs
0094 rate_scale = 1000 / (N × T)                  [kHz per counted hit]
0095 bin_rate = accumulated hits in bin × rate_scale
0096 surface_rate = sum of in-map bin rates
0097 peak_bin_rate = maximum of the accumulated bin rates
0098 ```
0099 
0100 At T = 2 µs, this reproduces the original `500/N` scale. It estimates hit
0101 arrival rates, not the probability of occupancy, event rate, or a rate per area.
0102 Single-particle or triggered/weighted DIS samples need an appropriate physical
0103 normalization; the default 2 µs assumption does not establish one.
0104 
0105 The source path is `RecHit → RawHit → RawHitAssociation → SimHit → MCParticle`.
0106 For multiple associations, choose the largest weight; equal weights choose
0107 the first row. For `generatorStatus == 0`, repeatedly follow the first MC
0108 parent to a nonzero status. Cycles, missing parents, invalid parent ranges,
0109 and chains beyond 100 links remain unresolved and enter `other`. ObjectID
0110 indices are event-local within the explicitly named collections; collection
0111 IDs are not remapped to alternative detector collections.
0112 
0113 | MC generatorStatus | Source label |
0114 | --- | --- |
0115 | 1, 2 | DIS |
0116 | 2001, 2002 | SR |
0117 | 3001, 3002 | Bremstrahlung (spelling retained from the parent workflow) |
0118 | 4001, 4002 | Coulomb |
0119 | 5001, 5002 | Touschek |
0120 | 6001, 6002 | Proton beam gas |
0121 | Other values, including unresolved 0 | other |
0122 
0123 `unmatched` means a valid raw-hit index has no association. `invalid_relation`
0124 covers null rec-hit relations, invalid selected sim/particle indices, and
0125 nonfinite or negative weights. Diagnostics are always saved in `*_run.json`.
0126 `ALL` includes every in-map rec hit, including these categories.
0127 `other background` is the inclusive sum of the four non-SR beam backgrounds;
0128 do not add it or `ALL` to the exclusive sources when computing a total.
0129 The program checks exclusive-source conservation against `ALL` bin by bin.
0130 
0131 Barrels use `(z, rφ)`, with `φ = atan2(y, x)` in radians and r in mm; disks
0132 use `(x, y)`. The five barrel and ten disk windows are listed in
0133 `svt_sources.py`; window endpoints are excluded. These fixed projected grids
0134 approximate RSU/tile dimensions, not the physical sensor segmentation or
0135 cellID layout. Bins are anchored at the negative map edge and have full nominal
0136 widths; the final bin may extend beyond the nominal map extent. Selected hits
0137 outside the grids appear in `outside_map_hits` and are excluded from rates.
0138 Update the windows when using a different geometry.
0139 
0140 ## Outputs and reuse
0141 
0142 | `LABEL_…` output | Contents |
0143 | --- | --- |
0144 | `SOURCE_svt_hit_rate.pdf` | One page per populated surface; color is bin rate in kHz. |
0145 | `summary.csv` | Long table by `lname`, `source`, and `rec_branch`; rates, raw counts, occupied-frame counts, and out-of-map counts. |
0146 | `input_files.csv` | Exact URLs/paths, available events, actual `[start, stop)` ranges, and processed counts, including skipped files. |
0147 | `maps.npz` | Integer raw histograms and bin edges in mm; axes are `(x, y)` as defined above. |
0148 | `run.json` | Normalization, arguments, versions, code hashes, windows, relations, diagnostics, and archive-key index. |
0149 
0150 `rsu_or_tile_max_rate_khz` is the peak of the time-averaged map;
0151 `max_raw_hits_per_event_tile` is the largest bin count in any single frame
0152 (the historical column name is retained for RSU runs too).
0153 Absent source/surface rows mean no hits were accumulated for that source.
0154 
0155 CSV headers beginning with `#` contain normalization metadata. Example:
0156 
0157 ```python
0158 import pandas as pd  # Optional; not required to run this release.
0159 summary = pd.read_csv("outputs/full/full_summary.csv", comment="#")
0160 ```
0161 
0162 Recover a rate map without rereading ROOT:
0163 
0164 ```python
0165 import json
0166 import numpy as np
0167 run = json.load(open("outputs/full/full_run.json"))
0168 with np.load("outputs/full/full_maps.npz") as maps:
0169     entry = next(m for m in run["maps"] if m["lname"] == "L0" and m["source"] == "ALL")
0170     rate_khz = maps[entry["key"]] * run["rate_scale_khz_per_count"]
0171     xedges_mm = maps[entry["xedges_key"]]
0172     yedges_mm = maps[entry["yedges_key"]]
0173 ```
0174