GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4PolyCond.cxx
Go to the documentation of this file.
1 // $Id: TGo4PolyCond.cxx 1922 2016-06-13 10:23:16Z adamczew $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4PolyCond.h"
15 
16 #include "Riostream.h"
17 #include "RVersion.h"
18 
19 #include "TMath.h"
20 #include "TROOT.h"
21 #include "TH2.h"
22 #include "TList.h"
23 #include "TCutG.h"
24 
25 #include "TGo4PolyCondPainter.h"
26 #include "TGo4Log.h"
27 
30 //#define POLYCOND_UPDATE_WITHCLONE 1
31 
32 
33  TString TGo4PolyCond::fgxURL_NPOINTS="npolygon";
34  TString TGo4PolyCond::fgxURL_XPRE="x";
35  TString TGo4PolyCond::fgxURL_YPRE="y";
36 
37 
38 
40 {
41  TString res;
42  Int_t cnt = 0;
43  do {
44  res.Form("CutG_%d",cnt++);
45  } while (gROOT->GetListOfSpecials()->FindObject(res)!=0);
46  return res;
47 }
48 
49 // ----------------------------------------------------------
51  TGo4Condition(),
52  fxCut(0)
53 {
54  SetDimension(2);
55  //SetBit(kCanDelete, kFALSE);
56  //std::cout <<"TGo4PolyCond default ctor, this="<<(long) this <<", threadid="<< (long) pthread_self()<<std::endl;
57 }
58 // ----------------------------------------------------------
59 TGo4PolyCond::TGo4PolyCond(const char* name, const char* title) :
60  TGo4Condition(name,title),
61  fxCut(0)
62 {
63  SetDimension(2);
64  //SetBit(kCanDelete, kFALSE);
65  //std::cout <<"TGo4PolyCond ctor of name:"<< name<< ", this="<<(long) this << std::endl;
66 }
67 // ----------------------------------------------------------
69 {
70  //std::cout <<"TGo4PolyCond dtor of this="<<(long) this <<", threadid="<< (long) pthread_self()<< std::endl;
71  //UnDraw(); // JAM 2016 - do it before cut has vanished!
72  if(fxCut != 0)
73  {
74  //std::cout <<"TGo4PolyCond dtor of this="<<(long) this <<" deletes the cut "<< (long) fxCut << std::endl;
75  delete fxCut;
76  fxCut=0; // JAM2016: reset for Unpaint in PolyCondView?
77  }
78 }
79 
81 {
82  if(fxCut==0) return 0;
83  Int_t n=fxCut->GetN();
84  Double_t* xarr=fxCut->GetX();
85  fxCut->SetBit(kMustCleanup,0);
86  Int_t nxmin=TMath::LocMin(n,xarr);
87  return (xarr[nxmin]);
88 }
90 {
91  if(fxCut==0) return 0;
92  Int_t n=fxCut->GetN();
93  Double_t* xarr=fxCut->GetX();
94  Int_t nxmax=TMath::LocMax(n,xarr);
95  return (xarr[nxmax]);
96 }
98 {
99  if(fxCut==0) return 0;
100  Int_t n=fxCut->GetN();
101  Double_t* yarr=fxCut->GetY();
102  Int_t nymin=TMath::LocMin(n,yarr);
103  return (yarr[nymin]);
104 }
106 {
107  if(fxCut==0) return 0;
108  Int_t n=fxCut->GetN();
109  Double_t* yarr=fxCut->GetY();
110  Int_t nymax=TMath::LocMax(n,yarr);
111  return (yarr[nymax]);
112 }
113 
115 {
116  return kTRUE;
117 }
118 
119 // ----------------------------------------------------------
120 TCutG* TGo4PolyCond::GetCut(Bool_t changeowner)
121 {
122  //std::cout <<"TGo4PolyCond "<<(long) this <<" ::GetCut for cut "<< (long) fxCut << std::endl;
123  TCutG* tempcut = fxCut;
124 
125  if(changeowner) {
126  fxCut = 0;
127  //std::cout <<"TGo4PolyCond "<<(long) this <<" ::GetCut deletes cuthistogram"<< (long) fxCutHis << std::endl;
128  delete fxCutHis;
129  fxCutHis=0;
130 
131  }
132  return tempcut;
133 }
134 
135 // ----------------------------------------------------------
137 {
138 
139  TCutG * tempcut = source->GetCut(false); // get fxCut pointer
140  //std::cout <<"TGo4PolyCond "<<(long) this <<" CloneCut "<< (long) tempcut<<"from polycond "<< (long) source << std::endl;
141  if(tempcut)
142  {
143  CleanupSpecials(); // JAM2016: Clone might delete cut of same name from list of specials, remove it first
144  TCutG* ret= (TCutG *)tempcut->Clone(GetName());
145  CleanupSpecials();
146  return ret;
147  }
148  else return 0;
149 }
150 // ----------------------------------------------------------
151 void TGo4PolyCond::SetValues(TCutG * newcut)
152 {
153  if(newcut==0) return;
154 #ifdef POLYCOND_UPDATE_WITHCLONE
155  if(fxCut!=0) delete fxCut;
156  CleanupSpecials(); // JAM2016: Clone might delete cut of same name from list of specials, remove it first
157  //fxCut = (TCutG*) newcut->Clone(NextAvailableName());
158  fxCut = (TCutG*) newcut->Clone(GetName());
159  fxCut->SetBit(kCanDelete,kFALSE);
160  CleanupSpecials();
161 #else
162  Int_t pn = newcut->GetN();
163  if(fxCut==0)
164  {
165  fxCut = new TCutG(GetName(),pn);
166  fxCut->SetBit(kMustCleanup);
167  TGo4PolyCond::CleanupSpecials(); // JAM2016
168  }
169  else
170  {
171  fxCut->Set(pn);
172  }
173  Double_t xp=0;
174  Double_t yp=0;
175  for(Int_t i=0; i<pn; ++i) {
176  newcut->GetPoint(i,xp,yp);
177  fxCut->SetPoint(i,xp,yp);
178  }
179 
180 
181 #endif
182  // when updated from view, we store graphical attributes:
183  SetLineColor(newcut->GetLineColor());
184  SetLineWidth(newcut->GetLineWidth());
185  SetLineStyle(newcut->GetLineStyle());
186  SetFillColor(newcut->GetFillColor());
187  SetFillStyle(newcut->GetFillStyle());
188  //std::cout << "TGo4PolyCond::SetValues deletes cut histogram " << (long) fxCutHis << std::endl;
189  delete fxCutHis; // fxCut changed, so discard previous fxCut histogram
190  fxCutHis=0;
191  //std::cout << "TGo4PolyCond::SetValues fxCut " << (long) fxCut << " from " << (long) newcut << std::endl;
192 }
193  // ----------------------------------------------------------
194 void TGo4PolyCond::SetValuesDirect(TCutG * newcut)
195 {
196  if(newcut==0) return;
197  if(fxCut!=0 && fxCut!=newcut) delete fxCut;
198 
199  fxCut = newcut;
200  //fxCut->SetName(NextAvailableName()); // JAM2016
201  fxCut->SetName(GetName());
202 
203  // when updated from view, we store graphical attributes:
204  SetLineColor(newcut->GetLineColor());
205  SetLineWidth(newcut->GetLineWidth());
206  SetLineStyle(newcut->GetLineStyle());
207  SetFillColor(newcut->GetFillColor());
208  SetFillStyle(newcut->GetFillStyle());
209 
210  delete fxCutHis; // fxCut changed, so discard previous fxCut histogram
211  fxCutHis=0;
212  //std::cout << "TGo4PolyCond::SetValuesDirect fxCut " << (long) fxCut << " from " << (long)newcut << std::endl;
213 }
214 
215 
216 // ----------------------------------------------------------
217 void TGo4PolyCond::SetValues(Double_t * x, Double_t * y, Int_t len)
218 {
219  if(fxCut != 0) delete fxCut;
220  TGo4PolyCond::CleanupSpecials(); // JAM2016
221  //fxCut = new TCutG(NextAvailableName(), len, x, y);
222  fxCut = new TCutG(GetName(), len, x, y);
223  fxCut->SetBit(kMustCleanup);
224  //fxCut->SetBit(kCanDelete,kFALSE);
225  TGo4PolyCond::CleanupSpecials(); // JAM2016
226 
227  //std::cout << "TGo4PolyCond::SetValues() Set new fxCut " << (long) fxCut << std::endl;
228  delete fxCutHis; // discard previous fxCut histogram
229  fxCutHis=0;
230 }
231 // ----------------------------------------------------------
232 Bool_t TGo4PolyCond::Test(Double_t x, Double_t y)
233 {
234  IncCounts();
235  if((!IsEnabled()) || (fxCut == 0)){
236  if(FixedResult()) IncTrueCounts();
237  return FixedResult();
238  }
239  Bool_t outside = (fxCut->IsInside(x,y) == 0);
240  if(outside) return IsFalse();
241  IncTrueCounts();
242  return IsTrue();
243 }
244 // ----------------------------------------------------------
245 void TGo4PolyCond::PrintCondition(Bool_t points)
246 {
248  if(points) {
249  if(fxCut == 0)
250  std::cout << "No polygon specified!" << std::endl;
251  else
252  fxCut->Print(0);
253  }
254 }
255 
256 // -----------------------------------------------
257 // PrintBar switch is handled in condition baseclass now.
258 //void TGo4PolyCond::Print(Option_t* opt) const{
260 // TGo4PolyCond* const localthis= const_cast<TGo4PolyCond* const>(this);
261 // localthis->PrintBar();
262 //}
263 // ----------------------------------------------------------
264 Bool_t TGo4PolyCond::UpdateFrom(TGo4Condition * cond, Bool_t counts)
265 {
266  if(!TGo4Condition::UpdateFrom(cond,counts)) return kFALSE;
267  if(cond->InheritsFrom(TGo4PolyCond::Class()))
268  {
269 
270 #ifdef POLYCOND_UPDATE_WITHCLONE
271  TCutG * temp = CloneCut((TGo4PolyCond*)cond); // get clone from source, still valid there!
272  CleanupSpecials(); // remove all references to cloned TCutG from list of specials
273  //std::cout << "Update " << GetName() << " from " << temp << std::endl;
274  if(temp != 0)
275  {
276  TCutG* old=fxCut; // JAM2016 change cut before deleting the old one!
277  fxCut=temp;
278  //std::cout << "Delete fxCut " << (long) old << std::endl;
279  if(old != 0) delete old;
280  delete fxCutHis;
281  fxCutHis=0;
282  //std::cout << "Update new fxCut " << (long) fxCut << std::endl;
283  return kTRUE;
284  }
285  else
286  {
287  return kFALSE;
288  }
289 #else
290  /* JAM2016: try to avoid streaming the cut multiple times when updating condition:*/
291  TGo4PolyCond* source=(TGo4PolyCond*)cond;
292  TCutG * srccut = source->GetCut(false);
293  //std::cout << "TGo4PolyCond::UpdateFrom without Clone of" << GetName() << ", srccut="<<(long )srccut<<", fxCut="<< (long)fxCut << std::endl;
294 
295  if(srccut==0) return kFALSE;
296  CleanupSpecials(); // redundant? do it to get rid of entries from streamer!?
297  Int_t pn = srccut->GetN();
298  fxCut->Set(pn);
299  Double_t xp=0;
300  Double_t yp=0;
301  for(Int_t i=0; i<pn; ++i) {
302  srccut->GetPoint(i,xp,yp);
303  fxCut->SetPoint(i,xp,yp);
304  }
305 
306  // still need this to reassign the bins of statistics histogram:
307  delete fxCutHis;
308  fxCutHis=0;
309 
310  return kTRUE;
311 #endif
312 
313  }
314  else
315  {
316  std::cout << "Cannot update " << GetName() << " from " << cond->ClassName() << std::endl;
317  return kFALSE;
318  }
319 }
320 
321 
322 Bool_t TGo4PolyCond::UpdateFromUrl(const char* rest_url_opt){
323  if(!TGo4Condition::UpdateFromUrl(rest_url_opt)) return kFALSE;
324  TString message;
325  message.Form("TGo4PolyCond::UpdateFromUrl - condition %s: with url:%s", GetName(), rest_url_opt);
326  TGo4Log::Message(1,message.Data());
327 
328  // evaluate options that change array of points
330  {
331  Int_t npoints = GetUrlOptionAsInt(TGo4PolyCond::fgxURL_NPOINTS, -1);
332  if(npoints>=0)
333  {
334  TString xname,yname;
335  Double_t* X = new Double_t[npoints];
336  Double_t* Y = new Double_t[npoints];
337  for(Int_t i=0; i<npoints;++i) {
338  xname.Form("%s%d",TGo4PolyCond::fgxURL_XPRE.Data(), i);
339  yname.Form("%s%d",TGo4PolyCond::fgxURL_YPRE.Data(), i);
340  X[i]=GetUrlOptionAsDouble(xname.Data(),0);
341  Y[i]=GetUrlOptionAsDouble(yname.Data(),0);
342  message.Form(" i:%d, X=%f, Y=%f\n",i,X[i],Y[i]);
343  }
344  SetValues(X, Y, npoints);
345  delete[] X; delete[] Y;
346  }
347  message.Form(" - setting Polygon condition to new values!");
348  TGo4Log::Message(1,message.Data());
349 
350  }
351  return kTRUE;
352 }
353 
354 
355 
356 Double_t TGo4PolyCond::GetIntegral(TH1* histo, Option_t* opt)
357 {
359 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,8)
360  if(fxCut)
361  #if ROOT_VERSION_CODE >= ROOT_VERSION(5,25,1)
362  return (fxCut->IntegralHist(dynamic_cast<TH2*>(histo),opt));
363  #else
364  return (fxCut->Integral(dynamic_cast<TH2*>(histo),opt));
365  #endif
366  else
367  return 0;
368 #else
369  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
370  if(fxCutHis!=0)
371  return (fxCutHis->Integral(opt));
372  else
373  return-1;
374 #endif // 40008
375 }
376 
377 Double_t TGo4PolyCond::GetMean(TH1* histo, Int_t axis)
378 {
379  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
380  if(fxCutHis!=0)
381  return (fxCutHis->GetMean(axis));
382  else
383  return-1;
384 }
385 Double_t TGo4PolyCond::GetRMS(TH1* histo, Int_t axis)
386 {
387  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
388  if(fxCutHis!=0)
389  return (fxCutHis->GetRMS(axis));
390  else
391  return -1;
392 }
393 Double_t TGo4PolyCond::GetSkewness(TH1* histo, Int_t axis)
394 {
395  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
396  if(fxCutHis!=0)
397  return (fxCutHis->GetSkewness(axis));
398  else
399  return -1;
400 }
401 Double_t TGo4PolyCond::GetCurtosis(TH1* histo, Int_t axis)
402 {
403  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
404  if(fxCutHis!=0)
405  return (fxCutHis->GetKurtosis(axis));
406  else
407  return -1;
408 }
409 Double_t TGo4PolyCond::GetXMax(TH1* histo)
410 {
411  Double_t result=0;
412  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
413  if(fxCutHis!=0)
414  {
415  TAxis* xax=fxCutHis->GetXaxis();
416  Int_t maxbin=fxCutHis->GetMaximumBin();
417  Int_t xmaxbin=maxbin%(fxCutHis->GetNbinsX()+2);
418  result=xax->GetBinCenter(xmaxbin);
419  }
420  else
421  {
422  result=-1;
423  }
424  return result;
425 }
426 Double_t TGo4PolyCond::GetYMax(TH1* histo)
427 {
428  Double_t result=0;
429  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
430  if(fxCutHis!=0)
431  {
432  TAxis* yax=fxCutHis->GetYaxis();
433  Int_t maxbin=fxCutHis->GetMaximumBin();
434  Int_t maxybin=maxbin/(fxCutHis->GetNbinsX()+2);
435  result=yax->GetBinCenter(maxybin);
436  }
437  else
438  {
439  result=-1;
440  }
441  return result;
442 }
443 Double_t TGo4PolyCond::GetCMax(TH1* histo)
444 {
445  if(fxCutHis==0) fxCutHis=CreateCutHistogram(histo);
446  if(fxCutHis!=0)
447  return(fxCutHis->GetMaximum());
448  else
449  return -1;
450 }
451 
453 {
454 if(painter==0) return;
455 if(painter->InheritsFrom(TGo4PolyCondPainter::Class()))
456  {
457  if(fxPainter) delete fxPainter;
458  fxPainter=painter;
459  fxPainter->SetCondition(this);
460  }
461 else
462  {
463  TGo4Log::Warn("Could not set painter of class %s for TGo4PolyCond %s",
464  painter->ClassName(),GetName());
465  }
466 
467 
468 }
469 
470 
472 {
473  TGo4ConditionPainter* painter=new TGo4PolyCondPainter(GetName());
474  painter->SetCondition(this);
475  //std::cout<<"TGo4PolyCond::CreatePainter() creates new painter"<< (long) painter<< std::endl;
476  return painter;
477 }
478 
480 {
481  TH2* his=dynamic_cast<TH2*>(source);
482  if(his==0) return 0;
483  TH2* work= (TH2*) his->Clone();
484  //std::cout<<"TGo4PolyCond::CreateCutHistogram creates new cut histogram"<< (long) work <<" from source:"<< (long)source<< std::endl;
485  Int_t nx=work->GetNbinsX();
486  Int_t ny=work->GetNbinsY();
487  TAxis* xaxis = work->GetXaxis();
488  TAxis* yaxis = work->GetYaxis();
489  xaxis->SetRange(0,0); // expand work histogram to full range
490  yaxis->SetRange(0,0);
491  // set all bins outside fxCut to zero:
492  for(Int_t i=0; i<nx;++i)
493  {
494  Double_t x = xaxis->GetBinCenter(i);
495  for(Int_t j=0; j<ny;++j)
496  {
497  Double_t y = yaxis->GetBinCenter(j);
498  if(fxCut && !(fxCut->IsInside(x,y)))
499  work->SetBinContent(i,j,0);
500  }
501  }
502  // prepare statistics:
503  Stat_t s[11]={0}; // dimension is kNstat of TH1.cxx
504  work->PutStats(s); // reset previous stats
505  work->GetStats(s); // recalculate
506  work->PutStats(s); // put back
507  work->SetDirectory(0); // important for first draw from marker setup file!
508  return work;
509 }
510 
511 // ----------------------------------------------------------
513 {
514  //std::cout<<"TGo4PolyCond::CleanupSpecials()..."<< std::endl;
515  TSeqCollection* specials=gROOT->GetListOfSpecials();
516  TIter iter(specials);
517  TObject* ob=0;
518  while((ob = iter())!=0) {
519  if(ob->InheritsFrom(TCutG::Class())) {
520  specials->Remove(ob);
521  //std::cout <<">>>>>>>>>> removed fxCut" << (long) ob<<" :" << ob->GetName() <<" from list of specials "<< std::endl;
522  }
523  }//while
524 }
525 
527 {
528  Int_t size = sizeof(*this);
529  if (GetName()!=0) size+=strlen(GetName());
530  if (GetTitle()!=0) size+=strlen(GetTitle());
531  if (fxCut!=0) {
532  size += sizeof(*fxCut);
533 #if ROOT_VERSION_CODE > ROOT_VERSION(4,0,8)
534  size += fxCut->GetMaxSize()*2*sizeof(Double_t);
535 #else
536  size += fxCut->GetN()*2*sizeof(Double_t);
537 #endif
538  }
539  return size;
540 }
541 
542 void TGo4PolyCond::SavePrimitive(std::ostream& out, Option_t* opt)
543 {
544  static int cnt = 0;
545  TString line, varname = MakeScript(out, Form("polycond%d", cnt++), opt);
546 
547  if ((fxCut==0) || (fxCut->GetN()==0))
548  line.Form(" %s->SetValues(0, 0, 0);", varname.Data());
549  else {
550  TString xname = varname;
551  xname.ReplaceAll("->At(","_sub");
552  xname.ReplaceAll(")","");
553  TString yname = xname + "_y";
554  xname = xname + "_x";
555  line.Form(" Double_t %s[%d], %s[%d];", xname.Data(), fxCut->GetN(), yname.Data(), fxCut->GetN());
556  out << line << std::endl;
557  for (Int_t n=0;n<fxCut->GetN();n++) {
558  Double_t x,y;
559  fxCut->GetPoint(n, x, y);
560  line.Form(" %s[%d] = %f; %s[%d] = %f;", xname.Data(), n, x, yname.Data(), n, y);
561  out << line << std::endl;
562  }
563  line.Form(" %s->SetValues(%s, %s, %d);", varname.Data(), xname.Data(), yname.Data(), fxCut->GetN());
564  }
565 
566  out << line << std::endl;
567 }
virtual void PrintCondition(Bool_t points=kTRUE)
Bool_t UrlOptionHasKey(const char *key)
static TString fgxURL_XPRE
Definition: TGo4PolyCond.h:131
virtual Double_t GetXUp()
virtual Bool_t UpdateFrom(TGo4Condition *cond, Bool_t counts)
virtual Double_t GetIntegral(TH1 *histo, Option_t *opt="")
virtual Int_t GetMemorySize()
Bool_t IsFalse() const
static TString NextAvailableName()
virtual Bool_t IsPolygonType()
virtual void PrintCondition(Bool_t full=kTRUE)
static void Warn(const char *text,...)
Definition: TGo4Log.cxx:296
TCutG * CloneCut(TGo4PolyCond *source)
void SetValuesDirect(TCutG *newcut)
TH2 * CreateCutHistogram(TH1 *source)
Bool_t IsEnabled() const
Definition: TGo4Condition.h:94
virtual Double_t GetYMax(TH1 *histo)
TCutG * fxCut
Definition: TGo4PolyCond.h:147
static void CleanupSpecials()
virtual void SetValues()
virtual Double_t GetXMax(TH1 *histo)
Bool_t FixedResult() const
virtual Double_t GetRMS(TH1 *histo, Int_t axis=1)
TCutG * GetCut(Bool_t changeowner)
static TString fgxURL_YPRE
Definition: TGo4PolyCond.h:133
virtual Double_t GetYUp()
virtual Double_t GetSkewness(TH1 *histo, Int_t axis=1)
virtual Bool_t UpdateFromUrl(const char *rest_url_opt)
virtual Bool_t UpdateFromUrl(const char *rest_url_opt)
virtual void SetPainter(TGo4ConditionPainter *painter)
virtual Double_t GetCurtosis(TH1 *histo, Int_t axis=1)
static const char * Message(Int_t prio, const char *text,...)
Definition: TGo4Log.cxx:209
Bool_t IsTrue() const
virtual void SetCondition(TGo4Condition *con)
const char * MakeScript(std::ostream &out, const char *varname, Option_t *opt="", const char *arrextraargs=0)
virtual ~TGo4PolyCond()
virtual void SavePrimitive(std::ostream &fs, Option_t *="")
virtual Bool_t Test()
Bool_t UpdateFrom(TGo4Condition *cond, Bool_t counts)
TGo4ConditionPainter * fxPainter
virtual TGo4ConditionPainter * CreatePainter()
Int_t GetUrlOptionAsInt(const char *key, Int_t def_value)
virtual Double_t GetCMax(TH1 *histo)
static TString fgxURL_NPOINTS
Definition: TGo4PolyCond.h:129
virtual Double_t GetXLow()
Double_t GetUrlOptionAsDouble(const char *key, Double_t def_value)
void SetDimension(Int_t d)
virtual Double_t GetYLow()
virtual Double_t GetMean(TH1 *histo, Int_t axis=1)