Skip to content
Snippets Groups Projects
gui.cpp 7.76 KiB
#include "gui.h"

MyMainFrame::MyMainFrame(const Setup* config_, const TGWindow *p,UInt_t w,UInt_t h): config(config_) {
   // use hierarchical cleaning
   fMain = new TGMainFrame(p,w,h);
   fMain->SetCleanup(kDeepCleanup);

   fMain->Connect("CloseWindow()", "MyMainFrame", this, "CloseWindow()");
   // create layout
   Init();
   canvas = fEcanvas->GetCanvas(); 
   canvas->Update();
   // popup window
   fMain->SetWindowName("Back projection reconstruction");
   fMain->MapSubwindows();
   fMain->Resize(fMain->GetDefaultSize());
   fMain->Resize(w, h);
   fMain->MapWindow();
}

MyMainFrame::~MyMainFrame() {
    // // Clean up used widgets: frames, buttons, layout hints
    // fMain->Cleanup();
    //buttons
    delete fF3;
    delete fL3;
    delete fStopB;
    delete fClearB;
    delete fStartB;
    // canvas
    delete fF5;
    delete fL4;
    delete fEcanvas;
    delete fMain;
    delete histo;
    for (int i = 0; i < Nl; i++)
    {
        delete latitudes[i];
    }
    for (int i = 0; i < NL; i++)
    {
        delete longitudes[i];
    }
    delete sourceMarker;
    delete countsText;
}

void MyMainFrame::CloseWindow() {
   // Got close message for this MainFrame. Terminates the application.
   gApplication->Terminate(0);
}

int MyMainFrame::Init(){
    // buttons
    fF3 = new TGCompositeFrame(fMain, 60, 20, kHorizontalFrame);
    fStartB = new TGTextButton(fF3, "Start");
    fStartB->Connect("Clicked()", "MyMainFrame", this, "Start()");
    fClearB = new TGTextButton(fF3, "Clear");
    fClearB->Connect("Clicked()", "MyMainFrame", this, "Clear()");
    fStopB = new TGTextButton(fF3, "Stop");
    fStopB->Connect("Clicked()", "MyMainFrame", this, "Stop()");

    fL3 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 
                        5, 5, 5, 5);
    fF3->AddFrame(fStartB, fL3);
    fF3->AddFrame(fClearB, fL3);
    fF3->AddFrame(fStopB, fL3);

    // embedded canvas
    fF5 = new TGCompositeFrame(fMain, 60, 60, kHorizontalFrame);
    fL4 = new TGLayoutHints(kLHintsTop | kLHintsLeft 
                            | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5);
    fEcanvas = new TRootEmbeddedCanvas("ec1", fF5, 100, 100);
    fF5->AddFrame(fEcanvas, fL4);
    fMain->AddFrame(fF3, fL3);
    fMain->AddFrame(fF5, fL4);

    initHist();
    drawGridlines();
    drawSource();
    std::string strtmp = "Total counts: " + std::to_string(counts);
    countsText = new TText(0.7, 0.92, strtmp.c_str());
    countsText->SetTextSizePixels(2);
    countsText->SetNDC(kTRUE);
    countsText->Draw("SAME");
    // end embeded canvas
    return 0;
}

void MyMainFrame::initHist() {
    histo = new TH2D("ROI", " ; Azimuth; Elevation", 
                            config->phiBins, -180, 180, 
                            config->thetaBins, -90, 90);
    // init image
    for (int i = 0; i < config->phiBins; i++)
    {
        for (int j = 0; j < config->thetaBins; j++)
        {
            histo->SetBinContent(i+1, j+1, 0);
        }
    }
    gStyle->SetOptStat(0);
    histo->GetZaxis()->SetLabelSize(0.02);
    histo->Draw("z aitoff");
}

void MyMainFrame::drawGridlines() {
    float conv=M_PI/180;
    float la, lo, x, y, z;
    for (int j=0;j<Nl;++j) {
        // latitudes[j]=new TGraph();
        latitudes.push_back(new TGraph());
        la = -90+180/(Nl-1)*j;
        for (int i=0;i<M+1;++i) {
            lo = -180+360/M*i;
            z  = sqrt(1+cos(la*conv)*cos(lo*conv/2));
            x  = 180*cos(la*conv)*sin(lo*conv/2)/z;
            y  = 90*sin(la*conv)/z;
            latitudes[j]->SetPoint(i,x,y);
        }
    } 
    
    for (int j=0;j<NL;++j) {
        // longitudes[j]=new TGraph();
        longitudes.push_back(new TGraph());
        lo = -180+360/(NL-1)*j;
        for (int i=0;i<M+1;++i) {
            la = -90+180/M*i;
            z  = sqrt(1+cos(la*conv)*cos(lo*conv/2));
            x  = 180*cos(la*conv)*sin(lo*conv/2)/z;
            y  = 90*sin(la*conv)/z;
            longitudes[j]->SetPoint(i,x,y);
        }
    }
    // Draw the grid	
    TPad *pad2 = new TPad("pad2","",0,0,1,1);
    pad2->SetFillStyle(4000);
    pad2->SetFillColor(0);
    pad2->SetBorderSize(0);
    pad2->SetFrameBorderMode(0);
    pad2->SetFrameLineColor(0); 
    pad2->SetFrameBorderMode(0);
    pad2->Draw();
    pad2->cd();
    Double_t ymin = -89.5;
    Double_t ymax = 89.5;
    Double_t dy = (ymax-ymin)/0.8; //10 per cent margins top and bottom
    Double_t xmin = -180;
    Double_t xmax = 180;
    Double_t dx = (xmax-xmin)/0.8; //10 per cent margins left and right

    pad2->Range(xmin-0.1*dx,ymin-0.1*dy,xmax+0.1*dx,ymax+0.1*dy);

    for (int j=0;j<Nl;++j) latitudes[j]->Draw("l");
    for (int j=0;j<NL;++j) longitudes[j]->Draw("l");
}

