-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix:Incorrect MET correction method CorrectedMETFactory.py #1066
base: master
Are you sure you want to change the base?
Conversation
for more information, see https://pre-commit.ci
Please fix the tests your change has cause to fail. https://github.com/CoffeaTeam/coffea/actions/runs/8376520077/job/22936434720?pr=1066#step:10:477 |
): | ||
sj, cj = numpy.sin(jet_phi), numpy.cos(jet_phi) | ||
x = met_pt * numpy.cos(met_phi) + awkward.sum((jet_pt - jet_pt_orig) * cj, axis=1) | ||
y = met_pt * numpy.sin(met_phi) + awkward.sum((jet_pt - jet_pt_orig) * sj, axis=1) | ||
x = met_pt * numpy.cos(met_phi) + awkward.sum(jet_pt * cj, axis=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be calculating a difference in the corrected momentum with respect to each jet? That's what it says in the equation you quote, that's what the code was doing before. Now it does not. Please justify this change.
That or create a test that compares to outputs from some other tool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, the +
here should be the -
, I have updated it.
I have attached the example code in the issue.
The Type-I correction calculation formula has been implemented in corrected_jets
:
def corrected_jets(self, jets, event_rho, lazy_cache):
jets_L123 = self.jec_factory.build(
add_jme_variables(jets, event_rho),
lazy_cache #events.caches[0]
)
jets_L1 = self.jec_factory_L1.build(
add_jme_variables(jets, event_rho),
lazy_cache #events.caches[0]
)
emFraction = jets_L123.chEmEF + jets_L123.neEmEF
mask_jec = (jets_L123.pt > 15) & (emFraction <= 0.9)
selected_jets_L123 = ak.mask(jets_L123, mask_jec)
jets_jec = selected_jets_L123
jets_jec['pt'] = selected_jets_L123.pt - jets_L1.pt
return jets_jec
Then propagate the difference value calculation of jet_pt corrected by L123 and L1 to MET through the following code:
jets_col = self._jmeu.corrected_jets(jets_col, rho, cache)
met = self._jmeu.corrected_met(event.RawMET,event.MET, jets_col, event.fixedGridRhoFastjetAll, event.caches[0])
Does this explain that my updated code is correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah this is a very clear to implement this since it now becomes unclear what the user is getting as a physics object. They expect to get the jets corrected by the stack that they put in, not something else that is suitable for MET correction.
Instead, it would be best to create two CorrectedJetsFactories:
jets_l123 = CorrectedJetFactory(config_L123).build(events.Jet) #add rho and whatnot to events.Jet
jets_l1 = CorrectedJetFactory(config_L1).build(events.Jet)
#then set ptRaw in the JECStack to jets_l1.pt
corr_met = CorrectedMetFactory(config_l123_l1).build(type1_met, jets_l123)
This would require no code changes to my understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that set ptRaw
to jets_L1.pt
,it's a good alternative.
But the plus signs +
here should be changed to -
. Just like:
x = met_pt * numpy.cos(met_phi) - awkward.sum((jet_pt - jet_pt_orig) * cj, axis=1)
@@ -36,7 +36,7 @@ def __init__(self, name_map): | |||
|
|||
self.name_map = name_map | |||
|
|||
def build(self, in_MET, in_corrected_jets): | |||
def build(self, in_MET, type1_MET, in_corrected_jets): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't you just set the Type1 MET as the MET that is input to the build function? This seems odd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
In order to obtain the corresponding uncertainty values of MET after correction for
JEC
andJER
, we must useRawMET
as input for correction.RawMET means uncorrected PF MET, while MET refers to Type-1 corrected PF MET. If using MET as input, it means that it has been corrected twice. -
But if we want to obtain the
UnclusterdEnergy
uncertainty value of MET, you must use MET as input, as inNanoAOD
, only MET has the branch forMetUnclusterEnUpDeltaX/Y
, while RawMET does not. Therefore, it is necessary to use MET to obtain theUnclusteredEnergy
uncertainty value.
So I have to input both in_MET
and type1_MET
meanwhile, they represent RawMET and MET respectively, for example:
met = self._jmeu.corrected_met(event.RawMET,event.MET, jets_col, event.fixedGridRhoFastjetAll, event.caches[0])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a better way to put this is I think this can be solved by changing the flexibility in the configuration as opposed to changing the meaning of the physics objects that people get out from correctors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it is obvious that the CorrectedMETFactory
function here cannot implement the correction of RawMET
as input. Because RawMET
does not have the MetUnclusterEnUpDeltaX/Y
branch, a bug will occur. How can I modify the configuration file to solve this problem? At the same time, I also need to obtain the uncertainty of MET_UnclusterdEnergy_up/down
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be better solved by making a new met object with the appropriate substitutions.
raw_met = events.RawMET
met_to_correct = events.MET
met_to_correct["pt"] = raw_met.pt
met_to_correct["phi"] = raw_met.phi
# then go on to correct met_to_correct, adjusting configuration as appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I'm not sure if this spoils the validity of the systematic variations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know what you mean! Great!
This will not spoils the validity of the systemic variations, the uncertainty of MET_UnclusteredEnergy
is calculated using the corrected MET_pt
value through corrected_polar_met
, rather than RawMET.pt.
You are incredibly smart, thank you so much for your patient and thoughtful answers.
Related issue is scikit-hep#1066
No description provided.