void NTupleEventReader::readDataTypes() {
    TIter nextFile(input->GetListOfFiles());
    TChainElement* file = 0;
    while ((file = (TChainElement*) nextFile()) != 0) {
        string fileName = file->GetTitle();
        DataType::value type = getDataType(fileName);
        seenDataTypes.at(type) = true;
    }
}
void TreeReader::PrintListOfFiles()
{
	if(!init)
	{
	        cout << "*** WARNING: tree " << fChain->GetName() << " not initialized" << endl;
		return;
	}

	TObjArray *fileElements = fChain->GetListOfFiles();
	TIter next(fileElements);
	TChainElement *chEl = 0;

	cout << endl;
	cout << "List of files" << endl;
	while ((chEl = (TChainElement*) next()))
	{
		cout << chEl->GetTitle() << endl;
	}
	cout << endl;

	return;
}
Exemple #3
0
void Classify_HWW( TString myMethodList = "" ) 
{   
#ifdef __CINT__
  gROOT->ProcessLine( ".O0" ); // turn off optimization in CINT
#endif

  //--------------------------------------------------------------------
  // path to weights dir (this is where MVA training info is stored)
  // output root file will be stored at [path]/output
  //--------------------------------------------------------------------

  TString path   = "Trainings/v5/H160_WW_10vars_dphi10/";
  //TString path   = "./";

  //-----------------------------------
  // select samples to run over
  //-----------------------------------

  char* babyPath = "/tas/cerati/HtoWWmvaBabies/latest";
  int mH         = 160;  // choose Higgs mass

  vector<char*> samples;
  samples.push_back("WWTo2L2Nu");
  samples.push_back("GluGluToWWTo4L");
  samples.push_back("WZ");
  samples.push_back("ZZ");
  samples.push_back("TTJets");
  samples.push_back("tW");
  samples.push_back("WJetsToLNu");
  samples.push_back("DY");
  //samples.push_back("WJetsFO3");

  if     ( mH == 130 ) samples.push_back("Higgs130");
  else if( mH == 160 ) samples.push_back("Higgs160");
  else if( mH == 200 ) samples.push_back("Higgs200");
  else{
    cout << "Error, unrecognized Higgs mass " << mH << " GeV, quitting" << endl;
    exit(0);
  }

  //--------------------------------------------------------------------------------
  // IMPORTANT: set the following variables to the same set used for MVA training!!!
  //--------------------------------------------------------------------------------
  
  std::map<std::string,int> mvaVar;
  mvaVar[ "lephard_pt" ]        = 1;
  mvaVar[ "lepsoft_pt" ]        = 1;
  mvaVar[ "dil_dphi" ]          = 1;
  mvaVar[ "dil_mass" ]          = 1;
  mvaVar[ "event_type" ]        = 0;
  mvaVar[ "met_projpt" ]        = 1;
  mvaVar[ "met_pt" ]            = 0;
  mvaVar[ "mt_lephardmet" ]     = 1;
  mvaVar[ "mt_lepsoftmet" ]     = 1;
  mvaVar[ "mthiggs" ]           = 1;
  mvaVar[ "dphi_lephardmet" ]   = 1;
  mvaVar[ "dphi_lepsoftmet" ]   = 1;
  mvaVar[ "lepsoft_fbrem" ]     = 0;
  mvaVar[ "lepsoft_eOverPIn" ]  = 0;
  mvaVar[ "lepsoft_qdphi" ]     = 0;

  //---------------------------------------------------------------

  // This loads the library
  TMVA::Tools::Instance();

  // Default MVA methods to be trained + tested
  std::map<std::string,int> Use;

  // --- Cut optimisation
  Use["Cuts"]            = 1;
  Use["CutsD"]           = 1;
  Use["CutsPCA"]         = 0;
  Use["CutsGA"]          = 0;
  Use["CutsSA"]          = 0;
  // 
  // --- 1-dimensional likelihood ("naive Bayes estimator")
  Use["Likelihood"]      = 1;
  Use["LikelihoodD"]     = 0; // the "D" extension indicates decorrelated input variables (see option strings)
  Use["LikelihoodPCA"]   = 1; // the "PCA" extension indicates PCA-transformed input variables (see option strings)
  Use["LikelihoodKDE"]   = 0;
  Use["LikelihoodMIX"]   = 0;
  //
  // --- Mutidimensional likelihood and Nearest-Neighbour methods
  Use["PDERS"]           = 1;
  Use["PDERSD"]          = 0;
  Use["PDERSPCA"]        = 0;
  Use["PDEFoam"]         = 1;
  Use["PDEFoamBoost"]    = 0; // uses generalised MVA method boosting
  Use["KNN"]             = 1; // k-nearest neighbour method
  //
  // --- Linear Discriminant Analysis
  Use["LD"]              = 1; // Linear Discriminant identical to Fisher
  Use["Fisher"]          = 0;
  Use["FisherG"]         = 0;
  Use["BoostedFisher"]   = 0; // uses generalised MVA method boosting
  Use["HMatrix"]         = 0;
  //
  // --- Function Discriminant analysis
  Use["FDA_GA"]          = 1; // minimisation of user-defined function using Genetics Algorithm
  Use["FDA_SA"]          = 0;
  Use["FDA_MC"]          = 0;
  Use["FDA_MT"]          = 0;
  Use["FDA_GAMT"]        = 0;
  Use["FDA_MCMT"]        = 0;
  //
  // --- Neural Networks (all are feed-forward Multilayer Perceptrons)
  Use["MLP"]             = 0; // Recommended ANN
  Use["MLPBFGS"]         = 0; // Recommended ANN with optional training method
  Use["MLPBNN"]          = 1; // Recommended ANN with BFGS training method and bayesian regulator
  Use["CFMlpANN"]        = 0; // Depreciated ANN from ALEPH
  Use["TMlpANN"]         = 0; // ROOT's own ANN
  //
  // --- Support Vector Machine 
  Use["SVM"]             = 1;
  // 
  // --- Boosted Decision Trees
  Use["BDT"]             = 1; // uses Adaptive Boost
  Use["BDTG"]            = 0; // uses Gradient Boost
  Use["BDTB"]            = 0; // uses Bagging
  Use["BDTD"]            = 0; // decorrelation + Adaptive Boost
  // 
  // --- Friedman's RuleFit method, ie, an optimised series of cuts ("rules")
  Use["RuleFit"]         = 1;
  // ---------------------------------------------------------------
  Use["Plugin"]          = 0;
  Use["Category"]        = 0;
  Use["SVM_Gauss"]       = 0;
  Use["SVM_Poly"]        = 0;
  Use["SVM_Lin"]         = 0;

  std::cout << std::endl;
  std::cout << "==> Start TMVAClassificationApplication" << std::endl;

  // Select methods (don't look at this code - not of interest)
  if (myMethodList != "") {
    for (std::map<std::string,int>::iterator it = Use.begin(); it != Use.end(); it++) it->second = 0;

    std::vector<TString> mlist = gTools().SplitString( myMethodList, ',' );
    for (UInt_t i=0; i<mlist.size(); i++) {
      std::string regMethod(mlist[i]);

      if (Use.find(regMethod) == Use.end()) {
        std::cout << "Method \"" << regMethod 
                  << "\" not known in TMVA under this name. Choose among the following:" << std::endl;
        for (std::map<std::string,int>::iterator it = Use.begin(); it != Use.end(); it++) {
          std::cout << it->first << " ";
        }
        std::cout << std::endl;
        return;
      }
      Use[regMethod] = 1;
    }
  }

  // --------------------------------------------------------------------------------------------------

  const unsigned int nsamples = samples.size();
  
  for( unsigned int i = 0 ; i < nsamples ; ++i ){

    // --- Create the Reader object

    TMVA::Reader *reader = new TMVA::Reader( "!Color:!Silent" );    

    // Create a set of variables and declare them to the reader
    // - the variable names MUST corresponds in name and type to those given in the weight file(s) used
    //    Float_t var1, var2;
    //    Float_t var3, var4;
    //    reader->AddVariable( "myvar1 := var1+var2", &var1 );
    //    reader->AddVariable( "myvar2 := var1-var2", &var2 );
    //    reader->AddVariable( "var3",                &var3 );
    //    reader->AddVariable( "var4",                &var4 );

    Float_t lephard_pt;
    Float_t lepsoft_pt;
    Float_t dil_dphi;
    Float_t dil_mass;
    Float_t event_type;
    Float_t met_projpt;
    Float_t met_pt;
    Float_t mt_lephardmet;
    Float_t mt_lepsoftmet;
    Float_t mthiggs;
    Float_t dphi_lephardmet;
    Float_t dphi_lepsoftmet;
    Float_t lepsoft_fbrem;
    Float_t lepsoft_eOverPIn;
    Float_t lepsoft_qdphi;

    if( mvaVar["lephard_pt"])       reader->AddVariable( "lephard_pt"                  ,   &lephard_pt        ); 
    if( mvaVar["lepsoft_pt"])       reader->AddVariable( "lepsoft_pt"                  ,   &lepsoft_pt        ); 
    if( mvaVar["dil_dphi"])         reader->AddVariable( "dil_dphi"                    ,   &dil_dphi          ); 
    if( mvaVar["dil_mass"])         reader->AddVariable( "dil_mass"                    ,   &dil_mass          ); 
    if( mvaVar["event_type"])       reader->AddVariable( "event_type"                  ,   &event_type        );
    if( mvaVar["met_projpt"])       reader->AddVariable( "met_projpt"                  ,   &met_pt            );
    if( mvaVar["met_pt"])           reader->AddVariable( "met_pt"                      ,   &met_pt            );
    if( mvaVar["mt_lephardmet"])    reader->AddVariable( "mt_lephardmet"               ,   &mt_lephardmet     );
    if( mvaVar["mt_lepsoftmet"])    reader->AddVariable( "mt_lepsoftmet"               ,   &mt_lepsoftmet     );
    if( mvaVar["mthiggs"])          reader->AddVariable( "mthiggs"                     ,   &mthiggs           );  
    if( mvaVar["dphi_lephardmet"])  reader->AddVariable( "dphi_lephardmet"             ,   &dphi_lephardmet   );
    if( mvaVar["dphi_lepsoftmet"])  reader->AddVariable( "dphi_lepsoftmet"             ,   &dphi_lepsoftmet   );
    if( mvaVar["lepsoft_fbrem"])    reader->AddVariable( "lepsoft_fbrem"               ,   &lepsoft_fbrem     );
    if( mvaVar["lepsoft_eOverPIn"]) reader->AddVariable( "lepsoft_eOverPIn"            ,   &lepsoft_eOverPIn  );
    if( mvaVar["lepsoft_qdphi"])    reader->AddVariable( "lepsoft_q * lepsoft_dPhiIn"  ,   &lepsoft_qdphi     );
 

    // Spectator variables declared in the training have to be added to the reader, too
    //    Float_t spec1,spec2;
    //    reader->AddSpectator( "spec1 := var1*2",   &spec1 );
    //    reader->AddSpectator( "spec2 := var1*3",   &spec2 );

    Float_t Category_cat1, Category_cat2, Category_cat3;
    if (Use["Category"]){
      // Add artificial spectators for distinguishing categories
      //       reader->AddSpectator( "Category_cat1 := var3<=0",             &Category_cat1 );
      //       reader->AddSpectator( "Category_cat2 := (var3>0)&&(var4<0)",  &Category_cat2 );
      //       reader->AddSpectator( "Category_cat3 := (var3>0)&&(var4>=0)", &Category_cat3 );
    }

    // --- Book the MVA methods

    //--------------------------------------------------------------------------------------
    // tell Classify_HWW where to find the weights dir, which contains the trained MVA's. 
    // In this example, the weights dir is located at [path]/[dir]
    // and the output root file is written to [path]/[output]
    //--------------------------------------------------------------------------------------

    TString dir    = path + "weights/";
    TString outdir = path + "output/";
    TString prefix = "TMVAClassification";

    // Book method(s)
    for (std::map<std::string,int>::iterator it = Use.begin(); it != Use.end(); it++) {
      if (it->second) {
        TString methodName = TString(it->first) + TString(" method");
        TString weightfile = dir + prefix + TString("_") + TString(it->first) + TString(".weights.xml");
        reader->BookMVA( methodName, weightfile ); 
      }
    }
   
    // Book output histograms
    UInt_t nbin = 1000;
    TH1F   *histLk(0), *histLkD(0), *histLkPCA(0), *histLkKDE(0), *histLkMIX(0), *histPD(0), *histPDD(0);
    TH1F   *histPDPCA(0), *histPDEFoam(0), *histPDEFoamErr(0), *histPDEFoamSig(0), *histKNN(0), *histHm(0);
    TH1F   *histFi(0), *histFiG(0), *histFiB(0), *histLD(0), *histNn(0),*histNnbfgs(0),*histNnbnn(0);
    TH1F   *histNnC(0), *histNnT(0), *histBdt(0), *histBdtG(0), *histBdtD(0), *histRf(0), *histSVMG(0);
    TH1F   *histSVMP(0), *histSVML(0), *histFDAMT(0), *histFDAGA(0), *histCat(0), *histPBdt(0);

    if (Use["Likelihood"])    histLk      = new TH1F( "MVA_Likelihood",    "MVA_Likelihood",    nbin, -1, 1 );               
    if (Use["LikelihoodD"])   histLkD     = new TH1F( "MVA_LikelihoodD",   "MVA_LikelihoodD",   nbin, -1, 0.9999 );
    if (Use["LikelihoodPCA"]) histLkPCA   = new TH1F( "MVA_LikelihoodPCA", "MVA_LikelihoodPCA", nbin, -1, 1 );
    if (Use["LikelihoodKDE"]) histLkKDE   = new TH1F( "MVA_LikelihoodKDE", "MVA_LikelihoodKDE", nbin,  -0.00001, 0.99999 );
    if (Use["LikelihoodMIX"]) histLkMIX   = new TH1F( "MVA_LikelihoodMIX", "MVA_LikelihoodMIX", nbin,  0, 1 );
    if (Use["PDERS"])         histPD      = new TH1F( "MVA_PDERS",         "MVA_PDERS",         nbin,  0, 1 );
    if (Use["PDERSD"])        histPDD     = new TH1F( "MVA_PDERSD",        "MVA_PDERSD",        nbin,  0, 1 );
    if (Use["PDERSPCA"])      histPDPCA   = new TH1F( "MVA_PDERSPCA",      "MVA_PDERSPCA",      nbin,  0, 1 );
    if (Use["KNN"])           histKNN     = new TH1F( "MVA_KNN",           "MVA_KNN",           nbin,  0, 1 );
    if (Use["HMatrix"])       histHm      = new TH1F( "MVA_HMatrix",       "MVA_HMatrix",       nbin, -0.95, 1.55 );
    if (Use["Fisher"])        histFi      = new TH1F( "MVA_Fisher",        "MVA_Fisher",        nbin, -4, 4 );
    if (Use["FisherG"])       histFiG     = new TH1F( "MVA_FisherG",       "MVA_FisherG",       nbin, -1, 1 );
    if (Use["BoostedFisher"]) histFiB     = new TH1F( "MVA_BoostedFisher", "MVA_BoostedFisher", nbin, -2, 2 );
    if (Use["LD"])            histLD      = new TH1F( "MVA_LD",            "MVA_LD",            nbin, -2, 2 );
    if (Use["MLP"])           histNn      = new TH1F( "MVA_MLP",           "MVA_MLP",           nbin, -1.25, 1.5 );
    if (Use["MLPBFGS"])       histNnbfgs  = new TH1F( "MVA_MLPBFGS",       "MVA_MLPBFGS",       nbin, -1.25, 1.5 );
    if (Use["MLPBNN"])        histNnbnn   = new TH1F( "MVA_MLPBNN",        "MVA_MLPBNN",        nbin, -1.25, 1.5 );
    if (Use["CFMlpANN"])      histNnC     = new TH1F( "MVA_CFMlpANN",      "MVA_CFMlpANN",      nbin,  0, 1 );
    if (Use["TMlpANN"])       histNnT     = new TH1F( "MVA_TMlpANN",       "MVA_TMlpANN",       nbin, -1.3, 1.3 );
    if (Use["BDT"])           histBdt     = new TH1F( "MVA_BDT",           "MVA_BDT",           nbin, -1. , 1. );
    if (Use["BDTD"])          histBdtD    = new TH1F( "MVA_BDTD",          "MVA_BDTD",          nbin, -0.8, 0.8 );
    if (Use["BDTG"])          histBdtG    = new TH1F( "MVA_BDTG",          "MVA_BDTG",          nbin, -1.0, 1.0 );
    if (Use["RuleFit"])       histRf      = new TH1F( "MVA_RuleFit",       "MVA_RuleFit",       nbin, -2.0, 2.0 );
    if (Use["SVM_Gauss"])     histSVMG    = new TH1F( "MVA_SVM_Gauss",     "MVA_SVM_Gauss",     nbin,  0.0, 1.0 );
    if (Use["SVM_Poly"])      histSVMP    = new TH1F( "MVA_SVM_Poly",      "MVA_SVM_Poly",      nbin,  0.0, 1.0 );
    if (Use["SVM_Lin"])       histSVML    = new TH1F( "MVA_SVM_Lin",       "MVA_SVM_Lin",       nbin,  0.0, 1.0 );
    if (Use["FDA_MT"])        histFDAMT   = new TH1F( "MVA_FDA_MT",        "MVA_FDA_MT",        nbin, -2.0, 3.0 );
    if (Use["FDA_GA"])        histFDAGA   = new TH1F( "MVA_FDA_GA",        "MVA_FDA_GA",        nbin, -2.0, 3.0 );
    if (Use["Category"])      histCat     = new TH1F( "MVA_Category",      "MVA_Category",      nbin, -2., 2. );
    if (Use["Plugin"])        histPBdt    = new TH1F( "MVA_PBDT",          "MVA_BDT",           nbin, -0.8, 0.8 );

    if (Use["Likelihood"])    histLk      ->Sumw2();
    if (Use["LikelihoodD"])   histLkD     ->Sumw2();
    if (Use["LikelihoodPCA"]) histLkPCA   ->Sumw2();
    if (Use["LikelihoodKDE"]) histLkKDE   ->Sumw2();
    if (Use["LikelihoodMIX"]) histLkMIX   ->Sumw2();
    if (Use["PDERS"])         histPD      ->Sumw2();
    if (Use["PDERSD"])        histPDD     ->Sumw2();
    if (Use["PDERSPCA"])      histPDPCA   ->Sumw2();
    if (Use["KNN"])           histKNN     ->Sumw2();
    if (Use["HMatrix"])       histHm      ->Sumw2();
    if (Use["Fisher"])        histFi      ->Sumw2();
    if (Use["FisherG"])       histFiG     ->Sumw2();
    if (Use["BoostedFisher"]) histFiB     ->Sumw2();
    if (Use["LD"])            histLD      ->Sumw2();
    if (Use["MLP"])           histNn      ->Sumw2();
    if (Use["MLPBFGS"])       histNnbfgs  ->Sumw2();
    if (Use["MLPBNN"])        histNnbnn   ->Sumw2();
    if (Use["CFMlpANN"])      histNnC     ->Sumw2();
    if (Use["TMlpANN"])       histNnT     ->Sumw2();
    if (Use["BDT"])           histBdt     ->Sumw2();
    if (Use["BDTD"])          histBdtD    ->Sumw2();
    if (Use["BDTG"])          histBdtG    ->Sumw2();
    if (Use["RuleFit"])       histRf      ->Sumw2();
    if (Use["SVM_Gauss"])     histSVMG    ->Sumw2();
    if (Use["SVM_Poly"])      histSVMP    ->Sumw2();
    if (Use["SVM_Lin"])       histSVML    ->Sumw2();
    if (Use["FDA_MT"])        histFDAMT   ->Sumw2();
    if (Use["FDA_GA"])        histFDAGA   ->Sumw2();
    if (Use["Category"])      histCat     ->Sumw2();
    if (Use["Plugin"])        histPBdt    ->Sumw2();

    // PDEFoam also returns per-event error, fill in histogram, and also fill significance
    if (Use["PDEFoam"]) {
      histPDEFoam    = new TH1F( "MVA_PDEFoam",       "MVA_PDEFoam",              nbin,  0, 1 );
      histPDEFoamErr = new TH1F( "MVA_PDEFoamErr",    "MVA_PDEFoam error",        nbin,  0, 1 );
      histPDEFoamSig = new TH1F( "MVA_PDEFoamSig",    "MVA_PDEFoam significance", nbin,  0, 10 );
    }

    // Book example histogram for probability (the other methods are done similarly)
    TH1F *probHistFi(0), *rarityHistFi(0);
    if (Use["Fisher"]) {
      probHistFi   = new TH1F( "MVA_Fisher_Proba",  "MVA_Fisher_Proba",  nbin, 0, 1 );
      rarityHistFi = new TH1F( "MVA_Fisher_Rarity", "MVA_Fisher_Rarity", nbin, 0, 1 );
    }

    // Prepare input tree (this must be replaced by your data source)
    // in this example, there is a toy tree with signal and one with background events
    // we'll later on use only the "signal" events for the test in this example.
    //   

 
    TChain *ch = new TChain("Events");

    if( strcmp( samples.at(i) , "DY" ) == 0 ){
      ch -> Add( Form("%s/DYToMuMuM20_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/DYToMuMuM10To20_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/DYToEEM20_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/DYToEEM10To20_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/DYToTauTauM20_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/DYToTauTauM10To20_PU_testFinal_baby.root",babyPath) );
    }
    if( strcmp( samples.at(i) , "WJetsFO3" ) == 0 ){
      ch -> Add( Form("%s/WJetsToLNu_FOv3_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/WToLNu_FOv3_testFinal_baby.root",babyPath) );
    }
    else if( strcmp( samples.at(i) , "Higgs130" ) == 0 ){
      ch -> Add( Form("%s/HToWWTo2L2NuM130_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWToLNuTauNuM130_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWTo2Tau2NuM130_PU_testFinal_baby.root",babyPath) );
    }
    else if( strcmp( samples.at(i) , "Higgs160" ) == 0 ){
      ch -> Add( Form("%s/HToWWTo2L2NuM160_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWToLNuTauNuM160_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWTo2Tau2NuM160_PU_testFinal_baby.root",babyPath) );
    }
    else if( strcmp( samples.at(i) , "Higgs200" ) == 0 ){
      ch -> Add( Form("%s/HToWWTo2L2NuM200_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWToLNuTauNuM200_PU_testFinal_baby.root",babyPath) );
      ch -> Add( Form("%s/HToWWTo2Tau2NuM200_PU_testFinal_baby.root",babyPath) );
    }
    else{
      ch -> Add( Form("%s/%s_PU_testFinal_baby.root",babyPath,samples.at(i)) );
    }

    // --- Event loop

    // Prepare the event tree
    // - here the variable names have to corresponds to your tree
    // - you can use the same variables as above which is slightly faster,
    //   but of course you can use different ones and copy the values inside the event loop
    //
  
    TTree *theTree     = (TTree*) ch;

    std::cout << "--- Using input files: -------------------" <<  std::endl;

    TObjArray *listOfFiles = ch->GetListOfFiles();
    TIter fileIter(listOfFiles);
    TChainElement* currentFile = 0;
    
    while((currentFile = (TChainElement*)fileIter.Next())) {
      std::cout << currentFile->GetTitle() << std::endl;
    }

    Float_t lephard_pt_;
    Float_t lepsoft_pt_;
    Float_t lepsoft_fr_;
    Float_t dil_dphi_;
    Float_t dil_mass_;
    Float_t event_type_;
    Float_t met_projpt_;
    Int_t   jets_num_;
    Int_t   extralep_num_;
    Int_t   lowptbtags_num_;
    Int_t   softmu_num_;
    Float_t event_scale1fb_;
    Float_t met_pt_;
    Int_t   lepsoft_passTighterId_;
    Float_t mt_lephardmet_;
    Float_t mt_lepsoftmet_;
    Float_t mthiggs_;
    Float_t dphi_lephardmet_;
    Float_t dphi_lepsoftmet_;
    Float_t lepsoft_fbrem_;
    Float_t lepsoft_eOverPIn_;
    Float_t lepsoft_q_;
    Float_t lepsoft_dPhiIn_;

    theTree->SetBranchAddress( "lephard_pt_"             ,   &lephard_pt_              ); 
    theTree->SetBranchAddress( "lepsoft_pt_"             ,   &lepsoft_pt_              ); 
    theTree->SetBranchAddress( "lepsoft_fr_"             ,   &lepsoft_fr_              ); 
    theTree->SetBranchAddress( "dil_dphi_"               ,   &dil_dphi_                ); 
    theTree->SetBranchAddress( "dil_mass_"               ,   &dil_mass_                ); 
    theTree->SetBranchAddress( "event_type_"             ,   &event_type_              ); 
    theTree->SetBranchAddress( "met_projpt_"             ,   &met_projpt_              ); 
    theTree->SetBranchAddress( "jets_num_"               ,   &jets_num_                ); 
    theTree->SetBranchAddress( "extralep_num_"           ,   &extralep_num_            ); 
    theTree->SetBranchAddress( "lowptbtags_num_"         ,   &lowptbtags_num_          ); 
    theTree->SetBranchAddress( "softmu_num_"             ,   &softmu_num_              ); 
    theTree->SetBranchAddress( "event_scale1fb_"         ,   &event_scale1fb_          ); 
    theTree->SetBranchAddress( "lepsoft_passTighterId_"  ,   &lepsoft_passTighterId_   );
    theTree->SetBranchAddress( "met_pt_"                 ,   &met_pt_                  );
    theTree->SetBranchAddress( "mt_lephardmet_"          ,   &mt_lephardmet_           );
    theTree->SetBranchAddress( "mt_lepsoftmet_"          ,   &mt_lepsoftmet_           );
    theTree->SetBranchAddress( "mthiggs_"                ,   &mthiggs_                 );
    theTree->SetBranchAddress( "dphi_lephardmet_"        ,   &dphi_lephardmet_         );
    theTree->SetBranchAddress( "dphi_lepsoftmet_"        ,   &dphi_lepsoftmet_         );
    theTree->SetBranchAddress( "lepsoft_fbrem_"          ,   &lepsoft_fbrem_           );
    theTree->SetBranchAddress( "lepsoft_eOverPIn_"       ,   &lepsoft_eOverPIn_        );
    theTree->SetBranchAddress( "lepsoft_q_"              ,   &lepsoft_q_               );
    theTree->SetBranchAddress( "lepsoft_dPhiIn_"         ,   &lepsoft_dPhiIn_          );

    // Efficiency calculator for cut method
    Int_t    nSelCutsGA = 0;
    Double_t effS       = 0.7;

    std::vector<Float_t> vecVar(4); // vector for EvaluateMVA tests

    std::cout << "--- Processing: " << theTree->GetEntries() << " events" << std::endl;
    TStopwatch sw;
    sw.Start();

    int npass   = 0;
    float yield = 0.;
    
    for (Long64_t ievt=0; ievt<theTree->GetEntries();ievt++) {

      if (ievt%1000 == 0) std::cout << "--- ... Processing event: " << ievt << std::endl;

      theTree->GetEntry(ievt);

      //-------------------------------------------------------
      // event selection
      //-------------------------------------------------------

      if( dil_dphi_ > 1. ) continue;

      //em
      if( event_type_ > 0.5 && event_type_ < 2.5 ){
        if( met_projpt_ < 20. )   continue;
      }
      //ee/mm
      if( event_type_ < 0.5 || event_type_ > 2.5 ){
        if( met_projpt_ < 35. )   continue;
      }
      if( lephard_pt_ < 20.           )             continue;
      if( jets_num_ > 0               )             continue;
      if( extralep_num_ > 0           )             continue;
      if( lowptbtags_num_ > 0         )             continue;
      if( softmu_num_ > 0             )             continue;
      if( dil_mass_ < 12.             )             continue;
      if( lepsoft_passTighterId_ == 0 )             continue;
      //if( event_type_ < 1.5    )                    continue;
      //if( event_type > 1.5 && lepsoft_pt_ < 15. )   continue;

      //mH-dependent selection
      if( mH == 130 ){
        if( lepsoft_pt_ < 10.    )                  continue;      
        if( dil_mass_   > 90.    )                  continue;     
      }
      else if( mH == 160 ){
        if( lepsoft_pt_ < 20.    )                  continue;      
        if( dil_mass_   > 100.   )                  continue;     
      }
      else if( mH == 200 ){
        if( lepsoft_pt_ < 20.    )                  continue;      
        if( dil_mass_   > 130.   )                  continue;     
      }

      float weight = event_scale1fb_ * lepsoft_fr_ * 0.5;

      //--------------------------------------------------------
      // important: here we associate branches to MVA variables
      //--------------------------------------------------------

      lephard_pt        = lephard_pt_;
      lepsoft_pt        = lepsoft_pt_;
      dil_mass          = dil_mass_;
      dil_dphi          = dil_dphi_;
      event_type        = event_type_;
      met_pt            = met_pt_;
      met_projpt        = met_projpt_;
      mt_lephardmet     = mt_lephardmet_;
      mt_lepsoftmet     = mt_lepsoftmet_;
      mthiggs           = mthiggs_;
      dphi_lephardmet   = dphi_lephardmet_;
      dphi_lepsoftmet   = dphi_lepsoftmet_;
      lepsoft_fbrem     = lepsoft_fbrem_;
      lepsoft_eOverPIn  = lepsoft_eOverPIn_;
      lepsoft_qdphi     = lepsoft_q_ * lepsoft_dPhiIn_;

      npass++;
      yield+=weight;

      //       var1 = userVar1 + userVar2;
      //       var2 = userVar1 - userVar2;

      // --- Return the MVA outputs and fill into histograms

      if (Use["CutsGA"]) {
        // Cuts is a special case: give the desired signal efficienciy
        Bool_t passed = reader->EvaluateMVA( "CutsGA method", effS );
        if (passed) nSelCutsGA++;
      }

      if (Use["Likelihood"   ])   histLk     ->Fill( reader->EvaluateMVA( "Likelihood method"    ) , weight);
      if (Use["LikelihoodD"  ])   histLkD    ->Fill( reader->EvaluateMVA( "LikelihoodD method"   ) , weight);
      if (Use["LikelihoodPCA"])   histLkPCA  ->Fill( reader->EvaluateMVA( "LikelihoodPCA method" ) , weight);
      if (Use["LikelihoodKDE"])   histLkKDE  ->Fill( reader->EvaluateMVA( "LikelihoodKDE method" ) , weight);
      if (Use["LikelihoodMIX"])   histLkMIX  ->Fill( reader->EvaluateMVA( "LikelihoodMIX method" ) , weight);
      if (Use["PDERS"        ])   histPD     ->Fill( reader->EvaluateMVA( "PDERS method"         ) , weight);
      if (Use["PDERSD"       ])   histPDD    ->Fill( reader->EvaluateMVA( "PDERSD method"        ) , weight);
      if (Use["PDERSPCA"     ])   histPDPCA  ->Fill( reader->EvaluateMVA( "PDERSPCA method"      ) , weight);
      if (Use["KNN"          ])   histKNN    ->Fill( reader->EvaluateMVA( "KNN method"           ) , weight);
      if (Use["HMatrix"      ])   histHm     ->Fill( reader->EvaluateMVA( "HMatrix method"       ) , weight);
      if (Use["Fisher"       ])   histFi     ->Fill( reader->EvaluateMVA( "Fisher method"        ) , weight);
      if (Use["FisherG"      ])   histFiG    ->Fill( reader->EvaluateMVA( "FisherG method"       ) , weight);
      if (Use["BoostedFisher"])   histFiB    ->Fill( reader->EvaluateMVA( "BoostedFisher method" ) , weight);
      if (Use["LD"           ])   histLD     ->Fill( reader->EvaluateMVA( "LD method"            ) , weight);
      if (Use["MLP"          ])   histNn     ->Fill( reader->EvaluateMVA( "MLP method"           ) , weight);
      if (Use["MLPBFGS"      ])   histNnbfgs ->Fill( reader->EvaluateMVA( "MLPBFGS method"       ) , weight);
      if (Use["MLPBNN"       ])   histNnbnn  ->Fill( reader->EvaluateMVA( "MLPBNN method"        ) , weight);
      if (Use["CFMlpANN"     ])   histNnC    ->Fill( reader->EvaluateMVA( "CFMlpANN method"      ) , weight);
      if (Use["TMlpANN"      ])   histNnT    ->Fill( reader->EvaluateMVA( "TMlpANN method"       ) , weight);
      if (Use["BDT"          ])   histBdt    ->Fill( reader->EvaluateMVA( "BDT method"           ) , weight);
      if (Use["BDTD"         ])   histBdtD   ->Fill( reader->EvaluateMVA( "BDTD method"          ) , weight);
      if (Use["BDTG"         ])   histBdtG   ->Fill( reader->EvaluateMVA( "BDTG method"          ) , weight);
      if (Use["RuleFit"      ])   histRf     ->Fill( reader->EvaluateMVA( "RuleFit method"       ) , weight);
      if (Use["SVM_Gauss"    ])   histSVMG   ->Fill( reader->EvaluateMVA( "SVM_Gauss method"     ) , weight);
      if (Use["SVM_Poly"     ])   histSVMP   ->Fill( reader->EvaluateMVA( "SVM_Poly method"      ) , weight);
      if (Use["SVM_Lin"      ])   histSVML   ->Fill( reader->EvaluateMVA( "SVM_Lin method"       ) , weight);
      if (Use["FDA_MT"       ])   histFDAMT  ->Fill( reader->EvaluateMVA( "FDA_MT method"        ) , weight);
      if (Use["FDA_GA"       ])   histFDAGA  ->Fill( reader->EvaluateMVA( "FDA_GA method"        ) , weight);
      if (Use["Category"     ])   histCat    ->Fill( reader->EvaluateMVA( "Category method"      ) , weight);
      if (Use["Plugin"       ])   histPBdt   ->Fill( reader->EvaluateMVA( "P_BDT method"         ) , weight);

      // Retrieve also per-event error
      if (Use["PDEFoam"]) {
        Double_t val = reader->EvaluateMVA( "PDEFoam method" );
        Double_t err = reader->GetMVAError();
        histPDEFoam   ->Fill( val );
        histPDEFoamErr->Fill( err );         
        if (err>1.e-50) histPDEFoamSig->Fill( val/err , weight);
      }         

      // Retrieve probability instead of MVA output
      if (Use["Fisher"])   {
        probHistFi  ->Fill( reader->GetProba ( "Fisher method" ) , weight);
        rarityHistFi->Fill( reader->GetRarity( "Fisher method" ) , weight);
      }
    }

    std::cout << npass << " events passing selection, yield " << yield << std::endl;
 
    // Get elapsed time
    sw.Stop();
    std::cout << "--- End of event loop: "; sw.Print();

    // Get efficiency for cuts classifier
    if (Use["CutsGA"]) std::cout << "--- Efficiency for CutsGA method: " << double(nSelCutsGA)/theTree->GetEntries()
                                 << " (for a required signal efficiency of " << effS << ")" << std::endl;

    if (Use["CutsGA"]) {

      // test: retrieve cuts for particular signal efficiency
      // CINT ignores dynamic_casts so we have to use a cuts-secific Reader function to acces the pointer  
      TMVA::MethodCuts* mcuts = reader->FindCutsMVA( "CutsGA method" ) ;

      if (mcuts) {      
        std::vector<Double_t> cutsMin;
        std::vector<Double_t> cutsMax;
        mcuts->GetCuts( 0.7, cutsMin, cutsMax );
        std::cout << "--- -------------------------------------------------------------" << std::endl;
        std::cout << "--- Retrieve cut values for signal efficiency of 0.7 from Reader" << std::endl;
        for (UInt_t ivar=0; ivar<cutsMin.size(); ivar++) {
          std::cout << "... Cut: " 
                    << cutsMin[ivar] 
                    << " < \"" 
                    << mcuts->GetInputVar(ivar)
                    << "\" <= " 
                    << cutsMax[ivar] << std::endl;
        }
        std::cout << "--- -------------------------------------------------------------" << std::endl;
      }
    }

    // --- Write histograms
    cout << "dir " << dir << endl;
    char* mydir = outdir;
    TFile *target  = new TFile( Form("%s/%s.root",mydir,samples.at(i) ) ,"RECREATE" );
    cout << "Writing to file " << Form("%s/%s.root",mydir,samples.at(i) ) << endl;

    if (Use["Likelihood"   ])   histLk     ->Write();
    if (Use["LikelihoodD"  ])   histLkD    ->Write();
    if (Use["LikelihoodPCA"])   histLkPCA  ->Write();
    if (Use["LikelihoodKDE"])   histLkKDE  ->Write();
    if (Use["LikelihoodMIX"])   histLkMIX  ->Write();
    if (Use["PDERS"        ])   histPD     ->Write();
    if (Use["PDERSD"       ])   histPDD    ->Write();
    if (Use["PDERSPCA"     ])   histPDPCA  ->Write();
    if (Use["KNN"          ])   histKNN    ->Write();
    if (Use["HMatrix"      ])   histHm     ->Write();
    if (Use["Fisher"       ])   histFi     ->Write();
    if (Use["FisherG"      ])   histFiG    ->Write();
    if (Use["BoostedFisher"])   histFiB    ->Write();
    if (Use["LD"           ])   histLD     ->Write();
    if (Use["MLP"          ])   histNn     ->Write();
    if (Use["MLPBFGS"      ])   histNnbfgs ->Write();
    if (Use["MLPBNN"       ])   histNnbnn  ->Write();
    if (Use["CFMlpANN"     ])   histNnC    ->Write();
    if (Use["TMlpANN"      ])   histNnT    ->Write();
    if (Use["BDT"          ])   histBdt    ->Write();
    if (Use["BDTD"         ])   histBdtD   ->Write();
    if (Use["BDTG"         ])   histBdtG   ->Write(); 
    if (Use["RuleFit"      ])   histRf     ->Write();
    if (Use["SVM_Gauss"    ])   histSVMG   ->Write();
    if (Use["SVM_Poly"     ])   histSVMP   ->Write();
    if (Use["SVM_Lin"      ])   histSVML   ->Write();
    if (Use["FDA_MT"       ])   histFDAMT  ->Write();
    if (Use["FDA_GA"       ])   histFDAGA  ->Write();
    if (Use["Category"     ])   histCat    ->Write();
    if (Use["Plugin"       ])   histPBdt   ->Write();

    // Write also error and significance histos
    if (Use["PDEFoam"]) { histPDEFoam->Write(); histPDEFoamErr->Write(); histPDEFoamSig->Write(); }

    // Write also probability hists
    if (Use["Fisher"]) { if (probHistFi != 0) probHistFi->Write(); if (rarityHistFi != 0) rarityHistFi->Write(); }
    target->Close();

    delete reader;
    
    std::cout << "==> TMVAClassificationApplication is done with sample " << samples.at(i) << endl << std::endl;
  } 
}
void background_rates_GMN( const char *setupfilename, const char *outfilename ){

  ifstream setupfile(setupfilename);

  TString filename;

  TChain *C = new TChain("T");
  
  while( setupfile >> filename ){
    C->Add(filename);
  }
  
  G4SBSRunData *rd;
  
  // C->Add(rootfilename);

  long ngen = 0;

  int nfiles = 0;

  TObjArray *FileList = C->GetListOfFiles();
  TIter next(FileList);
  
  TChainElement *chEl = 0;

  set<TString> bad_file_list;
  
  while( (chEl=(TChainElement*)next() )){
    TFile newfile(chEl->GetTitle());
    newfile.GetObject("run_data",rd);
    if( rd ){
      ngen += rd->fNtries;
      nfiles++;
    } else {
      bad_file_list.insert( chEl->GetTitle());
    }
    //cout << chEl->GetTitle() << endl;
  }

  cout << "Total number of generated events = " << ngen << endl;

  gmn_tree *T = new gmn_tree(C);

  TFile *fout = new TFile( outfilename, "RECREATE" );

  TH2D *hnphe_vs_edep_HCAL = new TH2D("hnphe_vs_edep_HCAL","",500,0.0,0.5,501,-0.5,500.5);
  TH2D *hrate_vs_nphe_HCAL = new TH2D("hrate_vs_nphe_HCAL","",288,-0.5,287.5,500,0.5,500.5);
  TH2D *hrate_vs_edep_HCALscint = new TH2D("hrate_vs_edep_HCALscint","",288,-0.5,287.5,500,0.0,1.0); //GeV

  TH2D *hnphe_vs_edep_CDET = new TH2D("hnphe_vs_edep_CDET","",500,0.0,0.25,501,-0.5,500.5);
  TH2D *hrate_vs_nphe_CDET = new TH2D("hrate_vs_nphe_CDET","",2352,-0.5,2351.5,500,0.5,500.5);
  TH2D *hrate_vs_edep_CDETscint = new TH2D("hrate_vs_edep_CDETscint","",2352,-0.5,2351.5,500,0.0,1.0); //GeV

  //TH2D *hnphe_vs_edep_BBhodo = new TH2D("hnphe_vs_edep_BBhodo","",500,0.0,0.25,501,-0.5,500.5);
  //TH2D *hrate_vs_nphe_BBhodo = new TH2D("hrate_vs_nphe_BBhodo","",2352,-0.5,2351.5,500,0.5,500.5);
  TH2D *hrate_vs_edep_BBHodoScint = new TH2D("hrate_vs_edep_BBHodoScint","",90,-0.5,89.5,500,0.0,0.15); //GeV

  TH2D *hnphe_vs_edep_BBPS = new TH2D("hnphe_vs_edep_BBPS","",500,0.0,0.25,501,-0.5,500.5);
  TH2D *hrate_vs_nphe_BBPS = new TH2D("hrate_vs_nphe_BBPS","",54,-0.5,53.5,501,-0.5,500.5);
  TH2D *hrate_vs_edep_BBPSTF1 = new TH2D("hrate_vs_edep_BBPSTF1","",54,-0.5,53.5,500,0.0,0.25); //GeV

  TH2D *hnphe_vs_edep_BBSH = new TH2D("hnphe_vs_edep_BBSH","",500,0.0,0.5,501,-0.5,500.5);
  TH2D *hrate_vs_nphe_BBSH = new TH2D("hrate_vs_nphe_BBSH","",189,-0.5,188.5,501,-0.5,500.5);
  TH2D *hrate_vs_edep_BBSHTF1 = new TH2D("hrate_vs_edep_BBSHTF1","",189,-0.5,188.5,500,0.0,0.5); //GeV
  
  double pmtnum[288];
  double sumedep_HCAL[288];
  // double sum2edep_HCAL[288];
  double sumnphe_HCAL[288];
  double hitrate_HCAL[288];
  
  for( int ipmt=0; ipmt<288; ipmt++ ){
    sumedep_HCAL[ipmt] = 0.0;
    pmtnum[ipmt] = ipmt;
    sumnphe_HCAL[ipmt] = 0.0;
    hitrate_HCAL[ipmt] = 0.0;
  }

  double pmt_CDET[2352];
  double sumedep_CDET[2352];
  double sumnphe_CDET[2352];
  double hitrate_CDET[2352];
  
  for( int ipmt=0; ipmt<2352; ipmt++ ){
    pmt_CDET[ipmt] = ipmt;
    sumedep_CDET[ipmt] = 0.0;
    sumnphe_CDET[ipmt] = 0.0;
    hitrate_CDET[ipmt] = 0.0;
  }

  double pmtBBHodo[90];
  double sumedep_BBHodo[90];
  double hitrate_BBHodo[90];
  
  for( int ipmt=0; ipmt<90; ipmt++ ){
    pmtBBHodo[ipmt] = ipmt;
    sumedep_BBHodo[ipmt] = 0.0;
    hitrate_BBHodo[ipmt] = 0.0;
  }

  double PMT_PS[2*27];
  double PMT_SH[189];

  double sumedep_PS[54];
  double sumedep_SH[189];
  double sumnphe_PS[54];
  double sumnphe_SH[189];
  double hitrate_PS[54];
  double hitrate_SH[189];
  
  for( int i=0; i<54; i++ ){
    PMT_PS[i] = i;
    sumedep_PS[i] = 0.0;
    sumnphe_PS[i] = 0.0;
    hitrate_PS[i] = 0.0;
  }

  for( int i=0; i<189; i++ ){
    PMT_SH[i] = i;
    sumedep_SH[i] = 0.0;
    sumnphe_SH[i] = 0.0;
    hitrate_SH[i] = 0.0;
  }

  
  double thresh_CDET = .0055; //5.5 MeV
  double thresh_BBhodo = 0.008; //3 MeV
  // double thresh_BBPS   = 0.02*0.751; //7.5 MeV
  // double thresh_BBSH   = 0.02*2.83; //28.3 MeV
  double thresh_BBPS   = 0.05;
  double thresh_BBSH   = 0.05;
  double thresh_HCAL   = 0.02*0.56; //~11 MeV
  
  long nevent=0;

  double Ibeam = 30e-6; //A
  double weight = Ibeam/double(ngen)/1.602e-19;

  
  
  while( T->GetEntry( nevent++ ) ){
    if( nevent % 1000 == 0 ) cout << nevent << endl;
    
    TFile *f = ( (TChain*) (T->fChain) )->GetFile();

    if( bad_file_list.find( f->GetName() ) == bad_file_list.end() ){
      for( int ihit=0; ihit<T->Harm_HCal_hit_nhits; ihit++ ){
	int PMT = (*(T->Harm_HCal_hit_PMT))[ihit];
	int nphe = (*(T->Harm_HCal_hit_NumPhotoelectrons))[ihit];

	double edep = 0.0;
	
	for( int jhit=0; jhit<T->Harm_HCalScint_hit_nhits; jhit++ ){
	  if( (*(T->Harm_HCalScint_hit_cell))[jhit] == PMT ){
	    edep = (*(T->Harm_HCalScint_hit_sumedep))[jhit];
	  }
	}
	hrate_vs_nphe_HCAL->Fill( PMT, nphe, weight );
	hrate_vs_edep_HCALscint->Fill( PMT, edep, weight );

	hnphe_vs_edep_HCAL->Fill( edep, nphe, weight );
	
	sumedep_HCAL[PMT] += edep * weight;
	sumnphe_HCAL[PMT] += nphe * weight;

	if( edep >= thresh_HCAL ) hitrate_HCAL[PMT] += weight;
      }

      for( int ihit=0; ihit<T->Harm_CDET_hit_nhits; ihit++ ){
	int PMT = (*(T->Harm_CDET_hit_PMT))[ihit];
	int nphe = (*(T->Harm_CDET_hit_NumPhotoelectrons))[ihit];

	double edep = 0.0;
	
	for( int jhit=0; jhit<T->Harm_CDET_Scint_hit_nhits; jhit++ ){
	  if( (*(T->Harm_CDET_Scint_hit_cell))[jhit] == PMT ){
	    edep = (*(T->Harm_CDET_Scint_hit_sumedep))[jhit];
	  }
	}
	hrate_vs_nphe_CDET->Fill( PMT, nphe, weight );
	hrate_vs_edep_CDETscint->Fill( PMT, edep, weight );

	hnphe_vs_edep_CDET->Fill( edep, nphe, weight );
	
	sumedep_CDET[PMT] += edep * weight;
	sumnphe_CDET[PMT] += nphe * weight;

	if( edep >= thresh_CDET ) hitrate_CDET[PMT] += weight;
      }

      for( int ihit=0; ihit<T->Earm_BBHodoScint_hit_nhits; ihit++ ){
	double edep = (*(T->Earm_BBHodoScint_hit_sumedep))[ihit];
	int PMT = (*(T->Earm_BBHodoScint_hit_cell))[ihit];
	hrate_vs_edep_BBHodoScint->Fill( PMT, edep, weight );

	sumedep_BBHodo[PMT] += edep * weight;

	if( edep >= thresh_BBhodo ) hitrate_BBHodo[PMT] += weight;
      }

      //BB PS:
      for( int ihit=0; ihit<T->Earm_BBPS_hit_nhits; ihit++ ){
	int PMT = (*(T->Earm_BBPS_hit_PMT))[ihit];
	int nphe = (*(T->Earm_BBPS_hit_NumPhotoelectrons))[ihit];
	double edep = 0.0;
	for( int jhit=0; jhit<T->Earm_BBPSTF1_hit_nhits; jhit++ ){
	  int cell = (*(T->Earm_BBPSTF1_hit_cell))[jhit];
	  if( cell == PMT ){
	    edep = (*(T->Earm_BBPSTF1_hit_sumedep))[jhit];
	  }
	}

	hrate_vs_nphe_BBPS->Fill( PMT, nphe, weight );
	hrate_vs_edep_BBPSTF1->Fill( PMT, edep, weight );

	hnphe_vs_edep_BBPS->Fill( edep, nphe, weight );

	sumnphe_PS[PMT] += nphe * weight;
	sumedep_PS[PMT] += edep * weight;

	if( edep >= thresh_BBPS ) hitrate_PS[PMT] += weight;
      }

      //BB SH:
      for( int ihit=0; ihit<T->Earm_BBSH_hit_nhits; ihit++ ){
	int PMT = (*(T->Earm_BBSH_hit_PMT))[ihit];
	int nphe = (*(T->Earm_BBSH_hit_NumPhotoelectrons))[ihit];
	double edep = 0.0;
	for( int jhit=0; jhit<T->Earm_BBSHTF1_hit_nhits; jhit++ ){
	  int cell = (*(T->Earm_BBSHTF1_hit_cell))[jhit];
	  if( cell == PMT ){
	    edep = (*(T->Earm_BBSHTF1_hit_sumedep))[jhit];
	  }
	}

	hrate_vs_nphe_BBSH->Fill( PMT, nphe, weight );
	hrate_vs_edep_BBSHTF1->Fill( PMT, edep, weight );

	hnphe_vs_edep_BBSH->Fill( edep, nphe, weight );
	
	sumnphe_SH[PMT] += nphe * weight;
	sumedep_SH[PMT] += edep * weight;

	if( edep >= thresh_BBSH ) hitrate_SH[PMT] += weight;
      }
      
    }
  }

  TGraph *edep_rate_HCAL = new TGraph( 288, pmtnum, sumedep_HCAL );
  TGraph *nphe_rate_HCAL = new TGraph( 288, pmtnum, sumnphe_HCAL );

  edep_rate_HCAL->SetMarkerStyle(20);
  edep_rate_HCAL->GetYaxis()->SetTitle("GeV/s (nphe >= 1)");
  edep_rate_HCAL->GetXaxis()->SetTitle("HCAL PMT number");
  nphe_rate_HCAL->SetMarkerStyle(20);
  nphe_rate_HCAL->GetYaxis()->SetTitle("phe/s");
  nphe_rate_HCAL->GetXaxis()->SetTitle("HCAL PMT number");
  
  edep_rate_HCAL->Write("edep_total_rate_vs_PMT_HCAL");
  nphe_rate_HCAL->Write("nphe_total_rate_vs_PMT_HCAL");

  TGraph *ghitrate_HCAL = new TGraph( 288, pmtnum, hitrate_HCAL );
  ghitrate_HCAL->SetMarkerStyle(20);
  ghitrate_HCAL->GetXaxis()->SetTitle("HCAL PMT number");
  ghitrate_HCAL->GetYaxis()->SetTitle("Hit rate (thresh. 11 MeV)");
  ghitrate_HCAL->Write("hitrate_HCAL");
  
  TGraph *edep_rate_CDET = new TGraph( 2352, pmt_CDET, sumedep_CDET );
  TGraph *nphe_rate_CDET = new TGraph( 2352, pmt_CDET, sumnphe_CDET );

  edep_rate_CDET->SetMarkerStyle(20);
  edep_rate_CDET->GetYaxis()->SetTitle("GeV/s (nphe >= 1)");
  edep_rate_CDET->GetXaxis()->SetTitle("CDET PMT number");
  nphe_rate_CDET->SetMarkerStyle(20);
  nphe_rate_CDET->GetYaxis()->SetTitle("phe/s");
  nphe_rate_CDET->GetXaxis()->SetTitle("CDET PMT number");

  
  edep_rate_CDET->Write("edep_total_rate_vs_PMT_CDET");
  nphe_rate_CDET->Write("nphe_total_rate_vs_PMT_CDET");

  TGraph *ghitrate_CDET = new TGraph( 2352, pmt_CDET, hitrate_CDET );
  ghitrate_CDET->SetMarkerStyle(20);
  ghitrate_CDET->GetXaxis()->SetTitle("CDET PMT number");
  ghitrate_CDET->GetYaxis()->SetTitle("Hit rate (thresh. 5.5 MeV)");
  ghitrate_CDET->Write("hitrate_CDET");
  
  TGraph *edep_rate_BBHodo = new TGraph( 90, pmtBBHodo, sumedep_BBHodo );
  edep_rate_BBHodo->SetMarkerStyle(20);
  edep_rate_BBHodo->GetYaxis()->SetTitle("GeV/s");
  edep_rate_BBHodo->GetXaxis()->SetTitle("BB hodo PMT number");

  edep_rate_BBHodo->Write("edep_rate_BBHodo");

  TGraph *ghitrate_BBHodo = new TGraph( 90, pmtBBHodo, hitrate_BBHodo );
  ghitrate_BBHodo->SetMarkerStyle(20);
  ghitrate_BBHodo->GetXaxis()->SetTitle("BBHodo PMT number");
  ghitrate_BBHodo->GetYaxis()->SetTitle("Hit rate (thresh. 3 MeV)");
  ghitrate_BBHodo->Write("hitrate_BBHodo");
  
  TGraph *edep_rate_PS = new TGraph( 54, PMT_PS, sumedep_PS );
  TGraph *nphe_rate_PS = new TGraph( 54, PMT_PS, sumnphe_PS );

  edep_rate_PS->SetMarkerStyle(20);
  edep_rate_PS->GetYaxis()->SetTitle( "GeV/s (nphe >= 1)" );
  edep_rate_PS->GetXaxis()->SetTitle( "PS PMT number" );
  edep_rate_PS->Write("edep_rate_PS");

  nphe_rate_PS->SetMarkerStyle(20);
  nphe_rate_PS->GetYaxis()->SetTitle( "nphe/s" );
  nphe_rate_PS->GetXaxis()->SetTitle( "PS PMT number" );
  nphe_rate_PS->Write("nphe_rate_PS");

  TGraph *ghitrate_PS = new TGraph( 54, PMT_PS, hitrate_PS );
  ghitrate_PS->SetMarkerStyle(20);
  ghitrate_PS->GetXaxis()->SetTitle("PS PMT number");
  ghitrate_PS->GetYaxis()->SetTitle("Hit rate (thresh. 7.5 MeV)");
  ghitrate_PS->Write("hitrate_PS");
  
  TGraph *edep_rate_SH = new TGraph( 189, PMT_SH, sumedep_SH );
  TGraph *nphe_rate_SH = new TGraph( 189, PMT_SH, sumnphe_SH );

  edep_rate_SH->SetMarkerStyle(20);
  edep_rate_SH->GetYaxis()->SetTitle( "GeV/s (nphe >= 1)" );
  edep_rate_SH->GetXaxis()->SetTitle( "SH PMT number" );
  edep_rate_SH->Write("edep_rate_SH");

  nphe_rate_SH->SetMarkerStyle(20);
  nphe_rate_SH->GetYaxis()->SetTitle( "nphe/s" );
  nphe_rate_SH->GetXaxis()->SetTitle( "SH PMT number" );
  nphe_rate_SH->Write("nphe_rate_SH");

  TGraph *ghitrate_SH = new TGraph( 189, PMT_SH, hitrate_SH );
  ghitrate_SH->SetMarkerStyle(20);
  ghitrate_SH->GetXaxis()->SetTitle("SH PMT number");
  ghitrate_SH->GetYaxis()->SetTitle("Hit rate (thresh. 28.3 MeV)");
  ghitrate_SH->Write("hitrate_SH");
  
  fout->Write();
  
}
Exemple #5
0
void Skim(TString fname="ZnnH125", TString outputname = "")
{
    gROOT->LoadMacro("HelperFunctions.h" );  // make functions visible to TTreeFormula
    gROOT->SetBatch(1);

    TChain * chain  = new TChain("tree");
    TString dijet   = "";
    TString outdir  = "/afs/cern.ch/work/d/degrutto/public/MiniAOD/ZnnHbb_Phys14_PU20bx25/skimV11_v2/";
    TString prefix  = "skim_";
    TString suffix  = "tree*.root";
    


    TCut selection = baseline.c_str();
    // Different baseline for dimuons
    // MET filters
    selection += metfilter.c_str();

    // JSON & trigger
    if (fname.Contains("Data")) {
        TCut trigger = mettrigger.c_str();
        selection += trigger;
        //selection.Print();
      }
      /*
    } else if (process == "Data_METBTag_R" || process == "Data_METBTag_P") {
        TCut trigger = metbtagtrigger.c_str();
        selection += trigger;
        //selection.Print();
    } else if (process == "Data_SingleMu_R" || process == "Data_SingleMu_P") {
        TCut trigger = singlemutrigger.c_str();
        selection += trigger;
        //selection.Print();
    } else if (process == "Data_SingleEl_R" || process == "Data_SingleEl_P") {
        TCut trigger = singleeltrigger.c_str();
        selection += trigger;
        //selection.Print();
    }
      */


    chain->Add(fname);

    // Sum Count, CountWithPU, CountWithPUP, CountWithPUM
    TObjArray * files = chain->GetListOfFiles();
    TIter next(files);
    TChainElement * chainElem = 0;
    TFile * f2 = 0;
    TH1D * h1 = new TH1D("Count", ";Counts", 16, 0, 16);
    TH1F * htemp = 0;

    while ((chainElem = (TChainElement*) next())) {
      //#ifndef XROOTD
      //      f2 = TFile::Open("dcache:" + TString(chainElem->GetTitle()));
      //#else
      std::cout << "chainElem->GetTitle() " << chainElem->GetTitle() << std::endl; 
        f2 = TFile::Open( TString(chainElem->GetTitle()));
	//#endif
        htemp = (TH1F*) f2->Get("Count");
        h1->SetBinContent(1, h1->GetBinContent(1)+htemp->GetBinContent(1));
	/*
        htemp = (TH1F*) f2->Get("CountWithPU");
        h1->SetBinContent(2, h1->GetBinContent(2)+htemp->GetBinContent(1));
        htemp = (TH1F*) f2->Get("CountWithPUP");
        h1->SetBinContent(3, h1->GetBinContent(3)+htemp->GetBinContent(1));
        htemp = (TH1F*) f2->Get("CountWithPUM");
        h1->SetBinContent(4, h1->GetBinContent(4)+htemp->GetBinContent(1));
        htemp = (TH1F*) f2->Get("CountWithMCProd");
        h1->SetBinContent(5, h1->GetBinContent(5)+htemp->GetBinContent(1));
        htemp = (TH1F*) f2->Get("CountWithPUMCProd");
        h1->SetBinContent(6, h1->GetBinContent(6)+htemp->GetBinContent(1));
        htemp = (TH1F*) f2->Get("countWithSignalQCDcorrections");
        h1->SetBinContent(7, h1->GetBinContent(7)+htemp->GetBinContent(1));
        */
        std::clog << fname << ": skimmed from " << chainElem->GetTitle() << std::endl;
    }
    
    // LHE Count
    
    TH1D * h2 = new TH1D("LHECount", ";LHE Counts", 16, 0, 16);
    TString process_lhe = fname;
    if (process_lhe.BeginsWith("WJets"))
        process_lhe = "WJets";
    else if (process_lhe.BeginsWith("ZJets"))
        process_lhe = "ZJets";
    else 
        process_lhe = "";
    const std::vector<std::string>& lhecuts = GetLHECuts(process_lhe.Data());
    for (unsigned int i=0; i < lhecuts.size(); i++) {
        TCut cut2 = lhecuts.at(i).c_str();
        h2->SetBinContent(i+1, chain->GetEntries(cut2));
    }
    
    

    // Make output directory if it doesn't exist
    if (gSystem->AccessPathName(outdir))
        gSystem->mkdir(outdir);
    TString outname = outdir + prefix + Form("%s.root", outputname.Data());
    std::cout << "outname is " << outname << std::endl;

    TFile* f1 = TFile::Open(outname, "RECREATE");
    TTree* t1 = (TTree*) chain->CopyTree(selection);
    std::clog << fname << ": skimmed from " << chain->GetEntriesFast() << " to " << t1->GetEntriesFast() << " entries." << std::endl;
    
    t1->Write();
    h1->Write();
     h2->Write();
    f1->Close();

    return;
}
Exemple #6
0
void flux(const char *rootfilename, const char *outputfilename){

  gStyle->SetMarkerStyle(20);
  
  TH1::SetDefaultSumw2();
  
  TChain *C = new TChain("T");
  C->Add(rootfilename);

  G4SBSRunData *rd;

  long ngen = 0;
  int nfiles = 0;
  
  TObjArray *FileList = C->GetListOfFiles();
  TIter next(FileList);

  TChainElement *chEl = 0;

  set<TString> bad_file_list;
  
  while( (chEl=(TChainElement*)next() )){
    TFile newfile(chEl->GetTitle());
    newfile.GetObject("run_data",rd);
    if( rd ){
      ngen += rd->fNtries;
      nfiles++;
    } else {
      bad_file_list.insert( chEl->GetTitle());
    }
    //cout << chEl->GetTitle() << endl;
  }

  cout << "number of generated events = " << ngen << endl;

  C16_tree_with_flux *T = new C16_tree_with_flux(C);
  
  TFile *fout = new TFile(outputfilename,"RECREATE");

  long nevent=0;

  double cutgamma = 0.05*1.e-3; //energy cutoff in GeV for photons
  double cutelectron = 5.e-3; //range cutoff in GeV for electrons:
  
  TH1D *hphoton_rate_vs_theta = new TH1D("hphoton_rate_vs_theta","",80,0.0,40.0);
  TH1D *helectron_rate_vs_theta = new TH1D("helectron_rate_vs_theta","",80,0.0,40.0);
  TH1D *hphoton_rate_vs_theta_Edep = new TH1D("hphoton_rate_vs_theta_Edep","",80,0.0,40.0);
  TH1D *helectron_rate_vs_theta_Edep = new TH1D("helectron_rate_vs_theta_Edep","",80,0.0,40.0);
  TH1D *hother_rate_vs_theta = new TH1D("hother_rate_vs_theta","",80,0.0,40.0);
  TH1D *hother_rate_vs_theta_Edep = new TH1D("hother_rate_vs_theta_Edep","",80,0.0,40.0);

  TH1D *htotal_rate_vs_theta = new TH1D("htotal_rate_vs_theta","",80,0.0,40.0);
  TH1D *htotal_rate_vs_theta_Edep = new TH1D("htotal_rate_vs_theta_Edep","",80,0.0,40.0);

  double PI = TMath::Pi();

  double binwidth_theta = 40.0/80.0*PI/180.0;

  double Ibeam = 20e-6;
  double e = 1.602e-19;
  
  while( T->GetEntry( nevent++ ) ){
    TFile *f = ( (TChain*) (T->fChain) )->GetFile();

    TString fname = f->GetName();
    
    if( bad_file_list.find( fname ) == bad_file_list.end() ){ 
    
      if( nevent%1000 == 0 ) {
	cout << nevent << endl;
	cout << "Current file = " << f->GetName() << endl;
      }
      
      for( int part=0; part<T->FLUX_npart_CAL; part++ ){
	double E = (*(T->FLUX_E))[part];
	double px = (*(T->FLUX_px))[part];
	double py = (*(T->FLUX_py))[part];
	double pz = (*(T->FLUX_pz))[part];
	double p = (*(T->FLUX_p))[part];
	double theta = acos( pz/p );
	double phi = atan2( py, px );

	int bintheta = hphoton_rate_vs_theta->FindBin( theta * 180.0/PI );

	double dcostheta = cos( PI/180.0*hphoton_rate_vs_theta->GetBinLowEdge(bintheta) ) -
	  cos( PI/180.0*hphoton_rate_vs_theta->GetBinLowEdge(bintheta+1) );
	double dOmega = 2.0*PI *dcostheta;

	double weight = Ibeam/e/double(ngen)/dOmega;
	
	int pid = (*(T->FLUX_pid))[part];

	htotal_rate_vs_theta->Fill( theta*180.0/PI, weight );
	htotal_rate_vs_theta_Edep->Fill( theta*180.0/PI, weight*E );
	
	if( pid == 22 && E >= cutgamma ){//photon
	  hphoton_rate_vs_theta->Fill( theta*180.0/PI, weight );
	  hphoton_rate_vs_theta_Edep->Fill( theta*180.0/PI, weight*E );
	} else if( fabs(pid) == 11 && E >= cutelectron ){ //e+/e-
	  helectron_rate_vs_theta->Fill( theta*180.0/PI, weight );
	  helectron_rate_vs_theta_Edep->Fill( theta*180.0/PI, weight*E );
	} else { //other
	  hother_rate_vs_theta->Fill( theta*180.0/PI, weight );
	  hother_rate_vs_theta_Edep->Fill( theta*180.0/PI, weight*E );
	}
      }

    }
  }

  hphoton_rate_vs_theta->GetXaxis()->SetTitle("#theta (#circ)");
  hphoton_rate_vs_theta->GetYaxis()->SetTitle("#frac{dN_{#gamma}}{dt d#Omega} (Photons/s/sr)");

  helectron_rate_vs_theta->GetXaxis()->SetTitle("#theta (#circ)");
  helectron_rate_vs_theta->GetYaxis()->SetTitle("#frac{dN_{e}}{dt d#Omega} (Electrons/s/sr)");

  hother_rate_vs_theta->GetXaxis()->SetTitle("#theta (#circ)");
  hother_rate_vs_theta->GetYaxis()->SetTitle("#frac{dN_{other}}{dt d#Omega} (Particles/s/sr)");

  htotal_rate_vs_theta->GetXaxis()->SetTitle("#theta (#circ)");
  htotal_rate_vs_theta->GetYaxis()->SetTitle("#frac{dN_{total}}{dt d#Omega} (Particles/s/sr)");

  hphoton_rate_vs_theta_Edep->GetXaxis()->SetTitle("#theta (#circ)");
  hphoton_rate_vs_theta_Edep->GetYaxis()->SetTitle("#frac{dE}{dt d#Omega} (GeV/s/sr)");

  helectron_rate_vs_theta_Edep->GetXaxis()->SetTitle("#theta (#circ)");
  helectron_rate_vs_theta_Edep->GetYaxis()->SetTitle("#frac{dE}{dt d#Omega} (GeV/s/sr)");

  hother_rate_vs_theta_Edep->GetXaxis()->SetTitle("#theta (#circ)");
  hother_rate_vs_theta_Edep->GetYaxis()->SetTitle("#frac{dE}{dt d#Omega} (GeV/s/sr)");

  htotal_rate_vs_theta_Edep->GetXaxis()->SetTitle("#theta (#circ)");
  htotal_rate_vs_theta_Edep->GetYaxis()->SetTitle("#frac{dE}{dt d#Omega} (GeV/s/sr)");
  
  fout->Write();
}
void gep_trigger_analysis_elastic( const char *rootfilename, const char *logicfilename_ecal, const char *logicfilename_hcal, const char *thresholdfilename_ecal, const char *thresholdfilename_hcal, const char *outputfilename, double thetacaldeg=29.0, int pheflag=0, const char *assocfilename="ECAL_HCAL_correlations_nophe.txt", int Q2cut=0 ){

  double nominal_threshold_HCAL = 0.5;
  double nominal_threshold_ECAL = 0.9;
  
  double thetacal = thetacaldeg*PI/180.0;
  
  TFile *fout = new TFile(outputfilename,"RECREATE");
  TChain *C = new TChain("T");
  C->Add(rootfilename);

  gep_tree_elastic *T = new gep_tree_elastic( C );

  G4SBSRunData *rd;

  long ngen = 0;
  int nfiles = 0;
  
  TObjArray *FileList = C->GetListOfFiles();
  TIter next(FileList);

  TChainElement *chEl = 0;

  set<TString> bad_file_list;
  
  while( (chEl=(TChainElement*)next() )){
    TFile newfile(chEl->GetTitle());
    newfile.GetObject("run_data",rd);
    if( rd ){
      ngen += rd->fNtries;
      nfiles++;
    } else {
      bad_file_list.insert( chEl->GetTitle());
    }
  }

  cout << "number of generated events = " << ngen << endl;
  
  set<int> list_of_nodes_ecal;
  map<int, set<int> > cells_logic_sums_ecal; //mapping between node numbers and cell numbers
  map<int, double> logic_mean_ecal; //mean peak positions by node number
  map<int, double> logic_sigma_ecal; //peak width by node number
  map<int, double> threshold_ecal; //threshold by node number
  map<std::pair<int,int>, int > cell_rowcol_ecal; //cell numbers mapped by unique row and column pairs
  map<int,set<int> > nodes_cells_ecal; //mapping of nodes by cell number:
  map<int,int> rows_cells_ecal;
  map<int,int> cols_cells_ecal;
  map<int,double> xcells_ecal;
  map<int,double> ycells_ecal;
  
  //keep track of min and max x by row number:
  double ycellmin,ycellmax;
  map<int,double> ycell_rows;
  map<int,double> cellsize_rows;
  map<int,double> xcellmin_rows;
  map<int,double> xcellmax_rows;
  
  int minrow=1000,maxrow=-1;
  
  set<int> rows_ecal;
  map<int,set<int> > columns_rows_ecal;
  
  map<int,double> elastic_peak_new_ecal;
  map<int,double> sigma_new_ecal;
  map<int,double> threshold_new_ecal;
  
  ifstream logicfile_ecal(logicfilename_ecal);
  //ifstream thresholdfile(thresholdfilename);

  TString currentline;
  
  int current_node = 1;

  bool first_cell = true;
  
  while( currentline.ReadLine( logicfile_ecal ) ){
    if( !currentline.BeginsWith( "#" ) ){
      
      TObjArray *tokens = currentline.Tokenize(" ");
      int ntokens = tokens->GetEntries();
      if( ntokens >= 11 ){
	cout << currentline.Data() << ", ntokens = " << ntokens << endl;
	
	TString snode = ( (TObjString*) (*tokens)[0] )->GetString();
	int nodenumber = snode.Atoi();
	
	TString scell = ( (TObjString*) (*tokens)[1] )->GetString();
	int cellnumber = scell.Atoi();
	
	TString speakpos = ( (TObjString*) (*tokens)[8] )->GetString();
	double mean = speakpos.Atof();
	
	TString ssigma = ( (TObjString*) (*tokens)[9] )->GetString();
	double sigma = ssigma.Atof();

	TString sthreshold = ( (TObjString*) (*tokens)[10] )->GetString();
	double threshold = sthreshold.Atof();

	TString srow = ( (TObjString*) (*tokens)[2] )->GetString();
	TString scol = ( (TObjString*) (*tokens)[3] )->GetString();

	std::pair<int,int> rowcoltemp( srow.Atoi(), scol.Atoi() );

	cell_rowcol_ecal[rowcoltemp] = cellnumber;
	
	list_of_nodes_ecal.insert( nodenumber );

	cells_logic_sums_ecal[nodenumber].insert( cellnumber );

	logic_mean_ecal[nodenumber] = mean;
	logic_sigma_ecal[nodenumber] = sigma;
	threshold_ecal[nodenumber] = threshold;

	nodes_cells_ecal[ cellnumber ].insert(nodenumber);

	TString sxcell = ( (TObjString*) (*tokens)[4] )->GetString(); 
	TString sycell = ( (TObjString*) (*tokens)[5] )->GetString(); 

	cols_cells_ecal[cellnumber] = scol.Atoi(); 
	rows_cells_ecal[cellnumber] = srow.Atoi();

	xcells_ecal[cellnumber] = sxcell.Atof()/1000.0; //convert to m
	ycells_ecal[cellnumber] = sycell.Atof()/1000.0; //convert to m

	if( ycell_rows.empty() || sycell.Atof()/1000.0 < ycellmin ) ycellmin = sycell.Atof()/1000.0;
	if( ycell_rows.empty() || sycell.Atof()/1000.0 > ycellmax ) ycellmax = sycell.Atof()/1000.0;
	
	ycell_rows[srow.Atoi()] = sycell.Atof()/1000.0;
	TString ssize = ( (TObjString*) (*tokens)[6] )->GetString();
	double size = ssize.Atof();

	cellsize_rows[srow.Atoi()] = size/1000.0; 
	
	if( xcellmin_rows.empty() || sxcell.Atof()/1000.0 < xcellmin_rows[srow.Atoi()] ){
	  xcellmin_rows[srow.Atoi()] = sxcell.Atof()/1000.0;
	}
	if( xcellmax_rows.empty() || sxcell.Atof()/1000.0 > xcellmax_rows[srow.Atoi()] ){
	  xcellmax_rows[srow.Atoi()] = sxcell.Atof()/1000.0;
	}
	
      }
    }
  }

  set<int> list_of_nodes_hcal;
  map<int, set<int> > cells_logic_sums_hcal; //mapping between node numbers and cell numbers
  map<int, double> logic_mean_hcal; //mean peak positions by node number
  map<int, double> logic_sigma_hcal; //peak width by node number
  map<int, double> threshold_hcal; //threshold by node number
  map<std::pair<int,int>, int > cell_rowcol_hcal; //cell numbers mapped by unique row and column pairs
  map<int,set<int> > nodes_cells_hcal; //mapping of nodes by cell number:

  ifstream logicfile_hcal(logicfilename_hcal);

  current_node = 1;
  //  bool first_cell = true;

  while( currentline.ReadLine(logicfile_hcal) ){
    if( !currentline.BeginsWith("#") ){
      TObjArray *tokens = currentline.Tokenize(" ");
      int ntokens = tokens->GetEntries();
      if( ntokens >= 11 ){
	cout << currentline.Data() << ", ntokens = " << ntokens << endl;

	TString snode = ( (TObjString*) (*tokens)[0] )->GetString();
	int nodenumber = snode.Atoi();
	
	TString scell = ( (TObjString*) (*tokens)[1] )->GetString();
	int cellnumber = scell.Atoi();
	
	TString speakpos = ( (TObjString*) (*tokens)[8] )->GetString();
	double mean = speakpos.Atof();
	
	TString ssigma = ( (TObjString*) (*tokens)[9] )->GetString();
	double sigma = ssigma.Atof();

	TString sthreshold = ( (TObjString*) (*tokens)[10] )->GetString();
	double threshold = sthreshold.Atof();

	TString srow = ( (TObjString*) (*tokens)[2] )->GetString();
	TString scol = ( (TObjString*) (*tokens)[3] )->GetString();

	std::pair<int,int> rowcoltemp( srow.Atoi(), scol.Atoi() );

	cell_rowcol_hcal[rowcoltemp] = cellnumber;
	
	list_of_nodes_hcal.insert( nodenumber );

	cells_logic_sums_hcal[nodenumber].insert( cellnumber );

	logic_mean_hcal[nodenumber] = mean;
	logic_sigma_hcal[nodenumber] = sigma;
	threshold_hcal[nodenumber] = threshold;

	nodes_cells_hcal[ cellnumber ].insert(nodenumber);
	
      }
    }
  }
  
  TH1D::SetDefaultSumw2();

  //double PI = TMath::Pi();

  //Photoelectron statistics:
  double phe_per_GeV_ECAL = 1000.0/1.33; //~ 750 pe/GeV
  double phe_per_GeV_HCAL = 1000.0/0.30; //~ 3,333 pe/GeV (but sampling fraction is small)

  //read in alternate threshold:
  ifstream thresholdfile_ecal(thresholdfilename_ecal);
  if( thresholdfile_ecal ){
    int node;
    double mean,sigma;
    while( thresholdfile_ecal >> node >> mean >> sigma ){
      if( list_of_nodes_ecal.find( node ) != list_of_nodes_ecal.end() ){
	logic_mean_ecal[ node ] = mean;
	logic_sigma_ecal[ node ] = sigma;
      }
    }
  }

  //read in alternate threshold:
  ifstream thresholdfile_hcal(thresholdfilename_hcal);
  if( thresholdfile_hcal ){
    int node;
    double mean,sigma;
    while( thresholdfile_hcal >> node >> mean >> sigma ){
      if( list_of_nodes_hcal.find( node ) != list_of_nodes_hcal.end() ){
	logic_mean_hcal[ node ] = mean;
	logic_sigma_hcal[ node ] = sigma;
      }
    }
  }

  ifstream assocfile( assocfilename );

  bool use_ECAL_HCAL_associations=false;
  map<int, set<int> > ECAL_nodes_HCAL;
  if( assocfile ){
    while( !assocfile.eof() ){
      int hcalnode, N;
      assocfile >> hcalnode >> N;
      for( int i=0; i<N; i++ ){
	int ecalnode;
	assocfile >> ecalnode;

	ECAL_nodes_HCAL[hcalnode].insert(ecalnode);
      }
    }
  }
  
  fout->cd();

  // TH1D *hrate_vs_threshold_ECAL = new TH1D("hrate_vs_threshold_ECAL","",30,0.0,1.5);
  // //TH1D *hnum_logic_sums_fired_vs_threshold = new TH1D("hnum_logic_sums_fired_vs_threshold

  // TH1D *hrate_vs_threshold_HCAL = new TH1D("hrate_vs_threshold_HCAL","",40,0.0,2.0);

  //TH2D *htrue_coincidence_rate_vs_threshold_ECAL_HCAL = new TH2D("htrue_coincidence_rate_vs_threshold_ECAL_HCAL","",40,0,2.0,30,0,1.5);
  
  TH2D *hnphesum_vs_node_ECAL_all = new TH2D("hnphesum_vs_node_ECAL_all","",list_of_nodes_ecal.size(),0.5,list_of_nodes_ecal.size()+0.5,100,0.0,5000.0);
  TH2D *hnphesum_vs_node_HCAL_all = new TH2D("hnphesum_vs_node_HCAL_all","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);

  //TH2D *hnphesum_vs_node_ECAL_FTcut = new TH2D("hnphesum_vs_node_ECAL_FTcut","",list_of_nodes_ecal.size(),0.5,list_of_nodes_ecal.size()+0.5,100,0.0,5000.0);
  TH2D *hnphesum_vs_node_HCAL_FTcut = new TH2D("hnphesum_vs_node_HCAL_FTcut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCAL_FPP1cut = new TH2D("hnphesum_vs_node_HCAL_FPP1cut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCAL_FPP2cut = new TH2D("hnphesum_vs_node_HCAL_FPP2cut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCAL_FPPbothcut = new TH2D("hnphesum_vs_node_HCAL_FPPbothcut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCAL_FPPeithercut = new TH2D("hnphesum_vs_node_HCAL_FPPeithercut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);

  TH2D *hnphesum_vs_node_HCALmax_all = new TH2D("hnphesum_vs_node_HCALmax_all","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCALmax_FTcut = new TH2D("hnphesum_vs_node_HCALmax_FTcut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCALmax_FPP1cut = new TH2D("hnphesum_vs_node_HCALmax_FPP1cut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCALmax_FPP2cut = new TH2D("hnphesum_vs_node_HCALmax_FPP2cut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCALmax_FPPbothcut = new TH2D("hnphesum_vs_node_HCALmax_FPPbothcut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  TH2D *hnphesum_vs_node_HCALmax_FPPeithercut = new TH2D("hnphesum_vs_node_HCALmax_FPPeithercut","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,100,0.0,3500.0);
  
  
  TH2D *hmaxnode_ECAL_vs_HCAL = new TH2D("hmaxnode_ECAL_vs_HCAL","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,list_of_nodes_ecal.size(),0.5,list_of_nodes_ecal.size()+0.5);
  TH2D *hallnodes_ECAL_vs_HCAL = new TH2D("hallnodes_ECAL_vs_HCAL","",list_of_nodes_hcal.size(),0.5,list_of_nodes_hcal.size()+0.5,list_of_nodes_ecal.size(),0.5,list_of_nodes_ecal.size()+0.5);

  TH1D *hshouldhit_vs_threshold_ECAL = new TH1D("hshouldhit_vs_threshold_ECAL","",30,0.025,1.525);
  TH1D *hefficiency_vs_threshold_ECAL = new TH1D("hefficiency_vs_threshold_ECAL","",30,0.025,1.525);
  TH1D *hshouldhit_vs_threshold_ECAL_FTcut = new TH1D("hshouldhit_vs_threshold_ECAL_FTcut","",30,0.025,1.525);
  TH1D *hefficiency_vs_threshold_ECAL_FTcut = new TH1D("hefficiency_vs_threshold_ECAL_FTcut","",30,0.025,1.525);
  
  TH1D *hefficiency_vs_threshold_HCAL_FTcut = new TH1D("hefficiency_vs_threshold_HCAL_FTcut","",30,0.025,1.525);
  TH1D *hefficiency_vs_threshold_HCAL_FPP1cut = new TH1D("hefficiency_vs_threshold_HCAL_FPP1cut","",30,0.025,1.525);
  TH1D *hefficiency_vs_threshold_HCAL_FPP2cut = new TH1D("hefficiency_vs_threshold_HCAL_FPP2cut","",30,0.025,1.525);

  TH2D *hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut = new TH2D("hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut","",30,0.025,1.525,30,0.025,1.525);
  TH2D *hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FTcut = new TH2D("hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FTcut","",30,0.025,1.525,30,0.025,1.525);

  TH2D *hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP1cut = new TH2D("hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP1cut","",30,0.025,1.525,30,0.025,1.525);
  TH2D *hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP1cut = new TH2D("hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP1cut","",30,0.025,1.525,30,0.025,1.525);

  TH2D *hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP2cut = new TH2D("hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP2cut","",30,0.025,1.525,30,0.025,1.525);
  TH2D *hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP2cut = new TH2D("hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP2cut","",30,0.025,1.525,30,0.025,1.525);
  
  TH1D *hshouldhit_HCAL_FTcut = new TH1D("hshouldhit_HCAL_FTcut","",30,0.025,1.525);
  TH1D *hshouldhit_HCAL_FPP1cut = new TH1D("hshouldhit_HCAL_FPP1cut","",30,0.025,1.525);
  TH1D *hshouldhit_HCAL_FPP2cut = new TH1D("hshouldhit_HCAL_FPP2cut","",30,0.025,1.525);
  
  TH2D *hnphe_vs_sum_edep_ECAL = new TH2D("hnphe_vs_sum_edep_ECAL","",125,0.0,5.0,125,0.0,5000.0 );
  TH2D *hnphe_vs_sum_edep_HCAL = new TH2D("hnphe_vs_sum_edep_HCAL","",125,0.0,0.75,125,0.0,2500.0 );

  TH1D *hthetaFPP1 = new TH1D("hthetaFPP1","",120,0.0,12.0);
  TH1D *hthetaFPP2 = new TH1D("hthetaFPP2","",120,0.0,12.0);

  TH1D *hthetaFPP1_cointrig = new TH1D("hthetaFPP1_cointrig","",120,0.0,12.0);
  TH1D *hthetaFPP2_cointrig = new TH1D("hthetaFPP2_cointrig","",120,0.0,12.0);

  TH1D *hshouldhit_vs_Q2_ECAL_FTcut = new TH1D("hshouldhit_vs_Q2_ECAL_FTcut","",100,8.0,16.0);
  TH1D *hefficiency_vs_Q2_ECAL_FTcut = new TH1D("hefficiency_vs_Q2_ECAL_FTcut","",100,8.0,16.0);

  
  
  double Ibeam = 75.0e-6; //Amps
  double Ltarget = 40.0; //cm
  double e = 1.602e-19; //electron charge;
  double rho_target = 0.072; //g/cm^3
  double N_A = 6.022e23; //atoms/mol:
  double Mmol_H = 1.008; //g/mol
  double Lumi = rho_target * Ltarget * N_A / Mmol_H * Ibeam/e; //~ 8e38;
  
  TRandom3 num(0);

  cout << "Entering event loop " << endl;
  
  long nevent=0;
  for( nevent=0; nevent<C->GetEntries(); ++nevent ){
    T->GetEntry(nevent);

    double weight;
    //cross section is given in mb: 1 mb = 1e-3 * 1e-24 = 1e-27 cm^2
    // if (pythia6flag != 0 ){
    //   weight = Lumi * T->primaries_Sigma * 1.0e-27/ double(ngen); //luminosity times cross section / number of events generated.
    // } else {
    weight = T->ev_rate / double(nfiles);

    if( Q2cut == 0 || (T->ev_Q2 >= 10.5 && T->ev_Q2 <= 14.0) ){
    
      bool FTtrack = false;
      int itrack_FT=-1;
      for( int itrack=0; itrack<T->Harm_FT_Track_ntracks; itrack++ ){
	if( (*(T->Harm_FT_Track_MID))[itrack] == 0 &&
	    (*(T->Harm_FT_Track_PID))[itrack] == 2212 ){ //primary elastically scattered proton track in FT:
	  FTtrack = true;
	  itrack_FT = itrack;
	}
      }

      TVector3 nhat_FT, nhat_FPP1, nhat_FPP2;
      if( FTtrack ){
	nhat_FT.SetXYZ( (*(T->Harm_FT_Track_Xp))[itrack_FT],
			(*(T->Harm_FT_Track_Yp))[itrack_FT],
			1.0 );
	nhat_FT = nhat_FT.Unit();
      }

      double thetaFPP1, thetaFPP2, pFPP1, pFPP2;
      bool FPP1track = false, FPP2track = false;
      //    if( FTtrack )
      if( T->Harm_FPP1_Track_ntracks > 0 && FTtrack ){
	for( int itrack=0; itrack<T->Harm_FPP1_Track_ntracks; itrack++ ){
	  if( (*(T->Harm_FPP1_Track_MID))[itrack] == 0 ){
	    nhat_FPP1.SetXYZ( (*(T->Harm_FPP1_Track_Xp))[itrack],
			      (*(T->Harm_FPP1_Track_Yp))[itrack],
			      1.0 );
	    nhat_FPP1 = nhat_FPP1.Unit();
	    thetaFPP1 = acos( nhat_FPP1.Dot( nhat_FT ) );
	    pFPP1 = (*(T->Harm_FPP1_Track_P))[itrack];
	    FPP1track = thetaFPP1 < 12.0*PI/180.0 && pFPP1 >= 0.5*T->ev_np;
	    if( FPP1track ) hthetaFPP1->Fill(thetaFPP1*180.0/PI,weight);
	  }
	}
      }

      if( T->Harm_FPP2_Track_ntracks > 0 && FTtrack && FPP1track){
	for( int itrack=0; itrack<T->Harm_FPP2_Track_ntracks; itrack++ ){
	  if( (*(T->Harm_FPP2_Track_MID))[itrack] == 0 ){
	    nhat_FPP2.SetXYZ( (*(T->Harm_FPP2_Track_Xp))[itrack],
			      (*(T->Harm_FPP2_Track_Yp))[itrack],
			      1.0 );
	    nhat_FPP2 = nhat_FPP2.Unit();
	    thetaFPP2 = acos( nhat_FPP2.Dot( nhat_FPP1 ) );
	    pFPP2 = (*(T->Harm_FPP2_Track_P))[itrack];
	    //FPP2track = thetaFPP2 < 24.0*PI/180.0 && pFPP2/T->ev_np > 0.5;
	    FPP2track = thetaFPP2 < 12.0*PI/180.0 && pFPP2/T->ev_np > 0.5;
	    if( FPP2track ) hthetaFPP2->Fill(thetaFPP2*180.0/PI,weight);
	  }
	}
      }
      
      double nu = T->ev_Q2 / 2.0 / 0.938272;
      double pp_elastic = sqrt(pow(nu,2)+2.0*.938272*nu);
    
   
      //}

      double R = T->gen_dbb;
      double thetacal = T->gen_thbb;
    
      //ECAL is on beam left:
      TVector3 nhat_e( sin( T->ev_th )*cos( T->ev_ph ), sin(T->ev_th)*sin(T->ev_ph), cos(T->ev_th) );
      TVector3 vertex( T->ev_vx, T->ev_vy, T->ev_vz );
      TVector3 ecal_z( sin(thetacal), 0, cos(thetacal) );
      TVector3 ecal_y(0,1,0);
      TVector3 ecal_x = (ecal_y.Cross(ecal_z)).Unit();

      TVector3 Rcalo = R * ecal_z;
      //ecal_z dot (vertex + s * nhat_e - Rcalo ) = 0;
      double s = (Rcalo - vertex).Dot( ecal_z )/ ( nhat_e.Dot( ecal_z ) );

      TVector3 pos_calo = vertex + s * nhat_e;

      double xcalo = (pos_calo - Rcalo).Dot( ecal_x );
      double ycalo = (pos_calo - Rcalo).Dot( ecal_y ); //
    
      if( (nevent+1) % 1000 == 0 ){ cout << "Event number " << nevent+1 << ", event weight = " << weight << endl; }
    
      map<int,double> node_sums; //initialize all node sums to zero:
      for( set<int>::iterator inode = list_of_nodes_ecal.begin(); inode != list_of_nodes_ecal.end(); ++inode ){
	node_sums[ *inode ] = 0.0;
      }

      bool should_hit_ECAL = false;

      if( ycalo >= ycellmin && ycalo <= ycellmax ){
	//make an initial guess at which row: (row runs from 1 to N):
	int closest_row = int( (ycalo - ycellmin)/4.0 ) + 1;

	map<int,double>::iterator rowguess = ycell_rows.find( closest_row );

	while( rowguess != ycell_rows.end() && ycalo > ycell_rows[rowguess->first] + 0.5*cellsize_rows[rowguess->first] ){ ++rowguess; }
	while( rowguess != ycell_rows.end() && ycalo < ycell_rows[rowguess->first] - 0.5*cellsize_rows[rowguess->first] ){ --rowguess; }

	if( rowguess != ycell_rows.end() ){
	  closest_row = rowguess->first;
	  if( xcalo >= xcellmin_rows[closest_row] + 0.5*cellsize_rows[closest_row] &&
	      xcalo <= xcellmax_rows[closest_row] - 0.5*cellsize_rows[closest_row] &&
	      ycalo >= ycellmin + 0.5*cellsize_rows[closest_row] && ycalo <= ycellmax - 0.5*cellsize_rows[closest_row] ){
	    should_hit_ECAL = true;
	  }
	}
      }

      int nphe = 0;
    
      if( pheflag == 0 ){
	for( int ihit = 0; ihit<T->Earm_ECalTF1_hit_nhits; ihit++ ){
	  int rowhit = ( *(T->Earm_ECalTF1_hit_row))[ihit]+1;
	  int colhit = ( *(T->Earm_ECalTF1_hit_col))[ihit]+1;
	  std::pair<int,int> rowcolhit( rowhit,colhit );
	
	  int cellhit = cell_rowcol_ecal[rowcolhit];
	
	  //int trigger_group = nodes_cells_ecal[cellhit];
	
	  double edep = (*(T->Earm_ECalTF1_hit_sumedep))[ihit];

	  double mean = 752.2*edep;
	  double sigma = 52.0*sqrt(edep) + 20.76*edep;

	  nphe = TMath::Max(0,TMath::Nint(num.Gaus(mean,sigma)));
	
	  for( set<int>::iterator inode = nodes_cells_ecal[cellhit].begin(); inode != nodes_cells_ecal[cellhit].end(); ++inode ){
	    node_sums[ *inode ] += double(nphe);
	  }
	
	}
      } else {
	for( int ihit = 0; ihit<T->Earm_ECAL_hit_nhits; ihit++){
	  int rowhit = ( *(T->Earm_ECAL_hit_row))[ihit]+1;
	  int colhit = ( *(T->Earm_ECAL_hit_col))[ihit]+1;
	  std::pair<int,int> rowcolhit( rowhit,colhit );
	
	  int cellhit = cell_rowcol_ecal[rowcolhit];
	
	  //int trigger_group = nodes_cells_ecal[cellhit];
	
	  //	double edep = (*(T->Earm_ECalTF1_hit_sumedep))[ihit];

	  int nphe = (*(T->Earm_ECAL_hit_NumPhotoelectrons))[ihit];
	
	  for( set<int>::iterator inode = nodes_cells_ecal[cellhit].begin(); inode != nodes_cells_ecal[cellhit].end(); ++inode ){
	    node_sums[ *inode ] += double(nphe);
	  }
	  for( int jhit=0; jhit<T->Earm_ECalTF1_hit_nhits; jhit++ ){
	    if( (*(T->Earm_ECalTF1_hit_row))[jhit]+1 == rowhit &&
		(*(T->Earm_ECalTF1_hit_col))[jhit]+1 == colhit &&
		fabs( (*(T->Earm_ECAL_hit_Time_avg))[ihit]-(*(T->Earm_ECalTF1_hit_tavg))[jhit]-2.5)<=10.0 ){
	      hnphe_vs_sum_edep_ECAL->Fill( (*(T->Earm_ECalTF1_hit_sumedep))[jhit], nphe );
	    }   
	  }
	}
      
	//node_sums[ trigger_group ] += double(nphe);
      }

      vector<int> trigger_nodes_fired(hefficiency_vs_threshold_ECAL->GetNbinsX());
      for( int ithr=0; ithr<hefficiency_vs_threshold_ECAL->GetNbinsX(); ithr++ ){
	trigger_nodes_fired[ithr] = 0;
      }

      int maxnode_ECAL=-1;
      int maxnode_HCAL=-1;
      double maxsum_ECAL = 0.0;
      double maxsum_HCAL = 0.0;

      bool ECALtrig_nominal = false;
    
      int nominal_threshold_bin_HCAL = hefficiency_vs_threshold_HCAL_FTcut->FindBin(nominal_threshold_HCAL);
      int nominal_threshold_bin_ECAL = hefficiency_vs_threshold_ECAL->FindBin(nominal_threshold_ECAL);
    
      for( set<int>::iterator inode = list_of_nodes_ecal.begin(); inode != list_of_nodes_ecal.end(); ++inode ){
	for( int bin=1; bin<=hefficiency_vs_threshold_ECAL->GetNbinsX(); bin++ ){
	  if( node_sums[*inode]/logic_mean_ecal[*inode] > hefficiency_vs_threshold_ECAL->GetBinCenter(bin) ){
	    //cout << "node above threshold, nphe, peak position = " << node_sums[*inode] << ", " << logic_mean_ecal[*inode] << endl;
	    trigger_nodes_fired[bin-1]++;
	    if( bin == nominal_threshold_bin_ECAL ) ECALtrig_nominal = true;
	  }
	
	}
	if( node_sums[*inode] > maxsum_ECAL ) {
	  maxsum_ECAL = node_sums[*inode];
	  maxnode_ECAL = *inode;
	}
      
	if( node_sums[*inode] > 0.0 ) hnphesum_vs_node_ECAL_all->Fill( *inode, node_sums[*inode], weight );
      }

      if( should_hit_ECAL ){
	for( int ithr=0; ithr<hefficiency_vs_threshold_ECAL->GetNbinsX(); ithr++ ){
	  hshouldhit_vs_threshold_ECAL->Fill( hefficiency_vs_threshold_ECAL->GetBinCenter(ithr+1), weight );
	  if( trigger_nodes_fired[ithr] > 0 ){
	    hefficiency_vs_threshold_ECAL->Fill( hefficiency_vs_threshold_ECAL->GetBinCenter(ithr+1), weight );
	  }
	  if( FTtrack ){
	    hshouldhit_vs_threshold_ECAL_FTcut->Fill( hefficiency_vs_threshold_ECAL->GetBinCenter(ithr+1), weight );
	    if( trigger_nodes_fired[ithr] > 0 ){
	      hefficiency_vs_threshold_ECAL_FTcut->Fill( hefficiency_vs_threshold_ECAL->GetBinCenter(ithr+1), weight );
	    }
	  }
	}
      }

      if( FTtrack ){
	hshouldhit_vs_Q2_ECAL_FTcut->Fill( T->ev_Q2, weight );
	if( ECALtrig_nominal ){
	  hefficiency_vs_Q2_ECAL_FTcut->Fill( T->ev_Q2, weight );
	}
      }
    
      map<int,double> node_sums_hcal;
      for( set<int>::iterator inode = list_of_nodes_hcal.begin(); inode != list_of_nodes_hcal.end(); ++inode ){
	node_sums_hcal[*inode] = 0.0;
      }

      //int nphe = 0;
    
      if( pheflag == 0 ){
	for( int ihit=0; ihit<T->Harm_HCalScint_hit_nhits; ihit++ ){
	  int rowhit = (*(T->Harm_HCalScint_hit_row))[ihit]+1;
	  int colhit = (*(T->Harm_HCalScint_hit_col))[ihit]+1;
	  std::pair<int,int> rowcolhit(rowhit,colhit);
	  int cellhit = cell_rowcol_hcal[rowcolhit];
	  //int trigger_group = nodes_cells_hcal[cellhit];
	  double edep = (*(T->Harm_HCalScint_hit_sumedep))[ihit];
	  //nphe = num.Poisson( phe_per_GeV_HCAL * edep );
	  double mean = 2981.0*edep;
	  double sigma = 69.54*sqrt(edep) + 155.3*edep;

	  nphe = TMath::Max(0,TMath::Nint(num.Gaus(mean,sigma)));
	
	  //cout << "HCAL hit " << ihit+1 << " node, edep, nphe = " << trigger_group << ", " << edep << ", " << nphe << endl;
	  //node_sums_hcal[trigger_group] += double(nphe);
	  for( set<int>::iterator inode = nodes_cells_hcal[cellhit].begin(); inode != nodes_cells_hcal[cellhit].end(); ++inode ){
	  
	    node_sums_hcal[*inode] += double(nphe);
	  
	  }
	}
      } else {
	for( int jhit=0; jhit<T->Harm_HCal_hit_nhits; jhit++ ){
	  int rowhit = (*(T->Harm_HCal_hit_row))[jhit]+1;
	  int colhit = (*(T->Harm_HCal_hit_col))[jhit]+1;
	  std::pair<int,int> rowcolhit(rowhit,colhit);
	  int cellhit = cell_rowcol_hcal[rowcolhit];
	  nphe = (*(T->Harm_HCal_hit_NumPhotoelectrons))[jhit];
	  for( set<int>::iterator inode = nodes_cells_hcal[cellhit].begin(); inode != nodes_cells_hcal[cellhit].end(); ++inode ){
	  
	    node_sums_hcal[*inode] += double(nphe);
	  
	  }

	  for( int khit=0; khit<T->Harm_HCalScint_hit_nhits; khit++ ){
	    if( (*(T->Harm_HCalScint_hit_row))[khit]+1 == rowhit &&
		(*(T->Harm_HCalScint_hit_col))[khit]+1 == colhit &&
		fabs( (*(T->Harm_HCal_hit_Time_avg))[jhit]-(*(T->Harm_HCalScint_hit_tavg))[khit] - 8.6 )<=15.0 ){
	      hnphe_vs_sum_edep_HCAL->Fill( (*(T->Harm_HCalScint_hit_sumedep))[khit], nphe );
	    }
	  }
	
	}
      }
    
      vector<int> trigger_nodes_fired_hcal(hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX());
      for( int ithr=0; ithr<hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX(); ithr++ ){
	trigger_nodes_fired_hcal[ithr] = 0;
      }

      vector<int> coin_trigger_fired( hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX()*hefficiency_vs_threshold_ECAL->GetNbinsX() );
      for( int ithr=0; ithr<coin_trigger_fired.size(); ithr++ ){
	coin_trigger_fired[ithr] = 0;
      }

    

      bool cointrig_nominal_threshold = false;
    
      for( set<int>::iterator inode = list_of_nodes_hcal.begin(); inode != list_of_nodes_hcal.end(); ++inode ){
	for( int bin=1; bin<=hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX(); bin++ ){
	  if( node_sums_hcal[*inode]/logic_mean_hcal[*inode] > hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin) ){ //this HCAL sum fired:
	    trigger_nodes_fired_hcal[bin-1]++;
	    for( set<int>::iterator enode = list_of_nodes_ecal.begin(); enode != list_of_nodes_ecal.end(); ++enode ){
	      if( ECAL_nodes_HCAL[*inode].find(*enode) != ECAL_nodes_HCAL[*inode].end() ){ //Check associated ECAL trigger sums:
		for( int ebin=1; ebin<=hefficiency_vs_threshold_ECAL->GetNbinsX(); ebin++ ){ //check ECAL sums:
		  if( node_sums[ *enode ]/logic_mean_ecal[*enode] > hefficiency_vs_threshold_ECAL->GetBinCenter(ebin) ){ //this ECAL sum fired:
		    coin_trigger_fired[ (ebin-1) + (bin-1)*hefficiency_vs_threshold_ECAL->GetNbinsX() ]++;
		    if( ebin == nominal_threshold_bin_ECAL && bin == nominal_threshold_bin_HCAL ){
		      cointrig_nominal_threshold = true;
		    }
		  }
		}
	      } 
	    }
	  }
	}
	if( node_sums_hcal[*inode] > maxsum_HCAL ) {
	  maxsum_HCAL = node_sums_hcal[*inode];
	  maxnode_HCAL = *inode;
	}

	hnphesum_vs_node_HCAL_all->Fill( *inode, node_sums_hcal[*inode], weight );
	if( FTtrack ){
	  hnphesum_vs_node_HCAL_FTcut->Fill( *inode, node_sums_hcal[*inode], weight );
	  if( FPP1track ) hnphesum_vs_node_HCAL_FPP1cut->Fill( *inode, node_sums_hcal[*inode], weight );
	  if( FPP2track ) hnphesum_vs_node_HCAL_FPP2cut->Fill( *inode, node_sums_hcal[*inode], weight );
	  if( FPP1track && FPP2track ) hnphesum_vs_node_HCAL_FPPbothcut->Fill( *inode, node_sums_hcal[*inode], weight );
	  if( FPP1track || FPP2track ) hnphesum_vs_node_HCAL_FPPeithercut->Fill( *inode, node_sums_hcal[*inode], weight );
	}
      }

      if( cointrig_nominal_threshold ){
	if( FPP1track ) hthetaFPP1_cointrig->Fill(thetaFPP1*180.0/PI,weight);
	if( FPP2track ) hthetaFPP2_cointrig->Fill(thetaFPP2*180.0/PI,weight);
      }
    
      for( int bin=1; bin<=hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX(); bin++ ){
	if( FTtrack ) hshouldhit_HCAL_FTcut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	if( FTtrack && FPP1track ) hshouldhit_HCAL_FPP1cut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	if( FTtrack && FPP2track ) hshouldhit_HCAL_FPP2cut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	if( trigger_nodes_fired_hcal[bin-1] > 0 ){
	  if( FTtrack ){
	    hefficiency_vs_threshold_HCAL_FTcut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	    if( FPP1track ) hefficiency_vs_threshold_HCAL_FPP1cut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	    if( FPP2track ) hefficiency_vs_threshold_HCAL_FPP2cut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(bin), weight );
	  }
	}
      }

      for( int ithr=0; ithr<coin_trigger_fired.size(); ithr++ ){
	int bin_e = ithr%(hefficiency_vs_threshold_ECAL->GetNbinsX())+1;
	int bin_h = ithr/(hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX())+1;
	double thr_e = hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut->GetYaxis()->GetBinCenter(bin_e);
	double thr_h = hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut->GetXaxis()->GetBinCenter(bin_h);
	if( FTtrack ) hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FTcut->Fill( thr_h, thr_e, weight );
	if( FTtrack && FPP1track ) hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP1cut->Fill( thr_h, thr_e, weight );
	if( FTtrack && FPP2track ) hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP2cut->Fill( thr_h, thr_e, weight );
	if( coin_trigger_fired[ithr] > 0 ){
	  if( FTtrack ) hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut->Fill( thr_h, thr_e, weight );
	  if( FTtrack && FPP1track ) hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP1cut->Fill( thr_h, thr_e, weight );
	  if( FTtrack && FPP2track ) hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP2cut->Fill( thr_h, thr_e, weight );
	}
      }
    
      hnphesum_vs_node_HCALmax_all->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
      if( FTtrack ){
	hnphesum_vs_node_HCALmax_FTcut->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
	if( FPP1track ) hnphesum_vs_node_HCALmax_FPP1cut->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
	if( FPP2track ) hnphesum_vs_node_HCALmax_FPP2cut->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
	if( FPP1track && FPP2track ) hnphesum_vs_node_HCALmax_FPPbothcut->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
	if( FPP1track || FPP2track ) hnphesum_vs_node_HCALmax_FPPeithercut->Fill( maxnode_HCAL, node_sums_hcal[maxnode_HCAL], weight );
      }
    
      // for( int ithr=0; ithr<hefficiency_vs_threshold_HCAL_FTcut->GetNbinsX(); ithr++ ){
      //   if( trigger_nodes_fired_hcal[ithr] > 0 ) hefficiency_vs_threshold_HCAL_FTcut->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(ithr+1),weight );
      //   for( int jthr=0; jthr<hefficiency_vs_threshold_ECAL->GetNbinsX(); jthr++ ){
      // 	if( trigger_nodes_fired[jthr] > 0 && trigger_nodes_fired_hcal[ithr] > 0 ){
      // 	  //htrue_coincidence_rate_vs_threshold_ECAL_HCAL->Fill( hefficiency_vs_threshold_HCAL_FTcut->GetBinCenter(ithr+1),hefficiency_vs_threshold_ECAL->GetBinCenter(jthr+1),weight );
      // 	}
      //   }
      // }

      // for( set<int>::iterator inode = list_of_nodes_ecal.begin(); inode != list_of_nodes_ecal.end(); ++inode ){
      //   for( set<int>::iterator jnode = list_of_nodes_hcal.begin(); jnode != list_of_nodes_hcal.end(); ++jnode ){
      // 	//Fill the correlation histogram for all true coincidence events for which ECAL and HCAL node are both above threshold:
      // 	if( node_sums[*inode] >= nominal_threshold_ECAL*logic_mean_ecal[*inode] && node_sums_hcal[*jnode] >= nominal_threshold_HCAL*logic_mean_hcal[*jnode] ){
      // 	  hallnodes_ECAL_vs_HCAL->Fill( *jnode, *inode, weight );
      // 	}
      //   }
      // }
      //if( maxsum_ECAL >= nominal_threshold_ECAL*logic_mean_ecal[maxnode_ECAL] && maxsum_HCAL >= nominal_threshold_HCAL*logic_mean_hcal[maxnode_HCAL] ){
      if( FTtrack && FPP2track) {
	hmaxnode_ECAL_vs_HCAL->Fill( maxnode_HCAL, maxnode_ECAL, weight );
      }
      //}
    }
  }

  hefficiency_vs_threshold_HCAL_FTcut->Divide( hshouldhit_HCAL_FTcut );
  hefficiency_vs_threshold_HCAL_FPP1cut->Divide( hshouldhit_HCAL_FPP1cut );
  hefficiency_vs_threshold_HCAL_FPP2cut->Divide( hshouldhit_HCAL_FPP2cut );

  hefficiency_vs_threshold_ECAL_HCAL_coincidence_FTcut->Divide( hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FTcut );
  hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP1cut->Divide( hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP1cut );
  hefficiency_vs_threshold_ECAL_HCAL_coincidence_FPP2cut->Divide( hshouldhit_vs_threshold_ECAL_HCAL_coincidence_FPP2cut );
  
  // TCanvas *c1 = new TCanvas("c1","c1",1200,900);
  
  // c1->Divide(2,1);

  // c1->cd(1)->SetLogy();
  // hefficiency_vs_threshold_ECAL->SetMarkerStyle(20);
  // hefficiency_vs_threshold_ECAL->Draw();
  
  // c1->cd(2)->SetLogy();
  // hefficiency_vs_threshold_HCAL_FTcut->SetMarkerStyle(20);
  // hefficiency_vs_threshold_HCAL_FTcut->Draw();

  hefficiency_vs_threshold_ECAL->Divide( hshouldhit_vs_threshold_ECAL );
  hefficiency_vs_threshold_ECAL_FTcut->Divide(hshouldhit_vs_threshold_ECAL_FTcut );
  
  hefficiency_vs_threshold_HCAL_FTcut->SetMarkerStyle(20);
  hefficiency_vs_threshold_ECAL->SetMarkerStyle(20);

  hefficiency_vs_Q2_ECAL_FTcut->Divide(hshouldhit_vs_Q2_ECAL_FTcut);
  
  fout->Write();
  fout->Close();
}