LOGO

RestFrames  v1.0.1
RestFrames HEP Event Analysis Software Library
RestFrame.cc
Go to the documentation of this file.
1 // RestFrames: particle physics event analysis library
3 // --------------------------------------------------------------------
4 // Copyright (c) 2014-2018, Christopher Rogan
14 // This file is part of RestFrames.
15 //
16 // RestFrames is free software; you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation; either version 2 of the License, or
19 // (at your option) any later version.
20 //
21 // RestFrames is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with RestFrames. If not, see <http://www.gnu.org/licenses/>.
29 
30 #include "RestFrames/RestFrame.hh"
32 
33 namespace RestFrames {
34 
35 
36  int RestFrame::m_class_key = 0;
37 
38 
40  m_Type = kVanillaFrame;
41  m_Log.SetSource("RestFrame "+GetName());
42  }
43 
44  RestFrame::~RestFrame(){
45  Clear();
46  }
47 
48  RestFrame::RestFrame(const std::string& sname, const std::string& stitle)
49  : RFBase(sname, stitle, RestFrame::m_class_key++)
50  {
51  m_Log.SetSource("RestFrame "+GetName());
52  m_Type = kVanillaFrame;
53  m_ParentFramePtr = nullptr;
54  m_ParentBoost.SetXYZ(0.,0.,0.);
55  }
56 
60  }
61 
64  }
65 
67  return m_EmptyList;
68  }
69 
70  TVector3 RestFrame::m_Axis = TVector3(0.,0.,1.);
71 
72  void RestFrame::SetAxis(const TVector3& axis){
73  RestFrame::m_Axis = axis;
74  }
75 
76  TVector3 const& RestFrame::GetAxis(){
77  return RestFrame::m_Axis;
78  }
79 
81  RestFrameList list;
82  list.Add(frame);
83  list.Add(*this);
84  return list;
85  }
86 
88  RestFrameList list = frames;
89  list.Add(*this);
90  return list;
91  }
92 
94  return m_Type;
95  }
96 
97  bool RestFrame::IsVisibleFrame() const {
98  return m_Type == kVisibleFrame;
99  }
100 
102  return m_Type == kInvisibleFrame;
103  }
104 
105  bool RestFrame::IsDecayFrame() const {
106  return m_Type == kDecayFrame;
107  }
108 
109  bool RestFrame::IsLabFrame() const {
110  return m_Type == kLabFrame;
111  }
112 
113  bool RestFrame::IsRecoFrame() const {
114  return m_Ana == kRecoFrame;
115  }
116 
117  bool RestFrame::IsGenFrame() const {
118  return m_Ana == kGenFrame;
119  }
120 
121  std::string RestFrame::PrintString(LogType type) const {
122  std::string output = RFBase::PrintString(type);
123  if(IsLabFrame())
124  output += " Frame Type: Lab \n";
125  if(IsDecayFrame())
126  output += " Frame Type: Decay \n";
127  if(IsVisibleFrame())
128  output += " Frame Type: Visible \n";
129  if(IsInvisibleFrame())
130  output += " Frame Type: Invisible \n";
131  if(IsGenFrame())
132  output += " Ana Type: Generator \n";
133  if(IsRecoFrame())
134  output += " Ana Type: Reconstruction \n";
135  return output;
136  }
137 
138  bool RestFrame::IsSoundBody() const {
139  if(RFBase::IsSoundBody()) return true;
140  int Nchild = GetNChildren();
141  for(int i = 0; i < Nchild; i++)
142  if(!GetChildFrame(i)){
143  m_Log << LogWarning << "Empty child frame:";
144  m_Log << Log(GetChildFrame(i)) << LogEnd;
145  return SetBody(false);
146  }
147  return SetBody(true);
148  }
149 
151  if(!IsSoundBody()) return false;
152  int Nchild = GetNChildren();
153  for(int i = 0; i < Nchild; i++){
155  m_Log << LogWarning;
156  m_Log << "Problem with recursive tree structure from frame: ";
157  m_Log << Log(GetChildFrame(i)) << LogEnd;
158  return SetBody(false);
159  }
160  }
161  return true;
162  }
163 
165  SetBody(false);
166  bool contains = m_ChildFrames.Contains(frame);
167  m_ChildBoosts.erase(&frame);
168  m_ChildFrames.Remove(frame);
169  if(contains)
170  frame.SetParentFrame();
171  }
172 
174  SetBody(false);
175  while(GetNChildren() > 0)
176  RemoveChildFrame(m_ChildFrames[0]);
177  m_ChildFrames.Clear();
178  m_ChildBoosts.clear();
179  }
180 
182  if(IsEmpty()) return;
183 
184  SetBody(false);
185 
186  RestFrame* prevPtr = m_ParentFramePtr;
187  if(m_ParentFramePtr)
188  if(*m_ParentFramePtr != frame){
189  m_ParentFramePtr = nullptr;
190  prevPtr->RemoveChildFrame(*this);
191  }
192  if(!frame)
193  m_ParentFramePtr = nullptr;
194  else
195  m_ParentFramePtr = &frame;
196  }
197 
199  if(IsEmpty()) return;
200 
201  SetBody(false);
202 
203  if(!frame){
204  m_Log << LogWarning;
205  m_Log << "Cannot add empty frame as child.";
206  m_Log << LogEnd;
207  return;
208  }
209  if(frame.IsLabFrame()){
210  m_Log << LogWarning;
211  m_Log << "Cannot add LabFrame frame as child:";
212  m_Log << Log(frame) << LogEnd;
213  return;
214  }
215  if(!m_ChildFrames.Add(frame)){
216  m_Log << LogWarning;
217  m_Log << "Unable to add child frame:";
218  m_Log << Log(frame) << LogEnd;
219  return;
220  }
221  frame.SetParentFrame(*this);
222  m_ChildBoosts[&frame] = m_Empty3Vector;
223  }
224 
226  int N = frames.GetN();
227  for(int i = 0; i < N; i++)
228  AddChildFrame(frames[i]);
229  }
230 
231  int RestFrame::GetNChildren() const {
232  return m_ChildFrames.GetN();
233  }
234 
236  int Nchild = GetNChildren();
237  if(i >= Nchild || i < 0){
238  m_Log << LogWarning;
239  m_Log << "Cannot GetChildFrame(" << i << "). ";
240  m_Log << "No " << i << "th child" << LogEnd;
241  }
242  return m_ChildFrames[i];
243  }
244 
246  if(m_ParentFramePtr)
247  return *m_ParentFramePtr;
248  else
249  return RestFrame::Empty();
250  }
251 
253  return m_ChildFrames;
254  }
255 
257  if(IsLabFrame())
258  return *this;
259 
260  if(!GetParentFrame()){
261  m_Log << LogWarning;
262  m_Log << "Unable to find LabFrame above this frame. ";
263  m_Log << "No parent frame set" << LogEnd;
264  return RestFrame::Empty();
265  }
266  return m_ParentFramePtr->GetLabFrame();
267  }
268 
270  if(!IsSoundBody())
271  return RestFrame::Empty();
272 
273  if(IsLabFrame())
274  return RestFrame::Empty();
275 
276  if(!GetParentFrame())
277  return RestFrame::Empty();
278 
279  int Nsib = GetParentFrame().GetNChildren();
280  for(int s = 0; s < Nsib; s++){
281  if(IsSame(m_ParentFramePtr->GetChildFrame(s)))
282  continue;
283  return m_ParentFramePtr->GetChildFrame(s);
284  }
285  return RestFrame::Empty();
286  }
287 
289  if(!IsSoundBody()) return 0.;
290 
291  int Nchild = GetNChildren();
292  if(Nchild == 0) return 1;
293  int Nd = 0;
294  for(int i = 0; i < Nchild; i++){
295  Nd += GetChildFrame(i).GetNDescendants();
296  }
297  return Nd;
298  }
299 
300  void RestFrame::SetChildBoostVector(RestFrame& frame, const TVector3& boost) {
301  if(!m_ChildFrames.Contains(frame)){
302  m_Log << LogWarning;
303  m_Log << "Unable to set child's boost vector. ";
304  m_Log << "Frame is not among children:";
305  m_Log << Log(frame) << LogEnd;
306  return;
307  }
308  m_ChildBoosts[&frame] = boost;
309  frame.SetParentBoostVector(-1.*boost);
310  }
311 
312  void RestFrame::SetParentBoostVector(const TVector3& boost) {
313  if(!GetParentFrame()){
314  m_Log << LogWarning;
315  m_Log << "Unable to set parent boost vector. ";
316  m_Log << "No parent frame set.";
317  m_Log << LogEnd;
318  return;
319  }
320  m_ParentBoost = boost;
321  }
322 
323  TVector3 const& RestFrame::GetChildBoostVector(RestFrame& frame) const {
324  if(!m_ChildFrames.Contains(frame)){
325  m_Log << LogWarning;
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;
330  }
331  return m_ChildBoosts[&frame];
332  }
333 
334  TVector3 const& RestFrame::GetParentBoostVector() const {
335  return m_ParentBoost;
336  }
337 
339  RestFrameList frames;
340  FillListFramesRecursive(frames,type);
341  return frames;
342  }
343 
345  return GetListFrames(kVisibleFrame);
346  }
347 
349  return GetListFrames(kInvisibleFrame);
350  }
351 
352  void RestFrame::FillListFramesRecursive(RestFrameList& frames, FrameType type) const {
353  if(frames.Contains(*this)) return;
354  if(type == GetType() || type == kLabFrame) frames.Add((RestFrame&)(*m_This));
355  int Nchild = GetNChildren();
356  for(int i = 0; i < Nchild; i++)
357  GetChildFrame(i).FillListFramesRecursive(frames, type);
358  }
359 
360  bool RestFrame::IsCircularTree(std::vector<RFKey>& keys) const {
361  int Nkey = keys.size();
362  for(int i = 0; i < Nkey; i++){
363  if(keys[i] == GetKey()){
364  m_Log << LogWarning;
365  m_Log << "This RestFrame appears more than once in the tree:";
366  m_Log << Log(*this) << LogEnd;
367  return true;
368  }
369  }
370  keys.push_back(GetKey());
371  int Nchild = GetNChildren();
372  for(int i = 0; i < Nchild; i++)
373  if(GetChildFrame(i).IsCircularTree(keys))
374  return true;
375 
376  return false;
377  }
378 
379  bool RestFrame::FindPathToFrame(const RestFrame& dest_frame,
380  const RestFrame& prev_frame,
381  std::vector<const TVector3*>& boosts) const {
382  if(IsSame(dest_frame)) return true;
383 
384  std::vector<const RestFrame*> try_frames;
385  std::vector<const TVector3*> try_boosts;
386 
387  if(!GetParentFrame().IsEmpty()){
388  try_frames.push_back(&GetParentFrame());
389  try_boosts.push_back(&GetParentBoostVector());
390  }
391  int Nchild = GetNChildren();
392  for(int i = 0; i < Nchild; i++){
393  try_frames.push_back(&GetChildFrame(i));
394  try_boosts.push_back(&GetChildBoostVector(GetChildFrame(i)));
395  }
396 
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))
403  return true;
404  boosts.pop_back();
405  }
406  return false;
407  }
408 
409  void RestFrame::SetFourVector(const TLorentzVector& V,
410  const RestFrame& frame){
411  if(!IsSoundBody()){
412  UnSoundBody(RF_FUNCTION);
413  return;
414  }
415  if(!frame)
416  m_ProdFramePtr = &GetLabFrame();
417  else
418  m_ProdFramePtr = &frame;
419 
420  m_P = V;
421  }
422 
424  // User Analysis functions
426 
428  RFCharge charge;
429 
430  if(!IsSoundBody()){
431  UnSoundBody(RF_FUNCTION);
432  return charge;
433  }
434 
435  int Nchild = GetNChildren();
436  if(Nchild == 0) return charge;
437  for(int i = 0; i < Nchild; i++){
438  charge += GetChildFrame(i).GetCharge();
439  }
440  return charge;
441  }
442 
443  double RestFrame::GetMass() const {
444  if(!IsSoundSpirit()){
445  UnSoundSpirit(RF_FUNCTION);
446  return 0.;
447  }
448  return m_P.M();
449  }
450 
451  TLorentzVector RestFrame::GetFourVector(const RestFrame& frame) const {
452  if(!IsSoundSpirit()){
453  UnSoundSpirit(RF_FUNCTION);
454  return m_Empty4Vector;
455  }
456 
457  if(!frame)
458  return GetFourVector(GetLabFrame());
459 
460  if(!GetProductionFrame()){
461  m_Log << LogWarning;
462  m_Log << "Unable to get four vector. ";
463  m_Log << "Production frame is not defined." << LogEnd;
464  return m_Empty4Vector;
465  }
466 
467  TLorentzVector V = m_P;
468  if(V.E() <= 1e-8)
469  return m_Empty4Vector;
470  if(frame == GetProductionFrame()) return V;
471 
472  std::vector<const TVector3*> boosts;
473  if(!GetProductionFrame().
474  FindPathToFrame(frame, RestFrame::Empty(), boosts)){
475  m_Log << LogWarning;
476  m_Log << "Unable to get four vector. ";
477  m_Log << "Cannot find a path to frame " << frame.GetName();
478  m_Log << " from frame " << GetProductionFrame().GetName() << LogEnd;
479  return m_Empty4Vector;
480  }
481 
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]));
486  }
487  return V;
488  }
489 
490  TLorentzVector RestFrame::GetVisibleFourVector(const RestFrame& frame) const {
491  if(!IsSoundSpirit()){
492  UnSoundSpirit(RF_FUNCTION);
493  return m_Empty4Vector;
494  }
495 
496  if(!frame){
497  if(!GetLabFrame())
498  return m_Empty4Vector;
499  else
501  }
502 
503  if(IsVisibleFrame())
504  return GetFourVector(frame);
505 
506  TLorentzVector V(0.,0.,0.,0.);
507  int Nc = GetNChildren();
508  for(int c = 0; c < Nc; c++){
510  int Nf = frames.GetN();
511  for(int f = 0; f < Nf; f++)
512  V += frames[f].GetFourVector(frame);
513  }
514  return V;
515  }
516 
517  TLorentzVector RestFrame::GetInvisibleFourVector(const RestFrame& frame) const {
518  if(!IsSoundSpirit()){
519  UnSoundSpirit(RF_FUNCTION);
520  return m_Empty4Vector;
521  }
522 
523  if(!frame){
524  if(!GetLabFrame())
525  return m_Empty4Vector;
526  else
528  }
529 
530  if(IsInvisibleFrame())
531  return GetFourVector(frame);
532 
533  TLorentzVector V(0.,0.,0.,0.);
534  int Nc = GetNChildren();
535  for(int c = 0; c < Nc; c++){
537  int Nf = frames.GetN();
538  for(int f = 0; f < Nf; f++)
539  V += frames[f].GetFourVector(frame);
540  }
541  return V;
542  }
543 
544  double RestFrame::GetEnergy(const RestFrame& frame) const {
545  if(!IsSoundSpirit()){
546  UnSoundSpirit(RF_FUNCTION);
547  return 0.;
548  }
549  return GetFourVector(frame).E();
550  }
551 
552  double RestFrame::GetMomentum(const RestFrame& frame) const {
553  if(!IsSoundSpirit()){
554  UnSoundSpirit(RF_FUNCTION);
555  return 0.;
556  }
557  return GetFourVector(frame).P();
558  }
559 
561  const TVector3& axis,
562  const RestFrame& axis_frame) const {
563  if(!IsSoundSpirit()){
564  UnSoundSpirit(RF_FUNCTION);
565  return 0.;
566  }
567 
568  if(frame == axis_frame){
569  TVector3 V = GetFourVector(frame).Vect();
570  return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
571  }
572 
573  TLorentzVector Pthis = GetFourVector(axis_frame);
574 
575  TLorentzVector Pframe;
576  if(!frame || frame.IsLabFrame()){
577  Pframe = axis_frame.GetFourVector(frame);
578  Pframe.SetVectM(-Pframe.Vect(),Pframe.M());
579  } else {
580  Pframe = frame.GetFourVector(axis_frame);
581  }
582 
583  TVector3 boost_par = Pframe.BoostVector();
584 
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);
590 
591  TVector3 V = Pthis.Vect();
592  return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
593  }
594 
595  TLorentzVector RestFrame::GetFourVector(const TLorentzVector& P,
596  const RestFrame& def_frame) const {
597  if(!IsSoundSpirit()){
598  UnSoundSpirit(RF_FUNCTION);
599  return m_Empty4Vector;
600  }
601 
602  if(IsSame(def_frame) || (!def_frame && IsLabFrame()))
603  return P;
604 
605  TLorentzVector Pret = P;
606 
607  std::vector<const TVector3*> boosts;
608  if(!def_frame){
609  if(!GetLabFrame().
610  FindPathToFrame(*this, RestFrame::Empty(), boosts)){
611  m_Log << LogWarning;
612  m_Log << "Unable to get four vector. ";
613  m_Log << "Cannot find a path to frame " << GetName();
614  m_Log << " from frame " << GetLabFrame().GetName() << LogEnd;
615  return m_Empty4Vector;
616  }
617  } else {
618  if(!def_frame.
619  FindPathToFrame(*this, RestFrame::Empty(), boosts)){
620  m_Log << LogWarning;
621  m_Log << "Unable to get four vector. ";
622  m_Log << "Cannot find a path to frame " << GetName();
623  m_Log << " from frame " << GetLabFrame().GetName() << LogEnd;
624  return m_Empty4Vector;
625  }
626  }
627  int Nboost = boosts.size();
628  for(int i = 0; i < Nboost; i++)
629  Pret.Boost(-1.*(*boosts[i]));
630  return Pret;
631  }
632 
633  TLorentzVector RestFrame::GetTransverseFourVector(const RestFrame& frame,
634  const TVector3& axis,
635  const RestFrame& axis_frame) const {
636  if(!IsSoundSpirit()){
637  UnSoundSpirit(RF_FUNCTION);
638  return TLorentzVector();
639  }
640 
641  if(frame == axis_frame){
642  TLorentzVector V = GetFourVector(frame);
643  TVector3 P = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
644  V.SetVectM(P, V.M());
645  return V;
646  }
647 
648  TLorentzVector Pthis = GetFourVector(axis_frame);
649 
650  TLorentzVector Pframe;
651  if(!frame || frame.IsLabFrame()){
652  Pframe = axis_frame.GetFourVector(frame);
653  Pframe.SetVectM(-Pframe.Vect(),Pframe.M());
654  } else {
655  Pframe = frame.GetFourVector(axis_frame);
656  }
657 
658  TVector3 boost_par = Pframe.BoostVector();
659 
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);
665 
666  TLorentzVector V = Pthis;
667  TVector3 P = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
668  V.SetVectM(P, V.M());
669  return V;
670 
671  }
672 
673  TLorentzVector RestFrame::GetTransverseFourVector(const TLorentzVector& P,
674  const TVector3& axis,
675  const RestFrame& axis_frame) const {
676  if(!IsSoundSpirit()){
677  UnSoundSpirit(RF_FUNCTION);
678  return TLorentzVector();
679  }
680 
681  if(IsLabFrame() && (!axis_frame || axis_frame.IsLabFrame())){
682  TLorentzVector V = P;
683  TVector3 vP = V.Vect() - V.Vect().Dot(axis.Unit())*axis.Unit();
684  V.SetVectM(vP, V.M());
685  return V;
686  }
687 
688  TLorentzVector Pret = P;
689 
690  // move P to axis_frame
691  if(!axis_frame.IsLabFrame() && !axis_frame.IsEmpty()){
692  std::vector<const TVector3*> boosts;
693  if(!GetLabFrame().
694  FindPathToFrame(axis_frame, RestFrame::Empty(), boosts)){
695  m_Log << LogWarning;
696  m_Log << "Unable to get four vector. ";
697  m_Log << "Cannot find a path to frame " << axis_frame.GetName();
698  m_Log << " from frame " << GetLabFrame().GetName() << LogEnd;
699  return TLorentzVector();
700  }
701  int Nboost = boosts.size();
702  for(int i = 0; i < Nboost; i++)
703  Pret.Boost(-1.*(*boosts[i]));
704  }
705 
706  if(*this == axis_frame){
707  TVector3 vP = Pret.Vect() - Pret.Vect().Dot(axis.Unit())*axis.Unit();
708  Pret.SetVectM(vP, Pret.M());
709  return Pret;
710  }
711 
712  TLorentzVector Pthis;
713  if(IsLabFrame()){
714  Pthis = axis_frame.GetFourVector();
715  Pthis.SetVectM(-Pthis.Vect(),Pthis.M());
716  } else {
717  Pthis = GetFourVector(axis_frame);
718  }
719 
720  TVector3 boost_par = Pthis.BoostVector();
721 
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);
727 
728  TVector3 vP = Pret.Vect() - Pret.Vect().Dot(axis.Unit())*axis.Unit();
729  Pret.SetVectM(vP, Pret.M());
730  return Pret;
731  }
732 
733  double RestFrame::GetTransverseMomentum(const TLorentzVector& P,
734  const TVector3& axis,
735  const RestFrame& axis_frame) const {
736  if(!IsSoundSpirit()){
737  UnSoundSpirit(RF_FUNCTION);
738  return 0.;
739  }
740 
741  if(IsLabFrame() && (!axis_frame || axis_frame.IsLabFrame())){
742  TVector3 V = P.Vect();
743  return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
744  }
745 
746  TLorentzVector Pret = P;
747 
748  // move P to axis_frame
749  if(!axis_frame.IsLabFrame() && !axis_frame.IsEmpty()){
750  std::vector<const TVector3*> boosts;
751  if(!GetLabFrame().
752  FindPathToFrame(axis_frame, RestFrame::Empty(), boosts)){
753  m_Log << LogWarning;
754  m_Log << "Unable to get four vector. ";
755  m_Log << "Cannot find a path to frame " << axis_frame.GetName();
756  m_Log << " from frame " << GetLabFrame().GetName() << LogEnd;
757  return 0.;
758  }
759  int Nboost = boosts.size();
760  for(int i = 0; i < Nboost; i++)
761  Pret.Boost(-1.*(*boosts[i]));
762  }
763 
764  if(*this == axis_frame){
765  TVector3 V = Pret.Vect();
766  return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
767  }
768 
769  TLorentzVector Pthis;
770  if(IsLabFrame()){
771  Pthis = axis_frame.GetFourVector();
772  Pthis.SetVectM(-Pthis.Vect(),Pthis.M());
773  } else {
774  Pthis = GetFourVector(axis_frame);
775  }
776 
777  TVector3 boost_par = Pthis.BoostVector();
778 
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);
784 
785  TVector3 V = Pret.Vect();
786  return (V-V.Dot(axis.Unit())*axis.Unit()).Mag();
787  }
788 
789 
790  int RestFrame::GetFrameDepth(const RestFrame& frame) const {
791  if(!IsSoundSpirit()){
792  UnSoundSpirit(RF_FUNCTION);
793  return 0.;
794  }
795 
796  if(!frame) return -1;
797  if(IsSame(frame)) return 0.;
798  int Nchild = GetNChildren();
799  for(int i = 0; i < Nchild; i++){
800  int depth = GetChildFrame(i).GetFrameDepth(frame);
801  if(depth >= 0) return depth+1;
802  }
803  return -1;
804  }
805 
806  RestFrame const& RestFrame::GetFrameAtDepth(int depth, const RestFrame& frame) const {
807  if(!IsSoundSpirit()){
808  UnSoundSpirit(RF_FUNCTION);
809  return RestFrame::Empty();
810  }
811 
812  if(!frame || depth < 1)
813  return RestFrame::Empty();
814 
815  int N = GetNChildren();
816  for(int i = 0; i < N; i++){
817  RestFrame& child = GetChildFrame(i);
818  if(child.GetListFrames().Contains(frame)){
819  if(depth == 1) return child;
820  else return child.GetFrameAtDepth(depth-1,frame);
821  }
822  }
823  return RestFrame::Empty();
824  }
825 
826  double RestFrame::GetVisibleShape() const {
827  if(!IsSoundSpirit()){
828  UnSoundSpirit(RF_FUNCTION);
829  return 0.;
830  }
831  double Psum = 0.;
832  double Xsum = 0.;
833  int N = GetNChildren();
834  for(int i = 0; i < N; i++)
835  Psum += GetChildFrame(i).GetVisibleFourVector(*this).P();
836  for(int i = 0; i < N-1; i++){
837  TVector3 P1 = GetChildFrame(i).GetVisibleFourVector(*this).Vect();
838  for(int j = i+1; j < N; j++){
839  TVector3 P2 = GetChildFrame(j).GetVisibleFourVector(*this).Vect();
840  Xsum += (P1.Mag()+P2.Mag())*(P1.Mag()+P2.Mag())-(P1-P2).Mag2();
841  }
842  }
843  if(Psum > 0.)
844  return sqrt(Xsum)/Psum;
845  else
846  return 0.;
847  }
848 
850  if(!IsSoundSpirit()){
851  UnSoundSpirit(RF_FUNCTION);
852  return 0.;
853  }
854 
855  double ret = 0.;
856  int N = GetNChildren();
857  for(int i = 0; i < N; i++)
858  ret += GetChildFrame(i).GetVisibleFourVector(*this).P();
859 
860  return ret;
861  }
862 
864  if(!IsSoundSpirit()){
865  UnSoundSpirit(RF_FUNCTION);
866  return 0.;
867  }
868 
869  double ret = 0.;
870  int N = GetNChildren();
871  for(int i = 0; i < N; i++)
872  ret += GetChildFrame(i).GetVisibleFourVector(*this).P();
873 
874  return ret;
875  }
876 
878  if(!IsSoundSpirit()){
879  UnSoundSpirit(RF_FUNCTION);
880  return RestFrame::Empty();
881  }
882 
883  if(m_ProdFramePtr)
884  return *m_ProdFramePtr;
885  else
886  return RestFrame::Empty();
887  }
888 
890  TVector3 V(0.,0.,0.);
891 
892  if(!IsSoundSpirit()){
893  UnSoundSpirit(RF_FUNCTION);
894  return V;
895  }
896 
897  if(!GetParentFrame()) return V;
898  return -1.*GetParentBoostVector();
899  }
900 
902  if(!IsSoundSpirit()){
903  UnSoundSpirit(RF_FUNCTION);
904  return 0.;
905  }
906 
907  TVector3 vbeta = GetBoostInParentFrame();
908  double beta = std::min(1.,vbeta.Mag());
909  return 1./sqrt(1.-beta*beta);
910  }
911 
912  double RestFrame::GetCosDecayAngle(const RestFrame& frame) const {
913  if(!IsSoundSpirit()){
914  UnSoundSpirit(RF_FUNCTION);
915  return 0.;
916  }
917 
918  TVector3 V1 = GetParentBoostVector().Unit();
919  if(IsLabFrame())
920  V1 = RestFrame::GetAxis();
921  TVector3 V2;
922  if(!frame.IsEmpty())
923  V2 = frame.GetFourVector(*this).Vect().Unit();
924  else
925  if(GetNChildren() < 1)
926  return 0.;
927  else
928  V2 = GetChildFrame(0).GetFourVector(*this).Vect().Unit();
929 
930  return V1.Dot(V2);
931  }
932 
933  TVector3 RestFrame::GetDecayPlaneNormalVector(const RestFrame& frame) const {
934  TVector3 n = RestFrame::GetAxis();
935 
936  if(!IsSoundSpirit()){
937  UnSoundSpirit(RF_FUNCTION);
938  return n;
939  }
940 
941  if(!frame)
942  if(GetNChildren() < 1)
943  return n;
944 
945  TVector3 V1, V2;
946  if(!IsLabFrame()){
947  if(!frame)
948  V1 = GetChildFrame(0).GetFourVector(GetParentFrame()).Vect();
949  else
950  V1 = frame.GetFourVector(GetParentFrame()).Vect();
951  V2 = GetFourVector(GetParentFrame()).Vect();
952  } else {
953  if(!frame)
954  V1 = GetChildFrame(0).GetFourVector(*this).Vect().Unit();
955  else
956  V1 = frame.GetFourVector(*this).Vect().Unit();
957  V2 = n;
958  }
959  TVector3 ret = V1.Cross(V2);
960  if(ret.Mag() > 0)
961  return ret.Unit();
962 
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++){
968  V2 = tries[i];
969  ret = V1.Cross(V2);
970  if(ret.Mag() > 0)
971  return ret.Unit();
972  }
973 
974  return n;
975  }
976 
977  double RestFrame::GetDeltaPhiDecayPlanes(const RestFrame& frame) const {
978  if(!IsSoundSpirit()){
979  UnSoundSpirit(RF_FUNCTION);
980  return 0.;
981  }
982 
983  if(!frame) return 0.;
984  if(GetNChildren() < 1) return 0.;
985 
986  TVector3 vNorm_frame = frame.GetDecayPlaneNormalVector();
987  TVector3 vNorm_this = GetDecayPlaneNormalVector();
988  double dphi = vNorm_this.Angle(vNorm_frame);
989 
990  if(frame.GetFourVector(*this).Vect().Cross(vNorm_frame).Dot(vNorm_this) < 0.){
991  dphi = TMath::Pi()*2. - dphi;
992  }
993 
994  return dphi;
995  }
996 
997  double RestFrame::GetDeltaPhiDecayAngle(const TVector3& axis, const RestFrame& frame) const {
998  if(!IsSoundSpirit()){
999  UnSoundSpirit(RF_FUNCTION);
1000  return 0.;
1001  }
1002 
1003  if(IsLabFrame())
1004  return 0.;
1005 
1006  TLorentzVector Pthis = GetFourVector(frame);
1007  TLorentzVector Pchild = GetChildFrame(0).GetFourVector(frame);
1008 
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);
1015 
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);
1021  }
1022 
1023  // Get angle between 'this' boost and visible children in plane
1024  // perpendicular to 3-vector 'axis', where axis is defined
1025  // in 'framePtr' (default gives lab frame).
1026  double RestFrame::GetDeltaPhiBoostVisible(const TVector3& axis, const RestFrame& frame) const {
1027  if(!IsSoundSpirit()){
1028  UnSoundSpirit(RF_FUNCTION);
1029  return 0.;
1030  }
1031 
1032  TLorentzVector Pvis = GetVisibleFourVector(frame);
1033  TLorentzVector Pthis = GetFourVector(frame);
1034 
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);
1041 
1042  TVector3 V = Pvis.Vect();
1043  V = V - V.Dot(axis.Unit())*axis.Unit();
1044 
1045  return V.Angle(boost_perp);
1046  }
1047 
1048  // Get angle between 'this' decay axis (defined by first child)
1049  // and visible children in plane
1050  // perpendicular to 3-vector 'axis', where axis is defined
1051  // in 'framePtr' (default gives lab frame).
1052  double RestFrame::GetDeltaPhiDecayVisible(const TVector3& axis, const RestFrame& frame) const {
1053  if(!IsSoundSpirit()){
1054  UnSoundSpirit(RF_FUNCTION);
1055  return 0.;
1056  }
1057 
1058  if(GetNChildren() < 1) return 0.;
1059 
1060  TLorentzVector Pvis = GetVisibleFourVector(frame);
1061  TLorentzVector Pchild = GetChildFrame(0).GetFourVector(frame);
1062  TLorentzVector Pthis = GetFourVector(frame);
1063 
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);
1072 
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();
1077 
1078  return Vv.Angle(Vc);
1079  }
1080 
1081  // Get angle between the visible portions of children 1 and 2
1082  // in the plane perpendicular to 3-vector 'axis', where
1083  // axis is defined in 'framePtr' (default gives lab frame).
1084  double RestFrame::GetDeltaPhiVisible(const TVector3& axis, const RestFrame& frame) const {
1085  if(!IsSoundSpirit()){
1086  UnSoundSpirit(RF_FUNCTION);
1087  return 0.;
1088  }
1089 
1090  if(GetNChildren() != 2) return 0.;
1091 
1092  TLorentzVector Pthis = GetFourVector(frame);
1093  TLorentzVector P1 = GetChildFrame(0).GetVisibleFourVector(frame);
1094  TLorentzVector P2 = GetChildFrame(1).GetVisibleFourVector(frame);
1095 
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);
1104 
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();
1109 
1110  return V1.Angle(V2);
1111  }
1112 
1113  const ConstRestFrameList RestFrame::m_EmptyList;
1114 
1115 }
RestFrames::RestFrame::GetMomentum
double GetMomentum(const RestFrame &frame) const
Returns magnitude of momentum.
Definition: RestFrame.cc:552
RestFrames::RestFrame::GetLabFrame
virtual RestFrame const & GetLabFrame() const
Returns the LabFrame that this frame inherits from.
Definition: RestFrame.cc:256
RestFrames::RestFrame::GetVisibleShape
double GetVisibleShape() const
Returns visible shape of frame.
Definition: RestFrame.cc:826
RestFrames::RestFrame::SetParentFrame
virtual void SetParentFrame(RestFrame &frame=RestFrame::Empty())
Sets the parent frame for this frame.
Definition: RestFrame.cc:181
RestFrames::RestFrame::GetVisibleFourVector
TLorentzVector GetVisibleFourVector(const RestFrame &frame=RestFrame::Empty()) const
Returns four-vector of visible descendants.
Definition: RestFrame.cc:490
RestFrames::RestFrame::GetChildFrame
virtual RestFrame & GetChildFrame(int i=0) const
Get the RestFrame of the i th child.
Definition: RestFrame.cc:235
RestFrames::RestFrame::RemoveChildFrames
void RemoveChildFrames()
Removes all the children of this frame.
Definition: RestFrame.cc:173
RestFrames::RestFrame::GetListInvisibleFrames
virtual RestFrameList GetListInvisibleFrames() const
Returns a list of InvisibleFrame s inheriting from this.
Definition: RestFrame.cc:348
RestFrames::RestFrame::GetNDescendants
int GetNDescendants() const
Returns the number of descendents of this frame.
Definition: RestFrame.cc:288
RestFrames::RestFrame::InitializeTreeRecursive
virtual bool InitializeTreeRecursive()
Recursively initialize this frame's tree.
Definition: RestFrame.cc:150
RestFrames::RestFrame::GetType
FrameType GetType() const
Returns RestFrame (FrameType) type.
Definition: RestFrame.cc:93
RestFrames::RFCharge
Definition: RFCharge.hh:40
RestFrames::RestFrame::GetDecayPlaneNormalVector
TVector3 GetDecayPlaneNormalVector(const RestFrame &frame=RestFrame::Empty()) const
Returns the vector normal to the decay plane of this frame.
Definition: RestFrame.cc:933
ReconstructionFrame.hh
RestFrames::RestFrame::GetTransverseMomentum
double GetTransverseMomentum(const RestFrame &frame=RestFrame::Empty(), const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &axis_frame=RestFrame::Empty()) const
Returns magnitude of transverse momentum.
Definition: RestFrame.cc:560
RestFrames::RestFrame::GetDeltaPhiVisible
double GetDeltaPhiVisible(const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &frame=RestFrame::Empty()) const
Returns difference of azimuthal angles between the angles of its visible particles kids.
Definition: RestFrame.cc:1084
RestFrames::RestFrame::GetDeltaPhiDecayVisible
double GetDeltaPhiDecayVisible(const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &frame=RestFrame::Empty()) const
Returns difference of azimuthal angles between the decay angles of the visible particles decaying fro...
Definition: RestFrame.cc:1052
RestFrames::RestFrame::IsRecoFrame
bool IsRecoFrame() const
Is this an ReconstructionFrame ? (yes/no)
Definition: RestFrame.cc:113
RestFrames::RestFrame::IsDecayFrame
bool IsDecayFrame() const
Is this a DecayFrame ? (yes/no)
Definition: RestFrame.cc:105
RestFrames::RestFrame
abstract base class for all Frame objects
Definition: RestFrame.hh:45
RestFrames::RestFrame::AddChildFrame
virtual void AddChildFrame(RestFrame &frame)
Adds a child RestFrame to this frame.
Definition: RestFrame.cc:198
RestFrames::RFBase::IsEmpty
bool IsEmpty() const
Checks whether this is default (empty) instance of class.
Definition: RFBase.cc:84
RestFrames::RestFrame::GetFourVector
TLorentzVector GetFourVector(const RestFrame &frame=RestFrame::Empty()) const
Returns this frame's four-vector in a specified frame.
Definition: RestFrame.cc:451
RestFrames::RestFrame::IsGenFrame
bool IsGenFrame() const
Is this a GeneratorFrame ? (yes/no)
Definition: RestFrame.cc:117
RestFrames::RestFrame::GetCosDecayAngle
double GetCosDecayAngle(const RestFrame &frame=RestFrame::Empty()) const
Returns the cosine of this frame's decay angle.
Definition: RestFrame.cc:912
RestFrames::RFBase::IsSame
bool IsSame(const RFKey &key) const
Tests whether key is the same as this.
Definition: RFBase.cc:92
RestFrames::RFList< const RestFrame >
RestFrames::RestFrame::GetSumVisibleMomentum
double GetSumVisibleMomentum() const
Returns scalar sum of visible child momenta.
Definition: RestFrame.cc:849
RestFrames::RestFrame::SetAxis
static void SetAxis(const TVector3 &axis)
Set axis perpendicular to transverse plane.
Definition: RestFrame.cc:72
RestFrames::RFBase
Base class for all RestFrame package objects.
Definition: RFBase.hh:53
RestFrames::RestFrame::GetFrameAtDepth
virtual RestFrame const & GetFrameAtDepth(int depth, const RestFrame &frame) const
Returns the frame at depth.
Definition: RestFrame.cc:806
RestFrames::RestFrame::GetSumInvisibleMomentum
double GetSumInvisibleMomentum() const
Returns scalar sum of invisible child momenta.
Definition: RestFrame.cc:863
RestFrames::RestFrame::GetProductionFrame
virtual RestFrame const & GetProductionFrame() const
Returns the production frame of this frame.
Definition: RestFrame.cc:877
RestFrames::RFBase::GetKey
RFKey GetKey() const
gets object identification key
Definition: RFBase.cc:100
RestFrames::RestFrame::GetNChildren
int GetNChildren() const
Returns the number of child frames inheriting from this one.
Definition: RestFrame.cc:231
RestFrames::RestFrame::PrintString
virtual std::string PrintString(LogType type) const
String of information about RestFrame.
Definition: RestFrame.cc:121
RestFrames::RestFrame::AddChildFrames
void AddChildFrames(const RestFrameList &frames)
Adds a list of children to this frame.
Definition: RestFrame.cc:225
RestFrames::RestFrame::GetChildFrames
RestFrameList const & GetChildFrames() const
Returns a list of this frame's child RestFrames.
Definition: RestFrame.cc:252
RestFrames::RestFrame::IsCircularTree
bool IsCircularTree(std::vector< RFKey > &keys) const
Check this RestFrame 's tree for circular connections.
Definition: RestFrame.cc:360
RestFrames::LogType
LogType
Type of Log Message.
Definition: RFLog.hh:45
RestFrames::RFBase::GetName
std::string GetName() const
Returns object name.
Definition: RFBase.cc:104
RestFrames::RFLog::SetSource
void SetSource(const std::string &source)
Sets name of instance that is associated with.
Definition: RFLog.cc:182
RestFrames::RestFrame::GetParentFrame
virtual RestFrame const & GetParentFrame() const
Returns the parent of this frame.
Definition: RestFrame.cc:245
RestFrames::RestFrame::IsInvisibleFrame
bool IsInvisibleFrame() const
Is this an InvisibleFrame ? (yes/no)
Definition: RestFrame.cc:101
RestFrames::RestFrame::GetTransverseFourVector
TLorentzVector GetTransverseFourVector(const RestFrame &frame=RestFrame::Empty(), const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &axis_frame=RestFrame::Empty()) const
Returns this frame's four-vector in a specified frame.
Definition: RestFrame.cc:633
RestFrames::RestFrame::GetCharge
virtual RFCharge GetCharge() const
Returns the charge of this frame.
Definition: RestFrame.cc:427
RestFrames::RestFrame::GetSiblingFrame
virtual RestFrame const & GetSiblingFrame() const
Returns the sibling frame of this frame.
Definition: RestFrame.cc:269
RestFrames::RestFrame::GetInvisibleFourVector
TLorentzVector GetInvisibleFourVector(const RestFrame &frame=RestFrame::Empty()) const
Returns four-vector of invisible descendants.
Definition: RestFrame.cc:517
RestFrames::RestFrame::Clear
virtual void Clear()
Clears RestFrame of all connections to other objects.
Definition: RestFrame.cc:57
RestFrames::RestFrame::GetListVisibleFrames
virtual RestFrameList GetListVisibleFrames() const
Returns a list of VisibleFrame s inheriting from this.
Definition: RestFrame.cc:344
RestFrames::RestFrame::GetMass
virtual double GetMass() const
Returns the mass of this frame.
Definition: RestFrame.cc:443
RestFrames::RestFrame::GetListFrames
virtual RestFrameList GetListFrames(FrameType type=kLabFrame) const
Returns a list of frames inheriting from this one.
Definition: RestFrame.cc:338
RestFrames::RestFrame::GetGammaInParentFrame
double GetGammaInParentFrame() const
Returns the gamma of this frame in its parent's frame.
Definition: RestFrame.cc:901
RestFrames::FrameType
FrameType
Type of RestFrame, with respect to its decays.
Definition: RestFrame.hh:39
RestFrames::RestFrame::IsVisibleFrame
bool IsVisibleFrame() const
Is this a VisibleFrame ? (yes/no)
Definition: RestFrame.cc:97
RestFrames::RestFrame::GetAxis
static TVector3 const & GetAxis()
Retrieve axis which defines transverse plane.
Definition: RestFrame.cc:76
RestFrames::RestFrame::RestFrame
RestFrame()
Empty constructor.
Definition: RestFrame.cc:39
RestFrames::RestFrame::EmptyList
static ConstRestFrameList const & EmptyList()
Returns empty RestFrameList.
Definition: RestFrame.cc:66
RestFrames::RestFrame::GetEnergy
double GetEnergy(const RestFrame &frame) const
Returns energy of this frame in specified reference frame.
Definition: RestFrame.cc:544
RestFrames::RestFrame::GetFrameDepth
int GetFrameDepth(const RestFrame &frame) const
Returns the depth of frame
Definition: RestFrame.cc:790
RestFrames::RestFrame::IsLabFrame
bool IsLabFrame() const
Is this a LabFrame ? (yes/no)
Definition: RestFrame.cc:109
RestFrames::RestFrame::Empty
static RestFrame & Empty()
Returns empty RestFrame.
Definition: RestFrame.cc:62
RestFrames::RestFrame::RemoveChildFrame
void RemoveChildFrame(RestFrame &frame)
Removes a child of this frame.
Definition: RestFrame.cc:164
RestFrames::ReconstructionFrame::Empty
static ReconstructionFrame & Empty()
Returns empty ReconstructionFrame.
Definition: ReconstructionFrame.cc:62
RestFrames::RestFrame::GetBoostInParentFrame
TVector3 GetBoostInParentFrame() const
Returns the boost of this frame in it's parent's frame.
Definition: RestFrame.cc:889
RestFrames::RestFrame::GetDeltaPhiDecayPlanes
double GetDeltaPhiDecayPlanes(const RestFrame &frame) const
Returns difference of azimuthal angle between decay planes.
Definition: RestFrame.cc:977
RestFrames::RestFrame::GetDeltaPhiDecayAngle
double GetDeltaPhiDecayAngle(const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &frame=RestFrame::Empty()) const
Returns difference of azimuthal decay angles in an axis.
Definition: RestFrame.cc:997
RestFrames::RestFrame::GetDeltaPhiBoostVisible
double GetDeltaPhiBoostVisible(const TVector3 &axis=RestFrame::GetAxis(), const RestFrame &frame=RestFrame::Empty()) const
Returns difference of azimuthal angles between the decay angles of the visible particles decaying fro...
Definition: RestFrame.cc:1026
RestFrames::RFBase::PrintString
virtual std::string PrintString(LogType type) const
String of information associated with object.
Definition: RFBase.cc:146
RestFrames::RestFrame::operator+
RestFrameList operator+(RestFrame &frame)
Combines RestFrames into RestFrameList.
Definition: RestFrame.cc:80
RestFrame.hh