MINT2
SpinFactors4Body_Tensors.cpp
Go to the documentation of this file.
1 // author: Jonas Rademacker (Jonas.Rademacker@bristol.ac.uk)
2 // created: 9 Oct 2013
3 #include "Mint/SpinFactors.h"
5 #include "Mint/DecayTree.h"
6 #include "Mint/Utils.h"
8 
9 #include "Mint/ZTspin1.h"
10 #include "Mint/ZTspin2.h"
11 #include "Mint/LeviCivita.h"
12 #include "Mint/SpinSumT.h"
13 
14 
15 using namespace std;
16 using namespace MINT;
17 
20 
24 
27 
29 
33 
34 
36 
37 //============================================================
38 
39 // ----------- D->VT, various L states --------
41  if(0==_exampleDecay){
42  _exampleDecay = new DecayTree(421);
43  // remark: addDgtr always returns a pointer to the
44  // last daughter that was added, thus allowing these
45  // chains:
46  _exampleDecay->addDgtr( 225)->addDgtr( 221, -211);
47  _exampleDecay->addDgtr( 333)->addDgtr(-321, 321);
48  }
49  return *_exampleDecay;
50 }
52  return getExampleDecay();
53 }
54 
56  if(0==_exampleDecayD){
57  _exampleDecayD = new DecayTree(421);
58  // remark: addDgtr always returns a pointer to the
59  // last daughter that was added, thus allowing these
60  // chains:
61  _exampleDecayD->addDgtr( 225)->addDgtr( 221, -211);
62  _exampleDecayD->addDgtr( 333)->addDgtr(-321, 321);
63 
64  _exampleDecayD->getVal().setL(2);
65  }
66  return *_exampleDecayD;
67 }
69  return getExampleDecay();
70 }
71 
72 // ------- D-> TT, varous L states ----------
74  // D->f2 f2 (with L=0)
75  _exampleDecay = new DecayTree(421);
76  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
77  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
78  return *_exampleDecay;
79 }
81  return getExampleDecay();
82 }
83 
85  // D->f2 f2 (with L=1)
86  _exampleDecay = new DecayTree(421);
87  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
88  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
89  _exampleDecay->getVal().setL(1);
90  return *_exampleDecay;
91 }
93  return getExampleDecay();
94 }
95 
97  // D->f2 f2 (with L=2)
98  _exampleDecay = new DecayTree(421);
99  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
100  _exampleDecay->addDgtr(225)->addDgtr(211, -211);
101  _exampleDecay->getVal().setL(2);
102  return *_exampleDecay;
103 }
105  return getExampleDecay();
106 }
107 
108 // ------- D->TP0, various subesquent decays of the T ----
109 
111  _exampleDecay = new DecayTree(421);
112  _exampleDecay->addDgtr(-211, 215)->addDgtr(211, 113)->addDgtr(-211, 211);
113  return *_exampleDecay;
114 }
116  return getExampleDecay();
117 }
119  _exampleDecay = new DecayTree(421);
120  _exampleDecay->addDgtr(-211, 100215)->addDgtr(211, 225)->addDgtr(-211, 211);
121  return *_exampleDecay;
122 }
124  return getExampleDecay();
125 }
126 
127 
128 // ----- D->TS ----------
130  if(0==_exampleDecay){
131  _exampleDecay = new DecayTree(421);
132  // remark: addDgtr always returns a pointer to the
133  // last daughter that was added, thus allowing these
134  // chains:
135  _exampleDecay->addDgtr( 225)->addDgtr( 221, -211);
136  _exampleDecay->addDgtr( 9010221)->addDgtr(-321, 321);
137  }
138  return *_exampleDecay;
139 }
141  return getExampleDecay();
142 }
143 
144 // ----- D->PseudoTensor P0, various modes
146  _exampleDecay = new DecayTree(421);
147  _exampleDecay->addDgtr(-211, 10215)->addDgtr(211, 225)->addDgtr(211, -211);
148  return *_exampleDecay;
149 }
151  return getExampleDecay();
152 }
154  _exampleDecay = new DecayTree(421);
155  _exampleDecay->addDgtr(-211, 10215)->addDgtr(211, 9000221)->addDgtr(211, -211);
156  return *_exampleDecay;
157 }
159  return getExampleDecay();
160 }
162  // (angular momenum of pi2->rho must be 1)
163  _exampleDecay = new DecayTree(421);
164  _exampleDecay->addDgtr(-211, 10215)->addDgtr(211, 113)->addDgtr(211, -211);
165  return *_exampleDecay;
166 }
168  return getExampleDecay();
169 }
170 
171 // ----- D->AP, A->TP, ---------
173  _exampleDecay = new DecayTree(421);
174  // example: D->a1(1260) pi, a1 -> f2(1270) pi
175  // (kinematically challenged, but in PDG - broad particles...)
176  _exampleDecay->addDgtr(-211, 20213)->addDgtr(211, 225)->addDgtr(211, -211);
177  return *_exampleDecay;
178 }
180  return getExampleDecay();
181 }
182 
183 //=============================================================
184 
186  // bool debugThis=false;
187  if(fsPS.size() < 4) fsPS.reserve(4);
188  if(theDecay(pat).nDgtr() != 2){
189  cout << "ERROR in SF_DtoVT_VtoP0P1_TtoP2P3_S::parseTree"
190  << " expected exactly 2 daughers of D, have "
191  << theDecay(pat).nDgtr();
192  return false;
193  }
194 
195  for(int i=0; i< theDecay(pat).nDgtr(); i++){
196  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
197  if(dgtr->getVal().SVPAT() == "V" && ! dgtr->isFinalState()) V = dgtr;
198  else if(dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T = dgtr;
199  }
200 
201  if(0==V || 0==T){
202  cout << "ERROR in SF_DtoVT_VtoP0P1_TtoP2P3_BASE::parseTree"
203  << " Didn't find V or T " << V.get() << ", " << T.get() << endl;
204  return false;
205  }
206  if(V->nDgtr() != 2){
207  cout << "ERROR in SF_DtoVT_VtoP0P1_TtoP2P3_BASE::parseTree"
208  << " V should have 2 daughters, but it says it has "
209  << V->nDgtr() << "."
210  << endl;
211  return false;
212  }
213  fsPS[0] = V->getDgtrTreePtr(0);
214  fsPS[1] = V->getDgtrTreePtr(1);
215  //normalOrder(fsPS[0], fsPS[1]);
216 
217  if(T->nDgtr() != 2){
218  cout << "ERROR in SF_DtoVT_VtoP0P1_TtoP2P3_BASE::parseTree"
219  << " T should have 2 daughters, but it says it has "
220  << T->nDgtr() << "."
221  << endl;
222  return false;
223  }
224  fsPS[2] = T->getDgtrTreePtr(0);
225  fsPS[3] = T->getDgtrTreePtr(1);
226  //normalOrder(fsPS[2], fsPS[3]);
227 
228  // this->printYourself();
229  return true;
230 }
231 
233  bool dbThis=false;
234  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
235 
236  const double units = GeV*GeV*GeV*GeV;
237 
238  TLorentzVector pV = p(0, evt) + p(1, evt);
239  TLorentzVector qV = p(0, evt) - p(1, evt);
240  TLorentzVector pT = p(2, evt) + p(3, evt);
241  TLorentzVector qT = p(2, evt) - p(3, evt);
242  TLorentzVector pD = pV + pT;
243  TLorentzVector qD = pV - pT;
244 
245  double MV = mRes(V, evt);
246  double MT = mRes(T, evt);
247 
248  ZTspin1 tV(qV, pV, MV);
249  ZTspin2 tT(qT, pT, MT);
250 
251  if (_useZemachTensors) {
252  ZTspin1 tD(qD,pD,pD.M());
253  return (tT.Contract(tV)).Dot(tD) / units;
254  }
255 
256  double returnVal = (tT.Contract(tV)).Dot(pV) / units;
257 
258  if(dbThis){
259  cout << " SF_DtoVT_VtoP0P1_TtoP2P3_P::getVal "
260  << " returning " << returnVal
261  << endl;
262  }
263  return returnVal;
264 
265 }
267  // bool debugThis = false;
268  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
269  os << "spin factor SF_DtoVT_VtoP0P1_TtoP2P3_P"
270  << "\n\t T1(V)_{\\mu} T2(T)^{\\mu\\nu} pV_{\\nu}"
271  << "\n\t implemented as: (tT.Contract(tV)).Dot(pV) / GeV^4"
272  << "\n\t with T1(V) = ZTspin1 tV(qV, pV, MV), T2(T)= ZTspin2 tT(qT, pT, MT);"
273  << "\n\t and pV = p(0) + p(1), qV = p(0) - p(1), pT = p(2) + p(3), qT = p(2) - p(3)"
274  << "\n\t parsed tree " << theDecay().oneLiner()
275  << "\n like this:" << endl;
276  this->printParsing(os);
277 }
278 // -------------------------------------
279 
281  bool dbThis=false;
282  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
283 
284  TLorentzVector pV = p(0, evt) + p(1, evt);
285  TLorentzVector qV = p(0, evt) - p(1, evt);
286  TLorentzVector pT = p(2, evt) + p(3, evt);
287  TLorentzVector qT = p(2, evt) - p(3, evt);
288 
289  TLorentzVector pD = pT + pV;
290  TLorentzVector qD = pT - qV;
291 
292  double MV = mRes(V, evt);
293  double MT = mRes(T, evt);
294 
295  ZTspin1 tV(qV, pV, MV);
296  ZTspin2 tT(qT, pT, MT);
297  TLorentzVector vecT(tT.Contract(pV));
298 
299  const double units = GeV*GeV * GeV*GeV * GeV*GeV;
300 
301  if (_useZemachTensors) {
302  ZTspin2 tD(qD,pD,pD.M());
303  LorentzMatrix M = tD.Contract_1(tT);
304  return LeviCivita(tV,pD,M) / units;
305  }
306 
307  double returnVal = LeviCivita(tV, vecT, qD, pD) /units;
308 
309 
310  if(dbThis){
311  cout << " SF_DtoVT_VtoP0P1_TtoP2P3_D::getVal "
312  << " returning " << returnVal
313  << endl;
314  double checkVal = LeviCivita(p(0, evt), p(1, evt), p(2, evt), p(3, evt))*MV*MT/units;
315  cout << "cross check: " << checkVal
316  << " ratio " << checkVal/returnVal << endl;
317  }
318  return returnVal;
319 
320 }
322  // bool debugThis = false;
323  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
324  os << "spin factor SF_DtoVT_VtoP0P1_TtoP2P3_D"
325  << "\n\t ZTspin1 tV(qV, pV, MV);"
326  << "\n\t ZTspin2 tT(qT, pT, MT);"
327  << "\n\t TLorentzVector vecT(tT.Contract(pV));"
328  << "\n\t const double units = GeV*GeV * GeV*GeV * GeV*GeV;"
329  << "\n\t double returnVal = LeviCivita(tV, vecT, qD, pD) /units;"
330  << "\n\t with pV = p(0) + p(1), qV = p(0) - p(1), pT = p(2) + p(3), qT = p(2) - p(3)"
331  << "\n\t and pD = pT + pV, qD = pT - qV;"
332  << "\n\t parsed tree " << theDecay().oneLiner()
333  << "\n like this:" << endl;
334  this->printParsing(os);
335 }
336 
337 //------------------------------------------
338 // D->TT, various L states
339 //-------------------------------------------
340 // -----------------------------------------------
342  // bool debugThis=false;
343  if(fsPS.size() < 4) fsPS.reserve(4);
344  if(theDecay(pat).nDgtr() != 2){
345  cout << "ERROR in SF_DtoT1T2_T1toP0P1_T2toP2P3_BASE::parseTree"
346  << " expected exactly 2 daughers of D, have "
347  << theDecay(pat).nDgtr();
348  return false;
349  }
350 
351  for(int i=0; i< theDecay(pat).nDgtr(); i++){
352  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
353  if(dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T[i] = dgtr;
354  else{
355  cout << "ERROR in SF_DtoT1T2_T1toP0P1_T2toP2P3_BASE::parseTree"
356  << " expected exactly 2 Tensors, have "
357  << theDecay(pat).nDgtr();
358  cout << "\n so daughter " << i << " is not a tensor." << endl;
359  return false;
360  }
361  }
362 
363  if(0==T[0] || 0==T[1]){
364  cout << "ERROR in SF_DtoT1T2_T1toP0P1_T2toP2P3_BASE::parseTree"
365  << " Didn't find T or S " << T[0].get() << ", " << T[1].get() << endl;
366  return false;
367  }
368  if(T[0]->nDgtr() != 2){
369  cout << "ERROR in SF_DtoT1T2_T1toP0P1_T2toP2P3_BASE::parseTree"
370  << " T[0] should have 2 daughters, but it says it has "
371  << T[0]->nDgtr() << "."
372  << endl;
373  return false;
374  }
375  fsPS[0] = T[0]->getDgtrTreePtr(0);
376  fsPS[1] = T[0]->getDgtrTreePtr(1);
377  // normalOrder(fsPS[0], fsPS[1]);
378 
379  if(T[1]->nDgtr() != 2){
380  cout << "ERROR in SF_DtoT1T2_T1toP0P1_T2toP2P3_S::parseTree"
381  << " T[1] should have 2 daughters, but it says it has "
382  << T[1]->nDgtr() << "."
383  << endl;
384  return false;
385  }
386  fsPS[2] = T[1]->getDgtrTreePtr(0);
387  fsPS[3] = T[1]->getDgtrTreePtr(1);
388  // normalOrder(fsPS[2], fsPS[3]);
389 
390  // this->printYourself();
391  return true;
392 }
393 // ------- same decay, s-wave -----
395  bool dbThis=false;
396  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
397 
398  TLorentzVector pT1 = p(0, evt) + p(1, evt);
399  TLorentzVector qT1 = p(0, evt) - p(1, evt);
400  TLorentzVector pT2 = p(2, evt) + p(3, evt);
401  TLorentzVector qT2 = p(2, evt) - p(3, evt);
402 
403  double MT1 = mRes(T[0], evt);
404  double MT2 = mRes(T[1], evt);
405 
406  ZTspin2 tT1(qT1, pT1, MT1);
407  ZTspin2 tT2(qT2, pT2, MT2);
408 
409  const double units = GeV*GeV*GeV*GeV;
410 
411  double returnVal = tT1.Contract_2(tT2) / units;
412 
413  if(dbThis){
414  cout << " SF_DtoT1T2_T1toP0P1_T2toP2P3_S::getVal "
415  << " returning " << returnVal
416  << endl;
417  }
418  return returnVal;
419 
420 }
421 
423  // bool debugThis = false;
424  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
425  os << "spin factor SF_DtoT1T2_T1toP0P1_T2toP2P3_S"
426  << "\n\t ZTspin2 tT1(qT1, pT1, MT1);"
427  << "\n\t ZTspin2 tT2(qT2, pT2, MT2);"
428  << "\n\t return: tT1.Contract_2(tT2) / GeV^8"
429  << "\n\t with pT1 = p(0) + p(1), qT = p(0) - p(1), pT2 = p(2) + p(3), qT2 = p(2)-p(3)"
430  << "\n\t parsed tree " << theDecay().oneLiner()
431  << "\n like this:" << endl;
432  this->printParsing(os);
433 }
434 // ------- same decay, P-wave -----
436  bool dbThis=false;
437  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
438 
439  TLorentzVector pT1 = p(0, evt) + p(1, evt);
440  TLorentzVector qT1 = p(0, evt) - p(1, evt);
441  TLorentzVector pT2 = p(2, evt) + p(3, evt);
442  TLorentzVector qT2 = p(2, evt) - p(3, evt);
443  TLorentzVector pD = pT1 + pT2;
444  TLorentzVector qD = pT1 - pT2;
445 
446 
447  double MT1 = mRes(T[0], evt);
448  double MT2 = mRes(T[1], evt);
449 
450  ZTspin2 tT1(qT1, pT1, MT1);
451  ZTspin2 tT2(qT2, pT2, MT2);
452 
453  const double units = GeV*GeV * GeV*GeV * GeV*GeV ;
454 
455  if (_useZemachTensors) {
456  ZTspin1 tD(qD,pD,pD.M());
457  return LeviCivita(pD, tD, tT1.Contract_1(tT2)) / units;
458  }
459 
460  double returnVal = LeviCivita(pD, qD, tT1.Contract_1(tT2)) / units;
461 
462  if(dbThis){
463  cout << " SF_DtoT1T2_T1toP0P1_T2toP2P3_P::getVal "
464  << " returning " << returnVal
465  << endl;
466  }
467  return returnVal;
468 
469 }
470 
472  // bool debugThis = false;
473  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
474  os << "spin factor SF_DtoT1T2_T1toP0P1_T2toP2P3_P"
475  << "\n\t ZTspin2 tT1(qT1, pT1, MT1);"
476  << "\n\t ZTspin2 tT2(qT2, pT2, MT2);"
477  << "\n\t pD = pT1 + pT2 "
478  << "\n\t qD = pT1 - pT2 "
479  << "\n\t return: LeviCivita(pD, qD, tT1.Contract_1(tT2))/ GeV^4"
480  << "\n\t with pT1 = p(0) + p(1), qT = p(0) - p(1), pT2 = p(2) + p(3), qT2 = p(2)-p(3)"
481  << "\n\t parsed tree " << theDecay().oneLiner()
482  << "\n like this:" << endl;
483  this->printParsing(os);
484 }
485 // ------- same decay, D-wave -----
487  bool dbThis=false;
488  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
489 
490  TLorentzVector pT1 = p(0, evt) + p(1, evt);
491  TLorentzVector qT1 = p(0, evt) - p(1, evt);
492  TLorentzVector pT2 = p(2, evt) + p(3, evt);
493  TLorentzVector qT2 = p(2, evt) - p(3, evt);
494  TLorentzVector qD = pT1 - pT2;
495  TLorentzVector pD = pT1 + pT2;
496 
497  double MT1 = mRes(T[0], evt);
498  double MT2 = mRes(T[1], evt);
499 
500  ZTspin2 tT1(qT1, pT1, MT1);
501  ZTspin2 tT2(qT2, pT2, MT2);
502 
503  TLorentzVector X1(tT1.Contract(qD));
504  TLorentzVector X2(tT2.Contract(qD));
505 
506  const double units = GeV*GeV*GeV * GeV*GeV*GeV;
507 
508  if (_useZemachTensors) {
509  ZTspin1 tD(qD,pD,pD.M());
510  double val = (tT1.Contract(tD)).Dot(tT2.Contract(tD));
511  val -= 1./3. * tD.Dot(tD) * tT1.Contract_2(tT2);
512  val += 1./3. * tD.Dot(tD) / (pD.Dot(pD)) * (tT1.Contract(pD)).Dot(tT2.Contract(pD));
513  return val/units;
514  }
515 
516  double returnVal = X1.Dot(X2) / units;
517 
518  if(dbThis){
519  cout << " SF_DtoT1T2_T1toP0P1_T2toP2P3_D::getVal "
520  << " returning " << returnVal
521  << endl;
522  }
523  return returnVal;
524 
525 }
526 
528  // bool debugThis = false;
529  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
530  os << "spin factor SF_DtoT1T2_T1toP0P1_T2toP2P3_D"
531  << "\n\t ZTspin2 tT1(qT1, pT1, MT1);"
532  << "\n\t ZTspin2 tT2(qT2, pT2, MT2);"
533  << "\n\t qD = pT1 - pT2"
534  << "\n\t return: (tT1.Contract(qD))* (tT2.Contract(qD))/ GeV^4"
535  << "\n\t with pT1 = p(0) + p(1), qT = p(0) - p(1), pT2 = p(2) + p(3), qT2 = p(2)-p(3)"
536  << "\n\t parsed tree " << theDecay().oneLiner()
537  << "\n like this:" << endl;
538  this->printParsing(os);
539 }
540 
541 // ------------------------------------------
542 // D->TP0, various subesquent decays of the T
543 //------------------------------------------------
545  // bool debugThis=false;
546  if(fsPS.size() < 4) fsPS.reserve(4);
547  if(theDecay(pat).nDgtr() != 2){
548  cout << "ERROR in SF_DtoTP0_TtoVP1_VtoP2P3_BASE::parseTree"
549  << " expected exactly 2 daughers of D, have "
550  << theDecay(pat).nDgtr();
551  return false;
552  }
553  for(int i=0; i< theDecay(pat).nDgtr(); i++){
554  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
555  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
556  else if(dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T = dgtr;
557  }
558  if(0==T || 0==fsPS[0]){
559  cout << "ERROR in SF_DtoTP0_TtoVP1_VtoP2P3_BASE::parseTree"
560  << " Didn't find T or P0 " << T.get() << ", " << fsPS[0].get() << endl;
561  return false;
562  }
563 
564  if(T->nDgtr() != 2){
565  cout << "ERROR in SF_DtoTP0_TtoVP1_VtoP2P3_BASE::parseTree"
566  << " T should have 2 daughters, but it says it has "
567  << T->nDgtr() << "."
568  << endl;
569  return false;
570  }
571  for(int i=0; i< T->nDgtr(); i++){
572  const_counted_ptr<AssociatedDecayTree> dgtr= T->getDgtrTreePtr(i);
573  if (dgtr->getVal().SVPAT() == "V" && ! dgtr->isFinalState()) V = dgtr;
574  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
575  }
576  if(0==V || 0==fsPS[1]){
577  cout << "ERROR in SF_DtoTP0_TtoVP1_VtoP2P3_BASE::parseTree"
578  << " Didn't find V2 or P1 " << V.get() << ", " << fsPS[1].get() << endl;
579  return false;
580  }
581 
582  if(V->nDgtr() != 2){
583  cout << "ERROR in SF_DtoTP0_TtoVP1_VtoP2P3_BASE::parseTree"
584  << " V should have 2 daughters, but it says it has "
585  << V->nDgtr() << "."
586  << endl;
587  return false;
588  }
589  fsPS[2] = V->getDgtrTreePtr(0);
590  fsPS[3] = V->getDgtrTreePtr(1);
591  // normalOrder(fsPS[2], fsPS[3]);
592 
593  // this->printYourself();
594  return true;
595 }
596 // ------- note that T->VP1 has to be in D-wave for parity and ang mom ----
598  bool dbThis=false;
599  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
600 
601  TLorentzVector pV = p(2, evt) + p(3, evt);
602  TLorentzVector qV = p(2, evt) - p(3, evt);
603  TLorentzVector pT = pV + p(1, evt);
604  TLorentzVector qT = pV - p(1, evt);
605  TLorentzVector pD = pT + p(0, evt);
606  TLorentzVector qD = pT - p(0, evt);
607 
608  double MT = mRes(T, evt);
609  double MV = mRes(V, evt);
610 
611  ZTspin2 t2T(qT, pT, MT);
612  ZTspin1 tV(qV, pV, MV);
613 
614  TLorentzVector DT(t2T.Contract(qD));
615 
616  const double units = GeV*GeV * GeV*GeV * GeV*GeV;
617 
618  if (_useZemachTensors) {
619  ZTspin1 tD(qD,pD,pD.M());
620  ZTspin1 t1T(qT, pT, MT);
621  SpinSumV P1T(pT,MT);
622  SpinSumT P2T(pT,MT);
623 
624  TLorentzVector tmp = LeviCivita(t1T,pT,P1T.Dot(tV));
625 
626  return P2T.Sandwich(tD,tD,tmp,t1T)/ units + 1./3. * tD.Dot(tD) / (pT.Dot(pT)) * P2T.Sandwich(pD,pD,tmp,t1T)/ units;
627  }
628 
629  double returnVal = LeviCivita(pD, qD, DT, tV) / units;
630 
631  if(dbThis){
632  cout << " SF_DtoTP0_TtoVP1_VtoP2P3::getVal "
633  << " returning " << returnVal
634  << endl;
635  }
636  return returnVal;
637 }
638 
640  // bool debugThis = false;
641  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
642  os << "spin factor SF_DtoTP0_TtoVP1_VtoP2P3"
643  << "\n\t ZTspin2 tT1(qT, pT, MT);"
644  << "\n\t ZTspin1 tT2(qV, pV, MV);"
645  << "\n\t pV = p(2) + p(3); qV = p(2) - p(3);"
646  << "\n\t pT = pV + p(1); qT = pV - p(1);"
647  << "\n\t pD = pT + p(0); qD = pT - p(0);"
648  << "\n\t return: DT(tT.Contract(qD))/GeV^6"
649  << "\n\t parsed tree " << theDecay().oneLiner()
650  << "\n like this:" << endl;
651  this->printParsing(os);
652 }
653 // -----------------------------------------------
655  // bool debugThis=false;
656  if(fsPS.size() < 4) fsPS.reserve(4);
657  if(theDecay(pat).nDgtr() != 2){
658  cout << "ERROR in SF_DtoT1P0_T1toT2P1_T2toP2P3_BASE::parseTree"
659  << " expected exactly 2 daughers of D, have "
660  << theDecay(pat).nDgtr();
661  return false;
662  }
663  for(int i=0; i< theDecay(pat).nDgtr(); i++){
664  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
665  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
666  else if(dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T1 = dgtr;
667  }
668  if(0==T1 || 0==fsPS[0]){
669  cout << "ERROR in SF_DtoT1P0_T1toT2P1_T2toP2P3_BASE::parseTree"
670  << " Didn't find T or P0 " << T1.get() << ", " << fsPS[0].get() << endl;
671  return false;
672  }
673 
674  if(T1->nDgtr() != 2){
675  cout << "ERROR in SF_DtoT1P0_T1toT2P1_T2toP2P3_BASE::parseTree"
676  << " T should have 2 daughters, but it says it has "
677  << T1->nDgtr() << "."
678  << endl;
679  return false;
680  }
681  for(int i=0; i< T1->nDgtr(); i++){
682  const_counted_ptr<AssociatedDecayTree> dgtr= T1->getDgtrTreePtr(i);
683  if (dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T2 = dgtr;
684  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
685  }
686  if(0==T2 || 0==fsPS[1]){
687  cout << "ERROR in SF_DtoT1P0_T1toT2P1_T2toP2P3_BASE::parseTree"
688  << " Didn't find T2 or P1 " << T2.get() << ", " << fsPS[1].get() << endl;
689  return false;
690  }
691 
692  if(T2->nDgtr() != 2){
693  cout << "ERROR in SF_DtoT1P0_T1toT2P1_T2toP2P3_BASE::parseTree"
694  << " V should have 2 daughters, but it says it has "
695  << T2->nDgtr() << "."
696  << endl;
697  return false;
698  }
699  fsPS[2] = T2->getDgtrTreePtr(0);
700  fsPS[3] = T2->getDgtrTreePtr(1);
701  // normalOrder(fsPS[2], fsPS[3]);
702 
703  // this->printYourself();
704  return true;
705 }
706 // ------- note that T->TP1 has to be in P-wave (or F, etc) for parity and ang mom ----
708  bool dbThis=false;
709  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
710 
711  TLorentzVector pT2 = p(2, evt) + p(3, evt);
712  TLorentzVector qT2 = p(2, evt) - p(3, evt);
713  TLorentzVector pT1 = pT2 + p(1, evt);
714  TLorentzVector qT1 = pT2 - p(1, evt);
715  TLorentzVector pD = pT1 + p(0, evt);
716  TLorentzVector qD = pT1 - p(0, evt);
717 
718  double MT1 = mRes(T1 ,evt);
719  double MT2 = mRes(T2, evt);
720 
721  ZTspin2 tT1(qT1, pT1, MT1);
722  ZTspin2 tT2(qT2, pT2, MT2);
723 
724  TLorentzVector DT(tT1.Contract(qT1));
725 
726  const double units = GeV*GeV * GeV*GeV * GeV*GeV;
727 
728  if (_useZemachTensors) {
729  ZTspin1 LT1(qT1, pT1, MT1);
730  ZTspin1 LT2(qT2, pT2, MT2);
731  SpinSumT PT1(pT1,MT1);
732 
733  TLorentzVector tmp1 = LeviCivita(LT1,pT1,LT2);
734  TLorentzVector tmp2 = LeviCivita(LT1,pT1,pT2);
735  tmp2 *= LT2.Dot(LT2)*1./(3.*pT2.Dot(pT2));
736 
737  return (PT1.Sandwich(qD,qD,tmp1,LT2)+PT1.Sandwich(qD,qD,tmp2,pT2))/units;
738  }
739 
740  //returns always 0 since tT2 is a symmetric matrix !
741  //should not be used !
742  double returnVal = LeviCivita(pD, DT, tT2) / units;
743 
744  if(dbThis){
745  cout << " SF_DtoT1P0_T1toT2P1_T2toP2P3::getVal "
746  << " returning " << returnVal
747  << endl;
748  }
749  return returnVal;
750 }
751 
753  // bool debugThis = false;
754  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
755  os << "spin factor SF_DtoT1P0_T1toT2P1_T2toP2P3"
756  << "\n\t ZTspin2 tT1(qT, pT, MT);"
757  << "\n\t ZTspin1 tT2(qV, pV, MV);"
758  << "\n\t TLorentzVector DT(tT1.Contract(qT1));"
759  << "\n\t pV = p(2, evt) + p(3); qV = p(2) - p(3);"
760  << "\n\t pT = pV + p(1); qT = pV - p(1);"
761  << "\n\t pD = pT + p(0); qD = pT - p(0);"
762  << "\n\t return: LeviCivita(pD, DT, tT2)/GeV^6"
763  << "\n\t parsed tree " << theDecay().oneLiner()
764  << "\n like this:" << endl;
765  this->printParsing(os);
766 }
767 
768 // -------------------
769 // D->TS
770 // ------------------
772  // bool debugThis=false;
773  if(fsPS.size() < 4) fsPS.reserve(4);
774  if(theDecay(pat).nDgtr() != 2){
775  cout << "ERROR in SF_DtoTS_TtoP0P1_StoP2P3::parseTree"
776  << " expected exactly 2 daughers of D, have "
777  << theDecay(pat).nDgtr();
778  return false;
779  }
780 
781  for(int i=0; i< theDecay(pat).nDgtr(); i++){
782  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
783  if(dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T = dgtr;
784  else if(dgtr->getVal().SVPAT() == "S" && ! dgtr->isFinalState()) S = dgtr;
785  }
786 
787  if(0==S || 0==T){
788  cout << "ERROR in SF_DtoTS_TtoP0P1_StoP2P3::parseTree"
789  << " Didn't find T or S " << T.get() << ", " << S.get() << endl;
790  return false;
791  }
792  if(T->nDgtr() != 2){
793  cout << "ERROR in SF_DtoTS_TtoP0P1_StoP2P3::parseTree"
794  << " T should have 2 daughters, but it says it has "
795  << T->nDgtr() << "."
796  << endl;
797  return false;
798  }
799  fsPS[0] = T->getDgtrTreePtr(0);
800  fsPS[1] = T->getDgtrTreePtr(1);
801  // normalOrder(fsPS[0], fsPS[1]);
802 
803  if(S->nDgtr() != 2){
804  cout << "ERROR in SF_DtoTS_TtoP0P1_StoP2P3::parseTree"
805  << " S should have 2 daughters, but it says it has "
806  << S->nDgtr() << "."
807  << endl;
808  return false;
809  }
810  fsPS[2] = S->getDgtrTreePtr(0);
811  fsPS[3] = S->getDgtrTreePtr(1);
812  // normalOrder(fsPS[2], fsPS[3]);
813 
814  // this->printYourself();
815  return true;
816 }
817 
818 
819 // -----------------------------------------------
820 
822  bool dbThis=false;
823  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
824 
825  TLorentzVector pT = p(0, evt) + p(1, evt);
826  TLorentzVector qT = p(0, evt) - p(1, evt);
827  TLorentzVector pS = p(2, evt) + p(3, evt);
828  TLorentzVector qD = pT - pS;
829  TLorentzVector pD = pT + pS;
830 
831  double MT = mRes(T, evt);
832 
833  ZTspin2 tT(qT, pT, MT);
834 
835  const double units = GeV*GeV * GeV*GeV;
836 
837  if (_useZemachTensors) {
838  ZTspin2 tD(qD,pD,pD.M());
839  SpinSumT P2T(pT,MT);
840  SpinSumV P1T(pT,MT);
841  ZTspin1 t1T(qT, pT, MT);
842 
843  SymmLorentzMatrix qq(qD);
844  //return tT.Contract_2(qq);
845  if(dbThis){
846  cout << "" << endl;
847  cout << P2T.Sandwich(qD,qD,qT,qT)/units << endl;
848  cout << tT.Contract_2(qq)/units << endl;
849  cout << tT.Contract(qD).Dot(qD)/units << endl;
850  cout << (qD.Dot(t1T)*qD.Dot(t1T) + 1./3. * t1T.Dot(t1T) * P1T.Sandwich(qD,qD))/units << endl;
851  cout << "" << endl;
852  }
853  //return P2T.Sandwich(qD,qD,qT,qT)/units;
854  return tT.Contract_2(tD)/units;
855  }
856 
857  double returnVal = (tT.Contract(qD)).Dot(qD) / units;
858 
859  if(dbThis){
860 
861 
862  cout << " SF_DtoTS_TtoP0P1_StoP2P3::getVal "
863  << " returning " << returnVal
864  << endl;
865  }
866  return returnVal;
867 
868 }
869 
871  // bool debugThis = false;
872  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
873  os << "spin factor SF_DtoTS_TtoP0P1_StoP2P3"
874  << "\n\t ZTspin2 tT(qT, pT, MT);"
875  << "\n\t return: (tT.Contract(qD)).Dot(qD) / GeV^4"
876  << "\n\t with pT = p(0) + p(1), qT = p(0) - p(1), pS = p(2) + p(3), qD = pT - qV;"
877  << "\n\t parsed tree " << theDecay().oneLiner()
878  << "\n like this:" << endl;
879  this->printParsing(os);
880 }
881 
882 // ---------------
883 // D->pseudoTensor P0, various modes
884 // --------------
885 
886 // -----------------------------------------------
888  // bool debugThis=false;
889  if(fsPS.size() < 4) fsPS.reserve(4);
890  if(theDecay(pat).nDgtr() != 2){
891  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3_BASE::parseTree"
892  << " expected exactly 2 daughers of D, have "
893  << theDecay(pat).nDgtr();
894  return false;
895  }
896  for(int i=0; i< theDecay(pat).nDgtr(); i++){
897  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
898  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
899  else if(dgtr->getVal().SVPAT() == "PT" && ! dgtr->isFinalState()) PT = dgtr;
900  }
901  if(0==PT || 0==fsPS[0]){
902  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3_BASE::parseTree"
903  << " Didn't find T or P0 " << PT.get() << ", " << fsPS[0].get() << endl;
904  return false;
905  }
906 
907  if(PT->nDgtr() != 2){
908  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3_BASE::parseTree"
909  << " T should have 2 daughters, but it says it has "
910  << PT->nDgtr() << "."
911  << endl;
912  return false;
913  }
914  for(int i=0; i< PT->nDgtr(); i++){
915  const_counted_ptr<AssociatedDecayTree> dgtr= PT->getDgtrTreePtr(i);
916  if (dgtr->getVal().SVPAT() == "V" && ! dgtr->isFinalState()) V = dgtr;
917  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
918  }
919  if(0==V || 0==fsPS[1]){
920  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3_BASE::parseTree"
921  << " Didn't find V2 or P1 " << V.get() << ", " << fsPS[1].get() << endl;
922  return false;
923  }
924 
925  if(V->nDgtr() != 2){
926  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3_BASE::parseTree"
927  << " V should have 2 daughters, but it says it has "
928  << V->nDgtr() << "."
929  << endl;
930  return false;
931  }
932  fsPS[2] = V->getDgtrTreePtr(0);
933  fsPS[3] = V->getDgtrTreePtr(1);
934  // normalOrder(fsPS[2], fsPS[3]);
935 
936  // this->printYourself();
937  return true;
938 }
939 // ------- note that pseudoT->VP1 has to be in P-wave for parity and ang mom ----
941  bool dbThis=false;
942  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
943 
944  TLorentzVector pV = p(2, evt) + p(3, evt);
945  TLorentzVector qV = p(2, evt) - p(3, evt);
946  TLorentzVector pT = pV + p(1, evt);
947  TLorentzVector qT = pV - p(1, evt);
948  TLorentzVector pD = pT + p(0, evt);
949  TLorentzVector qD = pT - p(0, evt);
950 
951  double MT = mRes(PT, evt);
952  double MV = mRes(V, evt);
953 
954  ZTspin1 tV(qV, pV, MV);
955  ZTspin2 tT(qT, pT, MT);
956  //SpinSumT ProT(pT, MT);
957 
958  const double units = GeV*GeV * GeV*GeV;
959 
960  if (_useZemachTensors) {
961  SpinSumT PT(pT,MT);
962  ZTspin1 LT(qT,pT,MT);
963  ZTspin1 LD(qD,pD,pD.M());
964  return PT.Sandwich(LD,LD,LT,tV)/units + 1./3. * LD.Dot(LD) / (pD.Dot(pD)) * PT.Sandwich(pD,pD,LT,tV)/units;
965  //return PT.Sandwich(qD,qD,LT,tV)/units;
966  }
967 
968  double returnVal = (tT.Contract(qT)).Dot(tV) / units;
969 
970  if(dbThis){
971  cout << " SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3::getVal "
972  << " returning " << returnVal
973  << endl;
974  SpinSumT ProT(pT, MT);
975  cout << " compare to: "
976  << ProT.Sandwich(qD, qD, qT, tV) / units
977  << endl;
978  }
979  return returnVal;
980 }
981 
983  // bool debugThis = false;
984  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
985  os << "spin factor SF_DtoPseudoTP0_PseudoTtoVP1_VtoP2P3"
986  << "\n\t ProT(pT, MT)"
987  << "\n\t ZTspin1 tT2(qV, pV, MV);"
988  << "\n\t pV = p(2) + p(3); qV = p(2) - p(3);"
989  << "\n\t pT = pV + p(1); qT = pV - p(1);"
990  << "\n\t pD = pT + p(0); qD = pT - p(0);"
991  << "\n\t return: ProT.Sandwich(qD, qD, qT, tV) / GeV^4"
992  << "\n\t parsed tree " << theDecay().oneLiner()
993  << "\n like this:" << endl;
994  this->printParsing(os);
995 }
996 // -----------------------------------------------
998  // bool debugThis=false;
999  if(fsPS.size() < 4) fsPS.reserve(4);
1000  if(theDecay(pat).nDgtr() != 2){
1001  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3_BASE::parseTree"
1002  << " expected exactly 2 daughers of D, have "
1003  << theDecay(pat).nDgtr();
1004  return false;
1005  }
1006  for(int i=0; i< theDecay(pat).nDgtr(); i++){
1007  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
1008  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
1009  else if(dgtr->getVal().SVPAT() == "PT" && ! dgtr->isFinalState()) PT = dgtr;
1010  }
1011  if(0==PT || 0==fsPS[0]){
1012  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3_BASE::parseTree"
1013  << " Didn't find T or P0 " << PT.get() << ", " << fsPS[0].get() << endl;
1014  return false;
1015  }
1016 
1017  if(PT->nDgtr() != 2){
1018  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3_BASE::parseTree"
1019  << " T should have 2 daughters, but it says it has "
1020  << PT->nDgtr() << "."
1021  << endl;
1022  return false;
1023  }
1024  for(int i=0; i< PT->nDgtr(); i++){
1025  const_counted_ptr<AssociatedDecayTree> dgtr= PT->getDgtrTreePtr(i);
1026  if (dgtr->getVal().SVPAT() == "S" && ! dgtr->isFinalState()) S = dgtr;
1027  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
1028  }
1029  if(0==S || 0==fsPS[1]){
1030  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3_BASE::parseTree"
1031  << " Didn't find S or P1 " << S.get() << ", " << fsPS[1].get() << endl;
1032  return false;
1033  }
1034 
1035  if(S->nDgtr() != 2){
1036  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3_BASE::parseTree"
1037  << " V should have 2 daughters, but it says it has "
1038  << S->nDgtr() << "."
1039  << endl;
1040  return false;
1041  }
1042  fsPS[2] = S->getDgtrTreePtr(0);
1043  fsPS[3] = S->getDgtrTreePtr(1);
1044  // normalOrder(fsPS[2], fsPS[3]);
1045 
1046  // this->printYourself();
1047  return true;
1048 }
1049 // ------- note that pseudoT->SP1 has to be in D-wave for parity and ang mom ----
1051  bool dbThis=false;
1052  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
1053 
1054  TLorentzVector pS = p(2, evt) + p(3, evt);
1055  TLorentzVector qS = p(2, evt) - p(3, evt);
1056  TLorentzVector pT = pS + p(1, evt);
1057  TLorentzVector qT = pS - p(1, evt);
1058  TLorentzVector pD = pT + p(0, evt);
1059  TLorentzVector qD = pT - p(0, evt);
1060 
1061  double MT = mRes(PT, evt);
1062  //double MV = mRes(S);
1063 
1064  ZTspin2 tT(qT, pT, MT);
1065 
1066  const double units = GeV*GeV * GeV*GeV;
1067 
1068  if(_useZemachTensors){
1069  ZTspin2 tD(qD,pD,pD.M());
1070  return tD.Contract_2(tT)/units;
1071  }
1072 
1073  double returnVal = (tT.Contract(qD)).Dot(qD) / units;
1074 
1075  if(dbThis){
1076  cout << " SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3::getVal "
1077  << " returning " << returnVal
1078  << endl;
1079  }
1080  return returnVal;
1081 }
1082 
1084  // bool debugThis = false;
1085  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
1086  os << "spin factor SF_DtoPseudoTP0_PseudoTtoSP1_StoP2P3"
1087  << "\n\t ProT(pT, MT)"
1088  << "\n\t ZTspin1 tT2(qV, pV, MV);"
1089  << "\n\t pS = p(2) + p(3); qS = p(2) - p(3);"
1090  << "\n\t pT = pV + p(1); qT = pV - p(1);"
1091  << "\n\t pD = pT + p(0); qD = pT - p(0);"
1092  << "\n\t (tT.Contract(qD)).Dot(qD) / GeV^4"
1093  << "\n\t parsed tree " << theDecay().oneLiner()
1094  << "\n like this:" << endl;
1095  this->printParsing(os);
1096 }
1097 
1098 // -------------------------------------------
1100  // bool debugThis=false;
1101  if(fsPS.size() < 4) fsPS.reserve(4);
1102  if(theDecay(pat).nDgtr() != 2){
1103  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3_BASE::parseTree"
1104  << " expected exactly 2 daughers of D, have "
1105  << theDecay(pat).nDgtr();
1106  return false;
1107  }
1108  for(int i=0; i< theDecay(pat).nDgtr(); i++){
1109  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
1110  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
1111  else if(dgtr->getVal().SVPAT() == "PT" && ! dgtr->isFinalState()) PT = dgtr;
1112  }
1113  if(0==PT || 0==fsPS[0]){
1114  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3_BASE::parseTree"
1115  << " Didn't find T or P0 " << PT.get() << ", " << fsPS[0].get() << endl;
1116  return false;
1117  }
1118 
1119  if(PT->nDgtr() != 2){
1120  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3_BASE::parseTree"
1121  << " T should have 2 daughters, but it says it has "
1122  << PT->nDgtr() << "."
1123  << endl;
1124  return false;
1125  }
1126  for(int i=0; i< PT->nDgtr(); i++){
1127  const_counted_ptr<AssociatedDecayTree> dgtr= PT->getDgtrTreePtr(i);
1128  if (dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T = dgtr;
1129  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
1130  }
1131  if(0==T || 0==fsPS[1]){
1132  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3_BASE::parseTree"
1133  << " Didn't find T or P1 " << T.get() << ", " << fsPS[1].get() << endl;
1134  return false;
1135  }
1136 
1137  if(T->nDgtr() != 2){
1138  cout << "ERROR in SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3_BASE::parseTree"
1139  << " V should have 2 daughters, but it says it has "
1140  << T->nDgtr() << "."
1141  << endl;
1142  return false;
1143  }
1144  fsPS[2] = T->getDgtrTreePtr(0);
1145  fsPS[3] = T->getDgtrTreePtr(1);
1146  // normalOrder(fsPS[2], fsPS[3]);
1147 
1148  // this->printYourself();
1149  return true;
1150 }
1151 // ------- note that pseudoT->SP1 has to be in D-wave for parity and ang mom ----
1153  bool dbThis=false;
1154  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
1155 
1156  double invGeV = 1;// 1.0/GeV;
1157 
1158  TLorentzVector pT = p(2, evt) + p(3, evt);
1159  TLorentzVector qT = p(2, evt) - p(3, evt);
1160  TLorentzVector pPT = pT + p(1, evt);
1161  TLorentzVector qPT = pT - p(1, evt);
1162  TLorentzVector pD = pPT + p(0, evt);
1163  TLorentzVector qD = pPT - p(0, evt);
1164 
1165  double MPT = mRes(PT, evt);
1166  double MT = mRes(T , evt);
1167  //double MV = mRes(S);
1168 
1169  ZTspin2 tPT(qD*invGeV, pPT*invGeV, MPT*invGeV);
1170  ZTspin2 tT(qT*invGeV, pT*invGeV, MT*invGeV);
1171 
1172  const double units = GeV*GeV*GeV*GeV;
1173 
1174  if (_useZemachTensors) {
1175  SpinSumT PT1(pPT,MPT);
1176  ZTspin1 LT(qT,pT,MT);
1177 
1178  return (PT1.Sandwich(qD,qD,LT,LT) + 1./3. * LT.Dot(LT)/(pT.Dot(pT)) * PT1.Sandwich(qD,qD,pT,pT))/units;
1179  }
1180 
1181  double returnVal = tPT.Contract_2(tT) / units;
1182 
1183  if(dbThis){
1184  cout << " SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3::getVal "
1185  << " returning " << returnVal
1186  << " = " << tPT.Contract_2(tT) << " / " << units
1187  << "\n MPT = " << MPT << ", MT = " << MT
1188  << endl;
1189  }
1190  return returnVal;
1191 }
1192 
1194  // bool debugThis = false;
1195  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
1196  os << "spin factor SF_DtoPseudoTP0_PseudoTtoTP1_TtoP2P3"
1197  << "\n\t ZTspin2 tPT(qD, pPT, MPT);"
1198  << "\n\t ZTspin2 tT(qT, pT, MT);"
1199  << "\n\t pT = p(2) + p(3); qT = p(2) - p(3);"
1200  << "\n\t pPT = pT + p(1); qPT = pT - p(1);"
1201  << "\n\t pD = pPT + p(0); qD = pPT - p(0);"
1202  << "\n\t tPT.Contract_2(tT)/ GeV^8"
1203  << "\n\t parsed tree " << theDecay().oneLiner()
1204  << "\n like this:" << endl;
1205  this->printParsing(os);
1206 }
1207 
1208 // ==========================================
1209 // -----------------------------------------------
1210 // D->PA, A->TP (ang mom L=1 at each vtx)
1211 // -----------------------------------------------
1212 
1214  // bool debugThis=false;
1215  if(fsPS.size() < 4) fsPS.reserve(4);
1216  if(theDecay(pat).nDgtr() != 2){
1217  cout << "ERROR in SF_DtoAP0_AtoTP1_TtoP2P3_BASE::parseTree"
1218  << " expected exactly 2 daughers of D, have "
1219  << theDecay(pat).nDgtr();
1220  return false;
1221  }
1222  for(int i=0; i< theDecay(pat).nDgtr(); i++){
1223  const_counted_ptr<AssociatedDecayTree> dgtr= theDecay(pat).getDgtrTreePtr(i);
1224  if (dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[0] = dgtr;
1225  else if(dgtr->getVal().SVPAT() == "A" && ! dgtr->isFinalState()) A = dgtr;
1226  }
1227  if(0==A || 0==fsPS[0]){
1228  cout << "ERROR in SF_DtoAP0_AtoTP1_TtoP2P3_BASE::parseTree"
1229  << " Didn't find T or P0 " << A.get() << ", " << fsPS[0].get() << endl;
1230  return false;
1231  }
1232 
1233  if(A->nDgtr() != 2){
1234  cout << "ERROR in SF_DtoAP0_AtoTP1_TtoP2P3_BASE::parseTree"
1235  << " T should have 2 daughters, but it says it has "
1236  << A->nDgtr() << "."
1237  << endl;
1238  return false;
1239  }
1240  for(int i=0; i< A->nDgtr(); i++){
1241  const_counted_ptr<AssociatedDecayTree> dgtr= A->getDgtrTreePtr(i);
1242  if (dgtr->getVal().SVPAT() == "T" && ! dgtr->isFinalState()) T = dgtr;
1243  else if(dgtr->getVal().SVPAT() == "P" && dgtr->isFinalState()) fsPS[1] = dgtr;
1244  }
1245  if(0==T || 0==fsPS[1]){
1246  cout << "ERROR in SF_DtoAP0_AtoTP1_TtoP2P3_BASE::parseTree"
1247  << " Didn't find T or P1 " << T.get() << ", " << fsPS[1].get() << endl;
1248  return false;
1249  }
1250 
1251  if(T->nDgtr() != 2){
1252  cout << "ERROR in SF_DtoAP0_AtoTP1_TtoP2P3_BASE::parseTree"
1253  << " A should have 2 daughters, but it says it has "
1254  << T->nDgtr() << "."
1255  << endl;
1256  return false;
1257  }
1258  fsPS[2] = T->getDgtrTreePtr(0);
1259  fsPS[3] = T->getDgtrTreePtr(1);
1260  // normalOrder(fsPS[2], fsPS[3]);
1261 
1262  // this->printYourself();
1263  return true;
1264 }
1265 // ---
1267  bool dbThis=false;
1268  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) parseTree(evt.eventPattern());
1269 
1270  TLorentzVector pT = p(2, evt) + p(3, evt);
1271  TLorentzVector qT = p(2, evt) - p(3, evt);
1272  TLorentzVector pA = pT + p(1, evt);
1273  TLorentzVector qA = pT - p(1, evt);
1274  TLorentzVector pD = pA + p(0, evt);
1275  TLorentzVector qD = pA - p(0, evt);
1276 
1277  double MA = mRes(A, evt);
1278  double MT = mRes(T, evt);
1279  //double MV = mRes(S);
1280 
1281  ZTspin1 tA(qA, pA, MA);
1282  ZTspin2 tT(qT, pT, MT);
1283 
1284  const double units = GeV*GeV*GeV*GeV;
1285 
1286  if (_useZemachTensors) {
1287  ZTspin1 LD(qD,pD,pD.M());
1288  SpinSumT PT(pT,MT);
1289  //return (tT.Contract(tA)).Dot(LD);
1290  return PT.Sandwich(qT,qT,LD,tA)/units;
1291  }
1292 
1293  double returnVal = (tT.Contract(tA)).Dot(qD) / units;
1294 
1295  if(dbThis){
1296  cout << " SF_DtoAP0_AtoTP1_TtoP2P3::getVal "
1297  << " returning " << returnVal
1298  << endl;
1299  }
1300  return returnVal;
1301 }
1302 
1304  // bool debugThis = false;
1305  if(! ( fsPS[0] && fsPS[1] && fsPS[2] && fsPS[3]) ) return;
1306  os << "spin factor SF_DtoAP0_AtoTP1_TtoP2P3"
1307  << "\n\t ZTspin1 tA(qA, pA, MA);"
1308  << "\n\t ZTspin2 tT(qT, pT, MT);"
1309  << "\n\t pT = p(2) + p(3); qT = p(2) - p(3);"
1310  << "\n\t pA = pT + p(1); qA = pT - p(1);"
1311  << "\n\t pD = pA + p(0); qD = pA - p(0);"
1312  << "\n\t (tT.Contract(tA)).Dot(qD) / GeV^4"
1313  << "\n\t parsed tree " << theDecay().oneLiner()
1314  << "\n like this:" << endl;
1315  this->printParsing(os);
1316 }
1317 
1318 //====================================
1319 
1320 //====================================
double Contract_2(const SymmLorentzMatrix &M)
virtual bool parseTree(const DalitzEventPattern &pat)
virtual const DecayTree & exampleDecay()
virtual bool parseTree(const DalitzEventPattern &pat)
virtual const DecayTree & exampleDecay()
static const DecayTree & getExampleDecay()
const X * get() const
Definition: counted_ptr.h:217
virtual const DecayTree & exampleDecay()
static const DecayTree & getExampleDecay()
virtual double getVal(IDalitzEvent &evt)
std::string SVPAT() const
TLorentzVector Dot(const TLorentzVector &rhs) const
Definition: SpinSumV.h:20
static const DecayTree & getExampleDecay()
static const DecayTree & getExampleDecay()
virtual void printYourself(std::ostream &os=std::cout) const
double Sandwich(const TLorentzVector &lhs, const TLorentzVector &rhs) const
Definition: SpinSumV.h:32
virtual bool parseTree(const DalitzEventPattern &pat)
const ValueType & getVal() const
Definition: DDTree.h:102
virtual const DecayTree & exampleDecay()
bool isFinalState() const
Definition: DDTree.h:93
virtual const DecayTree & exampleDecay()
virtual double getVal(IDalitzEvent &evt)
virtual void printYourself(std::ostream &os=std::cout) const
virtual bool parseTree(const DalitzEventPattern &pat)
virtual double getVal(IDalitzEvent &evt)
virtual void printYourself(std::ostream &os=std::cout) const
virtual double getVal(IDalitzEvent &evt)
virtual const DecayTree & exampleDecay()
virtual void printYourself(std::ostream &os=std::cout) const
virtual double getVal(IDalitzEvent &evt)
virtual bool parseTree(const DalitzEventPattern &pat)
static const DecayTree & getExampleDecay()
virtual bool parseTree(const DalitzEventPattern &pat)
LorentzMatrix Contract_1(const SymmLorentzMatrix &M)
virtual const DalitzEventPattern & eventPattern() const =0
virtual bool parseTree(const DalitzEventPattern &pat)
static const double GeV
virtual bool parseTree(const DalitzEventPattern &pat)
virtual void printYourself(std::ostream &os=std::cout) const
Definition: ZTspin1.h:9
virtual double getVal(IDalitzEvent &evt)
virtual void printYourself(std::ostream &os=std::cout) const
virtual bool parseTree(const DalitzEventPattern &pat)
double LeviCivita(const TLorentzVector &p0, const TLorentzVector &p1, const TLorentzVector &p2, const TLorentzVector &p3)
Definition: LeviCivita.h:12
virtual double getVal(IDalitzEvent &evt)
int nDgtr() const
Definition: DDTree.h:96
double Sandwich(const TLorentzVector &lm, const TLorentzVector &ln, const TLorentzVector &ra, const TLorentzVector &rb)
Definition: SpinSumT.h:19
static const DecayTree & getExampleDecay()
static const DecayTree & getExampleDecay()
virtual double getVal(IDalitzEvent &evt)
virtual const DecayTree & exampleDecay()
static const DecayTree & getExampleDecay()
virtual void printYourself(std::ostream &os=std::cout) const
virtual void printYourself(std::ostream &os=std::cout) const
virtual void printYourself(std::ostream &os=std::cout) const
DDTree< DecayTreeItem > DecayTree
Definition: DecayTree.h:35
virtual double getVal(IDalitzEvent &evt)
virtual void printYourself(std::ostream &os=std::cout) const
virtual double getVal(IDalitzEvent &evt)
virtual double getVal(IDalitzEvent &evt)
static const DecayTree & getExampleDecay()
virtual const DecayTree & exampleDecay()
virtual const DecayTree & exampleDecay()
virtual void printYourself(std::ostream &os=std::cout) const
virtual double getVal(IDalitzEvent &evt)
virtual void printYourself(std::ostream &os=std::cout) const
TLorentzVector Contract(const TLorentzVector &vec)