Skip to content

reco error update#4176

Merged
osbornjd merged 8 commits into
sPHENIX-Collaboration:masterfrom
bogui56:master
Feb 17, 2026
Merged

reco error update#4176
osbornjd merged 8 commits into
sPHENIX-Collaboration:masterfrom
bogui56:master

Conversation

@bogui56

@bogui56 bogui56 commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work for users)
  • Requiring change in macros repository (Please provide links to the macros pull request in the last section)
  • I am a member of GitHub organization of sPHENIX Collaboration, EIC, or ECCE (contact Chris Pinkenburg to join)

What kind of change does this PR introduce? (Bug fix, feature, ...)

TODOs (if applicable)

Links to other PRs in macros and calibration repositories (if applicable)

Cluster Error Parametrization Update for Data vs. MC Reconstruction

Motivation / Context

Introduce a runtime distinction between real data and Monte‑Carlo reconstruction so cluster error parametrizations can apply detector- and reconstruction‑mode specific scalings. This allows different phi/z error treatments for data vs MC while preserving existing public interfaces.

Key changes

  • Add runtime mode detection using phool/recoConsts.h to branch data vs MC reconstruction logic.
  • Expand ClusterErrorPara to initialize many TF1 polynomial fits and empirical constants (phi/z ADC polynomials, fine/adc corrections, MM-specific polynomials, etc.).
  • Rework get_clusterv5_modified_error and internal error computations to use data vs MC branches with:
    • Per-detector (MVTX, INTT, MICROMEGAS, TPC) and per-layer multipliers.
    • Size-dependent (PhiSize/ZSize) modifiers and piecewise/interval polynomial evaluations for phi and z scaling.
    • Clamping and thresholds to limit phi/z errors on the MC path.
  • Preserve public API signatures; changes are internal to ClusterErrorPara.{cc,h}.

Potential risk areas

  • Reconstruction behavior: Error estimates now depend on runtime tag — seeding, fits, and downstream tracking can change; validate on representative data and MC samples.
  • Mode detection fragility: Branch selection relies on recoConsts/global tag parsing; changes to tag naming or environment could mis-select behavior.
  • Thread-safety: ClusterErrorPara holds many TF1* members created/deleted in ctor/dtor. Ensure TF1 usage is safe in multi-threaded execution and that sharing these objects across threads does not cause races.
  • Performance: Added polynomial evaluations and extra branching per cluster may increase per-cluster cost; benchmark impact on reconstruction throughput.
  • Maintainability & correctness: Numerous hard-coded multipliers, piecewise ranges, and manual clamps increase complexity and risk of subtle bugs or mis-tuned parameters.
  • Silent downstream changes: No IO or interface versioning — consumers may observe different errors without explicit notification.

Possible future improvements

  • Move empirical constants, piecewise rules, and polynomials into recoConsts, calibration DB, or external config for easier tuning and provenance.
  • Replace raw TF1 pointers with thread-safe, central fit-evaluation utilities or per-thread instances to avoid races and simplify ownership.
  • Add unit/integration tests and validation jobs comparing data vs MC error distributions and tracking performance.
  • Provide an explicit API or config flag to force data/MC mode for reproducible testing (in addition to tag parsing).
  • Document the origin and validation plots for the empirical fits and multipliers.

Note: This summary was produced with AI assistance. Please verify numeric values and code details carefully — AI can make mistakes and may misinterpret subtle implementation specifics.

@coderabbitai

coderabbitai Bot commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces a runtime is_data_reco distinction (via phool/recoConsts.h and CDB_GLOBALTAG parsing) and splits cluster error parameterization into separate data vs MC branches. Expands per-detector and per-layer error scaling (TPC, MVTX, INTT, MICROMEGAS) with inline polynomial evaluations, size-dependent multipliers, clamps/thresholds, and initialization scaffolding for polynomial coefficients.

Changes

