Skip to content

CalPatRec: static-review audit — correctness, robustness, convention, dead-code findings #1804

@oksuzian

Description

@oksuzian

Preamble

The items below come from a static review of CalPatRec/ on main — no build, no runtime test, no physics validation was performed. Each finding is either a direct read of the source or (where noted) a cross-reference against sibling modules. I've verified the top-tier bugs by re-fetching the exact lines against main; the rest is best-effort.

Intent is to give maintainers a single triaged punch list. Items marked Bugs / Blockers are high-confidence; the rest decrease in certainty as the tier name suggests.


Bugs / Blockers

  1. src/DeltaFinderAlg.cc:596float y1 = dc1->Xc(); should be dc1->Yc();. The subsequent d2 = (x1-x2)² + (y1-y2)² compares the wrong coordinate, so two-delta merging uses (Xc, Xc) vs (Xc, Yc).
  2. src/DeltaFinderAlg.cc:792 — in pruneSeeds: float chi2_ds2 = ds1->Chi2TotN() + ds1->Chi2Time(); uses ds1 twice; should be ds2. ds2 is currently only rejected on ds1's recomputed value.
  3. src/PhiClusterFinder_module.cc:416–420 — right-walk loop has no nsteps/nbx guard that the left-walk has. If every bin ≥ _threshold, infinite loop.
  4. src/PhiClusterFinder_module.cc:404if (bincheck > _threshold) bincheck--; compares a bin index against a content threshold (category error). Should be bincheck > 1.
  5. src/AgnosticHelixFinder_module.cc:831, 843for (size_t i = 0; i < _tcHits.size() - 2; i++) unsigned-underflows when _tcHits.size() < 2. Add if (_tcHits.size() < 3) return false; before the triplet loops.
  6. src/CalHelixFinderAlg.cc:1916Helix._sxy.addPoint(fCaloX, fCaloY, 1./100.); is called unconditionally. When setCaloCluster took the "no cluster" path, fCaloX/Y = -9999 still enters the weighted circle fit with weight 1/100, biasing the fit. Line 834 (addCaloClusterToFitPhiZ) has the same pattern with fCaloZ. The correct guard exists elsewhere (line 1175, fCaloTime > 0).
  7. src/CalHelixFinderAlg.cc:1559float lambda = (Helix._dfdz != 0.) ? 1./Helix._dfdz : 0.; then phi_pred = fz0 + z/lambda;. When _dfdz == 0, the guard produces a division by zero on the very next use. Should early-return / skip the hit loop instead of setting lambda = 0.
  8. src/CalHelixFinder_module.cc:241goto END; on the error-return path bypasses event.put() of the unique_ptr'd output collections. Downstream art gets a "missing product" error with a confusing trace. Either put empty collections before the goto or throw cet::exception (as DeltaFinder_module.cc:249 does).
  9. fcl/prolog.fclMergeHelixFinder block and six derived tables (MHFinderTprDe, …CprDe, …De, plus the three Dmu variants) reference a module that has no backing source file. Any job instantiating them fails at art load time. Likely wants either deletion or replacement with TrkReco/src/MergeHelices_module.cc.

Risks / Robustness

  1. Stale handles between events. CalHelixFinder_module.cc:176–207 and CalTimePeakFinder_module.cc:101–122 keep art::Handles as class members; on findData partial-failure, previous-event pointers remain live. Clear at the top of produce() and avoid storing Handles as members.
  2. Throw-prone getValidHandle with unreachable "error" paths. AgnosticHelixFinder_module.cc:421–425 and PrefetchData_module.cc:167–205 call getValidHandle unchecked — it throws on absence, so the return false / null-handle branches are dead. Either switch to getByLabel + explicit check, or remove the dead error path.
  3. Inconsistent failure handling across modules. DeltaFinder_module.cc:249 and ComboHitFilter_module.cc:147 throw cet::exception("RECO"); CalHelixFinder_module.cc:181, CalTimePeakFinder_module.cc:109, TZClusterFinder_module.cc:258, TZClusterFilter_module.cc:226 printf and continue. Pick one convention module-wide.
  4. Silent fall-through in src/TZClusterFinder_module.cc:261–268. If _useCaloClusters==1 but the label is wrong, _data._ccColl = NULL silently; only downstream caloIdx != -1 guards catch this. Throw, or log at least once.
  5. Unguarded divisions / sqrts in hot paths.
    • DeltaFinderAlg.cc:321, 326: q12 = 1 - w1w2² divisor, no nearly-parallel-wires guard.
    • DeltaFinderAlg.cc:159, 479: d = snx2*sny2 - snxy² divisor, no positivity guard.
    • DeltaFinderAlg.cc:98–99: rho = sqrt(xseed² + yseed²), seed_nx = xseed/rho, no guard at origin.
    • CalHelixFinderAlg.cc:1837, 1870: costh2 = dxn²/(dx²+dy²) — zero denominator if hit sits at helix centre.
    • CalHelixFinderAlg.cc:3209: DfDz32 = dphi32/dz32, no guard; coplanar points → NaN propagates through refinement.
    • AgnosticHelixFinder_module.cc:650, 1641: lambda = 1/dfdz, no check.
    • AgnosticHelixFinder_module.cc:1464: nHitsRatio = seedCircleHits / nLineHits, no nLineHits > 0 guard.
  6. Unconditional printf debug output. CalHelixFinder_module.cc:154–165 dumps geometry on every beginRun; AgnosticHelixFinder_module.cc:382, 384, 521, 547, 805, 910 print unconditionally. Gate on _diagLevel / _debug.
  7. Magic-sentinel overload. -9999, -1000-idx, -1 are used as both "invalid" and encoded indices (CalHelixFinderAlg.cc:239–242; DeltaFinderAlg.cc:376, 630, 795, 824, 835, 838). Any future >= 0 check could misclassify.