void MyMainFrame::drawSource() {
    // draw source marker
    float conv=M_PI/180;
    double sigma = 1;
    double Ax, Ay;
    aitoff2xy(config->truePhi / conv, config->trueTheta / conv, Ax, Ay);
    sourceMarker = new TEllipse(Ax, Ay, sigma, sigma);
    sourceMarker->SetFillColor(0);
    sourceMarker->SetFillStyle(0);
    sourceMarker->SetLineWidth(2);
    sourceMarker->SetLineColor(kRed);
    sourceMarker->Draw("SAME");
}

void MyMainFrame::Start()
{
//    printf("\"Start updating\" Button Pressed!\n");
   stop = false;
}

void MyMainFrame::Stop()
{
//    printf("\"Stop updating\" Button Pressed!\n");
   stop = true;
}

void MyMainFrame::Clear()
{
//    printf("\"Clear image\" Button Pressed!\n");
   counts = 0;
   histo->Reset();
   redraw();
}

void MyMainFrame::addCone(std::vector<Cone>::const_iterator first, 
                          std::vector<Cone>::const_iterator last)
{
    if (first == last)
    {
        return;
    }
    
    // project cones onto the spherical surface
    // std::cout << "Projecting cones onto the designated spherical surface..."<<std::endl;
    double alpha(0);
    double beta(0);
    double sgma2(0);
    double sgmb2(0);
    Vector3D ray;
    for (auto k = first; k < last; k++)    
    {
        // update the image
        alpha = k->cosHalfAngle;
        sgma2 = std::pow(0.511*k->E0/std::pow((k->E0-k->Edpst),2)*config->sgmE, 2);
        #pragma omp parallel for private(ray, beta, sgmb2)
        for (int i = 0; i < config->thetaBins; i++)
        {
            for (int j = 0; j < config->phiBins; j++)
            {
                ray = k->apex - config->xbs[i][j];
                beta = getCosAngle(ray, k->axis);
                sgmb2 = std::pow((ray/(ray*ray) + k->axis/(k->axis*k->axis)-
                                (ray+k->axis)/(ray*k->axis))*config->sgmpos * beta, 2);
                sgmb2+= std::pow((ray/(ray*k->axis)-k->axis/(k->axis*k->axis))*config->sgmpos * beta, 2);
                histo->SetBinContent(j+1, i+1, 
                    histo->GetBinContent(j+1, i+1) + 
                    std::exp(-std::pow((std::pow(beta, config->order)-std::pow(alpha, config->order)), 2)/
                             (2*std::pow(config->order, 2)*
                              (std::pow(alpha,2*config->order-2)*sgma2 +std::pow(beta, 2*config->order-2)*sgmb2))));              
            }
        }
    }
    counts += (last - first);
    // redraw
    redraw();
}


void MyMainFrame::redraw() {
    std::string strtmp = "Total counts: " + std::to_string(counts);
    countsText->SetText(0.7, 0.92, strtmp.c_str());
    canvas->Modified();
    canvas->Update();
}

int aitoff2xy(const double& l, const double& b, double &Al, double &Ab)
{
   Double_t x, y;

   Double_t alpha2 = (l/2)*TMath::DegToRad();
   Double_t delta  = b*TMath::DegToRad();
   Double_t r2     = TMath::Sqrt(2.);
   Double_t f      = 2*r2/TMath::Pi();
   Double_t cdec   = TMath::Cos(delta);
   Double_t denom  = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
   x      = cdec*TMath::Sin(alpha2)*2.*r2/denom;
   y      = TMath::Sin(delta)*r2/denom;
   x     *= TMath::RadToDeg()/f;
   y     *= TMath::RadToDeg()/f;
   //  x *= -1.; // for a skymap swap left<->right
   Al = x;
   Ab = y;

   return 0;
}