Fork me on GitHub

source: git/modules/TrackSmearing.cc @ f298e48

ImprovedOutputFile
Last change on this file since f298e48 was f298e48, checked in by Roberto Preghenella <preghenella@…>, 6 months ago

Add radius (distance from beam line) to formula parameterisations

also redefines the DelphesFormula::Eval function to allow one to
include future parameters for parameterisations that can be
taken from Candidates in a generalised way.

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/** \class TrackSmearing
2 *
3 *  Performs d0, dZ, p, Theta, Phi smearing of tracks.
4 *
5 *  \authors A. Hart, M. Selvaggi
6 *
7*/
8
9#include "modules/TrackSmearing.h"
10
11#include "classes/DelphesClasses.h"
12#include "classes/DelphesFactory.h"
13#include "classes/DelphesFormula.h"
14
15#include "ExRootAnalysis/ExRootClassifier.h"
16#include "ExRootAnalysis/ExRootFilter.h"
17#include "ExRootAnalysis/ExRootResult.h"
18
19#include "TDatabasePDG.h"
20#include "TFile.h"
21#include "TFormula.h"
22#include "TLorentzVector.h"
23#include "TMath.h"
24#include "TObjArray.h"
25#include "TProfile2D.h"
26#include "TRandom3.h"
27#include "TString.h"
28
29#include <algorithm>
30#include <iostream>
31#include <sstream>
32#include <stdexcept>
33
34using namespace std;
35
36//------------------------------------------------------------------------------
37
38TrackSmearing::TrackSmearing() :
39  fD0Formula(0), fDZFormula(0), fPFormula(0), fCtgThetaFormula(0), fPhiFormula(0), fItInputArray(0)
40{
41  fD0Formula = new DelphesFormula;
42  fDZFormula = new DelphesFormula;
43  fPFormula = new DelphesFormula;
44  fCtgThetaFormula = new DelphesFormula;
45  fPhiFormula = new DelphesFormula;
46}
47
48//------------------------------------------------------------------------------
49
50TrackSmearing::~TrackSmearing()
51{
52  if(fD0Formula) delete fD0Formula;
53  if(fDZFormula) delete fDZFormula;
54  if(fPFormula) delete fPFormula;
55  if(fCtgThetaFormula) delete fCtgThetaFormula;
56  if(fPhiFormula) delete fPhiFormula;
57}
58
59//------------------------------------------------------------------------------
60
61void TrackSmearing::Init()
62{
63  fBz = GetDouble("Bz", 0.0);
64
65  // read resolution formula
66
67  // !!! IF WE WANT TO KEEP ROOT INPUT !!!
68  if(string(GetString("D0ResolutionFormula", "0.0")) != "0.0")
69  {
70    fD0Formula->Compile(GetString("D0ResolutionFormula", "0.0"));
71    fUseD0Formula = true;
72  }
73  else
74  {
75    fD0ResolutionFile = GetString("D0ResolutionFile", "errors.root");
76    fD0ResolutionHist = GetString("D0ResolutionHist", "d0");
77    fUseD0Formula = false;
78  }
79  if(string(GetString("DZResolutionFormula", "0.0")) != "0.0")
80  {
81    fDZFormula->Compile(GetString("DZResolutionFormula", "0.0"));
82    fUseDZFormula = true;
83  }
84  else
85  {
86    fDZResolutionFile = GetString("DZResolutionFile", "errors.root");
87    fDZResolutionHist = GetString("DZResolutionHist", "dz");
88    fUseDZFormula = false;
89  }
90  if(string(GetString("PResolutionFormula", "0.0")) != "0.0")
91  {
92    fPFormula->Compile(GetString("PResolutionFormula", "0.0"));
93    fUsePFormula = true;
94  }
95  else
96  {
97    fPResolutionFile = GetString("PResolutionFile", "errors.root");
98    fPResolutionHist = GetString("PResolutionHist", "p");
99    fUsePFormula = false;
100  }
101  if(string(GetString("CtgThetaResolutionFormula", "0.0")) != "0.0")
102  {
103    fCtgThetaFormula->Compile(GetString("CtgThetaResolutionFormula", "0.0"));
104    fUseCtgThetaFormula = true;
105  }
106  else
107  {
108    fCtgThetaResolutionFile = GetString("CtgThetaResolutionFile", "errors.root");
109    fCtgThetaResolutionHist = GetString("CtgThetaResolutionHist", "ctgTheta");
110    fUseCtgThetaFormula = false;
111  }
112  if(string(GetString("PhiResolutionFormula", "0.0")) != "0.0")
113  {
114    fPhiFormula->Compile(GetString("PhiResolutionFormula", "0.0"));
115    fUsePhiFormula = true;
116  }
117  else
118  {
119    fPhiResolutionFile = GetString("PhiResolutionFile", "errors.root");
120    fPhiResolutionHist = GetString("PhiResolutionHist", "phi");
121    fUsePhiFormula = false;
122  }
123
124  fApplyToPileUp = GetBool("ApplyToPileUp", true);
125
126  // import input array
127
128  fInputArray = ImportArray(GetString("InputArray", "ParticlePropagator/stableParticles"));
129  fItInputArray = fInputArray->MakeIterator();
130
131  // import beamspot
132  try
133  {
134    fBeamSpotInputArray = ImportArray(GetString("BeamSpotInputArray", "BeamSpotFilter/beamSpotParticle"));
135  }
136  catch(runtime_error &e)
137  {
138    fBeamSpotInputArray = 0;
139  }
140
141  // create output array
142
143  fOutputArray = ExportArray(GetString("OutputArray", "stableParticles"));
144}
145
146//------------------------------------------------------------------------------
147
148void TrackSmearing::Finish()
149{
150  if(fItInputArray) delete fItInputArray;
151}
152
153//------------------------------------------------------------------------------
154
155void TrackSmearing::Process()
156{
157  Int_t iCandidate = 0;
158  TLorentzVector beamSpotPosition;
159  Candidate *candidate, *mother;
160  Double_t pt, eta, e, d0, d0Error, trueD0, dz, dzError, trueDZ, p, pError, trueP, ctgTheta, ctgThetaError, trueCtgTheta, phi, phiError, truePhi;
161  Double_t x, y, z, t, px, py, pz, theta;
162  Double_t q, r;
163  Double_t x_c, y_c, r_c, phi_0;
164  Double_t rcu, rc2, xd, yd, zd;
165  const Double_t c_light = 2.99792458E8;
166  TProfile2D *d0ErrorHist = NULL,
167             *dzErrorHist = NULL,
168             *pErrorHist = NULL,
169             *ctgThetaErrorHist = NULL,
170             *phiErrorHist = NULL;
171
172  if(!fBeamSpotInputArray || fBeamSpotInputArray->GetSize() == 0)
173    beamSpotPosition.SetXYZT(0.0, 0.0, 0.0, 0.0);
174  else
175  {
176    Candidate &beamSpotCandidate = *((Candidate *)fBeamSpotInputArray->At(0));
177    beamSpotPosition = beamSpotCandidate.Position;
178  }
179
180  if(!fUseD0Formula)
181  {
182    TFile *fin = TFile::Open(fD0ResolutionFile.c_str());
183    d0ErrorHist = (TProfile2D *)fin->Get(fD0ResolutionHist.c_str());
184    d0ErrorHist->SetDirectory(0);
185    fin->Close();
186  }
187  if(!fUseDZFormula)
188  {
189    TFile *fin = TFile::Open(fDZResolutionFile.c_str());
190    dzErrorHist = (TProfile2D *)fin->Get(fDZResolutionHist.c_str());
191    dzErrorHist->SetDirectory(0);
192    fin->Close();
193  }
194  if(!fUsePFormula)
195  {
196    TFile *fin = TFile::Open(fPResolutionFile.c_str());
197    pErrorHist = (TProfile2D *)fin->Get(fPResolutionHist.c_str());
198    pErrorHist->SetDirectory(0);
199    fin->Close();
200  }
201  if(!fUseCtgThetaFormula)
202  {
203    TFile *fin = TFile::Open(fCtgThetaResolutionFile.c_str());
204    ctgThetaErrorHist = (TProfile2D *)fin->Get(fCtgThetaResolutionHist.c_str());
205    ctgThetaErrorHist->SetDirectory(0);
206    fin->Close();
207  }
208  if(!fUsePhiFormula)
209  {
210    TFile *fin = TFile::Open(fPhiResolutionFile.c_str());
211    phiErrorHist = (TProfile2D *)fin->Get(fPhiResolutionHist.c_str());
212    phiErrorHist->SetDirectory(0);
213    fin->Close();
214  }
215
216  fItInputArray->Reset();
217  while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
218  {
219
220    const TLorentzVector &momentum = candidate->Momentum;
221    const TLorentzVector &position = candidate->InitialPosition;
222
223    pt = momentum.Pt();
224    eta = momentum.Eta();
225    e = momentum.E();
226   
227    d0 = trueD0 = candidate->D0;
228    dz = trueDZ = candidate->DZ;
229
230    p = trueP = candidate->P;
231    ctgTheta = trueCtgTheta = candidate->CtgTheta;
232    phi = truePhi = candidate->Phi;
233
234    if(fUseD0Formula)
235      d0Error = fD0Formula->Eval(pt, eta, phi, e, candidate);
236    else
237    {
238      Int_t xbin, ybin;
239
240      xbin = pt < d0ErrorHist->GetXaxis()->GetXmax() ? d0ErrorHist->GetXaxis()->FindBin(pt) : d0ErrorHist->GetXaxis()->GetBinCenter(d0ErrorHist->GetXaxis()->GetNbins());
241      ybin = d0ErrorHist->GetYaxis()->FindBin(TMath::Abs(eta));
242      d0Error = d0ErrorHist->GetBinContent(xbin, ybin);
243      if(!d0Error)
244        d0Error = -1.0;
245    }
246    if(d0Error < 0.0)
247      continue;
248
249    if(fUseDZFormula)
250      dzError = fDZFormula->Eval(pt, eta, phi, e, candidate);
251    else
252    {
253      Int_t xbin, ybin;
254
255      xbin = pt < dzErrorHist->GetXaxis()->GetXmax() ? dzErrorHist->GetXaxis()->FindBin(pt) : dzErrorHist->GetXaxis()->GetBinCenter(dzErrorHist->GetXaxis()->GetNbins());
256      ybin = dzErrorHist->GetYaxis()->FindBin(TMath::Abs(eta));
257      dzError = dzErrorHist->GetBinContent(xbin, ybin);
258      if(!dzError)
259        dzError = -1.0;
260    }
261    if(dzError < 0.0)
262      continue;
263
264    if(fUsePFormula)
265      pError = fPFormula->Eval(pt, eta, phi, e, candidate) * p;
266    else
267    {
268      Int_t xbin, ybin;
269
270      xbin = pt < pErrorHist->GetXaxis()->GetXmax() ? pErrorHist->GetXaxis()->FindBin(pt) : pErrorHist->GetXaxis()->GetBinCenter(pErrorHist->GetXaxis()->GetNbins());
271      ybin = pErrorHist->GetYaxis()->FindBin(TMath::Abs(eta));
272      pError = pErrorHist->GetBinContent(xbin, ybin) * p;
273      if(!pError)
274        pError = -1.0;
275    }
276    if(pError < 0.0)
277      continue;
278
279    if(fUseCtgThetaFormula)
280      ctgThetaError = fCtgThetaFormula->Eval(pt, eta, phi, e, candidate);
281    else
282    {
283      Int_t xbin, ybin;
284
285      xbin = pt < ctgThetaErrorHist->GetXaxis()->GetXmax() ? ctgThetaErrorHist->GetXaxis()->FindBin(pt) : ctgThetaErrorHist->GetXaxis()->GetBinCenter(ctgThetaErrorHist->GetXaxis()->GetNbins());
286      ybin = ctgThetaErrorHist->GetYaxis()->FindBin(TMath::Abs(eta));
287      ctgThetaError = ctgThetaErrorHist->GetBinContent(xbin, ybin);
288      if(!ctgThetaError)
289        ctgThetaError = -1.0;
290    }
291    if(ctgThetaError < 0.0)
292      continue;
293
294    if(fUsePhiFormula)
295      phiError = fPhiFormula->Eval(pt, eta, phi, e, candidate);
296    else
297    {
298      Int_t xbin, ybin;
299
300      xbin = pt < phiErrorHist->GetXaxis()->GetXmax() ? phiErrorHist->GetXaxis()->FindBin(pt) : phiErrorHist->GetXaxis()->GetBinCenter(phiErrorHist->GetXaxis()->GetNbins());
301      ybin = phiErrorHist->GetYaxis()->FindBin(TMath::Abs(eta));
302      phiError = phiErrorHist->GetBinContent(xbin, ybin);
303      if(!phiError)
304        phiError = -1.0;
305    }
306    if(phiError < 0.0)
307      continue;
308
309    if(fApplyToPileUp || !candidate->IsPU)
310    {
311      d0 = gRandom->Gaus(d0, d0Error);
312      dz = gRandom->Gaus(dz, dzError);
313      p = gRandom->Gaus(p, pError);
314      ctgTheta = gRandom->Gaus(ctgTheta, ctgThetaError);
315      phi = gRandom->Gaus(phi, phiError);
316    }
317
318    if(p < 0.0) continue;
319    while(phi > TMath::Pi()) phi -= TMath::TwoPi();
320    while(phi <= -TMath::Pi()) phi += TMath::TwoPi();
321
322    mother = candidate;
323    candidate = static_cast<Candidate *>(candidate->Clone());
324    candidate->D0 = d0;
325    candidate->DZ = dz;
326    candidate->P = p;
327    candidate->CtgTheta = ctgTheta;
328    candidate->Phi = phi;
329
330    theta = TMath::ACos(ctgTheta / TMath::Sqrt(1.0 + ctgTheta * ctgTheta));
331    candidate->Momentum.SetPx(p * TMath::Cos(phi) * TMath::Sin(theta));
332    candidate->Momentum.SetPy(p * TMath::Sin(phi) * TMath::Sin(theta));
333    candidate->Momentum.SetPz(p * TMath::Cos(theta));
334    candidate->Momentum.SetE(candidate->Momentum.Pt() * TMath::CosH(eta));
335    candidate->PT = candidate->Momentum.Pt();
336
337    x = position.X();
338    y = position.Y();
339    z = position.Z();
340    t = position.T();
341    px = candidate->Momentum.Px();
342    py = candidate->Momentum.Py();
343    pz = candidate->Momentum.Pz();
344    pt = candidate->Momentum.Pt();
345
346    // -- solve for delta: d0' = ( (x+delta)*py' - (y+delta)*px' )/pt'
347
348    candidate->InitialPosition.SetX(x + ((px * y - py * x + d0 * pt) / (py - px)));
349    candidate->InitialPosition.SetY(y + ((px * y - py * x + d0 * pt) / (py - px)));
350    x = candidate->InitialPosition.X();
351    y = candidate->InitialPosition.Y();
352    candidate->InitialPosition.SetZ(z + ((pz * (px * (x - beamSpotPosition.X()) + py * (y - beamSpotPosition.Y())) + pt * pt * (dz - z)) / (pt * pt)));
353    z = candidate->InitialPosition.Z();
354
355    candidate->InitialPosition.SetT(t);
356
357    // update closest approach
358    x *= 1.0E-3;
359    y *= 1.0E-3;
360    z *= 1.0E-3;
361
362    q = candidate->Charge;
363
364    r = pt / (q * fBz) * 1.0E9 / c_light; // in [m]
365    phi_0 = TMath::ATan2(py, px); // [rad] in [-pi, pi]
366
367    // 2. helix axis coordinates
368    x_c = x + r * TMath::Sin(phi_0);
369    y_c = y - r * TMath::Cos(phi_0);
370    r_c = TMath::Hypot(x_c, y_c);
371
372    rcu = TMath::Abs(r);
373    rc2 = r_c * r_c;
374
375    // calculate coordinates of closest approach to track circle in transverse plane xd, yd, zd
376    xd = x_c * x_c * x_c - x_c * rcu * r_c + x_c * y_c * y_c;
377    xd = (rc2 > 0.0) ? xd / rc2 : -999;
378    yd = y_c * (-rcu * r_c + rc2);
379    yd = (rc2 > 0.0) ? yd / rc2 : -999;
380    zd = z + (TMath::Sqrt(xd * xd + yd * yd) - TMath::Sqrt(x * x + y * y)) * pz / pt;
381
382    candidate->Xd = xd * 1.0E3;
383    candidate->Yd = yd * 1.0E3;
384    candidate->Zd = zd * 1.0E3;
385
386    if(fApplyToPileUp || !candidate->IsPU)
387    {
388      candidate->ErrorD0 = d0Error;
389      candidate->ErrorDZ = dzError;
390      candidate->ErrorP = pError;
391      candidate->ErrorCtgTheta = ctgThetaError;
392      candidate->ErrorPhi = phiError;
393      candidate->ErrorPT = ptError(p, ctgTheta, pError, ctgThetaError);
394      candidate->TrackResolution = pError / p;
395    }
396
397    candidate->AddCandidate(mother);
398    fOutputArray->Add(candidate);
399
400    iCandidate++;
401  }
402}
403
404Double_t TrackSmearing::ptError(const Double_t p, const Double_t ctgTheta, const Double_t dP, const Double_t dCtgTheta)
405{
406  Double_t a, b;
407  a = (p * p * ctgTheta * ctgTheta * dCtgTheta * dCtgTheta) / ((ctgTheta * ctgTheta + 1) * (ctgTheta * ctgTheta + 1) * (ctgTheta * ctgTheta + 1));
408  b = (dP * dP) / (ctgTheta * ctgTheta + 1);
409  return sqrt(a + b);
410}
411
412//------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.