Code quality & convention drift

  1. fhicl key casing is inconsistent within CalPatRec itself. CalTimePeakFinder_module.cc binds PascalCase (DiagLevel, DebugLevel, StrawHitCollectionLabel); CalHelixFinder_module.cc, AgnosticHelixFinder_module.cc, DeltaFinder_module.cc, TZClusterFinder_module.cc bind lowerCamel (diagLevel, debugLevel, chCollLabel). User fcl overriding DiagLevel silently misses half the modules.
  2. No ProditionsHandle use anywhere in CalPatRec (grep 0 hits). TrkPatRec uses it (RobustHelixFinder_module.cc). CalPatRec fetches geometry via raw GeomHandle<Tracker>, against the current Offline norm for per-run-varying conditions.
  3. Per-module .hh headers expose class layout (inc/CalHelixFinder_module.hh, inc/CalTimePeakFinder_module.hh). TrkPatRec keeps module internals inside the .cc. Drift from project norm; accidentally shares ABI.
  4. Dictionary registration is incomplete. src/classes_def.xml registers only mu2e::DeltaSeed; DeltaCandidate, ProtonCandidate, CalHelixFinderData, DeltaFinder_types are built into the library but not registered. Persisting any of these to art output throws at runtime. Also, CMake uses NO_CHECK_CLASS_VERSION with a comment "segfaults" — that workaround should be root-caused.
  5. src/HlPrint_ComboHit.cc / inc/HlPrint.hh compiled but never used.
  6. Stray SConscript in CalPatRec/src/ left over from pre-CMake days (same in TrkPatRec/src/).
  7. Offline::BTrkLegacy / ROOT::Physics linked PUBLIC but usage not evident in headers (CalPatRec/CMakeLists.txt). Audit; if only .cc uses, move to PRIVATE or drop.
  8. Module-naming drift vs TrkPatRec. TrkPatRec uses TimeClusterFinder / TimeAndPhiClusterFinder; CalPatRec has CalTimePeakFinder, CalLineTimePeakFinder, and PhiClusterFinder (missing Cal prefix though it's in CalPatRec). Grepping for "TimeCluster…" misses the CalPatRec equivalents.
  9. using namespace hoisting at file scope. CalHelixFinder_module.cc hoists boost::accumulators plus CLHEP types; CalTimePeakFinder_module.cc has using namespace std; at file scope.
  10. Dead __GCCXML__A guard in inc/CalTimePeakFinder_module.hh. GCCXML has been inactive for years; the A suffix suggests it was already neutered.
  11. src/CalHelixFinderAlg.cc double-includes its own header.

Dead code & stale assets

  1. data/v5_7_7/ (10 files, ~136 KB). Only referenced by configure_file copies in CMakeLists.txt. No source code loads MLP_weights_* or cpr_qual_logfcons*. Delete the directory and the corresponding CMake lines.
  2. src/MergePatRecDiag_tool.cc + inc/MergePatRec_types.hh. Zero tool_type: "MergePatRecDiag" hits in any fcl across the repo.
  3. inc/ObjectDumpUtils.hh. Zero #include hits anywhere in Offline.
  4. test/ (46 files, ~233 KB). No Validation/, Trigger/, Production/, or CalPatRec CMakeLists.txt references any file in this directory except via doc/CalPatRec.org's mention of deltaFinder_debug.fcl. Either delete or move to legacy/ with a README noting none of it is wired into CI.
  5. Commented-out blocks in fcl/prolog.fclCalTrkFit (~201–225), CalSeedFit (~382–398), MHSeedFit (~408–424), CalHelixFinderDeP/CalHelixFinderDmuP (~651–656). All reference removed KalSeedFit/KalFinalFit.
  6. Commented-out algorithm loops in src/CalHelixFinderAlg.cc at lines 2549–2578 (30 lines) and 2993–3013 (21 lines). Replaced by countUsedHits(); the FIXME referenced is resolved.
  7. doc/CalPatRec.org is the only file still referencing deltaFinder_debug.fcl. If test/ is deleted, update or remove.

Nits

  • Per-file maintainer tags (P.Murat, G.Pezzullo, etc.) — Offline has been moving away from this convention.
  • Include-guard style CalPatRec_CalHelixFinder_module (no _hh suffix) diverges from Offline_..._hh used more broadly.
  • fcl/prolog.fcl whitespace inconsistency (module_type:X vs module_type : X).
  • Aspirational comment // try to order routines alphabetically left in CalHelixFinder_module.cc.
  • Commented #include "CalPatRec/inc/KalFitResult.hh" and // std::string _shpLabel; left in headers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions