GReWeightResonanceDecay.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2017, GENIE Neutrino MC Generator Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Authors: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
8  University of Liverpool & STFC Rutherford Appleton Lab
9 
10  For the class documentation see the corresponding header file.
11 
12  Important revisions after version 2.0.0 :
13  @ May 10, 2010 - CA
14  First included in v2.7.1.
15 
16 */
17 //____________________________________________________________________________
18 
19 #include <TFile.h>
20 #include <TNtupleD.h>
21 #include <TH1D.h>
22 #include <TParticlePDG.h>
23 #include <TDecayChannel.h>
24 
26 #include "Conventions/Controls.h"
27 #include "EVGCore/EventRecord.h"
28 #include "GHEP/GHepParticle.h"
29 #include "Messenger/Messenger.h"
30 #include "PDG/PDGCodes.h"
31 #include "PDG/PDGLibrary.h"
34 
35 using namespace genie;
36 using namespace genie::rew;
37 
38 //_______________________________________________________________________________________
40 GReWeightI()
41 {
42  this->Init();
43 }
44 //_______________________________________________________________________________________
46 {
47 #ifdef _G_REWEIGHT_RESDEC_DEBUG_
48  fTestFile->cd();
49  fTestNtp ->Write();
50  fTestFile->Close();
51  delete fTestFile;
52 #endif
53 }
54 //_______________________________________________________________________________________
56 {
57  switch(syst) {
58  case ( kRDcyTwkDial_BR1gamma ) :
59  case ( kRDcyTwkDial_BR1eta ) :
61  return true;
62  break;
63  default:
64  return false;
65  break;
66  }
67  return false;
68 }
69 //_______________________________________________________________________________________
71 {
72  switch(syst) {
73  case ( kRDcyTwkDial_BR1gamma ) :
74  fBR1gammaTwkDial = twk_dial;
75  break;
76  case ( kRDcyTwkDial_BR1eta ) :
77  fBR1etaTwkDial = twk_dial;
78  break;
80  fThetaDelta2NpiTwkDial = twk_dial;
81  break;
82  default:
83  return;
84  break;
85  }
86 }
87 //_______________________________________________________________________________________
89 {
90  fBR1gammaTwkDial = 0.;
91  fBR1etaTwkDial = 0.;
93 }
94 //_______________________________________________________________________________________
96 {
97 
98 }
99 //_______________________________________________________________________________________
101 {
102  Interaction * interaction = event.Summary();
103 
104  bool is_res = interaction->ProcInfo().IsResonant();
105  if(!is_res) return 1.;
106 
107  bool is_cc = interaction->ProcInfo().IsWeakCC();
108  bool is_nc = interaction->ProcInfo().IsWeakNC();
109  if(is_cc && !fRewCC) return 1.;
110  if(is_nc && !fRewNC) return 1.;
111 
112  int nupdg = interaction->InitState().ProbePdg();
113  if(nupdg==kPdgNuMu && !fRewNumu ) return 1.;
114  if(nupdg==kPdgAntiNuMu && !fRewNumubar) return 1.;
115  if(nupdg==kPdgNuE && !fRewNue ) return 1.;
116  if(nupdg==kPdgAntiNuE && !fRewNuebar ) return 1.;
117 
118  double wght =
119  this->RewBR(event) *
120  this->RewThetaDelta2Npi(event);
121 
122  return wght;
123 }
124 //_______________________________________________________________________________________
126 {
127  bool tweaked_br1gamma = (TMath::Abs(fBR1gammaTwkDial) > controls::kASmallNum);
128  bool tweaked_br1eta = (TMath::Abs(fBR1etaTwkDial) > controls::kASmallNum);
129 
130  bool tweaked = (tweaked_br1gamma || tweaked_br1eta);
131  if(!tweaked) return 1.;
132 
133  double wght = 1.;
134 
136 
137  LOG("ReW", pDEBUG) << "Checking resonance decay mode.";
138 
139  GHepParticle * p = 0;
140  TIter iter(&event);
141  while((p=(GHepParticle*)iter.Next())) {
143  int fd = p->FirstDaughter();
144  int ld = p->LastDaughter();
145  int ngamma = 0;
146  int neta = 0;
147  for(int i=fd; i<=ld; i++) {
148  int dpdg = event.Particle(i)->Pdg();
149  if(dpdg==kPdgGamma) ngamma++;
150  if(dpdg==kPdgEta ) neta++;
151  }//i
152  bool is_1gamma = (ngamma==1);
153  bool is_1eta = (neta ==1);
154 
155  if(is_1gamma) {
156  LOG("ReW", pDEBUG) << "A resonance -> X + 1gamma event";
157  }
158  if(is_1eta) {
159  LOG("ReW", pDEBUG) << "A resonance -> X + 1eta event";
160  }
161 
162  //
163  // For Resonance -> X + gamma, tweak the branching ratio as:
164  // BR_{tweaked} = BR_{default} * (1 + dial * fractional_error)
165  // so that, basically, weight = 1 + dial * fractional_error.
166  // For all other decay modes adjust the branching ratio so that Sum{BR} = 1.
167  //
168  if(tweaked_br1gamma) {
169  double frerr = uncertainty->OneSigmaErr(kRDcyTwkDial_BR1gamma);
170  double dial = fBR1gammaTwkDial;
171  double w = (1. + dial*frerr);
172  w = TMath::Max(0.,w);
173  TH1D * brfw = fMpBR1gammaDef[p->Pdg()];
174  double mass = p->P4()->M();
175  mass = TMath::Min(mass, brfw->GetXaxis()->GetXmax());
176  int ibin = brfw->FindBin(mass);
177  double brdef = brfw->GetBinContent(ibin);
178  double brtwk = brdef*w;
179  if(brtwk>1) {
180  brtwk = 1.;
181  w = brtwk/brdef;
182  }
183  if(is_1gamma) {
184  wght *= w;
185  } else {
186  wght *= ((1-brtwk)/(1-brdef));
187  }
188  }
189  // Similarly for Resonance -> X + eta
190  //
191  if(tweaked_br1eta) {
192  double frerr = uncertainty->OneSigmaErr(kRDcyTwkDial_BR1eta);
193  double dial = fBR1etaTwkDial;
194  double w = (1. + dial*frerr);
195  w = TMath::Max(0.,w);
196  TH1D * brfw = fMpBR1etaDef[p->Pdg()];
197  double mass = p->P4()->M();
198  mass = TMath::Min(mass, brfw->GetXaxis()->GetXmax());
199  int ibin = brfw->FindBin(mass);
200  double brdef = brfw->GetBinContent(ibin);
201  double brtwk = brdef*w;
202  if(brtwk>1) {
203  brtwk = 1.;
204  w = brtwk/brdef;
205  }
206  if(is_1eta) {
207  wght *= w;
208  } else {
209  wght *= ((1-brtwk)/(1-brdef));
210  }
211  }
212  // Similarly for other modes with tweaked BRs
213  //
214  //...
215  //...
216 
217  }//res?
218  }//p
219 
220  return wght;
221 }
222 //_______________________________________________________________________________________
224 {
225  bool tweaked = (TMath::Abs(fThetaDelta2NpiTwkDial) > controls::kASmallNum);
226  if(!tweaked) return 1.;
227 
228  bool is_Delta_1pi = false;
229  int ir = -1; // resonance position
230  int ip = -1; // pion position
231  int i = 0;
232  GHepParticle * p = 0;
233  TIter iter(&event);
234  while((p=(GHepParticle*)iter.Next())) {
235  bool is_Deltapp = (p->Pdg()==kPdgP33m1232_DeltaPP);
236  if(is_Deltapp) {
237  ir = i;
238  int fd = p->FirstDaughter();
239  int ld = p->LastDaughter();
240  int nd = 1 + ld - fd;
241  if(nd==2) {
242  int fpdg = event.Particle(fd)->Pdg();
243  int lpdg = event.Particle(ld)->Pdg();
244  if(fpdg==kPdgProton && lpdg==kPdgPiP) { is_Delta_1pi = true; ip = ld; }
245  if(lpdg==kPdgProton && fpdg==kPdgPiP) { is_Delta_1pi = true; ip = fd; }
246  }
247  }
248 
249  bool is_Deltap = (p->Pdg()==kPdgP33m1232_DeltaP);
250  if(is_Deltap) {
251  ir = i;
252  int fd = p->FirstDaughter();
253  int ld = p->LastDaughter();
254  int nd = 1 + ld - fd;
255  if(nd==2) {
256  int fpdg = event.Particle(fd)->Pdg();
257  int lpdg = event.Particle(ld)->Pdg();
258  if(fpdg==kPdgProton && lpdg==kPdgPi0) { is_Delta_1pi = true; ip = ld; }
259  if(lpdg==kPdgProton && fpdg==kPdgPi0) { is_Delta_1pi = true; ip = fd; }
260  if(fpdg==kPdgNeutron && lpdg==kPdgPiP) { is_Delta_1pi = true; ip = ld; }
261  if(lpdg==kPdgNeutron && fpdg==kPdgPiP) { is_Delta_1pi = true; ip = fd; }
262  }
263  }
264 
265  bool is_Delta0 = (p->Pdg()==kPdgP33m1232_Delta0);
266  if(is_Delta0) {
267  ir = i;
268  int fd = p->FirstDaughter();
269  int ld = p->LastDaughter();
270  int nd = 1 + ld - fd;
271  if(nd==2) {
272  int fpdg = event.Particle(fd)->Pdg();
273  int lpdg = event.Particle(ld)->Pdg();
274  if(fpdg==kPdgProton && lpdg==kPdgPiM) { is_Delta_1pi = true; ip = ld; }
275  if(lpdg==kPdgProton && fpdg==kPdgPiM) { is_Delta_1pi = true; ip = fd; }
276  if(fpdg==kPdgNeutron && lpdg==kPdgPi0) { is_Delta_1pi = true; ip = ld; }
277  if(lpdg==kPdgNeutron && fpdg==kPdgPi0) { is_Delta_1pi = true; ip = fd; }
278  }
279  }
280 
281  bool is_DeltaM = (p->Pdg()==kPdgP33m1232_DeltaM);
282  if(is_DeltaM) {
283  ir = i;
284  int fd = p->FirstDaughter();
285  int ld = p->LastDaughter();
286  int nd = 1 + ld - fd;
287  if(nd==2) {
288  int fpdg = event.Particle(fd)->Pdg();
289  int lpdg = event.Particle(ld)->Pdg();
290  if(fpdg==kPdgNeutron && lpdg==kPdgPiM) { is_Delta_1pi = true; ip = ld; }
291  if(lpdg==kPdgNeutron && fpdg==kPdgPiM) { is_Delta_1pi = true; ip = fd; }
292  }
293  }
294 
295  if(is_Delta_1pi) break;
296  i++;
297  }
298 
299  if(!is_Delta_1pi) return 1.;
300 
301  LOG("ReW", pDEBUG) << "A Delta++ -> p pi+ event:";
302  LOG("ReW", pDEBUG) << "Resonance is at position: " << ir;
303  LOG("ReW", pDEBUG) << "Pion is at position: " << ip;
304 //LOG("ReW", pDEBUG) << event;
305 
306  // Get Delta and pi+ 4-momentum vectors
307  TLorentzVector p4res(*event.Particle(ir)->P4());
308  TLorentzVector p4pip(*event.Particle(ip)->P4());
309 
310  // Boost pi+ to the Delta CM
311  TVector3 bv = -1*p4res.BoostVector();
312  p4pip.Boost(bv);
313 
314  //
315  // Calculate weight.
316  // Angular distribution for pi+, given 2 possible sub-states mi=1/2,3/2
317  // is: Wpi(theta) = 1 - p(3/2)*P2(costheta) + p(1/2)*P2(costheta).
318  // mi is the projection of Delta angular momentum along quantization axis.
319  // P2(costheta) is the 2nd order Legendre polynomial.
320  // Isotropy implies equal populations: p(3/2)=p(1/2)=0.5
321  // R/S predict: p(3/2)=0.75, p(1/2)=0.25
322  // The above follow the notation used in Sam Zeller's invited talk in a
323  // MINOS Physics Simulation mtg on Sep 28th, 2007.
324  // Sam's talk cited a paper by G.Garvey and O.Lalakulich which I haven't
325  // been able to locate.
326  //
327 
328  double p32iso = 0.50;
329  double p12iso = 0.50;
330  double p32rs = 0.75;
331  double p12rs = 0.25;
332  double costheta = p4pip.Vect().CosTheta();
333  double P2 = 0.5 * (3.*costheta*costheta - 1.);
334  double Wiso = 1 - p32iso * P2 + p12iso * P2; // = 1.0
335  double Wrs = 1 - p32rs * P2 + p12rs * P2;
336  double dial = fThetaDelta2NpiTwkDial;
337  double Wdef = Wiso;
338  double Wtwk = dial*Wrs + (1-dial)*Wiso;
339 
340  double wght = 1.;
341  if(Wdef>0. && Wtwk>0.) {
342  wght = Wtwk/Wdef;
343  }
344 
345  LOG("ReW", pDEBUG)
346  << "Pion Cos(ThetaCM) = " << costheta << ", weight = " << wght;
347 
348 #ifdef _G_REWEIGHT_RESDEC_DEBUG_
349  fTestNtp->Fill(costheta,wght);
350 #endif
351 
352  return wght;
353 }
354 //_______________________________________________________________________________________
356 {
357  this->RewNue (true);
358  this->RewNuebar (true);
359  this->RewNumu (true);
360  this->RewNumubar(true);
361  this->RewCC (true);
362  this->RewNC (true);
363 
364  fBR1gammaTwkDial = 0.;
365  fBR1etaTwkDial = 0.;
367 
368  const int respdgarray[] = {
385  0
386  };
387 
388  // init
389  const int kNW = 30;
390  const double kWmin = 0.9;
391  const double kWmax = 5.0;
392  unsigned int ires=0;
393  int respdg = 0;
394  while((respdg = respdgarray[ires++])) {
395  fMpBR1gammaDef [respdg] = new TH1D("","",kNW,kWmin,kWmax);
396  fMpBR1etaDef [respdg] = new TH1D("","",kNW,kWmin,kWmax);
397  fMpBR1gammaDef [respdg] -> SetDirectory(0);
398  fMpBR1etaDef [respdg] -> SetDirectory(0);
399  }
400 
401  // find corresponding decay channels and store default BR
402  PDGLibrary * pdglib = PDGLibrary::Instance();
403  ires=0;
404  while((respdg = respdgarray[ires++])) {
405  TParticlePDG * res = pdglib->Find(respdg);
406  if(!res) continue;
407  for(int j=0; j<res->NDecayChannels(); j++) {
408  TDecayChannel * dch = res->DecayChannel(j);
409  int ngamma = 0;
410  int neta = 0;
411  double br = dch->BranchingRatio();
412  double mt = 0.;
413  for(int k=0; k<dch->NDaughters(); k++) {
414  int dpdg = dch->DaughterPdgCode(k);
415  if(dpdg==kPdgGamma) ngamma++;
416  if(dpdg==kPdgEta ) neta++;
417  mt += 0;
418  }//decay channel f/s particles
419  bool is_1gamma = (ngamma==1);
420  bool is_1eta = (neta ==1);
421  for(int ibin = 1; ibin <= fMpBR1gammaDef[respdg]->GetNbinsX(); ibin++) {
422  double W = fMpBR1gammaDef[respdg]->GetBinLowEdge(ibin) +
423  fMpBR1gammaDef[respdg]->GetBinWidth(ibin);
424  bool is_allowed = (W>mt);
425  if(is_allowed && is_1gamma) { fMpBR1gammaDef[respdg]->Fill(W, br); }
426  if(is_allowed && is_1eta ) { fMpBR1etaDef [respdg]->Fill(W, br); }
427  }//W bins
428  }//decay channels
429  }//resonances
430 
431 #ifdef _G_REWEIGHT_RESDEC_DEBUG_
432  fTestFile = new TFile("./resdec_reweight_test.root","recreate");
433  fTestNtp = new TNtupleD("testntp","","costheta:wght");
434 #endif
435 }
436 //_______________________________________________________________________________________
const int kPdgP31m1910_DeltaP
Definition: PDGCodes.h:115
bool IsResonant(void) const
const int kPdgS31m1620_DeltaM
Definition: PDGCodes.h:99
const int kPdgP33m1232_DeltaPP
Definition: PDGCodes.h:88
double RewThetaDelta2Npi(const EventRecord &event)
virtual GHepParticle * Particle(int position) const
Definition: GHepRecord.cxx:148
bool IsWeakCC(void) const
const int kPdgF35m1905_DeltaM
Definition: PDGCodes.h:121
const int kPdgNuE
Definition: PDGCodes.h:25
#include "Numerical/GSFunc.h"
Definition: AlgCmp.h:26
const int kPdgD15m1675_N0
Definition: PDGCodes.h:97
const int kPdgF35m1905_Delta0
Definition: PDGCodes.h:122
void Reset(void)
set all nuisance parameters to default values
int FirstDaughter(void) const
Definition: GHepParticle.h:69
const int kPdgF15m1680_NP
Definition: PDGCodes.h:112
const int kPdgD33m1700_Delta0
Definition: PDGCodes.h:104
const int kPdgAntiNuE
Definition: PDGCodes.h:26
const int kPdgD13m1700_NP
Definition: PDGCodes.h:96
const int kPdgNuMu
Definition: PDGCodes.h:27
const int kPdgS11m1650_N0
Definition: PDGCodes.h:93
tweak Resonance -> X + eta branching ratio, eg N+(1440) -> p eta
Definition: GSyst.h:149
const int kPdgF37m1950_DeltaM
Definition: PDGCodes.h:125
const int kPdgF37m1950_DeltaP
Definition: PDGCodes.h:127
const int kPdgS11m1535_N0
Definition: PDGCodes.h:89
void Reconfigure(void)
propagate updated nuisance parameter values to actual MC, etc
const int kPdgP33m1232_DeltaP
Definition: PDGCodes.h:87
const int kPdgP33m1232_DeltaM
Definition: PDGCodes.h:85
const int kPdgP31m1910_DeltaM
Definition: PDGCodes.h:113
double OneSigmaErr(GSyst_t syst, int sign=0) const
int Pdg(void) const
Definition: GHepParticle.h:64
Summary information for an interaction.
Definition: Interaction.h:53
const int kPdgF37m1950_Delta0
Definition: PDGCodes.h:126
const int kPdgD33m1700_DeltaPP
Definition: PDGCodes.h:106
int LastDaughter(void) const
Definition: GHepParticle.h:70
const int kPdgF35m1905_DeltaP
Definition: PDGCodes.h:123
bool IsWeakNC(void) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:87
const int kPdgD15m1675_NP
Definition: PDGCodes.h:98
const int kPdgF35m1905_DeltaPP
Definition: PDGCodes.h:124
const int kPdgS31m1620_DeltaPP
Definition: PDGCodes.h:102
const int kPdgGamma
Definition: PDGCodes.h:163
const int kPdgP31m1910_DeltaPP
Definition: PDGCodes.h:116
int ProbePdg(void) const
Definition: InitialState.h:54
const int kPdgP33m1920_DeltaPP
Definition: PDGCodes.h:120
const int kPdgEta
Definition: PDGCodes.h:135
const int kPdgP31m1910_Delta0
Definition: PDGCodes.h:114
const int kPdgPiP
Definition: PDGCodes.h:132
const int kPdgPi0
Definition: PDGCodes.h:134
const int kPdgP33m1920_DeltaP
Definition: PDGCodes.h:119
const int kPdgD33m1700_DeltaM
Definition: PDGCodes.h:103
const int kPdgP33m1920_DeltaM
Definition: PDGCodes.h:117
const int kPdgF37m1950_DeltaPP
Definition: PDGCodes.h:128
static const double kASmallNum
Definition: Controls.h:40
const int kPdgD13m1520_NP
Definition: PDGCodes.h:92
An enumeration of systematic parameters.
const int kPdgF15m1680_N0
Definition: PDGCodes.h:111
const int kPdgP11m1710_N0
Definition: PDGCodes.h:129
const int kPdgS11m1650_NP
Definition: PDGCodes.h:94
const int kPdgAntiNuMu
Definition: PDGCodes.h:28
const int kPdgP33m1232_Delta0
Definition: PDGCodes.h:86
const int kPdgP13m1720_N0
Definition: PDGCodes.h:109
const int kPdgP11m1440_N0
Definition: PDGCodes.h:107
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition: EventRecord.h:38
const int kPdgP33m1920_Delta0
Definition: PDGCodes.h:118
p
Definition: test.py:228
const int kPdgD13m1520_N0
Definition: PDGCodes.h:91
const int kPdgP11m1440_NP
Definition: PDGCodes.h:108
const int kPdgS31m1620_Delta0
Definition: PDGCodes.h:100
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:45
double CalcWeight(const EventRecord &event)
calculate a weight for the input event using the current nuisance param values
Singleton class to load & serve a TDatabasePDG.
Definition: PDGLibrary.h:27
tweak Resonance -> X + gamma branching ratio, eg Delta+(1232) -> p gamma
Definition: GSyst.h:148
TParticlePDG * Find(int pdgc)
Definition: PDGLibrary.cxx:63
const int kPdgPiM
Definition: PDGCodes.h:133
const InitialState & InitState(void) const
Definition: Interaction.h:66
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:67
bool IsBaryonResonance(int pdgc)
is input a baryon resonance?
void SetSystematic(GSyst_t syst, double val)
update the value for the specified nuisance param
static GSystUncertainty * Instance(void)
const int kPdgProton
Definition: PDGCodes.h:62
const int kPdgP11m1710_NP
Definition: PDGCodes.h:130
const int kPdgS11m1535_NP
Definition: PDGCodes.h:90
TLorentzVector * P4(void) const
Definition: GHepParticle.h:79
bool IsHandled(GSyst_t syst)
does the current weight calculator handle the input nuisance param?
const int kPdgS31m1620_DeltaP
Definition: PDGCodes.h:101
double RewBR(const EventRecord &event)
const int kPdgNeutron
Definition: PDGCodes.h:64
distort pi angular distribution in Delta -> N + pi
Definition: GSyst.h:150
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:40
const int kPdgP13m1720_NP
Definition: PDGCodes.h:110
Event finding and building.
const int kPdgD13m1700_N0
Definition: PDGCodes.h:95
GENIE event reweighting engine ABC.
Definition: GReWeightI.h:31
#define pDEBUG
Definition: Messenger.h:54
const int kPdgD33m1700_DeltaP
Definition: PDGCodes.h:105