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 << "KVParticle mass=" << M() <<
217  " Theta=" << GetTheta() << " Phi=" << GetPhi()
218  << " KE=" << GetKE() << " Vpar=" << GetVpar() << endl;
219  print_frames();
220  GetParameters()->Print();
221 }
222 
223 
224 
229 
231 {
232  //Change particle KE, keeping momentum direction constant
233  //If momentum is zero (i.e. no direction defined) the particle will be given
234  //a velocity in the positive z-direction
235 
236  if (ecin > 0.) {
237  Double_t et = M() + ecin; // new total energy = KE + m
238  Double_t pmod = 0;
239  if (et * et > M2()) {
240  pmod = TMath::Sqrt(et * et - M2()); // p**2 = E**2 - m**2
241  TVector3 newp(Px(), Py(), Pz());
242  if (pmod && newp.Mag()) {
243  newp.SetMag(pmod);
244  }
245  else {
246  newp.SetXYZ(0, 0, 1);
247  newp.SetMag(pmod);
248  }
249  SetMomentum(newp);
250  }
251  else {
252  SetMomentum(0., 0., 0.);
253  }
254  }
255  else
256  SetMomentum(0., 0., 0.);
257 }
258 
259 
260 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
261 
268 
269 void KVParticle::Copy(TObject& obj) const
270 #else
271 void KVParticle::Copy(TObject& obj)
272 #endif
273 {
274  // Copy this to obj
275  // Particle kinematics are copied using operator=(const KVParticle&)
276  // List of particle's groups is copied
277  // The particle's name is copied
278  // The list of parameters associated with the particle is copied
279 
280  ((KVParticle&) obj) = *this;
281  if (!fFrameCopyOnly) {
282  // do not make a full copy if particle is just a new kinematical frame
283  ((KVParticle&) obj).SetGroups(GetGroups());
284  ((KVParticle&) obj).SetName(GetName());
285  fParameters.Copy(((KVParticle&) obj).fParameters);
286  }
287 }
288 
289 
290 
291 
294 
296 {
297  //Reset particle properties i.e. before creating/reading a new event
298 
299  SetXYZM(0., 0., 0., 0.);
300  if (fE0) {
301  delete fE0;
302  fE0 = 0;
303  }
304  ResetIsOK(); //in case IsOK() status was set "by hand" in previous event
306  fParameters.Clear();
307  fGroups.Clear();
308  fBoosted.Delete();
309 }
310 
311 
312 
317 
319 {
320  //Determine whether this particle is considered "good" or not for analysis,
321  //depending on a previous call to SetIsOK(Bool_t flag).
322  //If SetIsOK has not been called, IsOK returns kTRUE by default.
323 
324  if (GetOriginal()->TestBit(kIsOKSet)) { //status set by SetIsOK()
325  return TestBit(kIsOK);
326  }
327  //Default if SetIsOK not used: accept particle
328  return kTRUE;
329 }
330 
331 
332 
333 
338 
340 {
341  //Set acceptation/rejection status for the particle.
342  //
343  //In order to 'forget' this status (accept all particles) use ResetIsOK()
344 
345  GetOriginal()->SetBit(kIsOK, flag);
347 }
348 
349 
350 
352 
353 void KVParticle::ls(Option_t* option) const
354 {
355  std::cout << option << GetName() << ":" << GetFrameName() << ":" << this << "\n";
356  if (fBoosted.GetEntries()) {
357  TString nopt = option;
358  nopt += " ";
359  TIter next(&fBoosted);
361  while ((p = (KVKinematicalFrame*)next())) p->GetParticle()->ls(nopt.Data());
362  }
363 }
364 
365 
366 
367 
370 
372 {
373  //KVParticle assignment operator.
374 
375  if (this != &rhs) {
377  if (rhs.GetPInitial()) SetE0(rhs.GetPInitial());
378  }
379  return *this;
380 }
381 
382 
383 
384 
392 
394 {
395  //Used for simulated particles after passage through some absorber/detector.
396  //The passage of a particle through the different absorbers modifies its
397  //kinetic energies, indeed the particle may be stopped in the detector.
398  //Calling this method will reset the particle's momentum to its
399  //initial value i.e. before it entered the first absorber.
400  //Particles which have not encountered any absorbers/detectors are left as they are.
401 
402  if (IsDetected())
404 }
405 
406 
407 
408 
411 
412 void KVParticle::SetName(const Char_t* nom)
413 {
414  //Set Name of the particle
415  GetOriginal()->fName.Form("%s", nom);
416 }
417 
418 
419 
422 
424 {
425  // return the field fName
426  return GetOriginal()->fName.Data();
427 }
428 
429 
430 
435 
436 void KVParticle::AddGroup(const Char_t* groupname, const Char_t* from) const
437 {
438  // Associate this particle with the given named group.
439  // Optional argument "from" allows to put a condition on the already stored
440  // group list, is set to "" by default
441 
442  TString sfrom(from);
443  sfrom.ToUpper();
444  TString sgroupname(groupname);
445  sgroupname.ToUpper();
446 
447  if (BelongsToGroup(sfrom.Data()) && !BelongsToGroup(sgroupname.Data())) {
448  GetGroups()->Add(new TObjString(sgroupname.Data()));
449  }
450 }
451 
452 
453 
456 
458 {
459  //Define for the particle a new list of groups
460  GetGroups()->Clear();
461  AddGroups(un);
462 }
463 
464 
465 
468 
470 {
471  //list of groups added to the current one
472  TObjString* os = 0;
473  TIter no(un);
474  while ((os = (TObjString*)no.Next())) {
475  AddGroup(os->GetName());
476  }
477 
478 }
479 
480 
481 
486 
488 {
489  // \returns the number of kinematical frames defined by transformations of this frame
490  //
491  // \note this is always at least equal to one (we count the present frame of the particle)
492 
493  TIter it(GetListOfFrames());
495  Int_t nf = 1; // start with the current actual frame
496  while ((p = (KVKinematicalFrame*)it())) {
497  nf += p->GetParticle()->_GetNumberOfDefinedFrames();
498  }
499  return nf;
500 }
501 
502 
503 
508 
509 Bool_t KVParticle::BelongsToGroup(const Char_t* groupname) const
510 {
511  //Check if particle belong to a given group
512  //return kTRUE if groupname="".
513  //return kFALSE if no group has be defined
514 
515  TString sgroupname(groupname);
516  sgroupname.ToUpper();
517  //Important for KVEvent::GetNextParticle()
518  if (sgroupname.IsNull()) return kTRUE;
519  //retourne kFALSE si aucun groupe n'est defini
520  if (!GetNumberOfDefinedGroups()) return kFALSE;
521  if (GetGroups()->FindObject(sgroupname.Data())) return kTRUE;
522  return kFALSE;
523 }
524 
525 
526 
529 
530 void KVParticle::RemoveGroup(const Char_t* groupname)
531 {
532  // Remove group from list of groups
533  if (!GetGroups()->GetEntries()) return;
534  TString sgroupname(groupname);
535  sgroupname.ToUpper();
536 
537  TObjString* os = 0;
538  if ((os = (TObjString*)GetGroups()->FindObject(sgroupname.Data()))) delete GetGroups()->Remove(os);
539 }
540 
541 
542 
545 
547 {
548  //Remove all groups
549  GetGroups()->Clear();
550 }
551 
552 
553 
554 
557 
558 void KVParticle::ListGroups(void) const
559 {
560  //List all stored groups
561  if (GetGroups()->GetEntries()) {
562  cout << "Particle belongs to no groups" << endl;
563  return;
564  }
565  else {
566  cout << "----------------------------------------" << endl;
567  cout << "List of groups this particle belongs to:" << endl;
568  cout << "----------------------------------------" << endl;
569  }
570  TObjString* os = 0;
571  TIter no(GetGroups());
572  while ((os = (TObjString*)no.Next())) cout << "\t" << os->GetName() << endl;
573  cout << "----------------------------------------" << endl;
574 }
575 
576 
577 
581 
583 {
584  // Use this method to obtain 'on-the-fly' some information on particle kinematics
585  // in a different reference frame. The default kinematics of the particle are unchanged.
586 
587  KVParticle p;
588  p.Set4Mom(*this);
589  KVKinematicalFrame(&p, t);
590  return p;
591 }
592 
593 
594 
600 
602 {
603  // Permanently modify kinematics of particle according to the given transformation.
604  // You can optionally set the name of this new default kinematics.
605  // NB the current kinematics will be lost. If you want to keep it after changing the
606  // default kinematics, define the new frame with SetFrame and then use ChangeDefaultFrame.
607 
608  KVKinematicalFrame(this, t);
609  if (name != "") SetFrameName(name);
610 }
611 
612 
613 
621 
622 void KVParticle::ChangeDefaultFrame(const Char_t* newdef, const Char_t* defname)
623 {
624  // Make existing reference frame 'newdef' the new default frame for particle kinematics.
625  // The current default frame will then be accessible from the list of frames
626  // using its name (if set with SetFrameName).
627  //
628  // You can change/set the name of the previous default frame with 'defname'.
629  // If no name was set and none given, it will be renamed "default" by default.
630 
631  if (!fFrameName.CompareTo(newdef, TString::kIgnoreCase)) return;//newdef is already the default frame, do nothing
632 
633  TString _defname(defname);
634  if (_defname == "") _defname = GetFrameName();
635  if (_defname == "") _defname = "default";
636  // get list of all parents of new default
637  TList parents;
638  TString ff = newdef;
640  do {
641  f = get_parent_frame(ff);
642  if (f) {
643  parents.Add(f);
644  ff = f->GetName();
645  }
646  }
647  while (f);
648  // modify tree structure
649  TIter it(&parents);
650  KVKinematicalFrame* newdframe = get_frame(newdef);
651  KVKinematicalFrame* save_newdef = newdframe;
652  KVFrameTransform trans, next_trans = newdframe->GetTransform();
653  while ((f = (KVKinematicalFrame*)it())) {
654  f->GetParticle()->GetListOfFrames()->Remove(newdframe);
655  trans = next_trans;
656  next_trans = f->GetTransform();
657  newdframe->GetParticle()->GetListOfFrames()->Add(f);
658  f->SetTransform(trans.Inverse());
659  newdframe = f;
660  }
661  GetListOfFrames()->Remove(newdframe);
662  // copy current default kinematics particle momentum/energy
663  TLorentzVector old_def_p(*this);
664  // set momentum/energy of new default kinematics
665  Set4Mom(*(save_newdef->GetParticle()));
666  save_newdef->GetParticle()->Set4Mom(old_def_p);
667  save_newdef->SetTransform(next_trans.Inverse());
668  save_newdef->SetName(_defname);
669  save_newdef->GetParticle()->SetFrameName(_defname);
670  newdframe->GetParticle()->GetListOfFrames()->Add(save_newdef);
671  // copy frame list from new default frame
672  TList frame_list;
673  frame_list.AddAll(save_newdef->GetParticle()->GetListOfFrames());
674  save_newdef->GetParticle()->GetListOfFrames()->Clear("nodelete");
675  save_newdef->GetParticle()->GetListOfFrames()->AddAll(&fBoosted);
676  fBoosted.Clear("nodelete");
677  fBoosted.AddAll(&frame_list);
678  SetFrameName(newdef);
679 }
680 
681 
682 
742 
743 void KVParticle::SetFrame(const Char_t* frame, const KVFrameTransform& ft)
744 {
745  //Define a Lorentz-boosted and/or rotated frame in which to calculate this particle's momentum and energy.
746  //
747  //The new frame will have the name given in the string "frame", which can then be used to
748  //access the kinematics of the particle in different frames using GetFrame() (frame names are case-insensitive).
749  //Calling this method with the name of an existing frame will update the kinematics of the particle
750  //in that frame using the given transform (note that kinematics in all frames defined as 'subframes' of
751  //this frame will also be updated).
752  //
753  //USING BOOSTS
754  //The boost velocity vector is that of the boosted frame with respect to the original frame of the particles in the event.
755  //The velocity vector can be given either in cm/ns units (default) or in units of 'c' (beta=kTRUE).
756  //
757  //E.g. to define a frame moving at 0.1c in the +ve z-direction with respect to the original
758  //event frame:
759  //
760  // (...supposing a valid pointer KVParticle* my_part...)
761  // TVector3 vframe(0,0,0.1);
762  // my_part->SetFrame("my_frame", KVFrameTransform(vframe, kTRUE));
763  //
764  //or with velocity in cm/ns units (default):
765  // TVector3 vframe(0,0,3);
766  // my_part->SetFrame("my_frame", KVFrameTransform(vframe));
767  // OR my_part->SetFrame("my_frame", vframe);
768  //
769  //USING ROTATIONS
770  //According to the conventions adopted for the TRotation and TLorentzRotation classes,
771  //we actually use the inverse of the TLorentzRotation to make the transformation,
772  //to get the coordinates corresponding to a rotated coordinate system, not the coordinates
773  //of a rotated vector in the same coordinate system
774  //=> you do not need to invert the transformation matrix
775  //
776  //E.g. if you want to define a new frame whose coordinate axes are rotated with respect
777  //to the original axes, you can set up a TRotation like so:
778  //
779  // TRotation rot;
780  // TVector3 newX, newY, newZ; // the new coordinate axes
781  // rot.RotateAxes(newX, newY, newZ);
782  //
783  //If you are using one of the two global variables which calculate the event tensor
784  //(KVTensP and KVTensPCM) you can obtain the transformation to the tensor frame
785  //using:
786  //
787  // TRotation rot;
788  // KVTensP* tens_gv;// pointer to tensor global variable
789  // tens_gv->GetTensor()->GetRotation(rot);// see KVTenseur3::GetRotation
790  //
791  //Then the new frame can be defined by
792  // my_part->SetFrame("my_frame", KVFrameTransform(rot));
793  // OR my_part->SetFrame("my_frame", rot);
794  //
795  //USING COMBINED BOOST AND ROTATION
796  //You can define a frame using both a boost and a rotation like so:
797  // my_part->SetFrame("my_frame", KVFrameTransform(vframe,rot,kTRUE));
798  //
799  //ACCESSING KINEMATICS IN NEW FRAMES
800  //In order to access the kinematics of the particle in the new frame:
801  //
802  // my_part->GetFrame("my_frame")->GetTransverseEnergy();// transverse energy in "my_frame"
803 
804  if (!strcmp(frame, "")) return;
805 
807  // 'frame' is name of current default kinematics, therefore we do not want to add a new frame
808  // (which would have the same name as the current default, and the two would coexist),
809  // we want to change the kinematics of the current frame
810  ChangeFrame(ft);
811  return;
812  }
813 
815  if (!tmp) {
816  //if this frame has not already been defined, create a new one
817  tmp = new KVKinematicalFrame(frame, this, ft);
818  fBoosted.Add(tmp);
819  tmp->GetParticle()->SetOriginal(GetOriginal());
820  }
821  else
822  tmp->ApplyTransform(this, ft);
823 }
824 
825 
826 
864 
865 KVParticle const* KVParticle::GetFrame(const Char_t* frame, Bool_t warn_and_return_null_if_unknown) const
866 {
867  // Return the momentum of the particle in the Lorentz-boosted frame corresponding to the name
868  // "frame" given as argument (see SetFrame() for definition of different frames).
869  // If the default frame name has been set (see KVEvent::SetFrameName) and 'frame' is the
870  // name of this default frame (KVParticle::fFrameName), we return the address of the particle
871  // itself.
872  //
873  // This frame may have been defined by a direct transformation of the original kinematics of the
874  // particle (using SetFrame(newframe,...)) or by a transformation of the kinematics in another
875  // user-defined frame (using SetFrame(newframe,oldframe,...)).
876  //
877  // Note that frames are not "dynamic": if any changes are made to the original particle's kinematics
878  // after definition of a frame, if you want these changes to affect also the other frames you
879  // need to update them by hand by calling KVParticle::UpdateAllFrames().
880  //
881  // Frame names are case insensitive: "CM" or "cm" or "Cm" are all good...
882  //
883  // By default, if no frame with the given name is found, we return nullptr and print a warning.
884  // If `warn_and_return_null_if_unknown=kFALSE`, we return the address of the particle itself,
885  // i.e. the original/default kinematics.
886  // [Note that this is an inversion of the previous default behaviour]
887  //
888  // Note that the properties of the particle returned by this method can not be modified:
889  // this is deliberate, as any modifications e.g. to kinematics will have no effect
890  // in any other frames.
891  //
892  // The returned pointer corresponds to a "pseudoparticle" in the desired frame,
893  // therefore you can use any KVParticle method in order to access the kinematics of the
894  // particle in the boosted frame, e.g.
895  //
896  //~~~~~~~~~~~~~~~~~~~~
897  // (...supposing a valid pointer KVParticle* my_part...)
898  // my_part->GetFrame("cm_frame")->GetVpar();// //el velocity in "cm_frame"
899  // my_part->GetFrame("QP_frame")->GetTheta();// polar angle in "QP_frame"
900  // etc. etc.
901  //~~~~~~~~~~~~~~~~~~~~
902  //
903 
904  if (!fFrameName.CompareTo(frame, TString::kIgnoreCase)) return (KVParticle const*)this;
906  return f ? (KVParticle const*)f->GetParticle() :
907  (warn_and_return_null_if_unknown ?
908  Warning("GetFrame(const Char_t*)", "No frame \"%s\" defined for particle. 0x0 returned.",
909 #ifndef WITH_CPP11
910  frame), (KVParticle*)nullptr
911 #else
912  frame), nullptr
913 #endif
914  : this);
915 }
916 
917 
918 
922 
924 {
925  // Call this method to update particle kinematics in all defined frames if you change
926  // the kinematics of the particle in its original/default frame.
927 
928  if (fBoosted.GetEntries()) {
929  TIter it(&fBoosted);
931  while ((f = (KVKinematicalFrame*)it())) {
932  f->ReapplyTransform(this);
933  // recursively apply to all subframes
934  f->GetParticle()->UpdateAllFrames();
935  }
936  }
937 }
938 
939 
940 
946 
948 {
949  // \param[in] frame name of a kinematical frame
950  // \returns pointer to the kinematical frame if previously defined, nullptr otherwise
951  //
952  // \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()
953 
954  if (!fBoosted.GetEntries() || !strcmp(frame, "")) {
955  // no frames defined or no frame name given
956  return nullptr;
957  }
958  TString _frame(frame);
959  TIter it(&fBoosted);
960  KVKinematicalFrame* p(nullptr), *f(nullptr);
961  while ((p = f = (KVKinematicalFrame*)it())) {
962  if (!_frame.CompareTo(p->GetName(), TString::kIgnoreCase)) break;
963  // look for subframe
964  if ((f = p->GetParticle()->get_frame(_frame))) break;
965  }
966  return f;
967 }
968 
969 
970 
974 
976 {
977  // PRIVATE method for internal use only
978  // Returns pointer to parent frame of 'f'
979  if (!fBoosted.GetEntries() || !strcmp(f, "")) {
980  // no frames defined or no frame name given
981  return nullptr;
982  }
983  TString _frame(f);
984  TIter it(&fBoosted);
985  KVKinematicalFrame* p(nullptr), *r(nullptr);
986  while ((p = (KVKinematicalFrame*)it())) {
987  if (!_frame.CompareTo(p->GetName(), TString::kIgnoreCase)) return F;
988  // look for subframe
989  if ((r = p->GetParticle()->get_parent_frame(_frame, p))) return r;
990  }
991  return nullptr;
992 }
993 
994 
995 
996 
997 
1002 
1003 void KVParticle::SetFrame(const Char_t* newframe, const Char_t* oldframe, const KVFrameTransform& ft)
1004 {
1005  // Define new kinematical frame by transformation from existing frame
1006  // See SetFrame(const Char_t*,const KVFrameTransform&) for details on
1007  // defining kinematically-transformed frames.
1008 
1009  if (!fFrameName.CompareTo(oldframe, TString::kIgnoreCase)) {
1010  // 'oldframe' is name of current default kinematics, therefore this is same as
1011  // calling SetFrame(newframe,ft)
1012  SetFrame(newframe, ft);
1013  return;
1014  }
1015 
1017  if (!f) {
1018  Error("SetFrame(newframe,oldframe)", "oldframe=%s does not exist!", oldframe);
1019  return;
1020  }
1021  f->GetParticle()->SetFrame(newframe, ft);
1022 }
1023 
1024 
1025 
1026 
1029 
1031 {
1032  //returns velocity vector in cm/ns units
1033  TVector3 beta;
1034  if (E()) {
1035  beta = GetMomentum() * (1. / E());
1036  }
1037  else {
1038  beta.SetXYZ(0, 0, 0);
1039  }
1040  return (kSpeedOfLight * beta);
1041 }
1042 
1043 
1044 
1045 
1049 
1051 {
1052  //returns transverse velocity in cm/ns units
1053  //sign is +ve if py>=0, -ve if py<0
1054  return (GetV().y() >= 0.0 ? GetV().Perp() : -(GetV().Perp()));
1055 }
1056 
1057 
1058 
1059 
1065 
1067  Option_t* opt)
1068 {
1069  // Set Momentum components (in MeV/c)
1070  // if option is "cart" or "cartesian" we give cartesian components (x,y,z)
1071  // if option is "spher" or "spherical" we give components (rho,theta,phi) in spherical system
1072  // with theta, phi in DEGREES
1073  if (!strcmp("spher", opt) || !strcmp("spherical", opt)) {
1074  TVector3 pvec(0., 0., 1.);
1075  pvec.SetMag(px);
1076  pvec.SetTheta(TMath::Pi() * py / 180.);
1077  pvec.SetPhi(TMath::Pi() * pz / 180.);
1078  SetVectM(pvec, M());
1079  }
1080  else {
1081  if (strcmp("cart", opt) && strcmp("cartesian", opt)) {
1082  Warning("SetMomentum(Double_t,Double_t,Double_t,Option_t*)",
1083  "Unkown coordinate system\n known system are :\n\t\"cartesian\" or \"cart\" (default)\n\t\"spherical\" or \"spher\"");
1084  Warning("SetMomentum(Double_t,Double_t,Double_t,Option_t*)",
1085  "default used.");
1086  }
1087  TVector3 pvec(px, py, pz);
1088  SetVectM(pvec, M());
1089  }
1090 }
1091 
1092 
1093 
1096 
1098 {
1099  // Set velocity of particle (in cm/ns units)
1100  Double_t gamma = 1. / kSpeedOfLight / sqrt(1 - (vel.Mag2() / pow(kSpeedOfLight, 2)));
1101  TVector3 p = GetMass() * gamma * vel;
1102  SetMomentum(p);
1103 }
1104 
1105 
1106 
1111 
1112 void KVParticle::Streamer(TBuffer& R__b)
1113 {
1114  // Stream an object of class KVParticle.
1115  // When reading: If parameter "frameName" is set, use it to set non-persistent
1116  // fFrameName member (used by GetFrame)
1117 
1118  if (R__b.IsReading()) {
1119  R__b.ReadClassBuffer(KVParticle::Class(), this);
1120  if (GetParameters()->HasStringParameter("frameName")) fFrameName = GetParameters()->GetStringValue("frameName");
1121  }
1122  else {
1123  R__b.WriteClassBuffer(KVParticle::Class(), this);
1124  }
1125 }
1126 
1127 
1128 
1131 
1133 {
1134  // When a kinematical frame is added, this particle becomes the parent frame
1135  dynamic_cast<KVKinematicalFrame*>(f)->GetParticle()->SetParentFrame(parent);
1136  KVList::Add(f);
1137 }
1138 
1139 
1140 
1143 
1145 {
1146  // When a kinematical frame is removed, this particle is no longer the parent frame
1147  if (KVList::Remove(f) == f) {
1148  auto _f = dynamic_cast<KVKinematicalFrame*>(f);
1149  if (_f->GetParticle()->GetParentFrame() == parent) {
1150  _f->GetParticle()->SetParentFrame(nullptr);
1151  }
1152  return f;
1153  }
1154  return nullptr;
1155 }
1156 
1157 
1158 
1161 
1163 {
1164  // When the frame list is cleared, this particle is no longer the parent of any frames in the list
1165  TIter it(this);
1167  while ((f = (KVKinematicalFrame*)it())) {
1168  if (f->GetParticle()->GetParentFrame() == parent) {
1169  f->GetParticle()->SetParentFrame(nullptr);
1170  }
1171  }
1172  KVList::Clear(opt);
1173 }
1174 
1175 
1176 
1179 
1181 {
1182  // When all frames in a list are added to this one, this particle becomes the parent of all frames in the list
1183  TIter it(l);
1185  while ((f = (KVKinematicalFrame*)it())) {
1186  f->GetParticle()->SetParentFrame(parent);
1187  }
1188  KVList::AddAll(l);
1189 }
1190 
1191 
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
char name[80]
Utility class for kinematical transformations of KVParticle class.
Kinematical representation of a particle in different reference frames.
virtual void Print(Option_t *opt="") const
virtual void Clear(Option_t *opt="")
const Char_t * GetStringValue(const Char_t *name) const
void AddAll(const TCollection *)
When all frames in a list are added to this one, this particle becomes the parent of all frames in th...
void Clear(Option_t *="")
When the frame list is cleared, this particle is no longer the parent of any frames in the list.
TObject * Remove(TObject *)
When a kinematical frame is removed, this particle is no longer the parent frame.
void Add(TObject *)
When a kinematical frame is added, this particle becomes the parent frame.
KVParticle * parent
Definition: KVParticle.h:409
Base class for relativistic kinematics of massive particles.
Definition: KVParticle.h:396
Int_t GetNumberOfDefinedGroups() const
Definition: KVParticle.h:751
void AddGroups(KVUniqueNameList *un)
list of groups added to the current one
Definition: KVParticle.cpp:469
void SetIsOK(Bool_t flag=kTRUE)
Definition: KVParticle.cpp:339
TVector3 * GetPInitial() const
Definition: KVParticle.h:726
virtual void SetMass(Double_t m)
Definition: KVParticle.h:570
void RemoveGroup(const Char_t *groupname)
Remove group from list of groups.
Definition: KVParticle.cpp:530
void AddGroup(const Char_t *groupname, const Char_t *from="") const
Definition: KVParticle.cpp:436
void UpdateAllFrames()
Definition: KVParticle.cpp:923
const KVParticle * GetOriginal() const
Definition: KVParticle.h:530
TVector3 GetMomentum() const
Definition: KVParticle.h:604
void ResetIsOK()
Definition: KVParticle.h:704
void RemoveAllGroups()
Remove all groups.
Definition: KVParticle.cpp:546
KVUniqueNameList fGroups
list of momenta of the particle in different Lorentz-boosted frames
Definition: KVParticle.h:419
KVNameValueList * GetParameters() const
Definition: KVParticle.h:815
Double_t GetTheta() const
Definition: KVParticle.h:680
KVParticle & operator=(const KVParticle &rhs)
KVParticle assignment operator.
Definition: KVParticle.cpp:371
void SetVectM(const TVector3 &spatial, Double_t mass)
Definition: KVParticle.h:427
const Char_t * GetFrameName(void) const
Definition: KVParticle.h:800
void ResetEnergy()
Definition: KVParticle.cpp:393
void SetVelocity(const TVector3 &)
Set velocity of particle (in cm/ns units)
const Char_t * GetName() const
return the field fName
Definition: KVParticle.cpp:423
KVUniqueNameList * GetGroups() const
Definition: KVParticle.h:756
static Double_t C()
Definition: KVParticle.cpp:117
Bool_t IsDetected() const
Definition: KVParticle.h:734
void SetKE(Double_t ecin)
Definition: KVParticle.cpp:230
virtual void Clear(Option_t *opt="")
Reset particle properties i.e. before creating/reading a new event.
Definition: KVParticle.cpp:295
void ls(Option_t *option="") const
Definition: KVParticle.cpp:353
void init()
default initialisation
Definition: KVParticle.cpp:50
Double_t GetPhi() const
Definition: KVParticle.h:688
KVNameValueList fParameters
a general-purpose list of parameters associated with this particle
Definition: KVParticle.h:495
void SetMomentum(const TVector3 *v)
Definition: KVParticle.h:542
virtual void Copy(TObject &) const
Definition: KVParticle.cpp:269
void Set4Mom(const TLorentzVector &p)
Definition: KVParticle.h:589
KVKinematicalFrame * get_parent_frame(const Char_t *, KVKinematicalFrame *F=nullptr) const
Definition: KVParticle.cpp:975
virtual void Print(Option_t *t="") const
print out characteristics of particle
Definition: KVParticle.cpp:212
KVParticle InFrame(const KVFrameTransform &)
Definition: KVParticle.cpp:582
void SetE0(TVector3 *e=0)
Definition: KVParticle.h:715
TString fFrameName
non-persistent frame name field, sets when calling SetFrame method
Definition: KVParticle.h:406
Bool_t IsOK() const
Definition: KVParticle.cpp:318
void ListGroups() const
List all stored groups.
Definition: KVParticle.cpp:558
void SetFrameName(const Char_t *framename)
Definition: KVParticle.h:805
static Double_t kSpeedOfLight
speed of light in cm/ns
Definition: KVParticle.h:420
void SetParentFrame(KVParticle *p)
Definition: KVParticle.h:515
Double_t GetKE() const
Definition: KVParticle.h:614
Double_t GetVpar() const
Definition: KVParticle.h:675
void SetXYZM(Double_t x, Double_t y, Double_t z, Double_t m)
Definition: KVParticle.h:483
void SetName(const Char_t *nom)
Set Name of the particle.
Definition: KVParticle.cpp:412
void SetFrame(const Char_t *frame, const KVFrameTransform &)
Definition: KVParticle.cpp:743
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:865
void ChangeFrame(const KVFrameTransform &, const KVString &="")
Definition: KVParticle.cpp:601
FrameList fBoosted
Definition: KVParticle.h:418
void SetOriginal(KVParticle *p)
Definition: KVParticle.h:538
void SetGroups(KVUniqueNameList *un)
Define for the particle a new list of groups.
Definition: KVParticle.cpp:457
Bool_t BelongsToGroup(const Char_t *groupname) const
Definition: KVParticle.cpp:509
TVector3 * fE0
the momentum of the particle before it is slowed/stopped by an absorber
Definition: KVParticle.h:494
void ChangeDefaultFrame(const Char_t *, const Char_t *defname="")
Definition: KVParticle.cpp:622
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
TVector3 GetV() const
Definition: KVParticle.h:671
TString fName
non-persistent name field - Is useful
Definition: KVParticle.h:405
KVKinematicalFrame * get_frame(const Char_t *) const
Definition: KVParticle.cpp:947
Double_t GetMass() const
Definition: KVParticle.h:574
TVector3 GetVelocity() const
returns velocity vector in cm/ns units
Double_t GetVperp() const
const KVParticle * GetTopmostParentFrame() const
Definition: KVParticle.h:519
KVList * GetListOfFrames() const
Definition: KVParticle.h:709
Int_t _GetNumberOfDefinedFrames() const
used to inhibit full copying of particles in different kinematical frames
Definition: KVParticle.cpp:487
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
virtual void Clear(Option_t *option="")
virtual void Add(TObject *obj)
virtual TObject * Remove(TObject *obj)
Remove object from list.
virtual void Delete(Option_t *option="")
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.
virtual void Add(TObject *obj)
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
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]
#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)