ROOT 6.02/08 loading and using cuts

Hi.

I have a simple code that load some previously saved cut files (absE1.C, absE2.C) and use these cuts on data. The problem is that the while the code is executing, the gates are not defined, but once its finished, I can bring up the gates via the terminal command fine.

Main code

int gate_sample(const int firstEvent=0, int lastEvent=10, string infileName="name"){
  
  TCutG *absE1 = new TCutG();
  TCutG *absE2 = new TCutG();
  
  // load cut files
  gROOT->ProcessLine(".L absE1.C");
  gROOT->ProcessLine(".L absE2.C");
  //gROOT->ProcessLine(".x absE1.C"); // .x or .L makes no differences
  //gROOT->ProcessLine(".x absE2.C");
  double X=10.0;
  double Y=10.0;
  
  for (int currentEvent=firstEvent; currentEvent<lastEvent; currentEvent++){
    if(absE1->IsInside(X,Y)){
      printf("inside Gate");
    }
    printf("%i \n",absE1->IsInside(10,10));
  }
  
  printf("\n");

  return 1;
}

This is the gate file absE1.C

 TCutG *absE1 = new TCutG("absE1",6);
  absE1->SetVarX("Data.AE1");
  absE1->SetVarY("Data.SE1");
  absE1->SetPoint(0, 0.0, 5.0);
  absE1->SetPoint(1,51.5,56.5);
  absE1->SetPoint(2,55.0,51.0);
  absE1->SetPoint(3, 4.0, 0.0);
  absE1->SetPoint(4, 0.0, 0.0);
  absE1->SetPoint(5, 0.0, 5.0);

Your file absE1.C is really exactly like that ?
No open and close curly bracket ?
No macro name ?

Well, to make sure its not a root version issue, I made a new absE1.C macro exactly as shown bellow, and still it does not work.

{
//========= Macro generated from object: absE1/Graph
//========= by ROOT version6.02/08
   
   TCutG *absE1 = new TCutG("absE1",6);
   absE1->SetVarX("Data.AE1");
   absE1->SetVarY("Data.SE1");
   absE1->SetTitle("Graph");
   absE1->SetFillColor(1);
   absE1->SetPoint(0,1.3551,3.53203);
   absE1->SetPoint(1,24.8161,28.7962);
   absE1->SetPoint(2,27.7815,25.3286);
   absE1->SetPoint(3,3.19444,2.0459);
   absE1->SetPoint(4,1.80556,1.60007);
   absE1->SetPoint(5,1.3551,3.53203);
   absE1->Draw("");
}

you can do:

int gate_sample(const int firstEvent=0, int lastEvent=10){

   TCutG *absE1;
   // load cut files
   absE1 = cut();

   double X=10.0;
   double Y=10.0;

   for (int currentEvent=firstEvent; currentEvent<lastEvent; currentEvent++){
      if (absE1->IsInside(X,Y)) printf("inside Gate");
      printf("%i \n",absE1->IsInside(10,10));
   }

  printf("\n");

  return 1;
}
TCutG * cut(){
//========= Macro generated from object: absE1/Graph
//========= by ROOT version6.02/08

   TCutG *absE1 = new TCutG("absE1",6);
   absE1->SetVarX("Data.AE1");
   absE1->SetVarY("Data.SE1");
   absE1->SetTitle("Graph");
   absE1->SetFillColor(1);
   absE1->SetPoint(0,1.3551,3.53203);
   absE1->SetPoint(1,24.8161,28.7962);
   absE1->SetPoint(2,27.7815,25.3286);
   absE1->SetPoint(3,3.19444,2.0459);
   absE1->SetPoint(4,1.80556,1.60007);
   absE1->SetPoint(5,1.3551,3.53203);
   absE1->Draw("");
   return absE1;
}
root [0] gROOT->ProcessLine(".L cut.C");
root [1] .x gate_sample.C
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 
inside Gate1 

(int) 1
root [2] 

Hi Couet.

Is this the only way it is for ROOT6. I’m looking to write a script that will load lots of different prepared cut files, depending on different data files. So I would need to have the line [ gROOT->ProcessLine(".L cutg.C"); ] working right inside the script rather than having to manually typing it in before running the gate_sample.cxx script.

Not only that, now I have to manually edit all the gate macros to include [TCutG * xxxxxcut()] and [return absE1;]. It sounds like a step backward in term of reducing the programming efforts required to get to the data-analysis in ROOT 6

What do you think ?

Hi,

I’d recommend to put your cut definitions into header files, e.g. using static initialization, and to simply #include these files in your main macro. I.e.

// cut1.h
TCutG absE1("absE1", 4, /*x*/ {0., 1., 2, 3.}, /*y*/ {0.1, 1.1, 2.1, 3.1});

(Note: untested, I didn’t even bother compiling it…)

or, if you need SetVarX/Y(), using static init:

// cut1.h
TCutG absE1("absE1", 4, /*x*/ {0., 1., 2, 3.}, /*y*/ {0.1, 1.1, 2.1, 3.1});

struct absE1_Init_t {
  absE1_Init_t()
  {
    absE1.SetVarX("Data.AE1");
    absE1.SetVarY("Data.SE1");
  }
} absE1_Init;

That also makes it proper C++.

Cheers, Axel.

(1) Since the gSystem->Load(". …") and gROOT->ProcessLine(" ") features are provided within ROOT, they should be accepted by ROOT as being proper right ?

(2) Also since all the cut macros are generated by ROOT, by default, they should also be proper C++ objects on their own without user intervention.

Now putting (1) and (2) together, all cuts should load and work proper in ROOT 6, just like they are in ROOT 5.

[-X

OK - got a work around the problem (again its sloppy C++) but in case anyone interested in quick dirty fix.

  1. Declare your cuts globally before the main function e.g.
TCutG *absE1;
int main(){

 gROOT->ProcessLine(".x absE1.C");
 
 if(absE1->IsInside(X,Y)){
       do something;
 }
 
 return 1;
}

where absE1.C must be in the form shown below

{
//========= Macro generated from object:UTG/Graph
//========= by ROOT version5.34/25
   
   absE1 = new TCutG("absE1",6);
   absE1->SetVarX("Data.AE1");
   absE1->SetVarY("Data.SE1");
   absE1->SetPoint(0, 0.0, 2.0);
   absE1->SetPoint(1,44.0,46.0);
   absE1->SetPoint(2,46.0,44.0);
   absE1->SetPoint(3, 2.0, 0.0);
   absE1->SetPoint(4, 0.0, 0.0);
   absE1->SetPoint(5, 0.0, 2.0);
}