LOGO

RestFrames  v1.0.1
RestFrames HEP Event Analysis Software Library
CombinatoricJigsaw.cc
Go to the documentation of this file.
1 // RestFrames: particle physics event analysis library
3 // --------------------------------------------------------------------
4 // Copyright (c) 2014-2016, 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 
32 
33 namespace RestFrames {
34 
35  CombinatoricJigsaw::CombinatoricJigsaw(const std::string& sname,
36  const std::string& stitle,
37  int Ncomb, int Nobject)
38  : Jigsaw(sname, stitle, Ncomb, Nobject),
39  m_Ncomb(Ncomb), m_Nobj(Nobject)
40  {
41  m_Type = kCombinatoricJigsaw;
42  for(int i = 0; i < m_Ncomb; i++){
43  m_ChildStates += GetNewChildState();
44  }
45  m_SetTransverse = false;
46  }
47 
49  : Jigsaw(), m_Ncomb(0), m_Nobj(0) {}
50 
51  CombinatoricJigsaw::~CombinatoricJigsaw() {}
52 
54  Jigsaw::Clear();
55  }
56 
59  }
60 
62  if(!group) return;
63  if(!group.IsCombinatoricGroup()) return;
64  Jigsaw::SetGroup(group);
65  }
66 
68  if(!Jigsaw::GetGroup())
69  return CombinatoricGroup::Empty();
70  else
71  return static_cast<CombinatoricGroup&>(Jigsaw::GetGroup());
72  }
73 
74  void CombinatoricJigsaw::SetParentState(State& state){
75  if(!state) return;
76  if(!state.IsCombinatoricState()) return;
77  Jigsaw::SetParentState(state);
78  }
79 
80  CombinatoricState const& CombinatoricJigsaw::GetParentState() const {
81  if(!Jigsaw::GetParentState())
82  return CombinatoricState::Empty();
83  else
84  return static_cast<const CombinatoricState&>(Jigsaw::GetParentState());
85  }
86 
87  CombinatoricState& CombinatoricJigsaw::GetChildState(int i) const {
88  if(!Jigsaw::GetChildState(i))
89  return CombinatoricState::Empty();
90  else
91  return static_cast<CombinatoricState&>(Jigsaw::GetChildState(i));
92  }
93 
94  void CombinatoricJigsaw::AddCombFrame(const RestFrame& frame, int i){
95  if(!frame) return;
96 
97  ConstRestFrameList frames =
98  frame.GetListVisibleFrames();
99  int N = frames.GetN();
100  for(int f = 0; f < N; f++)
101  AddChildFrame(frames[f], i);
102  }
103 
105  int N = frames.GetN();
106  for(int f = 0; f < N; f++)
107  AddCombFrame(frames[f], i);
108  }
109 
111  if(!frame) return;
112 
113  ConstRestFrameList frames =
114  frame.GetListVisibleFrames()+
115  frame.GetListInvisibleFrames();
116  int N = frames.GetN();
117  for(int f = 0; f < N; f++)
118  AddDependancyFrame(frames[f], i);
119  }
120 
122  int N = frames.GetN();
123  for(int f = 0; f < N; f++)
124  AddObjectFrame(frames[f], i);
125  }
126 
127  void CombinatoricJigsaw::SetCombCharge(const RFCharge& charge, int i){
128  if(i < 0 || i >= m_Ncomb)
129  return;
130 
131  m_ChargeForChild[i] = charge;
132  }
133 
134  void CombinatoricJigsaw::SetCombCharge(int charge, int i){
135  SetCombCharge(RFCharge(charge), i);
136  }
137 
138  void CombinatoricJigsaw::SetCombCharge(int charge_num, int charge_den, int i){
139  SetCombCharge(RFCharge(charge_num, charge_den), i);
140  }
141 
143  if(m_ChargeForChild.count(i) > 0)
144  m_ChargeForChild.erase(i);
145  }
146 
147  void CombinatoricJigsaw::SetObjectCharge(const RFCharge& charge, int i){
148  if(i < 0 || i >= m_Nobj)
149  return;
150 
151  m_ChargeForObject[i] = charge;
152  }
153 
154  void CombinatoricJigsaw::SetObjectCharge(int charge, int i){
155  SetObjectCharge(RFCharge(charge), i);
156  }
157 
158  void CombinatoricJigsaw::SetObjectCharge(int charge_num, int charge_den, int i){
159  SetObjectCharge(RFCharge(charge_num, charge_den), i);
160  }
161 
163  if(m_ChargeForObject.count(i) > 0)
164  m_ChargeForObject.erase(i);
165  }
166 
167  bool CombinatoricJigsaw::InitializeJigsawExecutionList(JigsawList& exec_jigsaws, JigsawList& todo_jigsaws){
168  if(!IsSoundMind()) return false;
169  if(exec_jigsaws.Contains(*this)) return true;
170 
171  m_ExecuteJigsaws.Clear();
172 
173  // Add group dependancy jigsaws first
174  JigsawList group_jigsaws;
175  FillGroupJigsawDependancies(group_jigsaws);
176  group_jigsaws -= *this;
177 
178  int Ngroup = group_jigsaws.GetN();
179  for(int i = Ngroup-1; i >= 0; i--){
180  Jigsaw& jigsaw = group_jigsaws[i];
181  if(!exec_jigsaws.Contains(jigsaw))
182  if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, todo_jigsaws))
183  return SetMind(false);
184  m_DependancyJigsaws -= jigsaw;
185  }
186 
187  // Satisfy dependancy jigsaws
188  while(m_DependancyJigsaws.GetN() > 0){
189  Jigsaw& jigsaw = m_DependancyJigsaws[m_DependancyJigsaws.GetN()-1];
190  if(exec_jigsaws.Contains(jigsaw)){
191  m_DependancyJigsaws -= jigsaw;
192  continue;
193  }
194  if(!jigsaw.DependsOnJigsaw(*this)){
195  if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, todo_jigsaws)){
196  return SetMind(false);
197  }
198  m_DependancyJigsaws -= jigsaw;
199  continue;
200  }
201 
202  JigsawList temp_todo_jigsaws = todo_jigsaws;
203  exec_jigsaws += *this;
204  exec_jigsaws += m_ExecuteJigsaws;
205  m_DependancyJigsaws -= jigsaw;
206  if(!jigsaw.InitializeJigsawExecutionList(exec_jigsaws, temp_todo_jigsaws))
207  return SetMind(false);
208  temp_todo_jigsaws -= todo_jigsaws;
209  exec_jigsaws -= *this;
210  m_DependancyJigsaws -= exec_jigsaws;
211  m_ExecuteJigsaws += temp_todo_jigsaws;
212  }
213 
214  exec_jigsaws += *this;
215  todo_jigsaws += *this;
216 
217  return true;
218  }
219 
220  CombinatoricState& CombinatoricJigsaw::GetNewChildState(){
221  char strn[10];
222  sprintf(strn,"%d",GetNChildren());
223  std::string name = GetName()+"_"+std::string(strn);
224  CombinatoricState* statePtr = new CombinatoricState(name, name);
225  AddDependent(statePtr);
226  return *statePtr;
227  }
228 
229  bool CombinatoricJigsaw::ExecuteDependancyJigsaws(){
230  int N = m_ExecuteJigsaws.GetN();
231  for(int i = 0; i < N; i++){
232  if(!m_ExecuteJigsaws[i].AnalyzeEvent())
233  return false;
234  }
235  return true;
236  }
237 
238  bool CombinatoricJigsaw::AnalyzeEvent(){
239  if(!IsSoundMind() || !GetGroup())
240  return SetSpirit(false);
241 
242  if(!InitializeCombinatoric()){
243  m_Log << LogWarning;
244  m_Log << "Problem initializing event info" << LogEnd;
245  return SetSpirit(false);
246  }
247 
248  if(!LoopCombinatoric()){
249  m_Log << LogWarning;
250  m_Log << "Problem looping over combinatorics" << LogEnd;
251  return SetSpirit(false);
252  }
253 
254  return SetSpirit(true);
255  }
256 
257  bool CombinatoricJigsaw::InitializeAnalysis(){
258  if(!Jigsaw::InitializeAnalysis())
259  return SetMind(false);
260 
261  CombinatoricGroup& group = GetGroup();
262 
263  m_NForChild.clear();
264  m_NExclusive.clear();
265 
266  m_NinputTOT = 0;
267  m_NExclusiveTOT = true;
268 
269  for(int i = 0; i < m_Ncomb; i++){
270  RestFrameList const& frames = GetChildState(i).GetListFrames();
271  int Nf = frames.GetN();
272  int NTOT = 0;
273  bool exclTOT = true;
274  for(int f = 0; f < Nf; f++){
275  int N = -1;
276  bool excl = false;
277  group.GetNElementsForFrame(frames[f], N, excl);
278  if(N < 0) return SetMind(false);
279  NTOT += N;
280  exclTOT = exclTOT && excl;
281  }
282  m_NForChild.push_back(NTOT);
283  m_NExclusive.push_back(exclTOT);
284  m_NinputTOT += NTOT;
285  m_NExclusiveTOT = m_NExclusiveTOT && exclTOT;
286  }
287 
288  return SetMind(true);
289  }
290 
291  bool CombinatoricJigsaw::InitializeCombinatoric(){
292  if(!IsSoundMind())
293  return SetSpirit(false);
294 
295  if(!GetGroup())
296  return SetSpirit(false);
297 
298  if(!GetParentState())
299  return SetSpirit(false);
300 
301  m_InputStates.Clear();
302  m_InputStates = GetParentState().GetElements();
303 
304  if(m_InputStates.GetN() < m_NinputTOT){
305  m_Log << LogWarning;
306  m_Log << "Unable to execute Jigsaw. ";
307  m_Log << "Insufficienct number of inputs: ";
308  m_Log << m_NinputTOT << " (required) != ";
309  m_Log << m_InputStates.GetN() << " (provided)";
310  m_Log << LogEnd;
311  return SetSpirit(false);
312  }
313 
314  if(m_NExclusiveTOT &&
315  (m_InputStates.GetN() != m_NinputTOT)){
316  m_Log << LogWarning;
317  m_Log << "Unable to execute Jigsaw. ";
318  m_Log << "Incorrect number of exclusive inputs: ";
319  m_Log << m_NinputTOT << " (required) != ";
320  m_Log << m_InputStates.GetN() << " (provided)";
321  m_Log << LogEnd;
322  return SetSpirit(false);
323  }
324 
325  return SetSpirit(true);
326  }
327 
328  void CombinatoricJigsaw::SetTransverse(bool tran, const TVector3& axis){
329  m_SetTransverse = tran;
330  if(tran)
331  m_TranAxis = axis.Unit();
332  }
333 
334  bool CombinatoricJigsaw::IsTransverse() const {
335  return m_SetTransverse;
336  }
337 
338  const TVector3& CombinatoricJigsaw::GetTransverseAxis() const {
339  return m_TranAxis;
340  }
341 
342  int CombinatoricJigsaw::GetNInputStates() const {
343  return m_InputStates.GetN();
344  }
345 
346  VisibleState& CombinatoricJigsaw::GetInputState(int i) const {
347  return m_InputStates[i];
348  }
349 
350  int CombinatoricJigsaw::GetNinputForChild(int i) const {
351  if(i < 0 || i >= m_Ncomb)
352  return 0;
353  return m_NForChild[i];
354  }
355 
356  bool CombinatoricJigsaw::IsNinputExclForChild(int i) const {
357  if(i < 0 || i >= m_Ncomb)
358  return false;
359  return m_NExclusive[i];
360  }
361 
362  bool CombinatoricJigsaw::IsChargeSetForChild(int i) const {
363  return !(m_ChargeForChild.count(i) == 0);
364  }
365 
366  RFCharge CombinatoricJigsaw::GetChargeForChild(int i) const {
367  if(IsChargeSetForChild(i))
368  return m_ChargeForChild[i];
369  else
370  return RFCharge();
371  }
372 
373  bool CombinatoricJigsaw::IsChargeSetForObject(int i) const {
374  return !(m_ChargeForObject.count(i) == 0);
375  }
376 
377  RFCharge CombinatoricJigsaw::GetChargeForObject(int i) const {
378  if(IsChargeSetForObject(i))
379  return m_ChargeForObject[i];
380  else
381  return RFCharge();
382  }
383 
384  bool CombinatoricJigsaw::LoopCombinatoric(){
385  int Ninput = m_InputStates.GetN();
386 
387  int N_comb = 1;
388  for(int i = 0; i < Ninput; i++) N_comb *= m_Ncomb;
389 
390  int c_min = -1;
391  double metric_min = -1;
392 
393  for(int c = 0; c < N_comb; c++){
394  int key = c;
395  for(int i = 0; i < m_Ncomb; i++)
396  GetChildState(i).ClearElements();
397 
398  // set output states for combinatoric;
399  for(int i = 0; i < Ninput; i++){
400  int ihem = key%m_Ncomb;
401  key /= m_Ncomb;
402  GetChildState(ihem).AddElement(m_InputStates[i]);
403  }
404 
405  // check validity of combinatoric
406  bool valid = true;
407  for(int i = 0; i < m_Ncomb; i++){
408  if(IsNinputExclForChild(i)){
409  if(GetChildState(i).GetNElements() != GetNinputForChild(i)){
410  valid = false;
411  break;
412  }
413  } else {
414  if(GetChildState(i).GetNElements() < GetNinputForChild(i)){
415  valid = false;
416  break;
417  }
418  }
419  if(IsChargeSetForChild(i)){
420  if(GetChildState(i).GetCharge() != GetChargeForChild(i)){
421  valid = false;
422  break;
423  }
424  }
425  }
426  if(!valid)
427  continue;
428 
429  // Execute depedancy Jigsaws for this combintoric
430  if(!ExecuteDependancyJigsaws())
431  continue;
432 
433  // check validity of objects
434  for(int i = 0; i < m_Nobj; i++){
435  if(IsChargeSetForObject(i)){
436  if(GetDependancyStates(i).GetCharge() != GetChargeForObject(i)){
437  valid = false;
438  break;
439  }
440  }
441  }
442  if(!valid)
443  continue;
444 
445  // Evaluate metric for this combinatoric
446  double metric;
447  if(!EvaluateMetric(metric))
448  continue;
449 
450  if(metric < metric_min || c_min < 0){
451  metric_min = metric;
452  c_min = c;
453  }
454 
455  if((metric < metric_min && metric >= 0.) || c_min < 0){
456  metric_min = metric;
457  c_min = c;
458  }
459  }
460 
461  if(c_min < 0){
462  m_Log << LogWarning;
463  m_Log << "Unable to find combinatoric satisfying ";
464  m_Log << "requested conditions." << LogEnd;
465  return SetSpirit(false);
466  }
467 
468  // Set outputs to best combinatoric
469  for(int i = 0; i < m_Ncomb; i++)
470  GetChildState(i).ClearElements();
471  int key = c_min;
472  for(int i = 0; i < Ninput; i++){
473  int ihem = key%m_Ncomb;
474  key /= m_Ncomb;
475  GetChildState(ihem).AddElement(m_InputStates[i]);
476  }
477 
478  // Execute depedancy Jigsaws
479  if(!ExecuteDependancyJigsaws())
480  return SetSpirit(false);
481 
482  return SetSpirit(true);
483  }
484 
485  bool CombinatoricJigsaw::IsSoundBody() const {
486  if(RFBase::IsSoundBody())
487  return true;
488 
489  if(!Jigsaw::IsSoundBody())
490  return SetBody(false);
491 
492  for(int i = 0; i < m_Nobj; i++){
493  if(GetDependancyFrames(i).GetN() <= 0){
494  m_Log << LogWarning;
495  m_Log << "Empty collection of object frames: " << i;
496  m_Log << LogEnd;
497  return SetBody(false);
498  }
499  }
500 
501  return SetBody(true);
502  }
503 
504 }
RestFrames::State::IsCombinatoricState
bool IsCombinatoricState() const
Is this a CombinatoricState? (true/false)
Definition: State.cc:92
RestFrames::RestFrame::GetListInvisibleFrames
virtual RestFrameList GetListInvisibleFrames() const
Returns a list of InvisibleFrame s inheriting from this.
Definition: RestFrame.cc:348
RestFrames::Jigsaw::SetGroup
virtual void SetGroup(Group &group=Group::Empty())
Sets group (Group) to current jigsaw.
Definition: Jigsaw.cc:109
RestFrames::Jigsaw::GetGroup
virtual Group & GetGroup() const
Returns group (Group) associated with this jigsaw.
Definition: Jigsaw.cc:130
RestFrames::RFCharge
Definition: RFCharge.hh:40
RestFrames::Jigsaw::Jigsaw
Jigsaw()
Empty constructor.
Definition: Jigsaw.cc:61
RestFrames::CombinatoricState::GetElements
VisibleStateList const & GetElements() const
Returns elements of this state.
Definition: CombinatoricState.cc:97
MinMassesCombJigsaw.hh
RestFrames::CombinatoricState::Empty
static CombinatoricState & Empty()
Returns empty CombinatoricState.
Definition: CombinatoricState.cc:52
RestFrames::Jigsaw::GetDependancyFrames
virtual ConstRestFrameList const & GetDependancyFrames(int i) const
Returns list of frames in which this jigsaw depends on.
Definition: Jigsaw.cc:214
CombinatoricJigsaw.hh
RestFrames::RestFrame
abstract base class for all Frame objects
Definition: RestFrame.hh:45
RestFrames::Group
abstract base class for all Group objects
Definition: Group.hh:46
RestFrames::CombinatoricState::AddElement
void AddElement(VisibleState &state)
Adds element to this state.
Definition: CombinatoricState.cc:87
RestFrames::RFList< const RestFrame >
RestFrames::Jigsaw::Clear
virtual void Clear()
Clears Jigsaw of all connections to other objects.
Definition: Jigsaw.cc:74
RestFrames::CombinatoricJigsaw::SetTransverse
void SetTransverse(bool tran=true, const TVector3 &axis=RestFrame::GetAxis())
Sets transverse momentum.
Definition: CombinatoricJigsaw.cc:328
RestFrames::CombinatoricJigsaw::SetObjectCharge
void SetObjectCharge(const RFCharge &charge, int i)
Sets charge of ith object frame.
Definition: CombinatoricJigsaw.cc:147
RestFrames::CombinatoricJigsaw::Empty
static CombinatoricJigsaw & Empty()
Returns empty CombinatoricJigsaw.
Definition: CombinatoricJigsaw.cc:57
RestFrames::CombinatoricJigsaw::AddCombFrames
void AddCombFrames(const ConstRestFrameList &frames, int i=0)
Adds a list of frames (RestFrame) to this jigsaw.
Definition: CombinatoricJigsaw.cc:104
RestFrames::CombinatoricState::ClearElements
void ClearElements()
Clears all elements associated with this state.
Definition: CombinatoricState.cc:83
RestFrames::CombinatoricJigsaw::AddCombFrame
virtual void AddCombFrame(const RestFrame &frame, int i=0)
Adds a frame (RestFrame) to this jigsaw.
Definition: CombinatoricJigsaw.cc:94
RestFrames::RFBase::GetName
std::string GetName() const
Returns object name.
Definition: RFBase.cc:104
RestFrames::CombinatoricJigsaw::CombinatoricJigsaw
CombinatoricJigsaw()
Empty constructor.
Definition: CombinatoricJigsaw.cc:48
RestFrames::CombinatoricJigsaw::GetGroup
virtual CombinatoricGroup & GetGroup() const
Returns group (Group) associated with this jigsaw.
Definition: CombinatoricJigsaw.cc:67
RestFrames::State::GetListFrames
ConstRestFrameList const & GetListFrames() const
Returns list of frames (RestFrame) contained in this state.
Definition: State.cc:102
RestFrames::CombinatoricGroup::Empty
static CombinatoricGroup & Empty()
Returns empty CombinatoricGroup.
Definition: CombinatoricGroup.cc:53
RestFrames::RestFrame::GetListVisibleFrames
virtual RestFrameList GetListVisibleFrames() const
Returns a list of VisibleFrame s inheriting from this.
Definition: RestFrame.cc:344
RestFrames::CombinatoricJigsaw::AddObjectFrames
void AddObjectFrames(const ConstRestFrameList &frames, int i=0)
Adds a frame to this jigsaw.
Definition: CombinatoricJigsaw.cc:121
RestFrames::CombinatoricJigsaw::Clear
virtual void Clear()
Clears CombinatoricJigsaw from all connections to other objects.
Definition: CombinatoricJigsaw.cc:53
RestFrames::CombinatoricJigsaw
Definition: CombinatoricJigsaw.hh:40
RestFrames::MinMassesCombJigsaw::Empty
static MinMassesCombJigsaw & Empty()
Returns empty MinMassesCombJigsaw.
Definition: MinMassesCombJigsaw.cc:46
RestFrames::CombinatoricJigsaw::AddObjectFrame
virtual void AddObjectFrame(const RestFrame &frame, int i=0)
Adds a frame to this jigsaw.
Definition: CombinatoricJigsaw.cc:110
RestFrames::CombinatoricJigsaw::SetGroup
virtual void SetGroup(Group &group=Group::Empty())
Sets group (Group) to current jigsaw.
Definition: CombinatoricJigsaw.cc:61
RestFrames::CombinatoricJigsaw::UnsetObjectCharge
void UnsetObjectCharge(int i)
Unsets charge of the ith object frame.
Definition: CombinatoricJigsaw.cc:162
RestFrames::CombinatoricJigsaw::UnsetCombCharge
void UnsetCombCharge(int i)
Unsets charge of the ith combinatoric frame.
Definition: CombinatoricJigsaw.cc:142
RestFrames::CombinatoricGroup
Definition: CombinatoricGroup.hh:39
RestFrames::Jigsaw
abstract base class for all Jigsaw objects
Definition: Jigsaw.hh:44
RestFrames::State
Abstract base class for all State objects.
Definition: State.hh:47
RestFrames::RFBase::AddDependent
void AddDependent(RFBase *dep)
pointer to RFBase object owned by this one
Definition: RFBase.cc:88
RestFrames::Group::IsCombinatoricGroup
bool IsCombinatoricGroup() const
Is this a CombinatoricGroup? (true/false)
Definition: Group.cc:79
RestFrames::CombinatoricJigsaw::SetCombCharge
void SetCombCharge(const RFCharge &charge, int i)
Sets charge of ith combinatoric frame.
Definition: CombinatoricJigsaw.cc:127