示例#1
0
/**
 * 1. Data sample : pp200 W->e nu with  pile-up corresponding to 1 MHz min. bias
 * events, 50 K event y2011, 10 K event y2012.
 *
 * 2. Proof of principal: no pile-up for both PPV and KFV
 *
 *   a.  Reconstructed primary track multiplicity versus corresponding MC
 *   "reconstructable" (i.e. in n STAR acceptance,no. TPC MC hits >= 15)  tracks
 *   multiplicity.
 *
 *   b.  Corrected reconstructed primary track multiplicity (i.e. multiplied by
 *   QA/100.) versus corresponding MC "reconstructable"  (i.e. in n STAR
 *   acceptance,no. TPC MC hits >= 15)  tracks multiplicity.
 *
 *   c.  Efficiency primary vertex reconstruction versus  MC "reconstructable"
 *   tracks multiplicity.
 *
 * 3. With pileup. repeat above (a-c) with old ranking scheme for
 *
 *     I. Any reconstructed primary vertex which is matched with MC trigger
 *     vertex (MC = 1)
 *
 *    II. The best (in sense of ranking) reconstructed primary vertex which is
 *    matched with MC trigger vertex (MC = 1)
 *
 *   III. The best (in sense of ranking) reconstructed primary vertex which is
 *   not matched with MC trigger vertex (MC != 1)
 *
 * 4. With pileup. repeat above (a-c) with new ranking scheme for cases I-III
 */