Cohort / File(s) Summary
Cluster error logic
offline/packages/trackbase/ClusterErrorPara.cc
Added runtime is_data_reco flag using phool/recoConsts.h; replaced prior one-time/static determination. Split error computation into data and MC paths; added per-detector and per-layer branching for TPC, MVTX, INTT, MICROMEGAS; introduced size-dependent phi/z multipliers, clamps and thresholds; replaced several TF1-based evaluations with inline polynomial (pol2) calculations; added initialization scaffolding for polynomial coefficient members (e.g., f0,f1,f2,fz0,fz1,fz2,fmm_* , fadcphi*).
Header whitespace
offline/packages/trackbase/ClusterErrorPara.h
Minor formatting change: inserted a blank line in private member declarations (no public API or behavioral signature changes).

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Comment thread offline/packages/trackbase/ClusterErrorPara.cc Outdated
Comment on lines +533 to 692
}else{

if (TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId)
{
if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39 || layer == 54)
{
phierror *= 4;
zerror *= 4;
}
if (cluster->getEdge() >= 3)
{
phierror *= 4;
}
if (cluster->getOverlap() >= 2)
{
phierror *= 2;
}
if(layer>=7&&layer<(7+48)){
//Set phi error
if (cluster->getPhiSize() == 1)
{
phierror *= 1.0;
}
if (cluster->getPhiSize() == 2)
{
phierror*=3.15;
}
if (cluster->getPhiSize() == 3)
{
phierror *=3.5;
}
if (cluster->getPhiSize() >3)
{
phierror *= 4;
}
//Set Z Error
if (cluster->getZSize() == 1){
zerror*=1.0;
}
if (cluster->getZSize() == 2){
if(layer>=7&&layer<(7+16)){
zerror*=7;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=4.5;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=4.5;
}

}
if ((cluster->getZSize() == 3) || (cluster->getZSize() == 4)){
if(layer>=7&&layer<(7+16)){
zerror*=7;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=5;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=5;
}
// zerror*=6;
}
if (cluster->getZSize() >5){
if(layer>=7&&layer<(7+16)){
zerror*=20;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=6;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=7;
}
}
TF1 ftpcR1("ftpcR1", "pol2", 0, 60);
ftpcR1.SetParameter(0, 3.206);
ftpcR1.SetParameter(1, -0.252);
ftpcR1.SetParameter(2, 0.007);

TF1 ftpcR2("ftpcR2", "pol2", 0, 60);
ftpcR2.SetParameter(0, 4.48);
ftpcR2.SetParameter(1, -0.226);
ftpcR2.SetParameter(2, 0.00362);

TF1 ftpcR3("ftpcR3", "pol2", 0, 60);
ftpcR3.SetParameter(0, 14.8112);
ftpcR3.SetParameter(1, -0.577);
ftpcR3.SetParameter(2, 0.00605);

if(layer>=7&&layer<(7+16)){
phierror*= ftpcR1.Eval(layer);
}
if(layer>=(7+16)&&layer<(7+32)){
phierror*= ftpcR2.Eval(layer);
}
if(layer>=(7+32)&&layer<(7+48)){
phierror*= ftpcR3.Eval(layer);
}
ftpcR2.SetParameter(0, 5.593);
ftpcR2.SetParameter(1, -0.2458);
ftpcR2.SetParameter(2, 0.00333455);

ftpcR3.SetParameter(0, 5.6964);
ftpcR3.SetParameter(1, -0.21338);
ftpcR3.SetParameter(2, 0.002502);

if(layer>=(7+16)&&layer<(7+32)){
zerror*= ftpcR2.Eval(layer);
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*= ftpcR3.Eval(layer);
}
}
if (cluster->getPhiSize() >= 5)
{
phierror *= 10;
}
}

