33 namespace RestFrames {
36 int RestFrame::m_class_key = 0;
40 m_Type = kVanillaFrame;
44 RestFrame::~RestFrame(){
52 m_Type = kVanillaFrame;
53 m_ParentFramePtr =
nullptr;
54 m_ParentBoost.SetXYZ(0.,0.,0.);
70 TVector3 RestFrame::m_Axis = TVector3(0.,0.,1.);
73 RestFrame::m_Axis = axis;
77 return RestFrame::m_Axis;
98 return m_Type == kVisibleFrame;
102 return m_Type == kInvisibleFrame;
106 return m_Type == kDecayFrame;
110 return m_Type == kLabFrame;
114 return m_Ana == kRecoFrame;
118 return m_Ana == kGenFrame;
124 output +=
" Frame Type: Lab \n";
126 output +=
" Frame Type: Decay \n";
128 output +=
" Frame Type: Visible \n";
130 output +=
" Frame Type: Invisible \n";
132 output +=
" Ana Type: Generator \n";
134 output +=
" Ana Type: Reconstruction \n";
138 bool RestFrame::IsSoundBody()
const {
139 if(RFBase::IsSoundBody())
return true;
141 for(
int i = 0; i < Nchild; i++)
143 m_Log << LogWarning <<
"Empty child frame:";
145 return SetBody(
false);
147 return SetBody(
true);
151 if(!IsSoundBody())
return false;
153 for(
int i = 0; i < Nchild; i++){
156 m_Log <<
"Problem with recursive tree structure from frame: ";
158 return SetBody(
false);
166 bool contains = m_ChildFrames.Contains(frame);
167 m_ChildBoosts.erase(&frame);
168 m_ChildFrames.Remove(frame);
177 m_ChildFrames.Clear();
178 m_ChildBoosts.clear();
188 if(*m_ParentFramePtr != frame){
189 m_ParentFramePtr =
nullptr;
193 m_ParentFramePtr =
nullptr;
195 m_ParentFramePtr = &frame;
205 m_Log <<
"Cannot add empty frame as child.";
211 m_Log <<
"Cannot add LabFrame frame as child:";
212 m_Log << Log(frame) << LogEnd;
215 if(!m_ChildFrames.Add(frame)){
217 m_Log <<
"Unable to add child frame:";
218 m_Log << Log(frame) << LogEnd;
222 m_ChildBoosts[&frame] = m_Empty3Vector;
226 int N = frames.GetN();
227 for(
int i = 0; i < N; i++)
232 return m_ChildFrames.GetN();
237 if(i >= Nchild || i < 0){
239 m_Log <<
"Cannot GetChildFrame(" << i <<
"). ";
240 m_Log <<
"No " << i <<
"th child" << LogEnd;
242 return m_ChildFrames[i];
247 return *m_ParentFramePtr;
253 return m_ChildFrames;
262 m_Log <<
"Unable to find LabFrame above this frame. ";
263 m_Log <<
"No parent frame set" << LogEnd;
280 for(
int s = 0; s < Nsib; s++){
289 if(!IsSoundBody())
return 0.;
292 if(Nchild == 0)
return 1;
294 for(
int i = 0; i < Nchild; i++){
300 void RestFrame::SetChildBoostVector(
RestFrame& frame,
const TVector3& boost) {
301 if(!m_ChildFrames.Contains(frame)){
303 m_Log <<
"Unable to set child's boost vector. ";
304 m_Log <<
"Frame is not among children:";
305 m_Log << Log(frame) << LogEnd;
308 m_ChildBoosts[&frame] = boost;
309 frame.SetParentBoostVector(-1.*boost);
312 void RestFrame::SetParentBoostVector(
const TVector3& boost) {
315 m_Log <<
"Unable to set parent boost vector. ";
316 m_Log <<
"No parent frame set.";
320 m_ParentBoost = boost;
323 TVector3
const& RestFrame::GetChildBoostVector(RestFrame& frame)
const {
324 if(!m_ChildFrames.Contains(frame)){
326 m_Log <<
"Unable to get child's boost vector. ";
327 m_Log <<
"Frame is not among children:";
328 m_Log << Log(frame) << LogEnd;
329 return m_Empty3Vector;
331 return m_ChildBoosts[&frame];
334 TVector3
const& RestFrame::GetParentBoostVector()
const {
335 return m_ParentBoost;
340 FillListFramesRecursive(frames,type);
353 if(frames.Contains(*
this))
return;
354 if(type ==
GetType() || type == kLabFrame) frames.Add((
RestFrame&)(*m_This));
356 for(
int i = 0; i < Nchild; i++)
361 int Nkey = keys.size();
362 for(
int i = 0; i < Nkey; i++){
365 m_Log <<
"This RestFrame appears more than once in the tree:";
366 m_Log << Log(*
this) << LogEnd;
372 for(
int i = 0; i < Nchild; i++)
379 bool RestFrame::FindPathToFrame(
const RestFrame& dest_frame,
381 std::vector<const TVector3*>& boosts)
const {
382 if(
IsSame(dest_frame))
return true;
384 std::vector<const RestFrame*> try_frames;
385 std::vector<const TVector3*> try_boosts;
389 try_boosts.push_back(&GetParentBoostVector());
392 for(
int i = 0; i < Nchild; i++){
394 try_boosts.push_back(&GetChildBoostVector(
GetChildFrame(i)));
397 int Ntry = try_frames.size();
398 for(
int i = 0; i < Ntry; i++){
399 const RestFrame* nextPtr = try_frames[i];
400 if(nextPtr->IsSame(prev_frame))
continue;
401 boosts.push_back(try_boosts[i]);
402 if(nextPtr->FindPathToFrame(dest_frame,*
this,boosts))
409 void RestFrame::SetFourVector(
const TLorentzVector& V,
410 const RestFrame& frame){
412 UnSoundBody(RF_FUNCTION);
418 m_ProdFramePtr = &frame;
431 UnSoundBody(RF_FUNCTION);
436 if(Nchild == 0)
return charge;
437 for(
int i = 0; i < Nchild; i++){
444 if(!IsSoundSpirit()){
445 UnSoundSpirit(RF_FUNCTION);
452 if(!IsSoundSpirit()){
453 UnSoundSpirit(RF_FUNCTION);
454 return m_Empty4Vector;
462 m_Log <<
"Unable to get four vector. ";
463 m_Log <<
"Production frame is not defined." << LogEnd;
464 return m_Empty4Vector;
467 TLorentzVector V = m_P;
469 return m_Empty4Vector;
472 std::vector<const TVector3*> boosts;
476 m_Log <<
"Unable to get four vector. ";
477 m_Log <<
"Cannot find a path to frame " << frame.
GetName();
479 return m_Empty4Vector;
482 int Nboost = boosts.size();
483 for(
int i = 0; i < Nboost; i++){
484 if(boosts[i]->Mag() < 1.)
485 V.Boost(-1.*(*boosts[i]));
491 if(!IsSoundSpirit()){
492 UnSoundSpirit(RF_FUNCTION);
493 return m_Empty4Vector;
498 return m_Empty4Vector;
506 TLorentzVector V(0.,0.,0.,0.);
508 for(
int c = 0; c < Nc; c++){
510 int Nf = frames.GetN();
511 for(
int f = 0; f < Nf; f++)
518 if(!IsSoundSpirit()){
519 UnSoundSpirit(RF_FUNCTION);
520 return m_Empty4Vector;
525 return m_Empty4Vector;
533 TLorentzVector V(0.,0.,0.,0.);
535 for(
int c = 0; c < Nc; c++){
537 int Nf = frames.GetN();
538 for(
int f = 0; f < Nf; f++)
545 if(!IsSoundSpirit()){
546 UnSoundSpirit(RF_FUNCTION);
553 if(!IsSoundSpirit()){
554 UnSoundSpirit(RF_FUNCTION);
561 const TVector3& axis,
563 if(!IsSoundSpirit()){
564 UnSoundSpirit(RF_FUNCTION);
568 if(frame == axis_frame){
570 return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
575 TLorentzVector Pframe;
578 Pframe.SetVectM(-Pframe.Vect(),Pframe.M());
583 TVector3 boost_par = Pframe.BoostVector();
585 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
586 Pthis.Boost(-boost_par);
587 Pframe.Boost(-boost_par);
588 TVector3 boost_perp = Pframe.BoostVector();
589 Pthis.Boost(-boost_perp);
591 TVector3 V = Pthis.Vect();
592 return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
597 if(!IsSoundSpirit()){
598 UnSoundSpirit(RF_FUNCTION);
599 return m_Empty4Vector;
605 TLorentzVector Pret = P;
607 std::vector<const TVector3*> boosts;
612 m_Log <<
"Unable to get four vector. ";
613 m_Log <<
"Cannot find a path to frame " <<
GetName();
615 return m_Empty4Vector;
621 m_Log <<
"Unable to get four vector. ";
622 m_Log <<
"Cannot find a path to frame " <<
GetName();
624 return m_Empty4Vector;
627 int Nboost = boosts.size();
628 for(
int i = 0; i < Nboost; i++)
629 Pret.Boost(-1.*(*boosts[i]));
634 const TVector3& axis,
636 if(!IsSoundSpirit()){
637 UnSoundSpirit(RF_FUNCTION);
638 return TLorentzVector();
641 if(frame == axis_frame){
643 TVector3 P = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
644 V.SetVectM(P, V.M());
650 TLorentzVector Pframe;
653 Pframe.SetVectM(-Pframe.Vect(),Pframe.M());
658 TVector3 boost_par = Pframe.BoostVector();
660 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
661 Pthis.Boost(-boost_par);
662 Pframe.Boost(-boost_par);
663 TVector3 boost_perp = Pframe.BoostVector();
664 Pthis.Boost(-boost_perp);
666 TLorentzVector V = Pthis;
667 TVector3 P = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
668 V.SetVectM(P, V.M());
674 const TVector3& axis,
676 if(!IsSoundSpirit()){
677 UnSoundSpirit(RF_FUNCTION);
678 return TLorentzVector();
682 TLorentzVector V = P;
683 TVector3 vP = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
684 V.SetVectM(vP, V.M());
688 TLorentzVector Pret = P;
692 std::vector<const TVector3*> boosts;
696 m_Log <<
"Unable to get four vector. ";
697 m_Log <<
"Cannot find a path to frame " << axis_frame.
GetName();
699 return TLorentzVector();
701 int Nboost = boosts.size();
702 for(
int i = 0; i < Nboost; i++)
703 Pret.Boost(-1.*(*boosts[i]));
706 if(*
this == axis_frame){
707 TVector3 vP = Pret.Vect() - Pret.Vect().Dot(axis.Unit())*axis.Unit();
708 Pret.SetVectM(vP, Pret.M());
712 TLorentzVector Pthis;
715 Pthis.SetVectM(-Pthis.Vect(),Pthis.M());
720 TVector3 boost_par = Pthis.BoostVector();
722 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
723 Pret.Boost(-boost_par);
724 Pthis.Boost(-boost_par);
725 TVector3 boost_perp = Pthis.BoostVector();
726 Pret.Boost(-boost_perp);
728 TVector3 vP = Pret.Vect() - Pret.Vect().Dot(axis.Unit())*axis.Unit();
729 Pret.SetVectM(vP, Pret.M());
734 const TVector3& axis,
736 if(!IsSoundSpirit()){
737 UnSoundSpirit(RF_FUNCTION);
742 TVector3 V = P.Vect();
743 return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
746 TLorentzVector Pret = P;
750 std::vector<const TVector3*> boosts;
754 m_Log <<
"Unable to get four vector. ";
755 m_Log <<
"Cannot find a path to frame " << axis_frame.
GetName();
759 int Nboost = boosts.size();
760 for(
int i = 0; i < Nboost; i++)
761 Pret.Boost(-1.*(*boosts[i]));
764 if(*
this == axis_frame){
765 TVector3 V = Pret.Vect();
766 return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
769 TLorentzVector Pthis;
772 Pthis.SetVectM(-Pthis.Vect(),Pthis.M());
777 TVector3 boost_par = Pthis.BoostVector();
779 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
780 Pret.Boost(-boost_par);
781 Pthis.Boost(-boost_par);
782 TVector3 boost_perp = Pthis.BoostVector();
783 Pret.Boost(-boost_perp);
785 TVector3 V = Pret.Vect();
786 return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
791 if(!IsSoundSpirit()){
792 UnSoundSpirit(RF_FUNCTION);
796 if(!frame)
return -1;
797 if(
IsSame(frame))
return 0.;
799 for(
int i = 0; i < Nchild; i++){
801 if(depth >= 0)
return depth+1;
807 if(!IsSoundSpirit()){
808 UnSoundSpirit(RF_FUNCTION);
812 if(!frame || depth < 1)
816 for(
int i = 0; i < N; i++){
819 if(depth == 1)
return child;
827 if(!IsSoundSpirit()){
828 UnSoundSpirit(RF_FUNCTION);
834 for(
int i = 0; i < N; i++)
836 for(
int i = 0; i < N-1; i++){
838 for(
int j = i+1; j < N; j++){
840 Xsum += (P1.Mag()+P2.Mag())*(P1.Mag()+P2.Mag())-(P1-P2).Mag2();
844 return sqrt(Xsum)/Psum;
850 if(!IsSoundSpirit()){
851 UnSoundSpirit(RF_FUNCTION);
857 for(
int i = 0; i < N; i++)
864 if(!IsSoundSpirit()){
865 UnSoundSpirit(RF_FUNCTION);
871 for(
int i = 0; i < N; i++)
878 if(!IsSoundSpirit()){
879 UnSoundSpirit(RF_FUNCTION);
884 return *m_ProdFramePtr;
890 TVector3 V(0.,0.,0.);
892 if(!IsSoundSpirit()){
893 UnSoundSpirit(RF_FUNCTION);
898 return -1.*GetParentBoostVector();
902 if(!IsSoundSpirit()){
903 UnSoundSpirit(RF_FUNCTION);
908 double beta = std::min(1.,vbeta.Mag());
909 return 1./sqrt(1.-beta*beta);
913 if(!IsSoundSpirit()){
914 UnSoundSpirit(RF_FUNCTION);
918 TVector3 V1 = GetParentBoostVector().Unit();
936 if(!IsSoundSpirit()){
937 UnSoundSpirit(RF_FUNCTION);
959 TVector3 ret = V1.Cross(V2);
963 std::vector<TVector3> tries;
964 tries.push_back(TVector3(1.,0.,0.));
965 tries.push_back(TVector3(0.,1.,0.));
966 tries.push_back(TVector3(0.,0.,1.));
967 for(
int i = 0; i < 3; i++){
978 if(!IsSoundSpirit()){
979 UnSoundSpirit(RF_FUNCTION);
983 if(!frame)
return 0.;
988 double dphi = vNorm_this.Angle(vNorm_frame);
990 if(frame.
GetFourVector(*this).Vect().Cross(vNorm_frame).Dot(vNorm_this) < 0.){
991 dphi = TMath::Pi()*2. - dphi;
998 if(!IsSoundSpirit()){
999 UnSoundSpirit(RF_FUNCTION);
1009 TVector3 boost_par = Pthis.BoostVector();
1010 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
1011 Pthis.Boost(-boost_par);
1012 Pchild.Boost(-boost_par);
1013 TVector3 boost_perp = Pthis.BoostVector();
1014 Pchild.Boost(-boost_perp);
1016 TVector3 V1 = boost_perp;
1017 TVector3 V2 = Pchild.Vect();
1018 V1 = V1 - V1.Dot(axis.Unit())*axis.Unit();
1019 V2 = V2 - V2.Dot(axis.Unit())*axis.Unit();
1020 return V1.Angle(V2);
1027 if(!IsSoundSpirit()){
1028 UnSoundSpirit(RF_FUNCTION);
1035 TVector3 boost_par = Pthis.BoostVector();
1036 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
1037 Pthis.Boost(-boost_par);
1038 Pvis.Boost(-boost_par);
1039 TVector3 boost_perp = Pthis.BoostVector();
1040 Pvis.Boost(-boost_perp);
1042 TVector3 V = Pvis.Vect();
1043 V = V - V.Dot(axis.Unit())*axis.Unit();
1045 return V.Angle(boost_perp);
1053 if(!IsSoundSpirit()){
1054 UnSoundSpirit(RF_FUNCTION);
1064 TVector3 boost_par = Pthis.BoostVector();
1065 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
1066 Pthis.Boost(-boost_par);
1067 Pvis.Boost(-boost_par);
1068 Pchild.Boost(-boost_par);
1069 TVector3 boost_perp = Pthis.BoostVector();
1070 Pvis.Boost(-boost_perp);
1071 Pchild.Boost(-boost_perp);
1073 TVector3 Vv = Pvis.Vect();
1074 Vv = Vv - Vv.Dot(axis.Unit())*axis.Unit();
1075 TVector3 Vc = Pchild.Vect();
1076 Vc = Vc - Vc.Dot(axis.Unit())*axis.Unit();
1078 return Vv.Angle(Vc);
1085 if(!IsSoundSpirit()){
1086 UnSoundSpirit(RF_FUNCTION);
1096 TVector3 boost_par = Pthis.BoostVector();
1097 boost_par = boost_par.Dot(axis.Unit())*axis.Unit();
1098 Pthis.Boost(-boost_par);
1099 P1.Boost(-boost_par);
1100 P2.Boost(-boost_par);
1101 TVector3 boost_perp = Pthis.BoostVector();
1102 P1.Boost(-boost_perp);
1103 P2.Boost(-boost_perp);
1105 TVector3 V1 = P1.Vect();
1106 TVector3 V2 = P2.Vect();
1107 V1 = V1 - V1.Dot(axis.Unit())*axis.Unit();
1108 V2 = V2 - V2.Dot(axis.Unit())*axis.Unit();
1110 return V1.Angle(V2);