Maia/theta energy - #41
Conversation
|
Thanks for upstreaming these! I tested this in I have just a couple of comments on the track-consistency comparison and about the lookup's global state:
|
|
|
||
| mergedHadronicEnergy = LCEnergyCorrectionPlugins::GetThetaEnergyCorrectedEnergy( | ||
| pandora::HADRONIC, parentDirection, mergedHadronicEnergy); | ||
| addedHadronicEnergy = std::max(0.f, mergedHadronicEnergy - parentHadronicEnergy); |
There was a problem hiding this comment.
At this point parentHadronicEnergy is the fully corrected parent energy, while mergedHadronicEnergy is the raw sum with only the theta factor applied. The subtraction mixes two different correction chains.
When the theta factor is below 1, the corrected parent can exceed the theta-corrected
raw sum. addedHadronicEnergy then clamps to 0, and on line 144 0 > 1 GeV is false, so the chi cut is skipped entirely and the merge proceeds unchecked.
I'd suggest computing both sides through the same path, and gating on the daughter's own energy as master does rather than on a difference of differently-corrected quantities.
|
|
||
| if (m_useCorrectedHadronicEnergyForTrackComparison) { | ||
| parentHadronicEnergy = pBestParentCluster->GetCorrectedHadronicEnergy(this->GetPandora()); | ||
| mergedHadronicEnergy = pBestParentCluster->GetHadronicEnergy() + pDaughterCluster->GetHadronicEnergy(); |
There was a problem hiding this comment.
This is overwritten on line 137, and it already equals the value assigned in the initialiser on line 125. Safe to delete.
| float clusterEnergySum(daughterHadronicEnergy + parentHadronicEnergy); | ||
|
|
||
| if (m_useCorrectedHadronicEnergyForTrackComparison) { | ||
| parentTrackComparisonEnergy = pParentCluster->GetCorrectedHadronicEnergy(this->GetPandora()); |
There was a problem hiding this comment.
Same chain asymmetry as in ConeBasedMergingAlgorithm: this is the fully corrected parent, while clusterEnergySum on line 133 is the theta-corrected raw sum. The chi^2 - chi0^2 cut is dominated by the correction-chain difference rather than by the daughter.
I think we should apply the same manual theta correction to the parent alone so both sides go through identical treatment.
| const float energyDifference(std::fabs(pCluster->GetHadronicEnergy() - pTrack->GetEnergyAtDca())); | ||
| const float clusterHadronicEnergy(pCluster->GetHadronicEnergy()); | ||
| const float trackComparisonEnergy(m_useCorrectedHadronicEnergyForTrackComparison | ||
| ? pCluster->GetCorrectedHadronicEnergy(this->GetPandora()) |
There was a problem hiding this comment.
Suggest to use GetTrackComparisonEnergy(this->GetPandora()) here. It resolves to the corrected hadronic energy for hadronic clusters, so behaviour is unchanged for those, but it uses the corrected EM energy for the rest.
|
|
||
| typedef std::map<ThetaEnergyCorrectionKey, ThetaEnergyCorrectionTable> ThetaEnergyCorrectionTableMap; | ||
|
|
||
| ThetaEnergyCorrectionTableMap& GetThetaEnergyCorrectionTableMap() { |
There was a problem hiding this comment.
This function-local static is keyed on (name, EnergyCorrectionType) only. Two Pandora instances in one process share a single table, and the second registration silently overwrites the first. There's no way for an algorithm to ask for its Pandora's table.
Worth noting this is currently the only global mutable state in LCContent.
Suggest keying on const pandora::Pandora * as well, with the algorithms passing &this->GetPandora().
| const float cosTheta(std::max(-1.f, std::min(1.f, direction.GetCosOpeningAngle(CartesianVector(0.f, 0.f, 1.f))))); | ||
| const float theta(std::acos(cosTheta)); | ||
|
|
||
| for (const ThetaEnergyCorrectionTableMap::value_type& mapEntry : GetThetaEnergyCorrectionTableMap()) { |
There was a problem hiding this comment.
The loop skips entries whose type doesn't match, then unconditionally returns on the first survivor. If two HADRONIC tables are ever registered under different names, which one you get depends on std::map's ordering of the name strings.
We could the plugin name as a parameter, plumbed from each algorithm's XML block alongside the existing flag. This would also let a single job use different tables in different algorithms.
Related: pandora::HADRONIC is hard-coded at both merging call sites, so a table registered under any other correction type is silently ignored.
| return true; | ||
| } | ||
|
|
||
| int FindBin(const FloatVector& edges, const float value) { |
There was a problem hiding this comment.
value >= edges.back() returns -1, and GetCorrection then returns 1.0. So a cluster one MeV above the top energy edge jumps discontinuously from (say) 0.85 to 1.00. The same applies at both theta ends, but it's less damaging if a map is coded up to >pi.
I think we should clamp to the edge bin, making the last bin inclusive?
| throw StatusCodeException(STATUS_CODE_FAILURE); | ||
|
|
||
| const float eOverP(electromagneticEnergy / momentumAtDca); | ||
| const float eOverPEnergy(m_useCorrectedElectromagneticEnergyForEOverP |
There was a problem hiding this comment.
eOverPEnergy doesn't depend on the loop iterator, so it can be moved above the for over associatedTrackList.
|
I'll add a couple of tests for the new correction lookup and will take care of the deduplication of GetCorrection. I'm happy to do more if you need help! |
These commits are from @trholmes. I am submitting a PR because downstream
work depends on them.
Adds two energy correction plugins that look up a correction factor in a 2D
(theta, energy) table instead of applying one flat constant per subdetector:
The correction is applied inside Pandora, after clustering and before PFOs are
built, so cluster energies, PFO energies, and jets all come out consistent and
nothing has to be applied by hand downstream.
Also adds a three-argument RegisterNonLinearityEnergyCorrection overload taking
the bin edges and the table. The existing one-argument overload is unchanged,
and with no table supplied the plugins fall back to it, which is the identity.
So this is a no-op for anyone who does not configure a table.
These plugins have been in use in muon collider reconstruction and are being
upstreamed so they are available generally. key4hep/k4GaudiPandora#51 uses this
overload and cannot compile until this lands, and
MuonColliderSoft/MAIAConfig#90 sits on top of that.
This is a draft for now. This needs a rebase onto current master before it can be merged. Opening it so the dependency chain is visible.