if (TrkrDefs::getTrkrId(key) == TrkrDefs::mvtxId){
phierror*=2;
zerror*=2;
}
if (cluster->getPhiSize() >= 5)
{
phierror *= 10;

if (TrkrDefs::getTrkrId(key) == TrkrDefs::inttId){
phierror*=9;
if (cluster->getPhiSize() == 1){
phierror *= 1.25;
}
if (cluster->getPhiSize() == 2){
phierror *= 2.25;
}
if(layer==3||layer==4)
phierror*=0.8;
if(layer==5||layer==6)
phierror*=1.2;
}

phierror = std::min(phierror, 0.1);
if (phierror < 0.0005)
{
phierror = 0.1;

if (TrkrDefs::getTrkrId(key) == TrkrDefs::micromegasId){
if(layer==55){
/*
phierror*=5.4;
phierror*=4.6;
phierror*=3.0;
zerror*=0.82;
*/
phierror = 0.0289;
}

if(layer==56){
/*
phierror*=0.9;
phierror*=0.95;
zerror*=4.5;
zerror*=3.4;
*/
zerror = 0.577;
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Data-reco TPC path is missing the phierror floor/ceiling clamp present in the MC path.

The MC branch (lines 527–531) enforces phierror = std::min(phierror, 0.1) and floors small values to 0.1. The data branch has no equivalent bounds check for TPC phierror or zerror, so extreme values (very small errors from the polynomial, or very large accumulated multipliers) can propagate unchecked. Verify this is intentional — unbounded errors can destabilize track fitting.

Comment thread offline/packages/trackbase/ClusterErrorPara.cc Outdated
Comment thread offline/packages/trackbase/ClusterErrorPara.cc Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Comment on lines 25 to 34
ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)}
{
/*
ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10);
ftpcR1->SetParameter(0, 3.206);
ftpcR1->SetParameter(1, -0.252);
ftpcR1->SetParameter(2, 0.007);
*/

f0 = new TF1("f0", "pol1", 0, 10);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Memory leak: f0 is allocated twice — once in the member-initializer list, once in the constructor body.

Line 25 allocates f0 via the member-init list (f0{new TF1(...)}), then line 34 allocates a second TF1 and overwrites the pointer, leaking the first. Each leaked TF1 also registers itself in ROOT's gDirectory.

Remove the member-initializer allocation and keep only the body assignment (which sets the parameters), or vice versa.

Proposed fix
-ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)}
+ClusterErrorPara::ClusterErrorPara()
 {
-  /*
-  ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10);
-  ftpcR1->SetParameter(0, 3.206);
-  ftpcR1->SetParameter(1, -0.252);
-  ftpcR1->SetParameter(2, 0.007);
-  */
-  
   f0 = new TF1("f0", "pol1", 0, 10);

Comment on lines +546 to +650
if (cluster->getOverlap() >= 2)
{
phierror *= 2;
}
if(layer>=7&&layer<(7+48)){
//Set phi error
if (cluster->getPhiSize() == 1)
{
phierror *= 1.0;
}
if (cluster->getPhiSize() == 2)
{
phierror*=3.15;
}
if (cluster->getPhiSize() == 3)
{
phierror *=3.5;
}
if (cluster->getPhiSize() >3)
{
phierror *= 4;
}
//Set Z Error
if (cluster->getZSize() == 1){
zerror*=1.0;
}
if (cluster->getZSize() == 2){
if(layer>=7&&layer<(7+16)){
zerror*=7;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=4.5;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=4.5;
}

}
if ((cluster->getZSize() == 3) || (cluster->getZSize() == 4)){
if(layer>=7&&layer<(7+16)){
zerror*=7;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=5;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=5;
}
// zerror*=6;
}
if (cluster->getZSize() >5){
if(layer>=7&&layer<(7+16)){
zerror*=20;
}
if(layer>=(7+16)&&layer<(7+32)){
zerror*=6;
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*=7;
}
}
TF1 ftpcR1("ftpcR1", "pol2", 0, 60);
ftpcR1.SetParameter(0, 3.206);
ftpcR1.SetParameter(1, -0.252);
ftpcR1.SetParameter(2, 0.007);

TF1 ftpcR2("ftpcR2", "pol2", 0, 60);
ftpcR2.SetParameter(0, 4.48);
ftpcR2.SetParameter(1, -0.226);
ftpcR2.SetParameter(2, 0.00362);

TF1 ftpcR3("ftpcR3", "pol2", 0, 60);
ftpcR3.SetParameter(0, 14.8112);
ftpcR3.SetParameter(1, -0.577);
ftpcR3.SetParameter(2, 0.00605);

if(layer>=7&&layer<(7+16)){
phierror*= ftpcR1.Eval(layer);
}
if(layer>=(7+16)&&layer<(7+32)){
phierror*= ftpcR2.Eval(layer);
}
if(layer>=(7+32)&&layer<(7+48)){
phierror*= ftpcR3.Eval(layer);
}
ftpcR2.SetParameter(0, 5.593);
ftpcR2.SetParameter(1, -0.2458);
ftpcR2.SetParameter(2, 0.00333455);

ftpcR3.SetParameter(0, 5.6964);
ftpcR3.SetParameter(1, -0.21338);
ftpcR3.SetParameter(2, 0.002502);

if(layer>=(7+16)&&layer<(7+32)){
zerror*= ftpcR2.Eval(layer);
}
if(layer>=(7+32)&&layer<(7+48)){
zerror*= ftpcR3.Eval(layer);
}
}
if (cluster->getPhiSize() >= 5)
{
phierror *= 10;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

phiSize >= 5 gets a compounded 40× multiplier — likely unintentional double-hit.

Inside the layer>=7 && layer<55 block, line 564 applies phierror *= 4 for phiSize > 3 (which includes phiSize ≥ 5). Then outside that block but still inside the tpcId scope, line 646 applies phierror *= 10 for phiSize >= 5. The two multiply together yielding 40× for large clusters, whereas phiSize == 4 only gets 4×.

This 10× discontinuity between phiSize 4 and 5 (after TF1 factors) is suspicious. If both conditions are intentional, they should be documented; otherwise, the inner condition at line 564 should use == 4 or the outer check at line 646 should be removed.

If the intent is a single 10× for phiSize≥5 (matching MC branch pattern)
-	  if (cluster->getPhiSize() >3)
+	  if (cluster->getPhiSize() == 4)
	    {
	      phierror *= 4;
	    }

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit f34b4423c5e8e2d12394c46a3f52fd9ac84f397c:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit e13fbb091d87c78fdadf87e397640bad2df84d07:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Comment thread offline/packages/trackbase/ClusterErrorPara.cc Outdated
Comment thread offline/packages/trackbase/ClusterErrorPara.cc

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment thread offline/packages/trackbase/ClusterErrorPara.cc
@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit 3d74e878218b940240de2922392be3fd02545830:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit 0ae0e709d54e7f8ae674289c036dff0f79a4778a:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit ee1177c011476e8f7a8d535dd08ea25b3a5d04af:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit e18101b7274693507df186e239b1d9751a6ea263:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit e11adf0566fe8cfa6db382c1499077fabf2d29cd:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci

Copy link
Copy Markdown

Build & test report

Report for commit 4c4088d2cf901636843a4fdfb79731a895e818f4:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@osbornjd osbornjd merged commit 1a5eddd into sPHENIX-Collaboration:master Feb 17, 2026
22 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Mar 2, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants