#include "TPeakFitGUI.h"

ClassImp(TPeakFitGUI)

#define __FITGUIW__ 300
#define __FITGUIH__ 280
#define POS(A,B) A+B*16

TPeakFitGUI::TPeakFitGUI(TH1* hist, TVirtualPad* pad):TGTransientFrame(gClient->GetRoot(),gClient->GetRoot(),__FITGUIW__,__FITGUIH__)
{
  char title[200];
  int w = __FITGUIW__;
  int h = __FITGUIH__;
  TString system = gSystem->GetBuildArch();
  if(system.BeginsWith("linux"))
  {
    mFrame1 = new TGGroupFrame(this," Peaks ");
    mFrame1->MoveResize(4,4,w-8,77);
    mFrame2 = new TGGroupFrame(this," Background ");
    mFrame2->MoveResize(4,80,w-8,77);
  }
  else
  {
    TGHorizontal3DLine *h;
    TGVertical3DLine *v;
    TGLabel *l = new TGLabel(this," Peaks ");
    l->MoveResize(16,4);
    int x = 4;
    int y = 10;
    int wid = w-8;
    int hei = 62;
    h = new TGHorizontal3DLine(this,wid); h->Move(x,y);
    h = new TGHorizontal3DLine(this,wid); h->Move(x,y+hei-1);
    v = new TGVertical3DLine(this,2,hei); v->Move(x,y);
    v = new TGVertical3DLine(this,2,hei); v->Move(x+wid-1,y);

    l = new TGLabel(this," Background ");
    l->MoveResize(16,80);

    y = 86;
    h = new TGHorizontal3DLine(this,wid); h->Move(x,y);
    h = new TGHorizontal3DLine(this,wid); h->Move(x,y+hei-1);
    v = new TGVertical3DLine(this,2,hei); v->Move(x,y);
    v = new TGVertical3DLine(this,2,hei); v->Move(x+wid-1,y);
  }

  mP1 = new TGRadioButton(this,"Peaks",101);
  mP2 = new TGRadioButton(this,"Peaks + 1 width",102);
  mP3 = new TGRadioButton(this,"Peaks + width",103);
  mPC1 = new TGCheckButton(this,"Asymm. gaus",100);
  mPC2 = new TGCheckButton(this,"Same width",106);
  mP1->Move(8,POS(4,1));
  mP2->Move(8,POS(4,2));
  mP3->Move(8,POS(4,3));
  mPC1->Move(125,POS(4,1));
  mPC2->Move(125,POS(4,2));

  mB1 = new TGRadioButton(this,"None",201);
  mB2 = new TGRadioButton(this,"Const",202);
  mB3 = new TGRadioButton(this,"1st degree",203);
  mB4 = new TGRadioButton(this,"      degree",206);
  mBC1 = new TGCheckButton(this,"Independent",100);
  mBP = new TGTextEntry(this,"",-1);
  mB1->Move(8,POS(80,1));
  mB2->Move(8,POS(80,2));
  mB3->Move(8,POS(80,3));
  mB4->Move(125,POS(80,1));
  mBP->MoveResize(140,POS(80,1),24,16);
  mBC1->Move(125,POS(80,3));

  mPGrab = new TGTextButton(this,"Grab",104);
  mPReset = new TGTextButton(this,"Reset",105);
  mPGrab->MoveResize(230,POS(4,1),60,22);
  mPReset->MoveResize(230,POS(4,1)+26,60,22);

  mBGrab = new TGTextButton(this,"Grab",204);
  mBReset = new TGTextButton(this,"Reset",205);
  mBGrab->MoveResize(230,POS(80,1),60,22);
  mBReset->MoveResize(230,POS(80,1)+26,60,22);

  mDet = new TGTextButton(this,"Details",999);
  mFit = new TGTextButton(this,"Fit",1000);
  mImp = new TGTextButton(this,"Improve fit",1006);
  mReset = new TGTextButton(this,"Reset",1001);

  mDraw = new TGTextButton(this,"Draw",1003);
  mClear = new TGTextButton(this,"Clear",1004);
  mPrint = new TGTextButton(this,"Print",1005);

  mClose = new TGTextButton(this,"Close",1002);

  mDet->MoveResize(4,160,w/3-4,25);
  mReset->MoveResize(w/3+2,160,w/3-4,25);
  mClose->MoveResize(2*w/3,160,w/3-4,25);
  mDraw->MoveResize(4,190,w/3-4,25);
  mClear->MoveResize(w/3+2,190,w/3-4,25);
  mPrint->MoveResize(2*w/3,190,w/3-4,25);
  mFit->MoveResize(4,220,w-4,25);
  mImp->MoveResize(4,250,w-4,25);

  MapSubwindows();
  MapWindow();
  SetWMSizeHints(w, h, w, h,1,1);

  mTrash1 = new TContainer();
  mTrash1->setSizeMax(500);
  mTrash2 = new TContainer();
  mTrash2->setSizeMax(500);

  mPeakFit = new TPeakFit();
  mPeakFit->setHist(hist);
  mGrabPad = pad;

  gROOT->Add(this);
  TList *l = gROOT->GetList();
  int n = l->GetSize();
  int id = -1;
  for(int i=0;i<n;i++) if(l->At(i)==this) { id=i; break;}
  if(id<0) cout<<"Could not find pointer to this class\n";
  else
  {
    mCommand = "((TPeakFitGUI*)(gROOT->GetList()->At(";
    mCommand+=id;
    mCommand+= ")))->grab();";
    //cout <<mCommand<<endl;
  }

  if(!hist) delete this;
  sprintf(title,"Peak fit - %s",hist->GetName());
  SetWindowName(title);

  reset();

}
TPeakFitGUI::~TPeakFitGUI()
{
  delete mPeakFit;
  delete mTrash1;
  delete mTrash2;
  mGrabPad->Update();

  //GUI elements are deleted automatically????
  /*
  delete mFit;
  delete mP1;
  delete mP2;
  delete mP3;
  delete mB1;
  delete mB2;
  delete mB3;
  delete mB4;
  delete mPC1;
  delete mPC2;
  delete mBC1;
  delete mPGrab;
  delete mPReset;
  delete mBGrab;
  delete mBReset;
  delete mDet;
  delete mReset;
  delete mClose;
  delete mFrame1;
  delete mFrame2;
  */

}
void TPeakFitGUI::reset(int mode)
{
  mFitDone = false;
  if(mode==0 || mode==1)
  {
    mP1->SetState(kButtonDown);
    mP2->SetState(kButtonUp);
    mP3->SetState(kButtonUp);
    mPC1->SetState(kButtonUp);
    mPC2->SetState(kButtonUp);
    mTrash1->empty();
    mNP = 0;
    mSI[0] = 5;
  }

  if(mode==0 || mode==2)
  {
    mB1->SetState(kButtonUp);
    mB2->SetState(kButtonUp);
    mB3->SetState(kButtonDown);
    mB4->SetState(kButtonUp);
    mBC1->SetState(kButtonUp);
    mTrash2->empty();
    mNB = 0;
  }
  if(mGrabPad) mGrabPad->Update();
}
void TPeakFitGUI::CloseWindow()
{
  delete this;
}
bool TPeakFitGUI::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
{
  switch (GET_MSG(msg))
  {
    case kC_COMMAND:
      switch (GET_SUBMSG(msg))
      {
        case kCM_BUTTON:
          switch (parm1)
          {
            case 104:
              if(!strcmp("Stop grab",(mPGrab->GetString()).Data()))
              {
                mPGrab->SetText("Grab");
                mGrabPad->DeleteExec("grab");
              } else grabMode(1);
              break;
            case 105:
              reset(1);
              break;
            case 204:
              if(!strcmp("Stop grab",(mBGrab->GetString()).Data()))
              {
                mBGrab->SetText("Grab");
                mGrabPad->DeleteExec("grab");
              } else grabMode(2);
              break;
            case 205:
              reset(2);
              break;
            case 999:
              details();
              break;
            case 1000:
              fit();
              break;
            case 1001:
              reset();
              break;
            case 1002:
              delete this;
              break;
            case 1003:
              draw();
              break;
            case 1004:
              clear();
              break;
            case 1005:
              print();
              break;
            case 1006:
              fit(1);
              break;
          }
          break;
        case kCM_RADIOBUTTON:
          switch (parm1)
          {
            case 101:
              mP1->SetState(kButtonDown);
              mP2->SetState(kButtonUp);
              mP3->SetState(kButtonUp);
              break;
            case 102:
              mP1->SetState(kButtonUp);
              mP2->SetState(kButtonDown);
              mP3->SetState(kButtonUp);
              break;
            case 103:
              mP1->SetState(kButtonUp);
              mP2->SetState(kButtonUp);
              mP3->SetState(kButtonDown);
               break;
            case 201:
              mB1->SetState(kButtonDown);
              mB2->SetState(kButtonUp);
              mB3->SetState(kButtonUp);
              mB4->SetState(kButtonUp);
              break;
            case 202:
              mB1->SetState(kButtonUp);
              mB2->SetState(kButtonDown);
              mB3->SetState(kButtonUp);
              mB4->SetState(kButtonUp);
              break;
            case 203:
              mB1->SetState(kButtonUp);
              mB2->SetState(kButtonUp);
              mB3->SetState(kButtonDown);
              mB4->SetState(kButtonUp);
              break;
            case 206:
              mB1->SetState(kButtonUp);
              mB2->SetState(kButtonUp);
              mB3->SetState(kButtonUp);
              mB4->SetState(kButtonDown);
          }
          break;
     }
  }
  return true;
}
void TPeakFitGUI::grabMode(int mode)
{
  if(!mGrabPad) return;
  mGrabPad->cd();
  if(!strcmp("Stop grab",(mPGrab->GetString()).Data()))
  {
    mPGrab->SetText("Grab");
    mGrabPad->DeleteExec("grab");
    //mGrabPad = NULL;
  }
  if(!strcmp("Stop grab",(mBGrab->GetString()).Data()))
  {
    mBGrab->SetText("Grab");
    mGrabPad->DeleteExec("grab");
    //mGrabPad = NULL;
  }
  if(mode==1)
  {
    mGrabType = 1;
    mPGrab->SetText("Stop grab");
    if(mP1->GetState()==kButtonDown) mGrabMode = 0;
    if(mP2->GetState()==kButtonDown) mGrabMode = 1;
    if(mP3->GetState()==kButtonDown) mGrabMode = 2;
  }
  if(mode==2)
  {
    mBGrab->SetText("Stop grab");
    mGrabType = 2;
    mGrabMode = 0;
  }
  mFitDone = false;
  draw();
  mGrabPad->AddExec("grab",mCommand.Data());
  mFlag = 0;

}
void TPeakFitGUI::fit(int mode)
{
  int i;
  float y;
  float Y[MAXPOINTS];
  if(!mPeakFit) return;
  mGrabPad->cd();
  clear();

  mPeakFit->setXmin(mGrabPad->GetUxmin());
  mPeakFit->setXmax(mGrabPad->GetUxmax());

  if(mPC1->GetState()==kButtonDown)     mPeakFit->setAssymOnOff(true);
  else mPeakFit->setAssymOnOff(false);

  if(mPC2->GetState()==kButtonDown)     mPeakFit->setSameWidth(true);
  else mPeakFit->setSameWidth(false);

  if(mB1->GetState()==kButtonDown)      mPeakFit->setBackDegree(-1);
  else if(mB2->GetState()==kButtonDown) mPeakFit->setBackDegree(0);
  else if(mB3->GetState()==kButtonDown) mPeakFit->setBackDegree(1);
  else if(mB4->GetState()==kButtonDown)
  {
    int d = atoi(mBP->GetText());
    if(d<1) {d = 1; mBP->SetText("1");}
    if(d>9) {d = 9; mBP->SetText("9");}
    mPeakFit->setBackDegree(d);
  }

  if(mBC1->GetState()==kButtonDown)     mPeakFit->setIndependentBack(true);
  else mPeakFit->setIndependentBack(false);

  if(mode==0 || !mFitDone)
  {
    mPeakFit->removeAll();
    mPeakFit->setBackground(mNB,mBX,mBY);
    mPeakFit->fitBack();
    TF1 *f=mPeakFit->getBack();
    for(i=0;i<mNP;i++)
    {
      y  = f->Eval(mPX[i]);
      Y[i] = mPY[i]-y;
      mPeakFit->addPeak(Y[i],mPX[i],mSI[i],1);
    }
  }
  mPeakFit->fit();
  mPeakFit->draw();
  mFitDone = true;
}
void TPeakFitGUI::details()
{
  TString l[20];
  TString v[20];
  int n = 7;
  int stat;
  int i;

  for(i=0;i<20;i++)
  {
    l[i]="";
    v[i]="";
  }

  l[0] = "      Max peak position shift (absolute)     ";
  l[1] = "Max width variation (absolute)";
  l[2] = "Min area (relative)";
  l[3] = "Max area (relavite)";
  l[4] = "Min asymmetry (absolute)";
  l[5] = "Max asymmetry (absolute)";
  l[6] = "Max Back parameters variation (relavite)";

  if(mPeakFit)
  {
    v[0]+=mPeakFit->getPeakVar();
    v[1]+=mPeakFit->getWidthVar();
    v[2]+=mPeakFit->getMinArea();
    v[3]+=mPeakFit->getMaxArea();
    v[4]+=mPeakFit->getMinAssym();
    v[5]+=mPeakFit->getMaxAssym();
    v[6]+=mPeakFit->getBackVar();
  }

  new TDialog("Fit details",n,l,v,&stat);
  if(stat!=1) return;
  if(mPeakFit)
  {
    mPeakFit->setPeakVar(atof(v[0].Data()));
    mPeakFit->setWidthVar(atof(v[1].Data()));
    mPeakFit->setMinArea(atof(v[2].Data()));
    mPeakFit->setMaxArea(atof(v[3].Data()));
    mPeakFit->setMinAssym(atof(v[4].Data()));
    mPeakFit->setMaxAssym(atof(v[5].Data()));
    mPeakFit->setBackVar(atof(v[6].Data()));
  }

}
void TPeakFitGUI::grab()
{
   if(!mGrabPad) return;
   //example of macro called when a pad is redrawn
   //one must create a TExec object in the following way
   // TExec ex("ex",".x exec1.C");
   // ex.Draw();
   // this macro prints the bin number and the bin content when one clicks
   //on the histogram contour of any histogram in a pad
   int   event = mGrabPad->GetEvent();
   int   px = mGrabPad->GetEventX();
   int   py = mGrabPad->GetEventY();
   float xx = mGrabPad->AbsPixeltoX(px);
   float x  = mGrabPad->PadtoX(xx);
   float yy = mGrabPad->AbsPixeltoY(py);
   float y  = mGrabPad->PadtoY(yy);
   float X1 = mGrabPad->GetUxmin();
   float X2 = mGrabPad->GetUxmax();
   float Y1 = mGrabPad->GetUymin();
   float Y2 = mGrabPad->GetUymax();

   float XXX = x;
   float YYY = y;
   if(atoi(gROOT->GetVersion())<4)
   {
     XXX = xx;
     YYY = yy;
   }
   //printf("event=%d, px=%d, xx=%f, x=%f py=%d, yy=%f, y=%f \n",event,px,xx,x,py,yy,y);
   if(xx>X1 && xx<X2 && yy>Y1 && yy<Y2) // inside histogram region
   {
    if(event == 11 || event == 24) // click or enter
    {
      if(mGrabMode==0 || mFlag==0) // grab only points
      {
        if(mGrabType==1) // grab peaks
        {
          mPX[mNP] = x;
          mPY[mNP] = y;
          TMarker *p = new TMarker(XXX,YYY,2);
          p->Draw();
          p->SetMarkerColor(6);
          mTrash1->add(p);
        }
        if(mGrabType==2) // grab background
        {
          mGrabMode = 0;
          mBX[mNB] = x;
          mBY[mNB] = y;
          mBpX[mNB] = XXX;
          mBpY[mNB] = YYY;
          TMarker *p = new TMarker(XXX,YYY,3);
          p->Draw();
          p->SetMarkerColor(8);
          mTrash2->add(p);
          if(mNB>0)
          {
            TLine* L = new TLine(mBpX[mNB-1],mBpY[mNB-1],mBpX[mNB],mBpY[mNB]);
            L->Draw();
            L->SetLineColor(8);
            mTrash2->add(L);
          }
          mNB++;
        }
        if(mGrabMode==0 && mGrabType==1) { mSI[mNP] = mSI[0]; mNP++; }
        if(mGrabMode!=0) mFlag=1; // set mFlag to next level if mode != 0
        return;
      }
      if(mFlag==1) // grab first point of line
      {
        mXL = x;
        mYL = y;
        mpXL = XXX;
        mpYL = YYY;
        mFlag = 2;
        return;
      }
      if(mFlag==2) // grab last point
      {
        mSI[mNP] = fabs(mXL-x)/2.;
        mNP++;
        TLine* L = new TLine(mpXL,(mpYL+YYY)/2,XXX,(mpYL+YYY)/2);
        L->Draw();
        mTrash1->add(L);
        L->SetLineColor(6);
        mFlag = 0;
        if(mGrabMode==1) mGrabMode =0;
        return;
      }
    }
  }
}
void TPeakFitGUI::clear()
{
  int i;
  TList *l;
  if(!mGrabPad) return;
  l = mTrash1->getList();
  for(i=0;i<l->GetSize();i++) mGrabPad->RecursiveRemove(l->At(i));
  l = mTrash2->getList();
  for(i=0;i<l->GetSize();i++) mGrabPad->RecursiveRemove(l->At(i));
  mGrabPad->Update();
  return;
}
void TPeakFitGUI::draw()
{
  int i;
  TList *l;
  if(!mGrabPad) return;
  mGrabPad->cd();
  l = mTrash1->getList();
  for(i=0;i<l->GetSize();i++) l->At(i)->Draw();
  l = mTrash2->getList();
  for(i=0;i<l->GetSize();i++) l->At(i)->Draw();
  mGrabPad->Update();
  return;
}
void TPeakFitGUI::print()
{
  if(mPeakFit) mPeakFit->print();
  return;
}



ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.