void MuMcPrVKFV2012(Long64_t nevent, const char *file, const std::string& outFile, bool fillNtuple)
{
#ifdef __TMVA__
   boost::replace_last(outFile, ".root", "");
   outFile += ".TMVArank.root";

   // 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) that you use
   TString separator(":");
   TString Vnames(vnames);
   TObjArray *array = Vnames.Tokenize(separator);

   std::vector<std::string> inputVars;
   TIter next(array);
   TObjString *objs;

   while ((objs = (TObjString *) next())) {
      std::cout << objs->GetString() << std::endl;
   }

   inputVars.push_back("beam");
   inputVars.push_back("postx");
   inputVars.push_back("prompt");
   inputVars.push_back("cross");
   inputVars.push_back("tof");
   inputVars.push_back("notof");
   inputVars.push_back("EEMC");
   inputVars.push_back("noEEMC");
   inputVars.push_back("chi2");

   std::vector<double> *inputVec = new std::vector<double>( inputVars.size() );
   IClassifierReader *classReader = new ReadBDT( inputVars );

#endif /* __TMVA__ */

   TFile *fOut = TFile::Open(outFile.c_str(), "recreate");
   data_t data;

   // Book histograms
   const int nMcRecMult = 75;
   TArrayD xMult(nMcRecMult + 1);
   xMult[0] = -0.5;

   for (int i = 1; i <= nMcRecMult; i++) {
      if      (xMult[i - 1] <  50) xMult[i] = xMult[i - 1] +   1; //  1 - 50
      else if (xMult[i - 1] < 100) xMult[i] = xMult[i - 1] +   2; // 51 - 75
      else if (xMult[i - 1] < 200) xMult[i] = xMult[i - 1] +  10; // 76 - 85
      else                         xMult[i] = xMult[i - 1] + 100; // 86 -100
   }

   TH1D *McRecMulT = new TH1D("McRecMulT", "Reconstructable multiplicity for trigger Mc Vertex", nMcRecMult, xMult.GetArray());
   struct Name_t {
      const Char_t *Name;
      const Char_t *Title;
   };
   const Name_t HCases[3] = {
      {"Any", "Any vertex matched with MC == 1"},
      {"Good", "The best rank vertex with MC == 1"},
      {"Bad", "The best rank vertex with MC != 1"}
   };
   const Name_t Plots[4] = {
      {"Mult"    , "the reconstructed (uncorrected) track multiplicity versus Reconstructable multiplicity"},
      {"MultQA"  , "the reconstructed (corrected for QA) track multiplicity versus Reconstructable multiplicity"},
      {"McRecMul", "Reconstructable multiplicity"},
      {"YvsX"    , "Bad versus Good value"}
   };
   /*         h  p  */
   TH1 *hists[3][4];

   for (int h = 0; h < 3; h++) {
      for (int p = 0; p < 4; p++) {
         TString Name(Plots[p].Name); Name += HCases[h].Name;
         TString Title(Plots[p].Title); Title += " for "; Title += HCases[h].Title; Title += " vertex";

         if      (p <  2)  hists[h][p] = new TH2D(Name, Title, nMcRecMult, xMult.GetArray(), nMcRecMult, xMult.GetArray());
         else if (p == 2)  hists[h][p] = new TH1D(Name, Title, nMcRecMult, xMult.GetArray());
      }
   }

   TNtuple *VertexG = new TNtuple("VertexG", "good vertex & global params info", vnames);
   TNtuple *VertexB = new TNtuple("VertexB", "bad  vertex & global params info", vnames);
   // ----------------------------------------------
   StMuDstMaker *maker = new StMuDstMaker(0, 0, "", file, "st:MuDst.root", 1e9); // set up maker in read mode
   //                       0,0                        this mean read mode
   //                           dir                    read all files in this directory
   //                               file               bla.lis real all file in this list, if (file!="") dir is ignored
   //                                    filter        apply filter to filenames, multiple filters are separated by ':'
   //                                          10      maximum number of file to read
   maker->SetStatus("*", 0);

   std::vector<std::string> activeBranchNames = {
      "MuEvent",
      "PrimaryVertices",
      "StStMuMcVertex",
      "StStMuMcTrack"
   };

   // Set Active braches
   for (const auto& branchName : activeBranchNames)
      maker->SetStatus(branchName.c_str(), 1);

   TChain *tree = maker->chain();
   Long64_t nentries = tree->GetEntries();
   nevent = TMath::Min(nevent, nentries);
   std::cout << nentries << " events in chain " << nevent << " will be read." << std::endl;
   tree->SetCacheSize(-1);        //by setting the read cache to -1 we set it to the AutoFlush value when writing
   tree->SetCacheLearnEntries(1); //one entry is sufficient to learn
   tree->SetCacheEntryRange(0, nevent);

   for (Long64_t ev = 0; ev < nevent; ev++) {
      if (maker->Make()) break;

      StMuDst *muDst = maker->muDst();   // get a pointer to the StMuDst class, the class that points to all the data
      StMuEvent *muEvent = muDst->event(); // get a pointer to the class holding event-wise information
      int referenceMultiplicity = muEvent->refMult(); // get the reference multiplicity

      TClonesArray *PrimaryVertices   = muDst->primaryVertices();
      int nPrimaryVertices = PrimaryVertices->GetEntriesFast();

      TClonesArray *MuMcVertices   = muDst->mcArray(0);
      int nMuMcVertices = MuMcVertices->GetEntriesFast();

      TClonesArray *MuMcTracks     = muDst->mcArray(1);
      int nMuMcTracks = MuMcTracks->GetEntriesFast();

      if ( nevent >= 10 && ev % int(nevent*0.1) == 0 )
      {
         std::cout << "Event #" << ev << "\tRun\t" << muEvent->runId()
                   << "\tId: " << muEvent->eventId()
                   << " refMult= " << referenceMultiplicity
                   << "\tPrimaryVertices " << nPrimaryVertices
                   << "\t" << " " << nMuMcVertices
                   << "\t" << " " << nMuMcTracks
                   << std::endl;
      }

      //    const Double_t field = muEvent->magneticField()*kilogauss;
      if (! nMuMcVertices || ! nMuMcTracks || nPrimaryVertices <= 0) {
         std::cout << "Ev. " << ev << " has no MC information ==> skip it" << std::endl;
         std::cout << "OR no reconstructed verticies found" << std::endl;
         continue;
      }

      // Count number of MC tracks at a vertex with TPC reconstructable tracks
      std::multimap<int, int> Mc2McHitTracks;

      for (int m = 0; m < nMuMcTracks; m++) {
         StMuMcTrack *McTrack = (StMuMcTrack *) MuMcTracks->UncheckedAt(m);

         if (McTrack->No_tpc_hit() < 15) continue;

         Mc2McHitTracks.insert(std::pair<int, int>(McTrack->IdVx(), McTrack->Id()));
      }

      // This is the "reconstructable" track multiplicity
      int nMcTracksWithHits = Mc2McHitTracks.count(1);

      // Let's skip events in which we do not expect to reconstruct any tracks
      // (and thus vertex) from the primary vertex
      if (nMcTracksWithHits <= 0) continue;

      // This is our denominator histogram for efficiencies
      McRecMulT->Fill(nMcTracksWithHits);

      // =============  Build map between  Rc and Mc vertices
      std::map<StMuPrimaryVertex *, StMuMcVertex *> reco2McVertices;
      TArrayF vertexRanks(nPrimaryVertices);
      int mcMatchedVertexIndex  = -1; // any vertex with MC==1 and highest reconstrated multiplicity.
      int vertexMaxMultiplicity = -1;

      // First loop over all verticies in this event. There is at least one
      // must be available
      for (int recoVertexIndex = 0; recoVertexIndex < nPrimaryVertices; recoVertexIndex++)
      {
         vertexRanks[recoVertexIndex] = -1e10;

         StMuPrimaryVertex *recoVertex = (StMuPrimaryVertex *) PrimaryVertices->UncheckedAt(recoVertexIndex);

         if ( !AcceptVX(recoVertex) ) continue;

         // Check Mc
         if (recoVertex->idTruth() < 0 || recoVertex->idTruth() > nMuMcVertices) {
            std::cout << "ERROR: Illegal idTruth " << recoVertex->idTruth() << " The track is ignored" << std::endl;
            continue;
         }

         StMuMcVertex *mcVertex = (StMuMcVertex *) MuMcVertices->UncheckedAt(recoVertex->idTruth() - 1);

         if (mcVertex->Id() != recoVertex->idTruth()) {
            std::cout << "ERROR: Mismatched idTruth " << recoVertex->idTruth() << " and mcVertex Id " <<  mcVertex->Id()
                 << " The vertex is ignored" <<  std::endl;
            continue;
         }

         reco2McVertices[recoVertex] = mcVertex;
         vertexRanks[recoVertexIndex] = recoVertex->ranking();

         if (recoVertex->idTruth() == 1 && recoVertex->noTracks() > vertexMaxMultiplicity)
         {
            mcMatchedVertexIndex  = recoVertexIndex;
            vertexMaxMultiplicity = recoVertex->noTracks();
         }

         FillData(data, recoVertex);

#ifdef __TMVA__
         Float_t *dataArray = &data.beam;

         for (size_t j = 0; j < inputVec->size(); j++)
            (*inputVec)[j] = dataArray[j];

         vertexRanks[recoVertexIndex] = classReader->GetMvaValue( *inputVec );
#endif
      }

      // If we reconstructed a vertex which matches the MC one we fill the
      // numerator of the "Any" efficiency histogram
      if (mcMatchedVertexIndex != -1) {

         StMuPrimaryVertex *recoVertexMatchedMc = (StMuPrimaryVertex*) PrimaryVertices->UncheckedAt(mcMatchedVertexIndex);

         double nTracks = recoVertexMatchedMc->noTracks();
         double nTracksQA = nTracks * recoVertexMatchedMc->qaTruth() / 100.;

         hists[0][0]->Fill(nMcTracksWithHits, nTracks);
         hists[0][1]->Fill(nMcTracksWithHits, nTracksQA);
         hists[0][2]->Fill(nMcTracksWithHits);
      }

      // Now deal with the highest rank vertex
      int maxRankVertexIndex = TMath::LocMax(nPrimaryVertices, vertexRanks.GetArray());

      StMuPrimaryVertex *recoVertexMaxRank = (StMuPrimaryVertex*) PrimaryVertices->UncheckedAt(maxRankVertexIndex);
      StMuMcVertex *mcVertex = reco2McVertices[recoVertexMaxRank];

      double nTracks = recoVertexMaxRank->noTracks();
      double nTracksQA = nTracks * recoVertexMaxRank->qaTruth() / 100.;

      // Fill numerator for "good" and "bad" efficiencies
      int h = ( mcVertex && mcVertex->Id() == 1) ? 1 : 2;

      hists[h][0]->Fill(nMcTracksWithHits, nTracks);
      hists[h][1]->Fill(nMcTracksWithHits, nTracksQA);
      hists[h][2]->Fill(nMcTracksWithHits);


      // Proceed with filling ntuple only if requested by the user
      if ( !fillNtuple ) continue;


      // Second loop over all verticies in this event
      for (int recoVertexIndex = 0; recoVertexIndex < nPrimaryVertices; recoVertexIndex++)
      {
         StMuPrimaryVertex *recoVertex = (StMuPrimaryVertex *) PrimaryVertices->UncheckedAt(recoVertexIndex);

         if ( !AcceptVX(recoVertex) ) continue;

         StMuMcVertex *mcVertex = reco2McVertices[recoVertex];

         if ( !mcVertex ) {
            std::cout << "No Match from RC to MC" << std::endl;
            continue;
         }

         if (vtxeval::gDebugFlag) {
            std::cout << Form("Vx[%3i]", recoVertexIndex) << *recoVertex << " " << *mcVertex;
            int nMcTracksWithHitsatL = Mc2McHitTracks.count(recoVertex->idTruth());
            std::cout << Form("Number of McTkHit %4i rank %8.3f", nMcTracksWithHitsatL, vertexRanks[recoVertexIndex]);
         }

         int IdPar = mcVertex->IdParTrk();

         if (IdPar > 0 && IdPar <= nMuMcTracks) {
            StMuMcTrack *mcTrack = (StMuMcTrack *) MuMcTracks->UncheckedAt(IdPar - 1);

            if (mcTrack && vtxeval::gDebugFlag) std::cout << " " << mcTrack->GeName();
         }

         FillData(data, recoVertex);

         double nTracks = recoVertex->noTracks();

         if (mcVertex->Id() == 1 && nTracks == vertexMaxMultiplicity) {// good
            VertexG->Fill(&data.beam);
         }
         else {   // bad
            VertexB->Fill(&data.beam);
         }
      }

      if ( !gROOT->IsBatch() ) {
         if (vtxeval::ask_user()) return;
      }
      else { vtxeval::gDebugFlag = false; }
   }

   fOut->Write();
}