40 #include "KeySymbols.h"
50 #ifndef ROOT_TSpectrum
51 #include "TSpectrum.h"
62 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
66 #ifndef GW_MATPLAYER_H
75 Int_t MatPlayer::fLastX = 0, MatPlayer::fLastY = 0; TList *MatPlayer::fgPlayers = NULL;
77 MatPlayer::MatPlayer() : TNamed(
"Matplayer",
"To set gates interactively in a Canvas")
80 fMat = NULL; fPx = fPy = fTotx = fToty = fBx = fBy = NULL;
82 fLastGates.SetOwner(kTRUE);
85 gStyle->SetOptStat(0);
87 fStep.first = fStep.second = 1.0;
89 fWidthGate.first =
new TFormula(
"MatPlayer_WX",
"pol0"); fWidthGate.first->SetParameter(0,2.5);
90 fWidthGate.second =
new TFormula(
"MatPlayer_WY",
"pol0"); fWidthGate.second->SetParameter(0,2.5);
92 fBoxX.SetFillColor(2); fBoxX.SetFillStyle(3002);
93 fBoxY.SetFillColor(4); fBoxY.SetFillStyle(3013);
94 fBoxBX.SetFillColor(16); fBoxBX.SetFillStyle(3016);
95 fBoxBY.SetFillColor(16); fBoxBY.SetFillStyle(3020);
97 if ( fgPlayers == NULL ) { fgPlayers =
new TList(); fgPlayers->SetOwner(kTRUE); }
105 if ( fWidthGate.first )
delete fWidthGate.first;
if (fWidthGate.second )
delete fWidthGate.second;
107 fgPlayers->Remove(
this);
110 void MatPlayer::Clear(
const Option_t *)
112 if ( fTotx )
delete fTotx; fTotx = NULL;
if ( fToty )
delete fToty; fToty = NULL;
114 if ( fPx )
delete fPx; fPx = NULL;
if ( fPy )
delete fPy; fPy = NULL;
115 if ( fBx )
delete fBx; fBx = NULL;
if ( fBy )
delete fBy; fBy = NULL;
121 TVirtualPad *pad = TVirtualPad::Pad(); TCanvas *c = NULL;
124 c = pad->GetCanvas();
125 c->Clear(); c->Divide(1,1,0.001,0.001); c->cd(1);
128 if ( (c = dynamic_cast<TCanvas *>(gROOT->GetListOfCanvases()->FindObject(
"DefaultMatPlayer"))) == NULL ) {
129 c =
new TCanvas(
"DefaultMatPlayer",
"Canvas to interact with MatPlayer",1);
130 c->Divide(1,1,0.001,0.001); c->cd(1);
134 c->Connect(
"ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
135 "Gw::MatPlayer",
this,
"XEventAction(Int_t,Int_t,Int_t,TObject*)");
137 cout <<
" - Info - Interactive gating (by pressing any key) is now possible on any pad of the canvas " << c->GetName() <<
endl;
140 void MatPlayer::SetMatrix(
const char *matname)
142 TObject *obj = gDirectory->Get(matname);
144 cout <<
"Cannot find matrix named " << matname <<
" in the current TDirectory " <<
endl;
146 if ( obj->InheritsFrom(
"TH2") ) {
147 SetMatrix(dynamic_cast<TH2 *>(obj)); SetName(obj->GetName());
150 cout <<
"Object named " << matname <<
" is not a matrix !! " <<
endl;
154 void MatPlayer::SetMatrix(TH2 *mat)
156 TString hname; TH1D *Px, *Py, *Bx, *By, *Totx, *Toty;
159 if ( fMat == mat )
return;
161 fMat = mat; Totx = Toty = Px = Py = Bx = By = NULL;
164 if ( mat->GetDirectory() ) {
165 hname = mat->GetName(); hname +=
"_tx" ;
166 Totx =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
167 hname = mat->GetName(); hname +=
"_ty" ;
168 Toty =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
169 hname = mat->GetName(); hname +=
"_px" ;
170 Px =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
171 hname = mat->GetName(); hname +=
"_py" ;
172 Py =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
173 hname = mat->GetName(); hname +=
"_bx" ;
174 Bx =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
175 hname = mat->GetName(); hname +=
"_by" ;
176 By =
dynamic_cast<TH1D *
>( mat->GetDirectory()->Get(hname.Data()) );
179 if ( Totx == NULL ) { hname = mat->GetName(); hname +=
"_tx"; Totx = mat->ProjectionX(hname.Data()); }
180 if ( Toty == NULL ) { hname = mat->GetName(); hname +=
"_ty"; Toty = mat->ProjectionY(hname.Data()); }
183 if ( Px == NULL ) { hname = mat->GetName(); hname +=
"_px"; Px = (TH1D *)Totx->Clone(hname.Data()); Px->Reset(
"ICE"); }
184 if ( Py == NULL ) { hname = mat->GetName(); hname +=
"_py"; Py = (TH1D *)Toty->Clone(hname.Data()); Py->Reset(
"ICE"); }
187 if ( Bx == NULL ) hname = mat->GetName(); hname +=
"_bx"; Bx = (TH1D *)Totx->Clone(hname.Data()); Bx->Reset(
"ICE");
188 if ( By == NULL ) hname = mat->GetName(); hname +=
"_by"; By = (TH1D *)Toty->Clone(hname.Data()); By->Reset(
"ICE");
195 fPx =
dynamic_cast<TH1D *
>( Px->Clone(
"MatPlayer_px") ); fPx->SetDirectory(0);
196 fPy =
dynamic_cast<TH1D *
>( Py->Clone(
"MatPlayer_py") ); fPy->SetDirectory(0);
197 fBx =
dynamic_cast<TH1D *
>( Bx->Clone(
"MatPlayer_bx") ); fBx->SetDirectory(0);
198 fBy =
dynamic_cast<TH1D *
>( By->Clone(
"MatPlayer_by") ); fBy->SetDirectory(0);
200 fTotx =
dynamic_cast<TH1D *
>( Totx->Clone(
"MatPlayer_tx") ); fTotx->SetDirectory(0);
201 fToty =
dynamic_cast<TH1D *
>( Toty->Clone(
"MatPlayer_ty") ); fToty->SetDirectory(0);
209 if ( opt.Contains(
"Gx") )
return fWidthGate.first->Eval(pos);
210 else return fWidthGate.second->Eval(pos);
216 bool isTH2; TString opt = o; Double_t w, x1, x2, y1, y2; TH1 *hist; TObject *obj; TFrame *frame;
219 TVirtualPad *pad = TVirtualPad::Pad();
if ( pad == NULL )
return;
220 posx = pad->PadtoX(pad->AbsPixeltoX(fLastX));
221 posy = pad->PadtoY(pad->AbsPixeltoY(fLastY));
223 TIter next(pad->GetListOfPrimitives());
224 frame = pad->GetFrame();
227 while ( (obj = next()) ) {
228 if ( obj->InheritsFrom(
"TH1") ) {
229 hist =
dynamic_cast<TH1 *
>(obj);
if ( obj->InheritsFrom(
"TH2") ) isTH2 =
true;
break; }
231 if ( hist == NULL || frame == NULL ) { cout <<
"Cannot add a gate, no spectrum selected " <<
endl;
return; }
236 x1 = posx-w/2.0; y1 = frame->GetY1(); x2 = posx+w/2.0; y2 = frame->GetY2();
239 if ( opt.Contains(
"Gy") ) {
243 x1 = frame->GetX1(); y1 = posy-w/2.0; x2 = frame->GetX2(); y2 =posy+w/2.0;
247 x1 = posx-w/2.0; y1 = frame->GetY1(); x2 = posx+w/2.0; y2 = frame->GetY2();
250 if ( opt.Contains(
"Bx") ) {
252 x1 = posx-w/2.0; y1 = frame->GetY1(); x2 = posx+w/2.0; y2 = frame->GetY2();
254 if ( opt.Contains(
"By") ) {
258 x1 = frame->GetX1(); y1 = posy-w/2.0; x2 = frame->GetX2(); y2 =posy+w/2.0;
262 x1 = posx-w/2.0; y1 = frame->GetY1(); x2 = posx+w/2.0; y2 = frame->GetY2();
267 box->DrawBox(x1,y1,x2,y2); pad->Update();
270 bool MatPlayer::IsBox(
const TBox *box,
const TBox *boxref)
const
272 return ( box->GetFillStyle() == boxref->GetFillStyle() && box->GetFillColor() == boxref->GetFillColor() );
280 TObject *obj; TString opt = o;
282 if ( TVirtualPad::Pad() == NULL )
return 0;
284 TIter next(TVirtualPad::Pad()->GetListOfPrimitives());
285 bool isTH2 =
false, overlap;
286 while ( (obj = next()) ) {
287 if ( obj->InheritsFrom(
"TH1") ) {
288 if ( obj->InheritsFrom(
"TH2") ) isTH2 =
true;
break; }
292 TBox *boxnew, *boxadd ; fLastGates.Delete();
296 while ( (boxnew = (TBox *)next()) ) {
297 if ( boxnew->InheritsFrom(
"TBox") && opt.Contains(
"x") ) {
299 if ( IsBox(boxnew,&fBoxX) ) {
301 TIter existing(&fLastGates);
303 while ( (boxadd = (TBox *)existing()) ) {
304 if ( (boxnew->GetX1() >= boxadd->GetX1() && boxnew->GetX1() <= boxadd->GetX2()) ||
305 (boxnew->GetX2() >= boxadd->GetX1() && boxnew->GetX2() <= boxadd->GetX2()) ) { overlap =
true;
break; }
307 if ( overlap ==
false ) { fLastGates.Add(boxnew->Clone()); }
309 boxadd->SetX1( TMath::Min(boxadd->GetX1(),boxnew->GetX1()) );
310 boxadd->SetX2( TMath::Max(boxadd->GetX2(),boxnew->GetX2()) );
314 if ( IsBox(boxnew,&fBoxBX) ) {
316 TIter existing(&fLastGates);
318 while ( (boxadd = (TBox *)existing()) ) {
319 if ( (boxnew->GetX1() >= boxadd->GetX1() && boxnew->GetX1() <= boxadd->GetX2()) ||
320 (boxnew->GetX2() >= boxadd->GetX1() && boxnew->GetX2() <= boxadd->GetX2()) ) { overlap = kTRUE;
break; }
322 if ( overlap ==
false ) { fLastGates.Add(boxnew->Clone()); }
324 boxadd->SetX1( TMath::Min(boxadd->GetX1(),boxnew->GetX1()) );
325 boxadd->SetX2( TMath::Max(boxadd->GetX2(),boxnew->GetX2()) );
329 if ( boxnew->InheritsFrom(
"TBox") && opt.Contains(
"y") ) {
332 Double_t realY1, realY2;
334 realY1 = boxnew->GetY1();
335 realY2 = boxnew->GetY2();
338 realY1 = boxnew->GetX1();
339 realY2 = boxnew->GetX2();
341 if ( IsBox(boxnew,&fBoxY) ) {
343 TIter existing(&fLastGates);
345 while ( (boxadd = (TBox *)existing()) ) {
346 if ( (realY1 >= boxadd->GetY1() && realY1 <= boxadd->GetY2()) ||
347 (realY2 >= boxadd->GetY1() && realY2 <= boxadd->GetY2()) ) { overlap =
true;
break; }
349 if ( overlap ==
false ) {
350 TBox *box =
dynamic_cast<TBox *
>(boxnew->Clone());
356 boxadd->SetY1( TMath::Min(boxadd->GetY1(),realY1) );
357 boxadd->SetY2( TMath::Max(boxadd->GetY2(),realY2) );
361 if ( IsBox(boxnew,&fBoxBY) ) {
363 TIter existing(&fLastGates);
365 while ( (boxadd = (TBox *)existing()) ) {
366 if ( (realY1 >= boxadd->GetY1() && realY1 <= boxadd->GetY2()) ||
367 (realY2 >= boxadd->GetY1() && realY2 <= boxadd->GetY2()) ) { overlap =
true;
break; }
369 if ( overlap ==
false ) {
370 TBox *box =
dynamic_cast<TBox *
>(boxnew->Clone());
376 boxadd->SetX1( TMath::Min(boxadd->GetX1(),realY1) );
377 boxadd->SetX2( TMath::Max(boxadd->GetX2(),realY2) );
384 cout <<
" Nb Gates found in the current pad : " << fLastGates.GetSize() <<
endl;
return fLastGates.GetSize();
394 TObject *obj; TBox *box; TString opt = o;
396 if ( TVirtualPad::Pad() == NULL ) return ;
398 TIter next(TVirtualPad::Pad()->GetListOfPrimitives());
400 while ( (obj = next()) ) {
401 if ( obj->InheritsFrom(
"TH1") ) {
402 if ( obj->InheritsFrom(
"TH2") )
break; }
405 TFrame *frame = TVirtualPad::Pad()->GetFrame();
407 TIter existing(&fLastGates);
408 while ( (box = (TBox *) existing()) ) {
410 if ( IsBox(box,&fBoxX) ) {
411 box->DrawBox(box->GetX1(),frame->GetY1(),box->GetX2(),frame->GetY2());
413 if ( IsBox(box,&fBoxBX) ) {
414 box->DrawBox(box->GetX1(),frame->GetY1(),box->GetX2(),frame->GetY2());
422 TObject *obj; TList toremove;
424 if ( TVirtualPad::Pad() == NULL )
return;
426 TIter next(TVirtualPad::Pad()->GetListOfPrimitives());
427 while ( (obj = next()) ) {
428 if ( obj->InheritsFrom(
"TBox") ) { toremove.Add(obj); }
430 TIter
remove(&toremove);
431 while ( (obj =
remove()) ) {
432 TVirtualPad::Pad()->GetListOfPrimitives()->Remove(obj);
436 TVirtualPad::Pad()->Update();
442 TString opt = option;
444 if ( fMat == NULL ) {
445 cout <<
"Cannot Project in MatPlayer::ProjectionY, no matrix selected ! " <<
endl;
return;
450 fPy->Reset(
"ICE"); fBy->Reset(
"ICE");
452 bool isbg; Float_t w, wb; TBox *box; TH1D *h, *hb;
454 isbg =
false; w = wb = 0.0; h = hb = NULL;
455 TIter next(&fLastGates);
456 while ( (box = (TBox *)next()) ) {
457 if ( IsBox(box,&fBoxX) ) {
458 w += box->GetX2() - box->GetX1();
459 fPy->Add( h = fMat->ProjectionY(
"MatPlayer_tmp_py",fPx->FindBin(box->GetX1()),fPx->FindBin(box->GetX2()) ) );
461 if ( IsBox(box,&fBoxBX) ) {
462 isbg =
true; wb += box->GetX2() - box->GetX1();
463 fBy->Add( hb = fMat->ProjectionY(
"MatPlayer_tmp_by",fPx->FindBin(box->GetX1()),fPx->FindBin(box->GetX2()) ) );
466 if ( h )
delete h;
if ( hb )
delete hb;
471 hb =
dynamic_cast<TH1D *
>( fMat->GetDirectory()->Get( Form(
"%s_by",fMat->GetName()) ) );
479 h =
dynamic_cast<TH1D *
>( fMat->GetDirectory()->Get( Form(
"%s_py",fMat->GetName()) ) );
485 fPy->Draw(); cout <<
" Projection on Y DONE \n ";
493 TVirtualPad *pad = gROOT->GetSelectedPad();
if ( pad == NULL )
return;
498 fLastX = px; fLastY = py;
503 Int_t key = px, keysym = py;
504 switch ((EKeySym)keysym) {
506 cout<<
"left arrow"<<
endl;
509 cout<<
"rightarrow"<<
endl;
512 cout<<
"down arrow"<<
endl;
515 cout<<
"up arrow"<<
endl;
538 cout <<
"Keys used to interact with MatPlayer: " <<
endl;
539 cout <<
"\t x: add a gate on the x-axis " <<
endl;
540 cout <<
"\t y: add a gate on the y-axis " <<
endl;
541 cout <<
"\t b: background gate on the x-axis " <<
endl;
542 cout <<
"\t B: background gate on the y-axis " <<
endl;
543 cout <<
"\t X: Processed X-Gating " <<
endl;
544 cout <<
"\t Y: Processed Y-Gating " <<
endl;
545 cout <<
"\t r: Remove all gates in the current pad " <<
endl;
546 cout <<
"\t s: Show last gates in the current pad " <<
endl;
549 Reset(); pad->Update();
556 if ( gDebug ) cout <<
"key " << key <<
"key " << keysym <<
endl;
567 TString opt = option;
570 if ( (!opt.Contains(
"RAD")) && (!opt.Contains(
"SNIP")) ) {
571 cout <<
"Bad options - Choose 'RAD' or 'SNIP' " <<
endl;
return;
574 TObject *obj = gROOT->FindObject(matname);
576 cout <<
"Cannot find matrix named " << matname <<
endl;
578 if ( obj->InheritsFrom(
"TH2") ) {
579 if ( opt.Contains(
"RAD") ) SubstractBG_RAD((TH2 *)obj);
580 if ( opt.Contains(
"SNIP")) SubstractBG_SNIP((TH2 *)obj);
582 else cout <<
"Object named "<< matname <<
" is not a matrix !! ";
586 void MatPlayer::SubstractBG_RAD(TH2 *mat)
588 Int_t i, j; TSpectrum worker;
591 Float_t *ptoti, *ptotj, *bgi, *bgj; Stat_t T;
594 proji = mat->ProjectionX(
"tmp_rad_x"); projj = mat->ProjectionY(
"tmp_rad_y");
597 proji->Smooth(2); projj->Smooth(2);
601 cout <<
" Number of counts in the gamma-gamma matrix: " << T <<
endl;
603 ptoti =
new Float_t[mat->GetNbinsX()]; bgi =
new Float_t[mat->GetNbinsX()];
604 ptotj =
new Float_t[mat->GetNbinsY()]; bgj =
new Float_t[mat->GetNbinsY()];
605 for ( i = 0; i < mat->GetNbinsX(); i++ ) { ptoti[i] = bgi[i] = proji->GetBinContent(i+1); }
606 for ( j = 0; j < mat->GetNbinsY(); j++ ) { ptotj[j] = bgj[j] = projj->GetBinContent(j+1); }
608 delete proji;
delete projj;
616 cout <<
" Background substraction on " << mat->GetName() <<
" by using the RADFORD procedure ..." <<
endl;
619 for ( i = 0; i < mat->GetNbinsX(); i++ ) {
620 for ( j = 0; j < mat->GetNbinsY(); j++ ) {
622 cout <<
" [" << i <<
"," << j <<
"] \r" ;
625 c = mat->GetBinContent(i+1,j+1);
626 c = c - (ptoti[i]*ptotj[j] - (ptoti[i]-bgi[i])*(ptotj[j]-bgj[j]))/T;
627 if ( c < 0 && c < cmin ) { cmin = c; }
629 mat->SetBinContent(i+1,j+1,c);
632 cout <<
" ... DONE. Lowest value in the background substracted matrix " << cmin <<
endl;
634 delete [] ptoti;
delete [] ptotj;
delete [] bgi;
delete [] bgj;
637 void MatPlayer::SubstractBG_SNIP(TH2 *mat)
645 cout <<
"*********************************************\n";
646 cout <<
"* Background Substraction with SNIP Procedure\n";
647 cout <<
"* Number of iterations : " << param <<
endl;
648 cout <<
"*********************************************\n";
649 cout <<
"* TH2 name : " << mat->GetName() <<
endl;
652 Float_t **v, **w, **y;
654 Double_t P1, P2, P3, P4, S1, S2, S3, S4, a1, a2;
657 dimX = mat->GetNbinsX(); dimY = mat->GetNbinsY();
658 if (dimX <= 0) {cout <<
"Error, dimX <= 0\n";
return;}
659 if (dimY <= 0) {cout <<
"Error, dimY <= 0\n";
return;}
661 v =
new Float_t*[dimX]; w =
new Float_t*[dimX], y =
new Float_t*[dimX];
662 for (Int_t i=0 ; i<dimX ; i++){
663 v[i] =
new Float_t[dimY];
664 w[i] =
new Float_t[dimY];
665 y[i] =
new Float_t[dimY];
669 for (Int_t i=0 ; i<dimX ; i++){
670 for (Int_t j=0 ; j<dimY ; j++){
671 y[i][j] = mat->GetBinContent(i+1,j+1);
672 v[i][j] = mat->GetBinContent(i+1,j+1);
678 for (Int_t i=0 ; i<dimX ; i++){
679 for (Int_t j=0 ; j<dimY ; j++){
680 v[i][j] = TMath::Log( TMath::Log( TMath::Sqrt(y[i][j] + 1) + 1) + 1);
686 for (Int_t p=1 ; p<=param ; p++){
687 for (Int_t i=p ; i<dimX-p ; i++){
688 for (Int_t j=p ; j<dimY-p ; j++){
699 S1 = TMath::Max(S1,(P1+P3)/2) - (P1+P3)/2;
700 S2 = TMath::Max(S2,(P1+P2)/2) - (P1+P2)/2;
701 S3 = TMath::Max(S3,(P3+P4)/2) - (P3+P4)/2;
702 S4 = TMath::Max(S4,(P2+P4)/2) - (P2+P4)/2;
705 a2 = (S1+S4)/2 + (S2+S3)/2 + (P1+P2+P3+P4)/4;
706 w[i][j] = TMath::Min(a1,a2);
709 for (Int_t i=p ; i<dimX-p ; i++){
710 for (Int_t j=p ; j<dimY-p ; j++){
732 for (Int_t i=0 ; i<dimX ; i++){
733 for (Int_t j=0 ; j<dimY ; j++){
734 v[i][j] = TMath::Exp( TMath::Exp( v[i][j] - 1) -1 ) * TMath::Exp( TMath::Exp( v[i][j]-1) - 1) -1;
740 for (Int_t i=0 ; i<dimX ; i++){
741 for (Int_t j=0 ; j<dimY ; j++){
742 mat->SetBinContent(i+1,j+1,y[i][j]-v[i][j]);
747 for (Int_t i=0 ; i<dimX ; i++){
void SetCanvas()
set current canvas as the mother of the current pad
Int_t InitGating(Option_t *opt="Gx")
static void SubstractBG(const char *, Option_t *)
Generic method to substract background of the current matrix.
Double_t GetWidthGate(Double_t pos, Option_t *opt="Gx")
get width for gate at position pos
void ShowGates(Option_t *o="BGx")
to show the gates used for the last gating
void SetGateX(Option_t *opt="Gx")
set a gate using the last mouse position
void Reset()
to reset the conditions of gating in the current pad
void ProjectionY(Option_t *option)
to project
ADF::LogMessage & endl(ADF::LogMessage &log)
MatPlayer is a tool to play with 2D matrices.
void XEventAction(Int_t event, Int_t px, Int_t py, TObject *obj)
slots