LOGO

RestFrames  v1.0.1
RestFrames HEP Event Analysis Software Library
TreePlot.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 
30 #include "TArc.h"
31 #include "TLine.h"
32 #include "TLatex.h"
33 #include "TLegend.h"
34 #include "TLegendEntry.h"
35 
36 #include "RestFrames/TreePlot.hh"
39 #include "RestFrames/Jigsaw.hh"
40 #include "RestFrames/State.hh"
45 
46 namespace RestFrames {
47 
48  using std::string;
49  using std::vector;
50  using std::map;
51  using std::max;
52  using std::min;
53 
55  // TreePlot class methods
56  // class which can plot RestFrame trees
58  TreePlot::TreePlot(const std::string& sname,
59  const std::string& stitle)
60  : RFPlot(sname, stitle){
61  m_Type = kVanillaTree;
62  m_GroupPtr = nullptr;
63  m_CanvasPtr = nullptr;
64  m_Log.SetSource("TreePlot "+GetName());
65  }
66 
67  TreePlot::~TreePlot(){
68  ClearTree();
69  }
70 
72  ClearTree();
73  RFPlot::Clear();
74  }
75 
76  void TreePlot::ClearTree(){
77  int Ntreenode = m_TreeNodes.size();
78  for(int i = 0; i < Ntreenode; i++){
79  delete m_TreeNodes[i];
80  }
81  m_TreeNodes.clear();
82 
83  int Ntreelink = m_TreeLinks.size();
84  for(int i = 0; i < Ntreelink; i++){
85  delete m_TreeLinks[i];
86  }
87  m_TreeLinks.clear();
88 
89  int Nleaflink = m_LeafLinks.size();
90  for(int i = 0; i < Nleaflink; i++){
91  delete m_LeafLinks[i];
92  }
93  m_LeafLinks.clear();
94 
95  m_Frames.Clear();
96  m_Jigsaws.Clear();
97  m_GroupPtr = nullptr;
98  m_Type = kVanillaTree;
99 
100  m_SelfAssembling = false;
101 
102  m_JigsawColorMap.clear();
103  m_FrameColorMap.clear();
104  }
105 
106  TCanvas* TreePlot::GetNewCanvas(const std::string& name,
107  const std::string& title){
108  std::string sname, stitle;
109  if(name == ""){
110  char strn[10];
111  sprintf(strn,"%d",GetNCanvases()+1);
112  sname = GetName()+std::string(strn);
113  } else {
114  sname = name;
115  }
116  if(title == "")
117  stitle = GetTitle();
118  else
119  stitle = title;
120 
121  sname = GetUniqueName(sname);
122  TCanvas* can = new TCanvas(sname.c_str(),stitle.c_str(),600,600);
123  can->Range(0.,0.,1.,1.);
124  return can;
125  }
126 
127  void TreePlot::Draw(const std::string& name, const std::string& title,
128  bool invert_bkg_color,
129  bool invert_node_color){
130  if(m_Type == kVanillaTree)
131  return;
132 
133  SetColors(invert_bkg_color,
134  invert_node_color);
135 
136  m_CanvasPtr = GetNewCanvas(name,title);
137 
138  if(m_Type == kFrameTree){
139  bool do_jigsaws = (m_Jigsaws.GetN() > 0);
140  DrawTreeLinks();
141  if(do_jigsaws) DrawTreeNodes(true);
142  if(do_jigsaws) DrawLeafLinks();
143  DrawTreeNodes();
144  DrawFrameTypeLegend();
145  if(do_jigsaws) DrawJigsawLegend();
146  }
147 
148  if(m_Type == kGroupTree){
149  DrawTreeLinks();
150  DrawTreeNodes();
151  DrawTitle(m_GroupPtr->GetTitle());
152  }
153 
154  m_CanvasPtr->Draw();
155  m_CanvasPtr->SetFillColor(m_color_Bkg);
156  m_CanvasPtr->Modified();
157  AddCanvas(m_CanvasPtr);
158  }
159 
160  void TreePlot::SetTree(const RestFrame& frame){
161  if(!frame) return;
162  ClearTree();
163  m_Type = kFrameTree;
164 
165  FillFrameTree(frame);
166  InitTreeGrid();
167  ConvertNodeCoordinates(m_TreeNodes);
168  }
169 
170  void TreePlot::AddJigsaw(const Jigsaw& jigsaw){
171  if(m_Type != kFrameTree)
172  return;
173  if(!jigsaw)
174  return;
175  if(m_Jigsaws.Contains(jigsaw))
176  return;
177  if(!m_Frames.Contains(jigsaw.GetParentFrames()))
178  return;
179 
180  FillJigsawLink(jigsaw);
181  m_JigsawColorMap[&jigsaw] = int(m_JigsawColorMap.size());
182  m_Jigsaws.Add(jigsaw);
183  }
184 
185  void TreePlot::SetTree(const Group& group){
186  if(!group) return;
187  if(!group.IsSoundMind()) return;
188  ClearTree();
189  m_GroupPtr = &group;
190  m_Type = kGroupTree;
191 
192  FillGroupTree(group);
193  InitTreeGrid();
194  ConvertNodeCoordinates(m_TreeNodes);
195  }
196 
197  void TreePlot::SetTree(const Jigsaw& jigsaw){
198  if(!jigsaw) return;
199  if(!jigsaw.IsSoundMind()) return;
200  ClearTree();
201  m_GroupPtr = &jigsaw.GetGroup();
202  m_Type = kGroupTree;
203 
204  FillJigsawTree(jigsaw);
205  InitTreeGrid();
206  ConvertNodeCoordinates(m_TreeNodes);
207  }
208 
209  void TreePlot::InitTreeGrid(){
210  int NcolMAX = 0;
211  for(int irow = 0; irow < m_Nrow; irow++){
212  if(m_Ncol[irow] > NcolMAX) NcolMAX = m_Ncol[irow];
213  }
214  m_Node_R = min(min(0.85/double(2*NcolMAX+1),0.85*0.85/double(2*m_Nrow+1)),0.12);
215  if(m_Type == kGroupTree)
216  m_Node_R = min(min(0.65/double(2*NcolMAX+1),0.85/double(2*m_Nrow+1)),0.12);
217  }
218 
219  void TreePlot::ConvertNodeCoordinates(vector<TreePlotNode*>& nodes){
220  double xmin = 0.;
221  double xmax = 1.;
222  double ymin = 0.;
223  double ymax = 1.;
224  if(m_Type == kFrameTree) ymax = 0.8;
225  int Nnode = nodes.size();
226  for(int i = 0; i < Nnode; i++){
227  double new_x = nodes[i]->GetX();
228  double new_y = nodes[i]->GetY();
229  new_x = xmin + (xmax-xmin)*(new_x+0.5)/double(m_Ncol[int(new_y)]);
230  new_y = ymin + (ymax-ymin)*(1.-(new_y+0.5)/double(m_Nrow));
231  nodes[i]->SetX(new_x);
232  nodes[i]->SetY(new_y);
233  }
234  }
235 
236  void TreePlot::AddFrame(const RestFrame& frame){
237  m_Frames += frame;
238  if(m_FrameColorMap.count(frame.GetType()) <= 0)
239  m_FrameColorMap[frame.GetType()] = int(frame.GetType())-1;
240  }
241 
242  void TreePlot::FillFrameTree(const RestFrame& frame){
243  m_Nrow = 0;
244  m_Ncol.clear();
245 
246  TreePlotNode* top_nodePtr = new TreePlotNode();
247  top_nodePtr->SetX(0.);
248  top_nodePtr->SetY(0.);
249  top_nodePtr->SetFrame(frame);
250  top_nodePtr->SetLabel(frame.GetTitle());
251  m_TreeNodes.push_back(top_nodePtr);
252  AddFrame(frame);
253  m_Ncol.push_back(1);
254  FillFrameTreeMap(0, frame);
255  m_Nrow = m_Ncol.size();
256  }
257 
258  void TreePlot::FillFrameTreeMap(int irow, const RestFrame& frame){
259  if(frame.IsDecayFrame() && frame.IsRecoFrame()){
260  const DecayRecoFrame* rframePtr = dynamic_cast<const DecayRecoFrame*>(&frame);
261  if(rframePtr){
262  if(rframePtr->IsSelfAssemblingFrame()){
263  FillFrameTreeMap(irow, *rframePtr);
264  return;
265  }
266  }
267  }
268  TreePlotNode* frame_nodePtr = m_TreeNodes[m_TreeNodes.size()-1];
269 
270  int Nchild = frame.GetNChildren();
271  for(int i = 0; i < Nchild; i++){
272  const RestFrame& child = frame.GetChildFrame(i);
273  if(irow+1 >= int(m_Ncol.size())){
274  m_Ncol.push_back(0);
275  }
276  TreePlotNode* child_nodePtr = new TreePlotNode();
277  child_nodePtr->SetX(m_Ncol[irow+1]);
278  child_nodePtr->SetY(irow+1);
279  child_nodePtr->SetFrame(child);
280  child_nodePtr->SetLabel(child.GetTitle());
281  m_TreeNodes.push_back(child_nodePtr);
282  AddFrame(child);
283  TreePlotLink* linkPtr = new TreePlotLink(frame_nodePtr,child_nodePtr);
284  m_TreeLinks.push_back(linkPtr);
285  m_Ncol[irow+1]++;
286  FillFrameTreeMap(irow+1,child);
287  }
288  }
289 
290  void TreePlot::FillFrameTreeMap(int irow, const DecayRecoFrame& frame){
291  TreePlotNode* frame_nodePtr = m_TreeNodes[m_TreeNodes.size()-1];
292  frame_nodePtr->SetSquare(true);
293  m_SelfAssembling = true;
294  int Nchild = frame.GetNChildren();
295  for(int i = 0; i < Nchild; i++){
296  const ReconstructionFrame& child = frame.GetChildFrame(i);
297  bool expand_child = false;
298  int N = -1;
299  bool excl = false;
300  if(child.IsVisibleFrame())
301  if(dynamic_cast<CombinatoricGroup*>(&child.GetGroup())){
302  static_cast<CombinatoricGroup&>(child.GetGroup())
303  .GetNElementsForFrame(child, N, excl);
304  if( (N >= 2 && excl) || (N >= 1 && !excl) )
305  expand_child = true;
306  }
307  if(irow+1 >= int(m_Ncol.size())){
308  m_Ncol.push_back(0);
309  }
310  if(expand_child){
311  for(int j = 0; j < 3; j++){
312  TreePlotNode* child_nodePtr = new TreePlotNode();
313  child_nodePtr->SetX(m_Ncol[irow+1]+ double(j-1)*0.08);
314  child_nodePtr->SetY(irow+1);
315  child_nodePtr->SetFrame(child);
316  if(j == 2) child_nodePtr->SetLabel(GetSetTitle(child.GetTitle(),"i"));
317  m_TreeNodes.push_back(child_nodePtr);
318  TreePlotLink* linkPtr = new TreePlotLink(frame_nodePtr,child_nodePtr);
319  m_TreeLinks.push_back(linkPtr);
320  }
321  m_Ncol[irow+1]++;
322  AddFrame(child);
323  } else {
324  TreePlotNode* child_nodePtr = new TreePlotNode();
325  child_nodePtr->SetX(m_Ncol[irow+1]);
326  child_nodePtr->SetY(irow+1);
327  child_nodePtr->SetFrame(child);
328  child_nodePtr->SetLabel(child.GetTitle());
329  m_TreeNodes.push_back(child_nodePtr);
330  AddFrame(child);
331  TreePlotLink* linkPtr = new TreePlotLink(frame_nodePtr,child_nodePtr);
332  m_TreeLinks.push_back(linkPtr);
333  m_Ncol[irow+1]++;
334  FillFrameTreeMap(irow+1,child);
335  }
336  }
337  }
338 
339  void TreePlot::FillGroupTree(const Group& group){
340  m_Nrow = 0;
341  m_Ncol.clear();
342 
343  if(!group.GetParentState()) return;
344 
345  TreePlotNode* top_nodePtr = new TreePlotNode();
346  top_nodePtr->SetX(0.);
347  top_nodePtr->SetY(0.);
348  top_nodePtr->SetState(group.GetParentState());
349  top_nodePtr->SetLabel(GetStateTitle(group.GetParentState()));
350  m_TreeNodes.push_back(top_nodePtr);
351  m_Ncol.push_back(1);
352  FillStateTreeMap(0, group.GetParentState());
353 
354  m_Nrow = m_Ncol.size();
355  }
356 
357  void TreePlot::FillJigsawTree(const Jigsaw& jigsaw){
358  m_Nrow = 0;
359  m_Ncol.clear();
360 
361  if(!jigsaw.GetParentState()) return;
362 
363  TreePlotNode* top_nodePtr = new TreePlotNode();
364  top_nodePtr->SetX(0.);
365  top_nodePtr->SetY(0.);
366  top_nodePtr->SetState(jigsaw.GetParentState());
367  top_nodePtr->SetLabel(GetStateTitle(jigsaw.GetParentState()));
368  m_TreeNodes.push_back(top_nodePtr);
369  m_Ncol.push_back(1);
370  FillStateTreeMap(0, jigsaw.GetParentState());
371 
372  m_Nrow = m_Ncol.size();
373  }
374 
375  void TreePlot::FillStateTreeMap(int irow, const State& state){
376  const Jigsaw& jigsaw = state.GetChildJigsaw();
377  if(!jigsaw) return;
378 
379  TreePlotNode* state_nodePtr = m_TreeNodes[int(m_TreeNodes.size())-1];
380  int Nchild = jigsaw.GetNChildren();
381 
382  for(int i = 0; i < Nchild; i++){
383  State& child = jigsaw.GetChildState(i);
384  if(child.IsEmpty()) continue;
385  if(irow+1 >= int(m_Ncol.size())){
386  m_Ncol.push_back(0);
387  }
388  TreePlotNode *child_nodePtr = new TreePlotNode();
389  child_nodePtr->SetX(m_Ncol[irow+1]);
390  child_nodePtr->SetY(irow+1);
391  child_nodePtr->SetState(child);
392  child_nodePtr->SetLabel(GetStateTitle(child));
393  m_TreeNodes.push_back(child_nodePtr);
394  TreePlotLink* linkPtr = new TreePlotLink(state_nodePtr,child_nodePtr);
395  linkPtr->SetJigsaw(jigsaw);
396  linkPtr->SetLabel(jigsaw.GetTitle());
397  m_TreeLinks.push_back(linkPtr);
398  m_Ncol[irow+1]++;
399  FillStateTreeMap(irow+1, child);
400  }
401  }
402 
403  void TreePlot::FillJigsawLink(const Jigsaw& jigsaw){
404 
405  int Nsplit = jigsaw.GetNChildren();
406  if(!jigsaw.GetGroup()) return;
407  TreePlotNode* high_old = nullptr;
408  TreePlotNode* high_new = nullptr;
409 
410  for(int s = 0; s < Nsplit; s++){
411  RestFrameList frames =
412  jigsaw.GetChildFrames(s)+
413  jigsaw.GetDependancyFrames(s);
414  int Nnode = m_TreeNodes.size();
415  TreePlotNode* last_nodePtr = nullptr;
416  double high = -1.;
417  for(int n = 0; n < Nnode; n++){
418  TreePlotNode* nodePtr = m_TreeNodes[n];
419  const RestFrame& frame = nodePtr->GetFrame();
420  if(frames.Contains(frame)){
421  nodePtr->AddJigsaw(jigsaw);
422  if(jigsaw.GetGroup().ContainsFrame(frame)){
423  if(nodePtr->GetY() > high){
424  high_new = nodePtr;
425  high = nodePtr->GetY();
426  }
427  }
428  if(last_nodePtr){
429  if(!(last_nodePtr->GetFrame() == nodePtr->GetFrame())){
430  TreePlotLink* linkPtr = new TreePlotLink(last_nodePtr,nodePtr);
431  linkPtr->SetJigsaw(jigsaw);
432  m_LeafLinks.push_back(linkPtr);
433  }
434  }
435  last_nodePtr = nodePtr;
436  }
437  }
438 
439  if(s != 0){
440  TreePlotLink* linkPtr = new TreePlotLink(high_old,high_new);
441  linkPtr->SetWavy(true);
442  linkPtr->SetJigsaw(jigsaw);
443  m_LeafLinks.push_back(linkPtr);
444  }
445  high_old = high_new;
446  }
447  }
448 
449  void TreePlot::SetColors(bool invert_bkg_color,
450  bool invert_node_color){
451  if(invert_bkg_color)
452  invert_node_color = !invert_node_color;
453 
454  m_style_Default = 1;
455  m_style_Leaf = 7;
456  m_color_Leaf.clear();
457 
458  if(invert_node_color){
459  for(int i = 0; i < 3; i++){
460  m_color_Node_text[i] = 7000+i*10;
461  m_color_Node_fill[i] = 7003+i*10;
462  if(invert_bkg_color)
463  m_color_Node_line[i] = 7000+i*10;
464  else
465  m_color_Node_line[i] = 7002+i*10;
466  }
467  m_color_Node_text[3] = 18;
468  m_color_Node_fill[3] = kGray+3;
469  if(invert_bkg_color)
470  m_color_Node_line[3] = 18;
471  else
472  m_color_Node_line[3] = kGray+1;
473  } else {
474  for(int i = 0; i < 3; i++){
475  m_color_Node_text[i] = 7004+i*10;
476  m_color_Node_fill[i] = 7001+i*10;
477  if(invert_bkg_color)
478  m_color_Node_line[i] = 7002+i*10;
479  else
480  m_color_Node_line[i] = 7004+i*10;
481  }
482  m_color_Node_text[3] = kGray+3;
483  m_color_Node_fill[3] = 18;
484  if(invert_bkg_color)
485  m_color_Node_line[3] = kGray+2;
486  else
487  m_color_Node_line[3] = kGray+3;
488  }
489 
490  if(invert_bkg_color){
491  m_color_Text = kWhite;
492  m_color_Bkg = kBlack;
493  for(int i = 0; i < 2; i++)
494  for(int j = 0; j < 2; j++)
495  m_color_Leaf.push_back(7040+j*10+i*2);
496  for(int i = 0; i < 2; i++)
497  for(int j = 0; j < 2; j++)
498  m_color_Leaf.push_back(7060+j*10+i*2);
499  m_color_Default_text = kWhite;
500  m_color_Default_line = kWhite;
501  m_color_Default_fill = kBlack;
502  } else {
503  m_color_Text = kBlack;
504  m_color_Bkg = kWhite;
505  for(int i = 0; i < 2; i++)
506  for(int j = 0; j < 2; j++)
507  m_color_Leaf.push_back(7043+j*10-i*2);
508  for(int i = 0; i < 2; i++)
509  for(int j = 0; j < 2; j++)
510  m_color_Leaf.push_back(7063+j*10-i*2);
511  m_color_Default_text = kBlack;
512  m_color_Default_line = kBlack;
513  m_color_Default_fill = kWhite;
514  }
515  }
516 
517  void TreePlot::DrawTreeNodes(bool with_rings){
518  int Nnode = m_TreeNodes.size();
519  for(int i = 0; i < Nnode; i++)
520  DrawNode(m_TreeNodes[i], with_rings);
521  }
522 
523  void TreePlot::DrawTreeLinks(){
524  int Nlink = m_TreeLinks.size();
525  for(int i = 0; i < Nlink; i++)
526  DrawLink(m_TreeLinks[i]);
527  }
528 
529  void TreePlot::DrawLeafLinks(){
530  int Nlink = m_LeafLinks.size();
531  for(int i = 0; i < Nlink; i++)
532  DrawLink(m_LeafLinks[i]);
533  }
534 
535  void TreePlot::DrawLink(TreePlotLink* linkPtr){
536  double x0 = linkPtr->GetNode1()->GetX();
537  double y0 = linkPtr->GetNode1()->GetY();
538  double x1 = linkPtr->GetNode2()->GetX();
539  double y1 = linkPtr->GetNode2()->GetY();
540 
541  int icolor_line = m_color_Default_line;
542  int icolor_text = -1;
543  int icolor_fill = -1;
544  int istyle = m_style_Default;
545  int isize = int(m_Node_R*70.);
546  bool DoWavy = linkPtr->DoWavy();
547 
548  const Jigsaw& jigsaw = linkPtr->GetJigsaw();
549 
550  if(!jigsaw.IsEmpty()){
551  if(linkPtr->DoLabel()){
552  int priority = GetJigsawPriority(jigsaw.GetNChildren(), jigsaw.GetNDependancyStates());
553  icolor_line = m_color_Node_line[priority];
554  icolor_text = m_color_Node_text[priority];
555  icolor_fill = m_color_Node_fill[priority];
556  } else {
557  int Nj = m_Jigsaws.GetN();
558  int index = m_Jigsaws.GetIndex(jigsaw);
559  x0 += (double(index+1)-double(Nj+1)/2.)*m_Node_R*1./max(4.,double(Nj));
560  x1 += (double(index+1)-double(Nj+1)/2.)*m_Node_R*1./max(4.,double(Nj));
561  icolor_line = m_color_Leaf[m_JigsawColorMap[&jigsaw]%int(m_color_Leaf.size())];
562  if(DoWavy){
563  istyle = m_style_Leaf;
564  isize++;
565  }
566  }
567  }
568 
569  if(fabs(y0-y1) > 1e-10){ // nodes are at different heights - draw line
570  TLine *line = new TLine(x0,y0,x1,y1);
571  line->SetLineColor(icolor_line);
572  line->SetLineWidth(isize);
573  line->SetLineStyle(istyle);
574  m_CanvasPtr->cd();
575  line->Draw();
576  AddTObject(line);
577  } else { // nodes are at same height - draw arc
578  TArc *arc;
579  double c = fabs(x0-x1);
580  double h = 1./double(2*m_Nrow)*0.8;
581  if(h > c/2.){
582  double R = c/2.;
583  if(h > R+m_Node_R) arc = new TArc((x0+x1)/2.,y0+m_Node_R,R, 0., 180.);
584  else arc = new TArc((x0+x1)/2.,y0+h-R,R, 0., 180.);
585  } else {
586  double R = h/2. + c*c/(8.*h);
587  arc = new TArc((x0+x1)/2.,y0+h-R,R,
588  -asin(c/(2.*R))*180/TMath::Pi()+90.,
589  asin(c/(2.*R))*180/TMath::Pi()+90.);
590  }
591  arc->SetLineColor(icolor_line);
592  arc->SetLineStyle(istyle);
593  arc->SetFillStyle(0);
594  arc->SetLineWidth(isize);
595  m_CanvasPtr->cd();
596  arc->Draw("only");
597  AddTObject(arc);
598  }
599 
600  if(linkPtr->DoLabel()){
601  double x = x0;
602  double y = (y0+y1)/2.;
603 
604  char* slabel = new char[500];
605  sprintf(slabel,"#bf{%s}",linkPtr->GetLabel().c_str());
606  TLatex* lat = new TLatex(x,y,slabel);
607  lat->SetTextAlign(22);
608  lat->SetNDC();
609  lat->SetTextSize(1.);
610  lat->SetTextFont(132);
611  double Xsize = lat->GetXsize();
612  double Ysize = lat->GetYsize();
613  double scale = max(Xsize/(6.*m_Node_R),1.75*Ysize/(fabs(y0-y1)-2.*m_Node_R));
614  lat->SetTextSize(1./scale);
615  lat->SetTextColor(icolor_text);
616 
617  Xsize = lat->GetXsize()*1.05;
618  Ysize = lat->GetYsize()*1.5;
619  TBox *border = new TBox(x-Xsize/2., y-Ysize/2., x+Xsize/2.,y+Ysize/2.);
620  border->SetLineColor(icolor_line);
621  border->SetLineWidth(2);
622  border->SetLineStyle(1);
623  border->SetFillColor(icolor_fill);
624  m_CanvasPtr->cd();
625  border->Draw("l");
626  m_CanvasPtr->cd();
627  lat->DrawLatex(x,y,slabel);
628  delete[] slabel;
629  AddTObject(lat);
630  AddTObject(border);
631  }
632  }
633 
634  void TreePlot::DrawNode(TreePlotNode* nodePtr, bool with_rings){
635  double x = nodePtr->GetX();
636  double y = nodePtr->GetY();
637 
638  int icolor_line = m_color_Default_line;
639  int icolor_text = m_color_Default_text;
640  int icolor_fill = m_color_Default_fill;
641  int istyle = 1;
642  int iwidth = int(m_Node_R*50.);;
643  bool square = nodePtr->DoSquare();
644 
645  const RestFrame& frame = nodePtr->GetFrame();
646 
647  if(!frame.IsEmpty()){
648  icolor_text = m_color_Node_text[m_FrameColorMap[frame.GetType()]];
649  icolor_line = m_color_Node_line[m_FrameColorMap[frame.GetType()]];
650  icolor_fill = m_color_Node_fill[m_FrameColorMap[frame.GetType()]];
651  }
652 
653  if(with_rings){
654  JigsawList jigsaws = nodePtr->GetJigsawList();
655  int Njigsaw = jigsaws.GetN();
656  for(int i = 0; i < Njigsaw; i++){
657  double R = 1.03 + double(Njigsaw-i)*0.08;
658  const Jigsaw& jigsaw = jigsaws[i];
659  if(square){
660  TBox* ring = new TBox(x-m_Node_R*R*0.88,y-m_Node_R*R*0.88,
661  x+m_Node_R*R*0.88,y+m_Node_R*R*0.88);
662  int jcolor = m_color_Leaf[m_JigsawColorMap[&jigsaw]%int(m_color_Leaf.size())];
663  ring->SetLineColor(jcolor);
664  ring->SetFillColor(jcolor);
665 
666  m_CanvasPtr->cd();
667  ring->Draw();
668  AddTObject(ring);
669  } else {
670  TArc* ring = new TArc(x,y,m_Node_R*R);
671  int jcolor = m_color_Leaf[m_JigsawColorMap[&jigsaw]%int(m_color_Leaf.size())];
672  ring->SetLineColor(jcolor);
673  ring->SetFillColor(jcolor);
674 
675  m_CanvasPtr->cd();
676  ring->Draw();
677  AddTObject(ring);
678  }
679  }
680  }
681  if(square){
682  TBox *box = new TBox(x-m_Node_R*0.88,y-m_Node_R*0.88,
683  x+m_Node_R*0.88,y+m_Node_R*0.88);
684  box->SetLineColor(icolor_line);
685  box->SetFillColor(icolor_fill);
686  box->SetLineStyle(istyle);
687  box->SetLineWidth(iwidth);
688  m_CanvasPtr->cd();
689  box->Draw("l");
690  AddTObject(box);
691  } else {
692  TArc *circle = new TArc(x,y,m_Node_R);
693  circle->SetLineColor(icolor_line);
694  circle->SetFillColor(icolor_fill);
695  circle->SetLineStyle(istyle);
696  circle->SetLineWidth(iwidth);
697  m_CanvasPtr->cd();
698  circle->Draw();
699  AddTObject(circle);
700  }
701 
702  if(nodePtr->DoLabel()){
703  char* nodetitle = new char[200];
704  sprintf(nodetitle,"#bf{%s}",nodePtr->GetLabel().c_str());
705  TLatex* lat = new TLatex(x,y,nodetitle);
706  lat->SetTextAlign(22);
707  lat->SetNDC();
708  lat->SetTextSize(1.);
709  lat->SetTextFont(132);
710  double Rnorm =
711  sqrt(lat->GetXsize()*lat->GetXsize()+lat->GetYsize()*lat->GetYsize());
712  lat->SetTextSize(1.8*m_Node_R/Rnorm);
713  lat->SetTextColor(icolor_text);
714  m_CanvasPtr->cd();
715  lat->DrawLatex(x,y,nodetitle);
716  delete[] nodetitle;
717  AddTObject(lat);
718  }
719  }
720 
721  std::string TreePlot::GetStateTitle(const State& state){
722  RestFrameList frames = state.GetListFrames();
723  int Nf = frames.GetN();
724  std::string title = "";
725  if(Nf > 2) title.append("#splitline{");
726  title.append(frames.Get(0).GetTitle());
727  for(int f = 1; f < Nf; f++){
728  if(f%((Nf+1)/2) == 0 && Nf > 2) title.append("}{");
729  title.append("+ ");
730  title.append(frames[f].GetTitle());
731  }
732  if(Nf > 2) title.append("}");
733 
734  return title;
735  }
736 
737  std::string TreePlot::GetSetTitle(const std::string& set,
738  const std::string& index){
739  std::string title = "#left{#left(";
740  title.append(set);
741  title.append("#right)_{");
742  title.append(index);
743  title.append("}#right}");
744  return title;
745  }
746 
747  void TreePlot::DrawFrameTypeLegend(){
748  vector<std::string> frame_title;
749  frame_title.push_back("Lab State");
750  frame_title.push_back("Decay States");
751  frame_title.push_back("Visible States");
752  frame_title.push_back("Invisible States");
753  vector<FrameType> frame_type;
754  frame_type.push_back(kLabFrame);
755  frame_type.push_back(kDecayFrame);
756  frame_type.push_back(kVisibleFrame);
757  frame_type.push_back(kInvisibleFrame);
758 
759  TLatex* lat = new TLatex(0.,0.,"");
760  lat->SetNDC();
761  lat->SetTextAlign(12);
762  lat->SetTextSize(0.045);
763  lat->SetTextFont(132);
764  lat->SetTextColor(m_color_Default_text);
765  double X = 0.045;
766  double Y = 0.955;
767  double R = 0.035;
768  double step = 2.2*R;
769  for(int i = 0; i < 4; i++){
770  TBox* white = new TBox(X-step/2.,Y-step/2.,0.36,Y+step/2.);
771  white->SetFillColor(m_color_Bkg);
772  white->SetLineColor(m_color_Bkg);
773  white->Draw();
774  AddTObject(white);
775  if(m_FrameColorMap.count(frame_type[i]) <= 0) continue;
776  TArc* circle = new TArc(X,Y,R);
777  circle->SetLineColor(m_color_Node_line[m_FrameColorMap[frame_type[i]]]);
778  circle->SetFillColor(m_color_Node_fill[m_FrameColorMap[frame_type[i]]]);
779  circle->SetLineWidth(2);
780  circle->Draw();
781  AddTObject(circle);
782  lat->DrawLatex(X+R*1.3,Y,frame_title[i].c_str());
783  Y -= step;
784  }
785  if(m_SelfAssembling){
786  TBox* white = new TBox(X-step/2.,Y-step/2.,0.36,Y+step/2.);
787  white->SetFillColor(m_color_Bkg);
788  white->SetLineColor(m_color_Bkg);
789  white->Draw();
790  AddTObject(white);
791  TBox* box = new TBox(X-R*0.88,Y-R*0.88,X+R*0.88,Y+R*0.88);
792  box->SetLineColor(m_color_Node_line[m_FrameColorMap[kDecayFrame]]);
793  box->SetFillColor(m_color_Node_fill[m_FrameColorMap[kDecayFrame]]);
794  box->Draw("l");
795  AddTObject(box);
796  lat->DrawLatex(X+R*1.3,Y,"Self Assembling");
797  }
798  AddTObject(lat);
799  }
800 
801  void TreePlot::DrawJigsawLegend(){
802  vector<std::string> ititle;
803  vector<int> icolor_line;
804  vector<int> icolor_text;
805  int Nj = m_Jigsaws.GetN();
806  for(int i = 0; i < Nj; i++){
807  int jcolor = m_color_Leaf[m_JigsawColorMap[&m_Jigsaws[i]]%int(m_color_Leaf.size())];
808  icolor_line.push_back(jcolor);
809  icolor_text.push_back(jcolor);
810  ititle.push_back(m_Jigsaws[i].GetLabel().c_str());
811  }
812 
813  vector<TLine*> dum;
814  for(int i = 0; i < Nj; i++){
815  dum.push_back(new TLine(0.0,0.0,0.001,0.001));
816  dum[i]->SetLineWidth(int(m_Node_R*70.));
817  dum[i]->SetLineColor(icolor_line[i]);
818  AddTObject(dum[i]);
819  }
820 
821  TLegend* leg = new TLegend(0.60235,0.997-Nj*.078,0.8087,0.997);
822  AddTObject(leg);
823  vector<TLegendEntry*> entry;
824  for(int i = 0; i < Nj; i++){
825  entry.push_back(leg->AddEntry(dum[i], ititle[i].c_str()));
826  entry[i]->SetMarkerSize(0);
827  entry[i]->SetMarkerColor(icolor_line[i]);
828  entry[i]->SetFillColor(m_color_Bkg);
829  }
830  leg->SetLineColor(m_color_Bkg);
831  leg->SetFillColor(m_color_Bkg);
832  leg->SetShadowColor(m_color_Bkg);
833  leg->SetTextColor(m_color_Text);
834  leg->SetTextFont(132);
835  leg->SetTextSize(0.042);
836  leg->Draw();
837  }
838 
839  void TreePlot::DrawTitle(const std::string& title){
840  TLatex* lat = new TLatex(0.0,0.0,title.c_str());
841  lat->SetTextAlign(22);
842  lat->SetNDC();
843  lat->SetTextSize(0.045);
844  lat->SetTextFont(132);
845  lat->SetTextColor(m_color_Text);
846  double x = lat->GetXsize()/2. + 0.01;
847  double y = 1. - lat->GetYsize()/2. - 0.01;
848  m_CanvasPtr->cd();
849  lat->DrawLatex(x,y,title.c_str());
850  AddTObject(lat);
851  }
852 
853  int TreePlot::GetJigsawPriority(int Nout, int Ndep) const {
854  if(Nout == 1 && Ndep == 0) return 0;
855  if(Nout == 1 && Ndep == 1) return 1;
856  return 2;
857  }
858 
859 }
std::string GetName() const
Returns object name.
Definition: RFBase.cc:104
std::string GetTitle() const
Returns object title.
Definition: RFBase.cc:108
virtual void Clear()
Clears RFBase of all connections to other objects.
Definition: RFPlot.cc:48
virtual void Clear()
Clears RFBase of all connections to other objects.
Definition: TreePlot.cc:71