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