// Author: Pierre-Luc Drouin <http://www.pldrouin.net>
// Copyright Carleton University

#include "QSigExTTreePDF.h"

//#define DEBUG
//#define DEBUG2

#include "debugger.h"

////////////////////////////////////////////////////////////////////////
//                                                                    //
// QSigExTTreePDF                                                     //
//                                                                    //
// This class is a QSigExPDFs derived class that creates 1d           //
// QSigExDisTH marginal PDFs from raw TTree objects. For each flux    //
// group, it also creates a clean TTree which branches are those used //
// to create the marginal PDFs.                                       //
//                                                                    //
////////////////////////////////////////////////////////////////////////


ClassImp(QSigExTTreePDF)

QSigExDis* QSigExTTreePDF::GetFunction(const QList<TString>& pdfentry, TDirectory* fluxdir, const TCut& fgcuts, QList<TString>* inputs, Bool_t *pdfneedscuts)
{
  //This protected function uses the pdf card file formatted entry pdfentry, a
  //pointer to the TDirectory of the PDF flux group and the combined cuts fgcuts
  //to create a function used in QSigExPDFs::Get() to produce a marginal PDF
  //object. In order to create this function, it loads a raw TTree object from a
  //ROOT file for the PDF flux group, creates a new TTree using the combined
  //cuts and puts it in fluxdir. Finally, it creates a new 1d QSigExDisTH object from
  //this new TTree. GetFunction() returns a QSigExDis pointer to this new object.
  //inputs is filled with the coordinate name of the QSigExDisTH function.
  //pdfneedscuts is set to kFALSE since the function applies cuts on the
  //raw TTree. The clean TTree can be used by other QSigExDirHandler classes to
  //take into account the correlations between PDFs variables.
  //
  //Syntax of a card file entry: 
  //pdf  [...]  [objname]  [filename]  [c1] [nbins] 
  //where [...] are the fields defined in QSigExPDFs::LoadCardFile, [objname]
  //the name of the object in the ROOT file [filename], where [c1] is the
  //coordinate name and where [nbins] is the number of bins for the new QSigExDisTH
  //function. The [typeid] field defined in QSigExPDFs must be equal to "TTree".
  //If not, the pdf entry is ignored and GetFunction returns NULL.

  //WARNING: WHEN PDFS ARE GENERATED FROM A TTREE, ALL THE PDF LINES OF A
  //SPECIFIC FLUX GROUP IN THE CARD FILE THAT ARE OF THE TYPE TTREE MUST USE THE
  //SAME TTREE

  try{
    //Set up the indices for the fields in this part of the card file:
    const Int_t minfields = 7;         //minimum number of fields
    const Int_t maxfields = 8;         //maximum number of fields
    const Int_t pdftypeindex = 2;      //ROOT class name of the read function

    const Int_t pdfgroupindex = 3;     //Flux group name
    const Int_t systnameindex = 4;     //Systematics group name

    const Int_t objnameindex = 5 ;     //object name of the function
    const Int_t filenameindex = 6 ;    //ROOT filename
    const Int_t firstcoordindex = 7;   //First coordinate


    QSigExDis* pdfbuf=NULL;

    if(pdfentry[pdftypeindex]=="TTree"){
      CheckCardNFields(pdfentry.Count()-1,minfields,maxfields);

      TH1F* thbuf;         //TH1F buffer
      TTree *tbuf=NULL,*ctbuf=NULL;  //TTree buffers
      TFile *treefile;     //TFile pointer for PDFs generated from TTrees
      Int_t intbuf;        //Int_t buffer

      TString strbuf;

      //If there's no Event Info TDirectory in fluxdir
      if(!(fluxdir->FindObject("Event Info"))){
	//Open the filename specified in the card file
	treefile=new TFile(pdfentry[filenameindex],"READ");
	//Load the TTree
	tbuf=dynamic_cast<TTree*>(treefile->Get(pdfentry[objnameindex]));
	//Change directory to the fluxdir
	fluxdir->cd();
	//Get a clean TTree using all cuts
	ctbuf=tbuf->CopyTree(fgcuts);
	//Set the name of the clean TTree to "Event Info" 
	ctbuf->SetName("Event Info");
	cout << ctbuf->GetEntries() << "/" << tbuf->GetEntries() <<
	  " entries (" << 100.*ctbuf->GetEntries()/(tbuf->GetEntries()) <<
	  " %) have passed the cuts\n";
	
	//Call ClearBranchesAddresses to set clean
	//TTree branches addresses to NULL
	QTTreeUtils::ClearBranchesAddresses(ctbuf);
	
	//Close the read TTree
	treefile->Close();
	//Remove it from gROOT
	gROOT->Delete(pdfentry[filenameindex]);
	
	//Else if there's an "Event Info" object in fluxdir but it's
	//not dervied from TTree, throw an exception
      } else if(!(ctbuf=dynamic_cast<TTree*>(fluxdir->Get("Event Info")))){
	cout << "Error in QSigExPDFs::Get: Clean TTree not present\n";
	throw 1;
      }

      //Change directory to fluxdir
      fluxdir->cd();

      //Generate the name for the new PDF
      strbuf=(pdfentry[pdfgroupindex]+"_")+
	(pdfentry[systnameindex]+"_")+
	pdfentry[firstcoordindex];

      //Read the number of bins for the new PDF
      sscanf(pdfentry[firstcoordindex+1],"%i",&intbuf);

      //Create a new TH1F
      thbuf=new TH1F(strbuf,strbuf,intbuf,
		     ctbuf->GetMinimum(pdfentry[firstcoordindex]),
		     ctbuf->GetMaximum(pdfentry[firstcoordindex]));

      //Create a new PDF (QSigExDisTH) using the TH1F instance
      //(it's copied)
      pdfbuf=new QSigExDisTH("TH1F",*thbuf);
      //Delete the TH1F instance 
      thbuf->Delete();

      //Get a pointer to the new TH1F object
      thbuf=dynamic_cast<TH1F*>(dynamic_cast<QSigExDisTH*>(pdfbuf)->GetObject());

      //Append the TH1F instance of the PDF to fluxdir
      thbuf->SetDirectory(fluxdir);
      //Fill it using TTree::Draw
      ctbuf->Draw((pdfentry[firstcoordindex]+">>")+thbuf->GetName(),"1","goff");

      //Remove the TH1F instamce of the PDF from fluxdir
      thbuf->SetDirectory(NULL);
      //Set the name of the PDF (QSigExDisTH)
      pdfbuf->SetName(thbuf->GetName());

    }

    if(pdfbuf){
      (*inputs)=pdfentry[firstcoordindex];
    }
    (*pdfneedscuts)=kFALSE;

    return pdfbuf;
  }catch(Int_t e){
    cout << "Exception handled by QSigExTTreePDF::GetFunction\n";
    throw e;
  }
}

const Char_t* QSigExTTreePDF::GetPDFName(Int_t i)
{
  const Int_t pdfgroupindex = 3;     //Flux group name
  const Int_t systnameindex = 4;     //Systematics group name

  const Int_t firstcoordindex = 7;   //First coordinate

  try{
    return ((fPDFCard[i][pdfgroupindex]+"_")+(fPDFCard[i][systnameindex]+"_")+fPDFCard[i][firstcoordindex]).Data();

  }catch(Int_t e){
    cout << "Exception handled by QSigExStdPDFs::GetPDFName\n";
    throw e;
  }
}

#include "debugger.h"







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.