KaliVeda
Toolkit for HIC analysis
KVParticle.cpp
1 /***************************************************************************
2 $Id: KVParticle.cpp,v 1.50 2009/04/28 08:59:05 franklan Exp $
3  kvparticle.cpp - description
4  -------------------
5  begin : Sun May 19 2002
6  copyright : (C) 2002 by J.D. Frankland
7  email : frankland@ganil.fr
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 #include "TMath.h"
19 #include "Riostream.h"
20 #include "KVPosition.h"
21 #include "KVParticle.h"
22 #include "KVList.h"
23 #include "TRotation.h"
24 #include "TLorentzRotation.h"
25 #include "TObjString.h"
26 #include "TClass.h"
27 #include "KVKinematicalFrame.h"
28 
30 
31 using namespace std;
32 
34 
35 
36 
37 
38 
40 KVParticle::KVParticle() : fParameters("ParticleParameters", "Parameters associated with a particle in an event")
41 {
42  init();
43 }
44 
45 
46 
49 
51 {
52  //default initialisation
53  fE0 = nullptr;
54  SetFrameName("");
55  fGroups.SetOwner(kTRUE);
56 }
57 
58 
59 
62 
64 {
65  //copy ctor
66  init();
67 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
68  obj.Copy(*this);
69 #else
70  ((KVParticle&) obj).Copy(*this);
71 #endif
72 }
73 
74 
75 
78 
79 KVParticle::KVParticle(Double_t m, const TVector3& p) : fParameters("ParticleParameters", "Parameters associated with a particle in an event")
80 {
81  //create particle with given mass and momentum vector
82  init();
83  SetMass(m);
84  SetMomentum(p);
85 }
86 
87 
88 
91 
92 KVParticle::KVParticle(Double_t m, Double_t px, Double_t py, Double_t pz) : fParameters("ParticleParameters", "Parameters associated with a particle in an event")
93 {
94  //create particle with given mass and momentum vector
95  init();
96  SetMass(m);
97  SetMomentum(px, py, pz);
98 }
99 
100 
101 
104 
105 KVParticle::~KVParticle()
106 {
107  //Info("~KVParticle","%p",this);
108  Clear();
109 }
110 
111 
112 
116 
118 {
119  //Static function.
120  //Returns speed of light in cm/ns units.
121  return kSpeedOfLight;
122 }
123 
124 
125 
135 
137  Double_t thmax, Double_t phmin,
138  Double_t phmax, Option_t* opt)
139 {
140  //Give randomly directed momentum to particle with kinetic energy T
141  //Direction will be between (thmin,thmax) [degrees] limits in polar angle,
142  //and (phmin,phmax) [degrees] limits in azimuthal angle.
143  //
144  //If opt = "" or "isotropic" (default) : direction is isotropically distributed over the solid angle
145  //If opt = "random" : direction is randomly distributed over solid angle
146  //
147  //Based on KVPosition::GetRandomDirection().
148 
149  Double_t p = (T + M()) * (T + M()) - M2();
150  if (p > 0.)
151  p = (TMath::Sqrt(p)); // calculate momentum
152  else
153  p = 0.;
154 
155  TVector3 dir;
156  KVPosition pos(thmin, thmax, phmin, phmax);
157  dir = pos.GetRandomDirection(opt); // get isotropic unit vector dir
158  if (p && dir.Mag())
159  dir.SetMag(p); // set magnitude of vector to momentum required
160  SetMomentum(dir); // set momentum 4-vector
161 }
162 
163 
164 
168 
170 {
171  //set momentum with kinetic energy t and unit direction vector d
172  //(d is normalised first in case it is not a unit vector)
173 
174  Double_t p = (T + M()) * (T + M()) - M2();
175  TVector3 pdir;
176  TVector3 unit_dir = dir.Unit();
177  if (p > 0.) {
178  p = (TMath::Sqrt(p));
179  pdir = p * unit_dir;
180  }
181  SetMomentum(pdir);
182 };
183 
184 
185 
188 
190 {
191  // recursive print out of all defined kinematical frames
192 
193  fmt += "\t";
194  if (fBoosted.GetEntries()) {
195  TIter next(&fBoosted);
196  KVKinematicalFrame* frame;
197  while ((frame = (KVKinematicalFrame*)next())) {
198  cout << fmt << " [" << frame->GetName() << "] : ";
199  KVParticle* part = frame->GetParticle();
200  cout << " Theta=" << part->GetTheta() << " Phi=" << part->GetPhi()
201  << " KE=" << part->GetKE() << " Vpar=" << part->GetVpar() << endl;
202  part->print_frames(fmt);
203  }
204  }
205 }
206 
207 
208 
211 
213 {
214  // print out characteristics of particle
215 
216  cout << "Mass=" << M() << endl;
217  cout << "[" << GetFrameName() << "] :" <<
218  " Theta=" << GetTheta() << " Phi=" << GetPhi()
219  << " KE=" << GetKE() << " Vpar=" << GetVpar() << endl;
220  print_frames();
221  GetParameters()->ls();
222  if (GetNumberOfDefinedGroups()) {
223  auto ngroups = GetNumberOfDefinedGroups();
224  cout << "Group";
225  if (ngroups > 1) cout << "s";
226  cout << ": ";
227  TIter it(GetGroups());
228  TObject* gr;
229  int index = 1;
230  while ((gr = it())) {
231  cout << gr->GetName();
232  if (ngroups > 1 && index < ngroups) cout << ", ";
233  ++index;
234  }
235  cout << endl;
236  }
237 }
238 
239 
240 
245 
247 {
248  //Change particle KE, keeping momentum direction constant
249  //If momentum is zero (i.e. no direction defined) the particle will be given
250  //a velocity in the positive z-direction
251 
252  if (ecin > 0.) {
253  Double_t et = M() + ecin; // new total energy = KE + m
254  Double_t pmod = 0;
255  if (et * et > M2()) {
256  pmod = TMath::Sqrt(et * et - M2()); // p**2 = E**2 - m**2
257  TVector3 newp(Px(), Py(), Pz());
258  if (pmod && newp.Mag()) {
259  newp.SetMag(pmod);
260  }
261  else {
262  newp.SetXYZ(0, 0, 1);
263  newp.SetMag(pmod);
264  }
265  SetMomentum(newp);
266  }
267  else {
268  SetMomentum(0., 0., 0.);
269  }
270  }
271  else
272  SetMomentum(0., 0., 0.);
273 }
274 
275 
276 
285 
286 void KVParticle::Copy(TObject& obj) const
287 {
288  // Make a copy of this particle in obj
289  //
290  // When new kinematical frames are created this is just a shallow copy
291  // (no copy of parameters or groups - these are both handled by the original particle,
292  // i.e. the parent of all the kinematical frames)
293  //
294  // When a full copy is made, we recursively copy also all defined kinematical frames.
295 
296  ((KVParticle&) obj) = *this; // copy kinematics, i.e. underlying TLorentzVector
297  if (!fFrameCopyOnly) {
298  // do not make a full copy if particle is just a new kinematical frame
299  ((KVParticle&) obj).SetGroups(GetGroups());
300  ((KVParticle&) obj).SetName(GetName());
302  // copy kinematical frames
303  if (GetCurrentDefaultKinematics() != this) {
304  // When copying a particle through a reference/pointer to one of its derived
305  // kinematical frames, we need to copy all of the associated frames (starting from the
306  // topmost (default) kinematical frame in the graph
308  ((KVParticle&)obj).SetFrameName(GetCurrentDefaultKinematics()->GetFrameName());
309  // Then, so that the copy of the reference pointer behaves in the same way as the
310  // original, we change the default reference frame of the copy to that which is
311  // currently in use
312  ((KVParticle&)obj).ChangeDefaultFrame(GetFrameName());
313  }
314  else {
315  fBoosted.Copy(((KVParticle&)obj).fBoosted);
316  ((KVParticle&)obj).SetFrameName(GetFrameName());
317  }
318  }
319 }
320 
321 
322 
323 
326 
328 {
329  //Reset particle properties i.e. before creating/reading a new event
330 
331  SetXYZM(0., 0., 0., 0.);
332  if (fE0) {
333  delete fE0;
334  fE0 = 0;
335  }
336  ResetIsOK(); //in case IsOK() status was set "by hand" in previous event
338  fParameters.Clear();
339  fGroups.Clear();
340  fBoosted.Delete();
341 }
342 
343 
344 
349 
351 {
352  //Determine whether this particle is considered "good" or not for analysis,
353  //depending on a previous call to SetIsOK(Bool_t flag).
354  //If SetIsOK has not been called, IsOK returns kTRUE by default.
355 
356  if (GetOriginal()->TestBit(kIsOKSet)) { //status set by SetIsOK()
357  return TestBit(kIsOK);
358  }
359  //Default if SetIsOK not used: accept particle
360  return kTRUE;
361 }
362 
363 
364 
365 
370 
372 {
373  //Set acceptation/rejection status for the particle.
374  //
375  //In order to 'forget' this status (accept all particles) use ResetIsOK()
376 
377  GetOriginal()->SetBit(kIsOK, flag);
379 }
380 
381 
382 
384 
385 void KVParticle::ls(Option_t* option) const
386 {
387  std::cout << option << GetName() << ":" << GetFrameName() << ":" << this << "\n";
388  if (fBoosted.GetEntries()) {
389  TString nopt = option;
390  nopt += " ";
391  TIter next(&fBoosted);
393  while ((p = (KVKinematicalFrame*)next())) p->GetParticle()->ls(nopt.Data());
394  }
395 }
396 
397 
398 
399 
402 
404 {
405  //KVParticle assignment operator.
406 
407  if (this != &rhs) {
409  if (rhs.GetPInitial()) SetE0(rhs.GetPInitial());
410  }
411  return *this;
412 }
413 
414 
415 
416 
424 
426 {
427  //Used for simulated particles after passage through some absorber/detector.
428  //The passage of a particle through the different absorbers modifies its
429  //kinetic energies, indeed the particle may be stopped in the detector.
430  //Calling this method will reset the particle's momentum to its
431  //initial value i.e. before it entered the first absorber.
432  //Particles which have not encountered any absorbers/detectors are left as they are.
433 
434  if (IsDetected())
436 }
437 
438 
439 
440 
443 
444 void KVParticle::SetName(const Char_t* nom)
445 {
446  //Set Name of the particle
447  GetOriginal()->fName.Form("%s", nom);
448 }
449 
450 
451 
454 
456 {
457  // return the field fName
458  return GetOriginal()->fName.Data();
459 }
460 
461 
462 
467 
468 void KVParticle::AddGroup(const Char_t* groupname, const Char_t* from) const
469 {
470  // Associate this particle with the given named group.
471  // Optional argument "from" allows to put a condition on the already stored
472  // group list, is set to "" by default
473 
474  TString sfrom(from);
475  sfrom.ToUpper();
476  TString sgroupname(groupname);
477  sgroupname.ToUpper();
478 
479  if (BelongsToGroup(sfrom.Data()) && !BelongsToGroup(sgroupname.Data())) {
480  GetGroups()->Add(new TObjString(sgroupname.Data()));
481  }
482 }
483 
484 
485 
488 
490 {
491  //Define for the particle a new list of groups
492  GetGroups()->Clear();
493  AddGroups(un);
494 }
495 
496 
497 
500 
502 {
503  //list of groups added to the current one
504  TObjString* os = 0;
505  TIter no(un);
506  while ((os = (TObjString*)no.Next())) {
507  AddGroup(os->GetName());
508  }
509 
510 }
511 
512 
513 
518 
520 {
521  // \returns the number of kinematical frames defined by transformations of this frame
522  //
523  // \note this is always at least equal to one (we count the present frame of the particle)
524 
525  TIter it(GetListOfFrames());
527  Int_t nf = 1; // start with the current actual frame
528  while ((p = (KVKinematicalFrame*)it())) {
529  nf += p->GetParticle()->_GetNumberOfDefinedFrames();
530  }
531  return nf;
532 }
533 
534 
535 
540 
541 Bool_t KVParticle::BelongsToGroup(const Char_t* groupname) const
542 {
543  //Check if particle belong to a given group
544  //return kTRUE if groupname="".
545  //return kFALSE if no group has be defined
546 
547  TString sgroupname(groupname);
548  sgroupname.ToUpper();
549  //Important for KVEvent::GetNextParticle()
550  if (sgroupname.IsNull()) return kTRUE;
551  //retourne kFALSE si aucun groupe n'est defini
552  if (!GetNumberOfDefinedGroups()) return kFALSE;
553  if (GetGroups()->FindObject(sgroupname.Data())) return kTRUE;
554  return kFALSE;
555 }
556 
557 
558 
561 
562 void KVParticle::RemoveGroup(const Char_t* groupname)
563 {
564  // Remove group from list of groups
565  if (!GetGroups()->GetEntries()) return;
566  TString sgroupname(groupname);
567  sgroupname.ToUpper();
568 
569  TObjString* os = 0;
570  if ((os = (TObjString*)GetGroups()->FindObject(sgroupname.Data()))) delete GetGroups()->Remove(os);
571 }
572 
573 
574 
577 
579 {
580  //Remove all groups
581  GetGroups()->Clear();
582 }
583 
584 
585 
586 
589 
590 void KVParticle::ListGroups(void) const
591 {
592  //List all stored groups
593  if (GetGroups()->GetEntries()) {
594  cout << "Particle belongs to no groups" << endl;
595  return;
596  }
597  else {
598  cout << "----------------------------------------" << endl;
599  cout << "List of groups this particle belongs to:" << endl;
600  cout << "----------------------------------------" << endl;
601  }
602  TObjString* os = 0;
603  TIter no(GetGroups());
604  while ((os = (TObjString*)no.Next())) cout << "\t" << os->GetName() << endl;
605  cout << "----------------------------------------" << endl;
606 }
607 
608 
609 
613 
615 {
616  // Use this method to obtain 'on-the-fly' some information on particle kinematics
617  // in a different reference frame. The default kinematics of the particle are unchanged.
618 
619  KVParticle p;
620  p.Set4Mom(*this);
621  KVKinematicalFrame(&p, t);
622  return p;
623 }
624 
625 
626 
632 
634 {
635  // Permanently modify kinematics of particle according to the given transformation.
636  // You can optionally set the name of this new default kinematics.
637  // NB the current kinematics will be lost. If you want to keep it after changing the
638  // default kinematics, define the new frame with SetFrame and then use ChangeDefaultFrame.
639 
640  KVKinematicalFrame(this, t);
641  if (name != "") SetFrameName(name);
642 }
643 
644 
645 
653 
654 void KVParticle::ChangeDefaultFrame(const Char_t* newdef, const Char_t* defname)
655 {
656  // Make existing reference frame 'newdef' the new default frame for particle kinematics.
657  // The current default frame will then be accessible from the list of frames
658  // using its name (if set with SetFrameName).
659  //
660  // You can change/set the name of the previous default frame with 'defname'.
661  // If no name was set and none given, it will be renamed "default" by default.
662 
663  if (!fFrameName.CompareTo(newdef, TString::kIgnoreCase)) return;//newdef is already the default frame, do nothing
664 
665  TString _defname(defname);
666  if (_defname == "") _defname = GetFrameName();
667  if (_defname == "") _defname = "default";
668  // get list of all parents of new default
669  TList parents;
670  TString ff = newdef;
672  do {
673  f = get_parent_frame(ff);
674  if (f) {
675  parents.Add(f);
676  ff = f->GetName();
677  }
678  }
679  while (f);
680  // modify tree structure
681  TIter it(&parents);
682  KVKinematicalFrame* newdframe = get_frame(newdef);
683  KVKinematicalFrame* save_newdef = newdframe;
684  KVFrameTransform trans, next_trans = newdframe->GetTransform();
685  while ((f = (KVKinematicalFrame*)it())) {
686  f->GetParticle()->GetListOfFrames()->Remove(newdframe);
687  trans = next_trans;
688  next_trans = f->GetTransform();
689  newdframe->GetParticle()->GetListOfFrames()->Add(f);
690  f->SetTransform(trans.Inverse());
691  newdframe = f;
692  }
693  GetListOfFrames()->Remove(newdframe);
694  // copy current default kinematics particle momentum/energy
695  TLorentzVector old_def_p(*this);
696  // set momentum/energy of new default kinematics
697  Set4Mom(*(save_newdef->GetParticle()));
698  save_newdef->GetParticle()->Set4Mom(old_def_p);
699  save_newdef->SetTransform(next_trans.Inverse());
700  save_newdef->SetName(_defname);
701  save_newdef->GetParticle()->SetFrameName(_defname);
702  newdframe->GetParticle()->GetListOfFrames()->Add(save_newdef);
703  // copy frame list from new default frame
704  TList frame_list;
705  frame_list.AddAll(save_newdef->GetParticle()->GetListOfFrames());
706  save_newdef->GetParticle()->GetListOfFrames()->Clear("nodelete");
707  save_newdef->GetParticle()->GetListOfFrames()->AddAll(&fBoosted);
708  fBoosted.Clear("nodelete");
709  fBoosted.AddAll(&frame_list);
710  SetFrameName(newdef);
711 }
712 
713 
714 
774 
775 void KVParticle::SetFrame(const Char_t* frame, const KVFrameTransform& ft)
776 {
777  //Define a Lorentz-boosted and/or rotated frame in which to calculate this particle's momentum and energy.
778  //
779  //The new frame will have the name given in the string "frame", which can then be used to
780  //access the kinematics of the particle in different frames using GetFrame() (frame names are case-insensitive).
781  //Calling this method with the name of an existing frame will update the kinematics of the particle
782  //in that frame using the given transform (note that kinematics in all frames defined as 'subframes' of
783  //this frame will also be updated).
784  //
785  //USING BOOSTS
786  //The boost velocity vector is that of the boosted frame with respect to the original frame of the particles in the event.
787  //The velocity vector can be given either in cm/ns units (default) or in units of 'c' (beta=kTRUE).
788  //
789  //E.g. to define a frame moving at 0.1c in the +ve z-direction with respect to the original
790  //event frame:
791  //
792  // (...supposing a valid pointer KVParticle* my_part...)
793  // TVector3 vframe(0,0,0.1);
794  // my_part->SetFrame("my_frame", KVFrameTransform(vframe, kTRUE));
795  //
796  //or with velocity in cm/ns units (default):
797  // TVector3 vframe(0,0,3);
798  // my_part->SetFrame("my_frame", KVFrameTransform(vframe));
799  // OR my_part->SetFrame("my_frame", vframe);
800  //
801  //USING ROTATIONS
802  //According to the conventions adopted for the TRotation and TLorentzRotation classes,
803  //we actually use the inverse of the TLorentzRotation to make the transformation,
804  //to get the coordinates corresponding to a rotated coordinate system, not the coordinates
805  //of a rotated vector in the same coordinate system
806  //=> you do not need to invert the transformation matrix
807  //
808  //E.g. if you want to define a new frame whose coordinate axes are rotated with respect
809  //to the original axes, you can set up a TRotation like so:
810  //
811  // TRotation rot;
812  // TVector3 newX, newY, newZ; // the new coordinate axes
813  // rot.RotateAxes(newX, newY, newZ);
814  //
815  //If you are using one of the two global variables which calculate the event tensor
816  //(KVTensP and KVTensPCM) you can obtain the transformation to the tensor frame
817  //using:
818  //
819  // TRotation rot;
820  // KVTensP* tens_gv;// pointer to tensor global variable
821  // tens_gv->GetTensor()->GetRotation(rot);// see KVTenseur3::GetRotation
822  //
823  //Then the new frame can be defined by
824  // my_part->SetFrame("my_frame", KVFrameTransform(rot));
825  // OR my_part->SetFrame("my_frame", rot);
826  //
827  //USING COMBINED BOOST AND ROTATION
828  //You can define a frame using both a boost and a rotation like so:
829  // my_part->SetFrame("my_frame", KVFrameTransform(vframe,rot,kTRUE));
830  //
831  //ACCESSING KINEMATICS IN NEW FRAMES
832  //In order to access the kinematics of the particle in the new frame:
833  //
834  // my_part->GetFrame("my_frame")->GetTransverseEnergy();// transverse energy in "my_frame"
835 
836  if (!strcmp(frame, "")) return;
837 
839  // 'frame' is name of current default kinematics, therefore we do not want to add a new frame
840  // (which would have the same name as the current default, and the two would coexist),
841  // we want to change the kinematics of the current frame
842  ChangeFrame(ft);
843  return;
844  }
845 
847  if (!tmp) {
848  //if this frame has not already been defined, create a new one
849  tmp = new KVKinematicalFrame(frame, this, ft);
850  fBoosted.Add(tmp);
851  tmp->GetParticle()->SetOriginal(GetOriginal());
852  }
853  else
854  tmp->ApplyTransform(this, ft);
855 }
856 
857 
858 
896 
897 KVParticle const* KVParticle::GetFrame(const Char_t* frame, Bool_t warn_and_return_null_if_unknown) const
898 {
899  // Return the momentum of the particle in the Lorentz-boosted frame corresponding to the name
900  // "frame" given as argument (see SetFrame() for definition of different frames).
901  // If the default frame name has been set (see KVEvent::SetFrameName) and 'frame' is the
902  // name of this default frame (KVParticle::fFrameName), we return the address of the particle
903  // itself.
904  //
905  // This frame may have been defined by a direct transformation of the original kinematics of the
906  // particle (using SetFrame(newframe,...)) or by a transformation of the kinematics in another
907  // user-defined frame (using SetFrame(newframe,oldframe,...)).
908  //
909  // Note that frames are not "dynamic": if any changes are made to the original particle's kinematics
910  // after definition of a frame, if you want these changes to affect also the other frames you
911  // need to update them by hand by calling KVParticle::UpdateAllFrames().
912  //
913  // Frame names are case insensitive: "CM" or "cm" or "Cm" are all good...
914  //
915  // By default, if no frame with the given name is found, we return nullptr and print a warning.
916  // If `warn_and_return_null_if_unknown=kFALSE`, we return the address of the particle itself,
917  // i.e. the original/default kinematics.
918  // [Note that this is an inversion of the previous default behaviour]
919  //
920  // Note that the properties of the particle returned by this method can not be modified:
921  // this is deliberate, as any modifications e.g. to kinematics will have no effect
922  // in any other frames.
923  //
924  // The returned pointer corresponds to a "pseudoparticle" in the desired frame,
925  // therefore you can use any KVParticle method in order to access the kinematics of the
926  // particle in the boosted frame, e.g.
927  //
928  //~~~~~~~~~~~~~~~~~~~~
929  // (...supposing a valid pointer KVParticle* my_part...)
930  // my_part->GetFrame("cm_frame")->GetVpar();// //el velocity in "cm_frame"
931  // my_part->GetFrame("QP_frame")->GetTheta();// polar angle in "QP_frame"
932  // etc. etc.
933  //~~~~~~~~~~~~~~~~~~~~
934  //
935 
936  if (!fFrameName.CompareTo(frame, TString::kIgnoreCase)) return (KVParticle const*)this;
938  return f ? (KVParticle const*)f->GetParticle() :
939  (warn_and_return_null_if_unknown ?
940  Warning("GetFrame(const Char_t*)", "No frame \"%s\" defined for particle. 0x0 returned.",
941 #ifndef WITH_CPP11
942  frame), (KVParticle*)nullptr
943 #else
944  frame), nullptr
945 #endif
946  : this);
947 }
948 
949 
950 
954 
956 {
957  // Call this method to update particle kinematics in all defined frames if you change
958  // the kinematics of the particle in its original/default frame.
959 
960  if (fBoosted.GetEntries()) {
961  TIter it(&fBoosted);
963  while ((f = (KVKinematicalFrame*)it())) {
964  f->ReapplyTransform(this);
965  // recursively apply to all subframes
966  f->GetParticle()->UpdateAllFrames();
967  }
968  }
969 }
970 
971 
972 
978 
980 {
981  // \param[in] frame name of a kinematical frame
982  // \returns pointer to the kinematical frame if previously defined, nullptr otherwise
983  //
984  // \note PRIVATE method for internal use only. This method allows to modify the returned frame, i.e. in order to define new frames in SetFrame()
985 
986  if (!fBoosted.GetEntries() || !strcmp(frame, "")) {
987  // no frames defined or no frame name given
988  return nullptr;
989  }
990  TString _frame(frame);
991  TIter it(&fBoosted);
992  KVKinematicalFrame* p(nullptr), *f(nullptr);
993  while ((p = f = (KVKinematicalFrame*)it())) {
994  if (!_frame.CompareTo(p->GetName(), TString::kIgnoreCase)) break;
995  // look for subframe
996  if ((f = p->GetParticle()->get_frame(_frame))) break;
997  }
998  return f;
999 }
1000 
1001 
1002 
1006 
1008 {
1009  // PRIVATE method for internal use only
1010  // Returns pointer to parent frame of 'f'
1011  if (!fBoosted.GetEntries() || !strcmp(f, "")) {
1012  // no frames defined or no frame name given
1013  return nullptr;
1014  }
1015  TString _frame(f);
1016  TIter it(&fBoosted);
1017  KVKinematicalFrame* p(nullptr), *r(nullptr);
1018  while ((p = (KVKinematicalFrame*)it())) {
1019  if (!_frame.CompareTo(p->GetName(), TString::kIgnoreCase)) return F;
1020  // look for subframe
1021  if ((r = p->GetParticle()->get_parent_frame(_frame, p))) return r;
1022  }
1023  return nullptr;
1024 }
1025 
1026 
1027 
1028 
1029 
1034 
1035 void KVParticle::SetFrame(const Char_t* newframe, const Char_t* oldframe, const KVFrameTransform& ft)
1036 {
1037  // Define new kinematical frame by transformation from existing frame
1038  // See SetFrame(const Char_t*,const KVFrameTransform&) for details on
1039  // defining kinematically-transformed frames.
1040 
1041  if (!fFrameName.CompareTo(oldframe, TString::kIgnoreCase)) {
1042  // 'oldframe' is name of current default kinematics, therefore this is same as
1043  // calling SetFrame(newframe,ft)
1044  SetFrame(newframe, ft);
1045  return;
1046  }
1047 
1049  if (!f) {
1050  Error("SetFrame(newframe,oldframe)", "oldframe=%s does not exist!", oldframe);
1051  return;
1052  }
1053  f->GetParticle()->SetFrame(newframe, ft);
1054 }
1055 
1056 
1057 
1058 
1061 
1063 {
1064  //returns velocity vector in cm/ns units
1065  TVector3 beta;
1066  if (E()) {
1067  beta = GetMomentum() * (1. / E());
1068  }
1069  else {
1070  beta.SetXYZ(0, 0, 0);
1071  }
1072  return (kSpeedOfLight * beta);
1073 }
1074 
1075 
1076 
1077 
1081 
1083 {
1084  //returns transverse velocity in cm/ns units
1085  //sign is +ve if py>=0, -ve if py<0
1086  return (GetV().y() >= 0.0 ? GetV().Perp() : -(GetV().Perp()));
1087 }
1088 
1089 
1090 
1091 
1097 
1099  Option_t* opt)
1100 {
1101  // Set Momentum components (in MeV/c)
1102  // if option is "cart" or "cartesian" we give cartesian components (x,y,z)
1103  // if option is "spher" or "spherical" we give components (rho,theta,phi) in spherical system
1104  // with theta, phi in DEGREES
1105  if (!strcmp("spher", opt) || !strcmp("spherical", opt)) {
1106  TVector3 pvec(0., 0., 1.);
1107  pvec.SetMag(px);
1108  pvec.SetTheta(TMath::Pi() * py / 180.);
1109  pvec.SetPhi(TMath::Pi() * pz / 180.);
1110  SetVectM(pvec, M());
1111  }
1112  else {
1113  if (strcmp("cart", opt) && strcmp("cartesian", opt)) {
1114  Warning("SetMomentum(Double_t,Double_t,Double_t,Option_t*)",
1115  "Unkown coordinate system\n known system are :\n\t\"cartesian\" or \"cart\" (default)\n\t\"spherical\" or \"spher\"");
1116  Warning("SetMomentum(Double_t,Double_t,Double_t,Option_t*)",
1117  "default used.");
1118  }
1119  TVector3 pvec(px, py, pz);
1120  SetVectM(pvec, M());
1121  }
1122 }
1123 
1124 
1125 
1128 
1130 {
1131  // Set velocity of particle (in cm/ns units)
1132  Double_t gamma = 1. / kSpeedOfLight / sqrt(1 - (vel.Mag2() / pow(kSpeedOfLight, 2)));
1133  TVector3 p = GetMass() * gamma * vel;
1134  SetMomentum(p);
1135 }
1136 
1137 
1138 
1143 
1144 void KVParticle::Streamer(TBuffer& R__b)
1145 {
1146  // Stream an object of class KVParticle.
1147  // When reading: If parameter "frameName" is set, use it to set non-persistent
1148  // fFrameName member (used by GetFrame)
1149 
1150  if (R__b.IsReading()) {
1151  R__b.ReadClassBuffer(KVParticle::Class(), this);
1152  if (GetParameters()->HasStringParameter("frameName")) fFrameName = GetParameters()->GetStringValue("frameName");
1153  }
1154  else {
1155  R__b.WriteClassBuffer(KVParticle::Class(), this);
1156  }
1157 }
1158 
1159 
1161 
1162 
1163 
1167 {
1168  // When a kinematical frame is added, this particle becomes the parent frame
1169  dynamic_cast<KVKinematicalFrame*>(f)->GetParticle()->SetParentFrame(parent);
1170  KVList::Add(f);
1171 }
1172 
1173 
1174 
1177 
1179 {
1180  // When a kinematical frame is removed, this particle is no longer the parent frame
1181  if (KVList::Remove(f) == f) {
1182  auto _f = dynamic_cast<KVKinematicalFrame*>(f);
1183  if (_f->GetParticle()->GetParentFrame() == parent) {
1184  _f->GetParticle()->SetParentFrame(nullptr);
1185  }
1186  return f;
1187  }
1188  return nullptr;
1189 }
1190 
1191 
1192 
1195 
1197 {
1198  // When the frame list is cleared, this particle is no longer the parent of any frames in the list
1199  TIter it(this);
1201  while ((f = (KVKinematicalFrame*)it())) {
1202  if (f->GetParticle()->GetParentFrame() == parent) {
1203  f->GetParticle()->SetParentFrame(nullptr);
1204  }
1205  }
1206  KVList::Clear(opt);
1207 }
1208 
1209 
1210 
1213 
1215 {
1216  // When all frames in a list are added to this one, this particle becomes the parent of all frames in the list
1217  TIter it(l);
1219  while ((f = (KVKinematicalFrame*)it())) {
1220  f->GetParticle()->SetParentFrame(parent);
1221  }
1222  KVList::AddAll(l);
1223 }
1224 
1225 
1226 
1233 
1234 void KVParticle::FrameList::Copy(TObject& _new_list) const
1235 {
1236  // Copy all kinematical frames in the list to a new one
1237  //
1238  // Note that this deliberately overrides the KVSeqCollection::Copy() method.
1239  //
1240  // Note also that we do not copy the KVParticle pointer, parent.
1241 
1242  auto new_list = dynamic_cast<KVParticle::FrameList*>(&_new_list);
1243  TIter next(this);
1244  KVKinematicalFrame* kf;
1245  while ((kf = (KVKinematicalFrame*)next())) {
1246  KVKinematicalFrame* new_frame;
1247  new_list->Add(new_frame = new KVKinematicalFrame(*kf)); // use KVKinematicalFrame copy constructor
1248  if (kf->GetParticle()->GetListOfFrames()->GetEntries()) {
1249  // recursively copy all subframes
1250  dynamic_cast<KVParticle::FrameList*>(kf->GetParticle()->GetListOfFrames())
1251  ->Copy(*dynamic_cast<KVParticle::FrameList*>(new_frame->GetParticle()->GetListOfFrames()));
1252  }
1253  }
1254 }
1255 
1256 
int Int_t
ROOT::R::TRInterface & r
#define f(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
char name[80]
Utility class for kinematical transformations of KVParticle class.
Kinematical representation of a particle in different reference frames.
void Copy(TObject &nvl) const override
void ls(Option_t *opt="") const override
void Clear(Option_t *opt="") override
const Char_t * GetStringValue(const Char_t *name) const
void Clear(Option_t *="") override
When the frame list is cleared, this particle is no longer the parent of any frames in the list.
TObject * Remove(TObject *) override
When a kinematical frame is removed, this particle is no longer the parent frame.
void Add(TObject *) override
When a kinematical frame is added, this particle becomes the parent frame.
void Copy(TObject &_new_list) const override
KVParticle * parent
Definition: KVParticle.h:410
void AddAll(const TCollection *) override
When all frames in a list are added to this one, this particle becomes the parent of all frames in th...
Base class for relativistic kinematics of massive particles.
Definition: KVParticle.h:396
Int_t GetNumberOfDefinedGroups() const
Definition: KVParticle.h:754
void AddGroups(KVUniqueNameList *un)
list of groups added to the current one
Definition: KVParticle.cpp:501
void SetIsOK(Bool_t flag=kTRUE)
Definition: KVParticle.cpp:371
TVector3 * GetPInitial() const
Definition: KVParticle.h:729
virtual void SetMass(Double_t m)
Definition: KVParticle.h:573
void RemoveGroup(const Char_t *groupname)
Remove group from list of groups.
Definition: KVParticle.cpp:562
void AddGroup(const Char_t *groupname, const Char_t *from="") const
Definition: KVParticle.cpp:468
void UpdateAllFrames()
Definition: KVParticle.cpp:955
const KVParticle * GetOriginal() const
Definition: KVParticle.h:533
TVector3 GetMomentum() const
Definition: KVParticle.h:607
void ResetIsOK()
Definition: KVParticle.h:707
void RemoveAllGroups()
Remove all groups.
Definition: KVParticle.cpp:578
KVUniqueNameList fGroups
list of momenta of the particle in different Lorentz-boosted frames
Definition: KVParticle.h:422
KVNameValueList * GetParameters() const
Definition: KVParticle.h:818
Double_t GetTheta() const
Definition: KVParticle.h:683
KVParticle & operator=(const KVParticle &rhs)
KVParticle assignment operator.
Definition: KVParticle.cpp:403
void SetVectM(const TVector3 &spatial, Double_t mass)
Definition: KVParticle.h:430
const Char_t * GetFrameName(void) const
Definition: KVParticle.h:803
void ResetEnergy()
Definition: KVParticle.cpp:425
void ls(Option_t *option="") const override
Definition: KVParticle.cpp:385
void SetVelocity(const TVector3 &)
Set velocity of particle (in cm/ns units)
KVUniqueNameList * GetGroups() const
Definition: KVParticle.h:759
static Double_t C()
Definition: KVParticle.cpp:117
Bool_t IsDetected() const
Definition: KVParticle.h:737
const Char_t * GetName() const override
return the field fName
Definition: KVParticle.cpp:455
void SetKE(Double_t ecin)
Definition: KVParticle.cpp:246
void init()
default initialisation
Definition: KVParticle.cpp:50
Double_t GetPhi() const
Definition: KVParticle.h:691
KVNameValueList fParameters
a general-purpose list of parameters associated with this particle
Definition: KVParticle.h:498
void Copy(TObject &) const override
Definition: KVParticle.cpp:286
void SetMomentum(const TVector3 *v)
Definition: KVParticle.h:545
void Set4Mom(const TLorentzVector &p)
Definition: KVParticle.h:592
KVKinematicalFrame * get_parent_frame(const Char_t *, KVKinematicalFrame *F=nullptr) const
KVParticle InFrame(const KVFrameTransform &)
Definition: KVParticle.cpp:614
void SetE0(TVector3 *e=0)
Definition: KVParticle.h:718
TString fFrameName
non-persistent frame name field, sets when calling SetFrame method
Definition: KVParticle.h:406
void Clear(Option_t *opt="") override
Reset particle properties i.e. before creating/reading a new event.
Definition: KVParticle.cpp:327
Bool_t IsOK() const
Definition: KVParticle.cpp:350
void ListGroups() const
List all stored groups.
Definition: KVParticle.cpp:590
Bool_t fFrameCopyOnly
if != nullptr, this object is a representation of the particle in a kinematical frame
Definition: KVParticle.h:503
void SetFrameName(const Char_t *framename)
Definition: KVParticle.h:808
static Double_t kSpeedOfLight
speed of light in cm/ns
Definition: KVParticle.h:423
void SetParentFrame(KVParticle *p)
Definition: KVParticle.h:518
Double_t GetKE() const
Definition: KVParticle.h:617
Double_t GetVpar() const
Definition: KVParticle.h:678
void SetXYZM(Double_t x, Double_t y, Double_t z, Double_t m)
Definition: KVParticle.h:486
void SetName(const Char_t *nom)
Set Name of the particle.
Definition: KVParticle.cpp:444
void SetFrame(const Char_t *frame, const KVFrameTransform &)
Definition: KVParticle.cpp:775
friend class KVKinematicalFrame
Definition: KVParticle.h:398
KVParticle const * GetFrame(const Char_t *frame, Bool_t warn_and_return_null_if_unknown=kTRUE) const
Definition: KVParticle.cpp:897
void ChangeFrame(const KVFrameTransform &, const KVString &="")
Definition: KVParticle.cpp:633
FrameList fBoosted
Definition: KVParticle.h:421
void SetOriginal(KVParticle *p)
Definition: KVParticle.h:541
void SetGroups(KVUniqueNameList *un)
Define for the particle a new list of groups.
Definition: KVParticle.cpp:489
Bool_t BelongsToGroup(const Char_t *groupname) const
Definition: KVParticle.cpp:541
TVector3 * fE0
the momentum of the particle before it is slowed/stopped by an absorber
Definition: KVParticle.h:497
void ChangeDefaultFrame(const Char_t *, const Char_t *defname="")
Definition: KVParticle.cpp:654
void SetRandomMomentum(Double_t T, Double_t thmin, Double_t thmax, Double_t phmin, Double_t phmax, Option_t *opt="isotropic")
Definition: KVParticle.cpp:136
const KVParticle * GetCurrentDefaultKinematics() const
Definition: KVParticle.h:773
TVector3 GetV() const
Definition: KVParticle.h:674
TString fName
non-persistent name field - Is useful
Definition: KVParticle.h:405
KVKinematicalFrame * get_frame(const Char_t *) const
Definition: KVParticle.cpp:979
void Print(Option_t *t="") const override
print out characteristics of particle
Definition: KVParticle.cpp:212
Double_t GetMass() const
Definition: KVParticle.h:577
TVector3 GetVelocity() const
returns velocity vector in cm/ns units
Double_t GetVperp() const
const KVParticle * GetTopmostParentFrame() const
Definition: KVParticle.h:522
KVList * GetListOfFrames() const
Definition: KVParticle.h:712
Int_t _GetNumberOfDefinedFrames() const
used to inhibit full copying of particles in different kinematical frames
Definition: KVParticle.cpp:519
void print_frames(TString fmt="") const
recursive print out of all defined kinematical frames
Definition: KVParticle.cpp:189
Base class used for handling geometry in a multidetector array.
Definition: KVPosition.h:91
virtual TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVPosition.cpp:242
TObject * Remove(TObject *obj) override
Remove object from list.
void Add(TObject *obj) override
void Clear(Option_t *option="") override
void Delete(Option_t *option="") override
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
Optimised list in which named objects can only be placed once.
void Add(TObject *obj) override
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
TObject * Next()
void Add(TObject *obj) override
TLorentzRotation Inverse() const
TLorentzVector & operator=(const TLorentzVector &)
Double_t Px() const
Double_t M() const
Double_t M2() const
Double_t Pz() const
Double_t Py() const
void Streamer(TBuffer &) override
static TClass * Class()
Double_t Perp() const
Double_t E() const
Double_t T() const
const char * GetName() const override
const char * GetName() const override
virtual const char * GetName() const
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual TObject * FindObject(const char *name) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void ls(Option_t *option="") const
void ResetBit(UInt_t f)
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
const char * Data() const
void ToUpper()
Bool_t IsNull() const
void Form(const char *fmt,...)
void SetXYZ(Double_t x, Double_t y, Double_t z)
void SetPhi(Double_t)
Double_t Mag2() const
TVector3 Unit() const
Double_t Mag() const
void SetMag(Double_t)
void SetTheta(Double_t)
RooCmdArg Parameters(const RooArgSet &params)
Expr< UnaryOp< Sqrt< T >, SMatrix< T, D, D2, R >, T >, T, D, D2, R > sqrt(const SMatrix< T, D, D2, R > &rhs)
double beta(double x, double y)
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
Double_t y[n]
TGraphErrors * gr
#define F(x, y, z)
double gamma(double x)
void init()
constexpr Double_t C()
Double_t Sqrt(Double_t x)
constexpr Double_t Pi()
TMarker m
TLine l
ClassImp(TPyArg)