#include "CXTH1Proj.h" #include #include #include #include #include "TH2.h" #include "TCanvas.h" #include "KeySymbols.h" #include "TPadPainter.h" #include "TColor.h" #include "TROOT.h" #include "TFrame.h" #include "TError.h" #include "CXMainWindow.h" #include "CXHist2DPlayer.h" #include "CXGateBox.h" using namespace std; CXTH1Proj::CXTH1Proj(const TH1D &hist): TH1D::TH1D(hist) { GetXaxis()->SetTitle("Energy (kev) [X axis]"); GetXaxis()->SetTitleSize(0.05); GetXaxis()->SetTitleOffset(0.8); GetXaxis()->SetTitleFont(132); GetXaxis()->SetLabelFont(132); GetYaxis()->SetTitle(Form("Counts/%g kev",GetBinWidth(1))); GetYaxis()->SetTitleSize(0.05); GetYaxis()->SetTitleOffset(0.5); GetYaxis()->SetTitleFont(132); GetYaxis()->SetLabelFont(132); fListOfGates = new TList; fListOfGates->SetOwner(); fListOfGates->SetName("ListOfGates"); SetStats(); } CXTH1Proj::CXTH1Proj(): TH1D::TH1D() { fListOfGates = new TList; fListOfGates->SetOwner(); fListOfGates->SetName("ListOfGates"); SetStats(); } CXTH1Proj::~CXTH1Proj() { delete fListOfGates; } void CXTH1Proj::UpdateProjection(Int_t Axis) { if(fGGHist->GetXaxis()->GetNbins() != fGGHist->GetYaxis()->GetNbins()) { WARN_MESS << "X and Y axis needs to have the same number of bins for GG projections" << ENDL; return; } if(Axis == 0) { GetXaxis()->SetTitle("Energy (kev) [X axis]"); TH1 *projtmp = fGGHist->ProjectionX(); for(int i=0 ; iGetNbinsX()+2 ; i++) SetBinContent(i,projtmp->GetBinContent(i)); delete projtmp; } else if(Axis == 1) { GetXaxis()->SetTitle("Energy (kev) [Y axis]"); TH1 *projtmp = fGGHist->ProjectionY(); for(int i=0 ; iGetNbinsX()+2 ; i++) SetBinContent(i,projtmp->GetBinContent(i)); delete projtmp; } fProjectionAxis = Axis; fCurrentPad->Modified(); fCurrentPad->Update(); } void CXTH1Proj::SetPlayer(CXHist2DPlayer *p) { f2DPlayer = p; } void CXTH1Proj::SetMainWindow(CXMainWindow *w) { fMainWindow = w; } void CXTH1Proj::SetTH2(TH2 *hist) { if(fGGHist) delete fGGHist; fGGHist = (TH2*)hist->Clone(); } void CXTH1Proj::SetProjPad(TPad *pad) { fProjPad = pad; } void CXTH1Proj::SetCurrentPad(TPad *pad) { fCurrentPad = pad; fCurrentPad->GetCanvas()->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", "CXTH1Proj", this, "HandleMovement(Int_t,Int_t,Int_t, TObject*)"); fCurrentPad->Connect("RangeChanged()", "CXTH1Proj", this, "UpdateGates()"); fCurrentPad->Connect("RangeAxisChanged()", "CXTH1Proj", this, "UpdateGates()"); fCurrentPad->Connect("Resized()", "CXTH1Proj", this, "UpdateGates()"); fCurrentPad->Connect("UnZoomed()", "CXTH1Proj", this, "UpdateGates()"); } void CXTH1Proj::AddBackgd(Float_t Mean, Float_t Width) { CXGateBox *box = new CXGateBox(Mean,Width,fCurrentPad); box->SetBGD(); fListOfGates->Add(box); box->Draw(); fAddNewBacground = false; } void CXTH1Proj::AddGate1(Float_t Mean, Float_t Width) { CXGateBox *box = new CXGateBox(Mean,Width,fCurrentPad); box->SetGate1(); fListOfGates->Add(box); fCurrentPad->cd(); box->Draw(); fAddNewGate = false; } void CXTH1Proj::Project(Bool_t FixRange){ Float_t SavedRange[2]; if( FixRange ){ if(fMainWindow->GetHisto(fProjPad)){ SavedRange[0] = fProjPad->GetUxmin(); SavedRange[1] = fProjPad->GetUxmax(); } } Float_t TotalGateWidth = 0; Float_t TotalBGDWidth = 0; TString ProjName = Form("%s_Proj",fGGHist->GetName()); TString NameGates = ""; TString NameBGD = ""; for(int i=0 ; iGetEntries() ; i++) { CXGateBox* box = static_cast(fListOfGates->At(i)); if(box->IsBGD()){ TotalBGDWidth += box->GetWidth(); NameBGD += Form("_B%.1f(%.1f)",box->GetCentroid(),box->GetWidth()); } else if(box->IsGate2()){ WARN_MESS << "Cube gates not possible in GG mode, ignores" << ENDL; } else{ TotalGateWidth += box->GetWidth(); NameGates += Form("_E%.1f(%.1f)",box->GetCentroid(),box->GetWidth()); } } ProjName += NameGates + NameBGD; if(gROOT->FindObject(ProjName.Data())) delete gROOT->FindObject(ProjName.Data()); gErrorIgnoreLevel = kError; TH1D *FinalProj = fGGHist->ProjectionX("tempproj"); FinalProj->SetStats(); FinalProj->Reset(); FinalProj->SetName(ProjName.Data()); FinalProj->SetTitle(ProjName.Data()); Float_t WidthRef = FinalProj->GetBinWidth(1); TString XAxis = GetXaxis()->GetTitle(); if(XAxis.Contains("[X")) XAxis.ReplaceAll("[X","[Y"); else if(XAxis.Contains("[Y")) XAxis.ReplaceAll("[Y","[X"); FinalProj->GetXaxis()->SetTitle(XAxis); FinalProj->GetXaxis()->SetTitleSize(GetXaxis()->GetTitleSize()); FinalProj->GetXaxis()->SetTitleOffset(GetXaxis()->GetTitleOffset()); FinalProj->GetXaxis()->SetTitleFont(GetXaxis()->GetTitleFont()); FinalProj->GetXaxis()->SetLabelFont(GetXaxis()->GetLabelFont()); FinalProj->GetYaxis()->SetTitle(GetYaxis()->GetTitle()); FinalProj->GetYaxis()->SetTitleSize(GetYaxis()->GetTitleSize()); FinalProj->GetYaxis()->SetTitleOffset(GetYaxis()->GetTitleOffset()); FinalProj->GetYaxis()->SetTitleFont(GetYaxis()->GetTitleFont()); FinalProj->GetYaxis()->SetLabelFont(GetYaxis()->GetLabelFont()); for(int i=0 ; iGetEntries() ; i++) { CXGateBox* box = static_cast(fListOfGates->At(i)); Float_t X1 = box->GetX1(); Float_t X2 = box->GetX2(); Float_t BinX1 = fGGHist->GetXaxis()->FindBin(X1); Float_t BinX2 = fGGHist->GetXaxis()->FindBin(X2); // cout<<"add_gate("<ProjectionX("tmp",ibin,ibin); temp->Scale(FinalProj->GetBinWidth(ibin)/WidthRef); FinalProj->Add(temp,Weight); delete temp; } } INFO_MESS<<"Integral of projection: "<Integral()<cd(); FinalProj->Draw("hist"); if(FixRange) FinalProj->GetXaxis()->SetRangeUser(SavedRange[0],SavedRange[1]); gErrorIgnoreLevel = kPrint; fProjPad->Update(); fProjPad->Modified(); fProjPad->SetBit(TPad::kCannotMove); fProjPad->GetFrame()->SetBit(TObject::kCannotPick); } void CXTH1Proj::ClearGates(){ fListOfGates->Clear(); UpdateGates(); } void CXTH1Proj::RemoveGate(CXGateBox *box){ fCurrentPad->GetListOfPrimitives()->Remove(box); fListOfGates->Remove(box); UpdateGates(); } void CXTH1Proj::HandleMovement(Int_t EventType, Int_t EventX, Int_t EventY, TObject *selected) { // cout<GetSelectedPad() == fCurrentPad) ClearGates(); if( KeySym == kKey_p ) f2DPlayer->Project(); if( KeySym == kKey_d && selected && selected->InheritsFrom("CXGateBox")) RemoveGate(((CXGateBox*)selected)); if( KeySym == kKey_l ) f2DPlayer->ApplyLastGate(); UpdateGates(); break; } case kButton1Down:{ if(!fAddNewGate && !fAddNewBacground) break; if(selected && selected->InheritsFrom("TAxis")) break; gPad = fCurrentPad; gVirtualX->SetLineWidth(1); gPad->GetCanvas()->FeedbackMode(kTRUE); // to draw in rubberband mode oldx = gPad->AbsPixeltoX(gPad->GetCanvas()->GetEventX()); oldy = gPad->AbsPixeltoY(gPad->GetCanvas()->GetEventY()); xinit = oldx; yinit = oldy; ((TPadPainter*)gPad->GetPainter())->DrawBox(xinit,yinit,xinit,yinit, TVirtualPadPainter::kHollow); fGateVirtualBox = new TBox(xinit, yinit, xinit, yinit); Int_t ci; if(fAddNewBacground) ci = TColor::GetColor("#7d7dff"); else ci = TColor::GetColor("#ff7d7d"); TColor *zoomcolor = gROOT->GetColor(ci); if (!TCanvas::SupportAlpha() || !zoomcolor) fGateVirtualBox->SetFillStyle(3002); else zoomcolor->SetAlpha(0.5); fGateVirtualBox->SetFillColor(ci); fGateVirtualBox->Draw(); gPad->Update(); gPad->Modified(); moved = true; break; } case kButton1Motion:{ if(!fAddNewGate && !fAddNewBacground) break; if(moved==false) break; gPad = fCurrentPad; // don't use cd() because we won't draw in pad gPad->GetPainter()->SetFillStyle(kFDotted1); gPad->GetPainter()->SetFillColor(kRed); ((TPadPainter*)gPad->GetPainter())->DrawBox(xinit,yinit,oldx,oldy, TVirtualPadPainter::kHollow); oldx = gPad->AbsPixeltoX(gPad->GetCanvas()->GetEventX()); oldy = gPad->AbsPixeltoY(gPad->GetCanvas()->GetEventY()); if (fGateVirtualBox){ fGateVirtualBox->SetX1(xinit); fGateVirtualBox->SetY1(yinit); fGateVirtualBox->SetX2(oldx); fGateVirtualBox->SetY2(oldy); } gPad->Modified(); gPad->Update(); xmax = oldx; ymax = oldy; xmin = xinit; ymin = yinit; Double_t toto = 0; if (xmax < xmin){ toto = xmax; xmax = xmin; xmin = toto; } if (ymax < ymin){ toto = ymax; ymax = ymin; ymin = toto; } break; } case kButton1Up:{ if(!fAddNewGate && !fAddNewBacground){ UpdateGates(); break; } if(moved){ gPad = fCurrentPad; Float_t Mean = (xmax+xmin)/2; Float_t Width = (xmax-xmin)/2.; if(fAddNewGate) AddGate1(Mean,Width); if(fAddNewBacground) AddBackgd(Mean,Width); xmax = xmin = ymax = ymin = 0.; } moved = false; if (fGateVirtualBox) { fGateVirtualBox->Delete(); fGateVirtualBox = nullptr; } UpdateGates(); break; } default:{ break; } } } void CXTH1Proj::UpdateGates() { fCurrentPad->Modified(); fCurrentPad->Update(); for(int i=0 ; iGetEntries() ; i++){ CXGateBox* box = static_cast(fListOfGates->At(i)); box->Update(); } fCurrentPad->Modified(); fCurrentPad->Update(); } ClassImp(CXTH1Proj)