Example #1
0
int   OutTreeManager::InitTree(string trname) {
 if(npar==0) return 0;
 thetreeo=new TTree(trname.c_str(),trname.c_str());
 if(thetreeo==0) return 0;
 SetBranches(thetreeo);
 return 1;

}
Example #2
0
int   OutTreeManager::InitTree(string aname, string trname) {
 if(npar==0) return 0;
 thefileo  = new TFile(aname.c_str(), "RECREATE" ); 
 thefileo->cd();
 thetreeo=new TTree(trname.c_str(),trname.c_str());
 if(thetreeo==0) return 0;
 SetBranches(thetreeo);
 return 1;

}
Int_t Dst2640Analysis::ReduceNtuple(){
  cout<<"Going to reduce the ntuple"<<endl;

  if(_fChain==NULL){
    cout<<"No chain."<<endl;
    return 0;
  } 


  ///set the branches to be read on tree 
  SetBranches();


  //the file must be created here so the 'new' histos and Tree is created in hard drive 
  OutPutFile=new TFile(_OutputDir+"/Dst2640Reduced.root","recreate",_OutputDir+"/Dst2640Reduced.root",4);
  if(OutPutFile==NULL){cout<<"Failed to create file"<<endl;return 0;}


  //create new reduced ntuple
  ReducedNtuple=new TTree("Dst2640Ntuple","Dst2640 Reduced Ntuple",99);        
 
  //create the branches in the ReducedNtuple
  MakeReducedNtupleBranches();


  if(TruthMatch){
    //create the MC Histos
    HMCDst2640Mass=new TH1F();
    SetHistoXY(HMCDst2640Mass,"HMCDst2640Mass",100,Dst2640PDGMass-Dst2640MassWindow,Dst2640PDGMass+Dst2640MassWindow,
	       "Dst2640 Cand. Mass (GeV/c^{2})","Entries/1MeV");
  
    HMCDst2640DeltaM=new TH1F();
    SetHistoXY(HMCDst2640DeltaM,"HMCDst2640DeltaM",database.GetDst2640DeltaMNbins(),database.GetDst2640DeltaMMin(),database.GetDst2640DeltaMMax(),"D*(2640) Mass - D*(2010) (GeV/c^{2})","");

    HMCDst2640p3CM=new TH1F();
    SetHistoXY(HMCDst2640p3CM,"HMCDst2640p3CM",Dst2640p3CMNbins,Dst2640p3CMmin,Dst2640p3CMmax,
	       "p* (GeV/c)","Entries/100MeV");
  
    HMCDst2640costhCM=new TH1F();
    SetHistoXY(HMCDst2640costhCM,"HMCDst2640costhCM",Dst2640CosstarNbins,Dst2640Cosstarmin,Dst2640Cosstarmax,
	       "cos(#theta)*","Entries/.04");
  
    H2MCDst2640CMPvsTheta=new TH2F();
    SetHisto2D(H2MCDst2640CMPvsTheta,"H2MCDst2640CMPvsTheta",Dst2640p3CMNbins,Dst2640p3CMmin,Dst2640p3CMmax,
	       "p* (GeV/c)",Dst2640CosstarNbins,Dst2640Cosstarmin,Dst2640Cosstarmax,"cos(#theta*)","entries/(.04x100MeV)");
  
    H2MCDst2640DalitzPlot=new TH2F();
    SetHisto2D(H2MCDst2640DalitzPlot,"H2MCDst2640DalitzPlot",NDalitzPlotBins,DalitzMin,DalitzMax,"m^{2}(D*#pi^{-})  (GeV^{2}/c^{4})",NDalitzPlotBins,DalitzMin,DalitzMax,"m^{2}(D*#pi^{+})  (GeV^{2}/c^{4})","");
    

    HMCNDst2640=new TH1F();
    SetHistoXY(HMCNDst2640,"HMCNDst2640",11,-.5,10.5,
	       "nDst2640/event","Counts");

  
    HLundCheck=new TH1F();
    SetHisto(HLundCheck,"HLundCheck",15,-.5,14.5,
	     "ParticleLund - LundExp");
  }
  //////


  //Start the event loop;
  Long_t MaxNumberEvents=1000000000;
  if(_RunInTestMode)MaxNumberEvents=5000;
  
  Int_t RemovedCands=0;
  Int_t InitialdCands=0;

  Int_t eventid=0;
  while(_fChain->GetEntry(eventid,0)>0&&eventid<MaxNumberEvents){   
    eventid++;
     
    if(eventid%5000==0)cout<<eventid<<" Events done.   With "<<RecoDst2640CounterTotal<<" Candidates saved."<<endl;    
           
    InitialdCands+=nDst2640;
    if(nDst2640>MAXNCANDS){
      cout<<"Too many cands at event "<<eventid<<" Only first "<<MAXNCANDS<<" of "<<nDst2640<<" will be used"<<endl;
      RemovedCands+=nDst2640-MAXNCANDS; 
      nDst2640=MAXNCANDS;      
    }

    ///Loop over the reconstructed
    RecoDst2640CounterPerEvent=0;      
    
    //------beam quantities
    TVector3 beamVtx(primVtxX,primVtxY,primVtxZ);


    for(Dst2640Idx=0;Dst2640Idx<nDst2640;Dst2640Idx++){

      ////////////cut out the unconverged fits
      if(Dst2640VtxStatus[Dst2640Idx]!=0)continue;               


      DstarIdx=Dst2640d1Idx[Dst2640Idx];
      SlowPiIdx=Dstard2Idx[DstarIdx];
      D0Idx=Dstard1Idx[DstarIdx];
      PiIdx=D0d2Idx[D0Idx];
      KIdx=D0d1Idx[D0Idx];
      Pi1Idx=Dst2640d2Idx[Dst2640Idx];
      Pi2Idx=Dst2640d3Idx[Dst2640Idx]; 
      if(_Mode=="D0ToK3Pi"){
	D0Pi2Idx=D0d3Idx[D0Idx];
	D0Pi3Idx=D0d4Idx[D0Idx];
      }
      
      PitrkIdx=PiTrkIdx[PiIdx];
      KtrkIdx=KTrkIdx[KIdx];
      SlowPitrkIdx=PiTrkIdx[SlowPiIdx];
      Pi1trkIdx=PiTrkIdx[Pi1Idx];
      Pi2trkIdx=PiTrkIdx[Pi2Idx];
      if(_Mode=="D0ToK3Pi"){
	D0Pi2trkIdx=PiTrkIdx[D0Pi2Idx];
	D0Pi3trkIdx=PiTrkIdx[D0Pi3Idx];
      }

 

      //Check that Im using proper indexes
      if(TruthMatch){
	if(Dstard1Lund[DstarIdx]!=D0Lund[D0Idx])HLundCheck->Fill(1);
	if(Dstard2Lund[DstarIdx]!=PiLund[SlowPiIdx])HLundCheck->Fill(2);
	if(D0d1Lund[D0Idx]!=KLund[KIdx])HLundCheck->Fill(3);
	if(D0d2Lund[D0Idx]!=PiLund[PiIdx])HLundCheck->Fill(4);
	if(TRKLund[SlowPitrkIdx]!=PiLund[SlowPiIdx])HLundCheck->Fill(5);
	if(TRKLund[PitrkIdx]!=PiLund[PiIdx])HLundCheck->Fill(6);
	if(Dst2640d1Lund[Dst2640Idx]!=DstarLund[DstarIdx])HLundCheck->Fill(7);
	if(TRKLund[Pi1trkIdx]!=PiLund[Pi1Idx])HLundCheck->Fill(9);
	if(TRKLund[Pi2trkIdx]!=PiLund[Pi2Idx])HLundCheck->Fill(10);
	if(Dst2640d2Lund[Dst2640Idx]!=PiLund[Pi1Idx])HLundCheck->Fill(11);
	if(Dst2640d3Lund[Dst2640Idx]!=PiLund[Pi2Idx])HLundCheck->Fill(12);
	//if(TRKLund[KtrkIdx]!=KLund[KIdx])HLundCheck->Fill(13);//TRKLund is always Pion

	if(_Mode=="D0ToK3Pi"){
	  if(D0d3Lund[D0Idx]!=PiLund[D0Pi2Idx])HLundCheck->Fill(13);
	  if(D0d4Lund[D0Idx]!=PiLund[D0Pi3Idx])HLundCheck->Fill(14);
	  if(TRKLund[D0Pi2trkIdx]!=PiLund[D0Pi2Idx])HLundCheck->Fill(15);
	  if(TRKLund[D0Pi3trkIdx]!=PiLund[D0Pi3Idx])HLundCheck->Fill(16);
	}
      }

      //////fill reduced ntuple variables    
      dst2640mass=Dst2640Mass[Dst2640Idx];
      dst2640pstar=Dst2640p3CM[Dst2640Idx];
      dst2640cosstar=Dst2640costhCM[Dst2640Idx];
      dst2640deltam=Dst2640Mass[Dst2640Idx]-DstarMass[DstarIdx];  
      if(TMath::Prob(Dst2640Chi2[Dst2640Idx],Dst2640nDof[Dst2640Idx])>0)
	dst2640logvtxprob=log10(TMath::Prob(Dst2640Chi2[Dst2640Idx],Dst2640nDof[Dst2640Idx]));
      else dst2640logvtxprob=-100;
      dst2640charge=Dst2640Lund[Dst2640Idx]/abs(Dst2640Lund[Dst2640Idx]);
      dst2640nDst2640=nDst2640;     

      //-------Dstar quantities
      dstarmass=DstarMass[DstarIdx];
      dstardeltam=DstarMass[DstarIdx]-D0Mass[D0Idx];
      if(DstarVtxStatus[DstarIdx]==0) dstarlogvtxprob=log10(TMath::Prob(DstarChi2[DstarIdx],DstarnDof[DstarIdx]));   
      else dstarlogvtxprob=0;
      dstarcostheta= ComputeDstarAngle();
      dstarpstar=Dstarp3CM[DstarIdx];

      //-------D0 quantities
      d0mass=D0Mass[D0Idx];
      //if(D0VtxStatus[D0Idx]==0)
      if(TMath::Prob(D0Chi2[D0Idx],D0nDof[D0Idx])>0) d0logvtxprob = log10(TMath::Prob(D0Chi2[D0Idx],D0nDof[D0Idx]));
      else d0logvtxprob=0;
      d0pstar=D0p3CM[D0Idx];
      d0mode=0;
      if(D0Pi2Idx==-1&&D0Pi3Idx==-1) d0mode=1;
      if(D0Pi2Idx>=0&&D0Pi3Idx>=0) d0mode=2;
      if(d0mode==0)cout<<"d0mode=0"<<endl;

      //track quantities
      kp3=Kp3[KIdx];
      pip3=Pip3[PiIdx];
      slowpip3=Pip3[SlowPiIdx];
      pi1p3=Pip3[Pi1Idx];
      pi2p3=Pip3[Pi2Idx];
      pi1charge=PiLund[Pi1Idx]/abs(PiLund[Pi1Idx]);
      pi2charge=PiLund[Pi2Idx]/abs(PiLund[Pi2Idx]);
      pi1pluspi2charge=pi1charge+pi2charge;
      
      //other
      msqdstarpiplus=ComputeMsqDstarPi(Pi1Idx);
      msqdstarpiminus=ComputeMsqDstarPi(Pi2Idx);
      pipimass=ComputePiPiMass();
      dstarpipicosine=ComputeDstarPiPiCosine();      
      pipicosine=ComputePiPiCosine();
      ComputeDstarPiMass(&mdstarpirs,&mdstarpiws);
      dstarpideltam=mdstarpirs-dstarmass;
      dstarpideltamws=mdstarpiws-dstarmass;
      if(nDst2640==2&&Dst2640Idx==0)ComputeDstarPiPiMass(&mdstarpipirs,&mdstarpipiws);
      else{mdstarpipirs=0;mdstarpipiws=0;}
      ComputeDstarPiCosHel(&dstarpicoshelrs,&dstarpicoshelws);
      ComputeDstarPipstar(&dstarpipstarrs,&dstarpipstarws);
	
      klh=14;  
   //    for(Int_t i=10;i<=14;i++)//10=notpion,11=veryloose,12=loose,13=tight,14=verytight
// 	if((KSelectorsMap[KtrkIdx] & (1<<i)) == (1<<i))	
// 	  klh=i;  
      
  
      pilh=5;pi1lh=5;pi2lh=5;  d0pi2lh=5; d0pi3lh=5; 
 //      for(Int_t i=2;i<=5;i++){//2=veryloose,3=loose,4=tight,5=verytight
// 	if((PiSelectorsMap[PitrkIdx] & (1<<i) ) == (1<<i))	
// 	  pilh=i;
// 	if((PiSelectorsMap[Pi1trkIdx] & (1<<i) ) == (1<<i))	
// 	  pi1lh=i;
// 	if((PiSelectorsMap[Pi2trkIdx] & (1<<i) ) == (1<<i))	
// 	  pi2lh=i;  

// 	if(_Mode=="D0ToK3Pi"){
// 	  if((PiSelectorsMap[D0Pi2trkIdx] & (1<<i) ) == (1<<i))	
// 	    d0pi2lh=i;  
// 	  if((PiSelectorsMap[D0Pi3trkIdx] & (1<<i) ) == (1<<i))	
// 	    d0pi3lh=i;  
// 	}

//       }
	

      dst2640mctrue=1;
      dstarmctrue=1;
      d0mctrue=1;
      pimctrue=1;
      slowpimctrue=1;
      kmctrue=1;
      pi1mctrue=1;
      pi2mctrue=1;     
      d0pi2mctrue=1;  
      d0pi3mctrue=1;      
      if(TruthMatch){
	dst2640mctrue=(Dst2640MCIdx[Dst2640Idx]>0);
	dstarmctrue=(DstarMCIdx[DstarIdx]>0);
	d0mctrue=(D0MCIdx[D0Idx]>0);
	pimctrue=(PiMCIdx[PiIdx]>0);
	slowpimctrue=(PiMCIdx[SlowPiIdx]>0);
	kmctrue=(KMCIdx[KIdx]>0);
	pi1mctrue=(PiMCIdx[Pi1Idx]>0);
	pi2mctrue=(PiMCIdx[Pi2Idx]>0);
	if(_Mode=="D0ToK3Pi"){
	  d0pi2mctrue=(PiMCIdx[D0Pi2Idx]>0);
	  d0pi3mctrue=(PiMCIdx[D0Pi3Idx]>0);
	}
      }

      if(TruthMatch&&dst2640mctrue)
	dst2640dmres=dst2640deltam-(mcmass[Dst2640MCIdx[Dst2640Idx]]-mcmass[DstarMCIdx[DstarIdx]]);
      else dst2640dmres=100000;
      
      eventnumber=eventid;
  
      
      ///Make some cuts due to much background  
      //if(!Dst2640Cuts.EvalCuts(1,100))continue;

      if(!(
	   //      KLHCut.EvalCut()&&
	   // 	   PiLHCut.EvalCut()&&
	   // 	   D0ProbCut.EvalCut()&&
	   D0MassCut.EvalCut()&&
	   // 	   D0pstarCut.EvalCut()&&   
	   DstarDeltaMCut.EvalCut()&&
	   // 	   Pi1LHCut.EvalCut()&&
	   // 	   Pi2LHCut.EvalCut()&&
	   Pi1Pi2ChargeCut.EvalCut()&&
	   Dst2640pstarCut.EvalCut()
	   ))continue;
 //      if(_Mode=="D0ToK3pi")
// 	if(!(
// 	     //D0Pi2LHCut.EvalCut()&&
// 	     //D0Pi3LHCut.EvalCut()
// 	))continue;
  

      ReducedNtuple->Fill();	              
     
          
      RecoDst2640CounterTotal++;
           
   
    }//Dst2640 loop    
   
    
    ///-------------------------------
    ///Fill the Generated Quantities
    ///-----------------------------
    if(TruthMatch){
      Float_t msqplus=0;
      Float_t msqminus=0;
      //now loop over the Generated MC
      MCDst2640CounterPerEvent=0; 
      Int_t mcid=-1;
      while(mcid<mcLen){
	mcid++;

	if(mcLund[mcid]==_MatterOrAntiMatter*myDst2640Lund){
	  MCDst2640CounterPerEvent++; 
	  MCDst2640CounterTotal++;
		
	  HMCDst2640Mass->Fill(mcmass[mcid]);
	  HMCDst2640p3CM->Fill(mcp3CM[mcid]); 
	  HMCDst2640costhCM->Fill(mccosthCM[mcid]); 	
	  H2MCDst2640CMPvsTheta->Fill(mcp3CM[mcid],mccosthCM[mcid]);

	  //calculate deltaM   //mcmass[dauIdx[mcid]]=first daughter; mcmass[dauIdx[mcid] + 1] = second daughter ...	    
	  HMCDst2640DeltaM->Fill(mcmass[mcid]-mcmass[dauIdx[mcid]]);


	  //calculate Dalitz plot:	  
	  TVector3 Dstarp3vec;Dstarp3vec.SetMagThetaPhi(mcp3CM[dauIdx[mcid]],acos(mccosthCM[dauIdx[mcid]]),mcphiCM[dauIdx[mcid]]);     
	  TLorentzVector Dstarp4(Dstarp3vec,sqrt(Dstarp3vec*Dstarp3vec+mcmass[dauIdx[mcid]]*mcmass[dauIdx[mcid]]));
	  
	  TVector3 Pi1p3vec;Pi1p3vec.SetMagThetaPhi(mcp3CM[dauIdx[mcid]+1],acos(mccosthCM[dauIdx[mcid]+1]),mcphiCM[dauIdx[mcid]+1]);
	  TLorentzVector Pi1p4(Pi1p3vec,sqrt(Pi1p3vec*Pi1p3vec+mcmass[dauIdx[mcid]+1]*mcmass[dauIdx[mcid]+1]));

	  TVector3 Pi2p3vec;Pi2p3vec.SetMagThetaPhi(mcp3CM[dauIdx[mcid]+2],acos(mccosthCM[dauIdx[mcid]+2]),mcphiCM[dauIdx[mcid]+2]);
	  TLorentzVector Pi2p4(Pi2p3vec,sqrt(Pi2p3vec*Pi2p3vec+mcmass[dauIdx[mcid]+2]*mcmass[dauIdx[mcid]+2]));
	  
	  msqplus=(Dstarp4+Pi1p4).Mag2();
	  msqminus=(Dstarp4+Pi2p4).Mag2();	  	  
	  if((msqplus-4.5) > (1.5 - (msqminus-4.5))) H2MCDst2640DalitzPlot->Fill(msqminus,msqplus);

	}
      }
      HMCNDst2640->Fill(MCDst2640CounterPerEvent);
    }

  }

  //print summary
  cout<<"--------Summary-------"<<endl;
  cout<<"Total events="<<eventid<<endl;
  cout<<"Total Generated="<<MCDst2640CounterTotal<<" Reconstructed="<<RecoDst2640CounterTotal<<endl;
  cout<<"Total candidates removed "<<RemovedCands<<" ( "<<(int)(100*RemovedCands/InitialdCands + .5)<<"%)"<<endl;
  cout<<"--------End Summary---"<<endl;

  ////Save the Ntuple and histograms
  cout<<"Going to save the ntuple and histograms"<<endl; 

  
  if(ReducedNtuple->Write()){ cout<<"Ntuple written."<<endl;}
  else{ cout<<"Failed to write ntuple"<<endl;return 0;}
  delete  ReducedNtuple;   

  if(TruthMatch){
    
    if(HMCDst2640Mass->Write()&&
       HMCDst2640DeltaM->Write()&&
       HMCDst2640p3CM->Write()&&
       HMCDst2640costhCM->Write()&&     
       H2MCDst2640CMPvsTheta->Write()&&
       H2MCDst2640DalitzPlot->Write()&&
       HMCNDst2640->Write()&&     
       HLundCheck->Write()
       ){ 
      cout<<" Histograms have been written"<<endl;
    }
    else{
      cout<<"Failed to write Histos"<<endl;return 0;
    }

    delete  HMCDst2640Mass;
    delete  HMCDst2640p3CM;
    delete  HMCDst2640costhCM;     
    delete  H2MCDst2640CMPvsTheta;
    delete  H2MCDst2640DalitzPlot;
    delete  HMCNDst2640;     
    delete  HLundCheck;   
    delete  HMCDst2640DeltaM;
    
    cout<<"histos deleted."<<endl;

  }

  OutPutFile->Write(); //necesary otherwise file is not closed 
  OutPutFile->Close();  
  cout<<OutPutFile->GetName()<<" has been closed."<<endl;
  delete OutPutFile;

  return 1;
}
Int_t DstPiAnalysis::ReduceNtuple(Bool_t RunInTestMode){
  cout<<"Going to reduce the ntuple"<<endl;

  if(_fChain==NULL){
    cout<<"No chain."<<endl;
    return 0;
  } 


  ///link the branches in the input chain
  SetBranches();


  //the file must be created here so the 'new' histos and Tree is created in hard drive 
  OutPutFile=new TFile(_OutputDir+"/DstPiReduced.root","recreate",_OutputDir+"/DstPiReduced.root",4);
  if(OutPutFile==NULL){cout<<"Failed to create file"<<endl;return 0;}


  //create new reduced ntuple
  ReducedNtuple=new TTree("DstPiNtuple","DstPi Reduced Ntuple",99);        
 
  //create the branches in the ReducedNtuple
  MakeReducedNtupleBranches();


  if(_TruthMatch){
    //create the MC Histos
    HMCDstPiMass=new TH1F();
    SetHistoXY(HMCDstPiMass,"HMCDstPiMass",database.GetDstPiMassNbins(),database.GetDstPiMassMin(),database.GetDstPiMassMax(),"DstPi Cand. Mass (GeV/c^{2})","");
  
    HMCDstPiDeltaM=new TH1F();
    SetHistoXY(HMCDstPiDeltaM,"HMCDstPiDeltaM",database.GetDstPiDeltaMNbins(),database.GetDstPiDeltaMMin(),database.GetDstPiDeltaMMax(),"D*(2640) Mass - D*(2010) (GeV/c^{2})","");

    HMCDstPip3CM=new TH1F();
    SetHistoXY(HMCDstPip3CM,"HMCDstPip3CM",50,0,5,
	       "p* (GeV/c)","Entries/100MeV");
  
    HMCDstPicosthCM=new TH1F();
    SetHistoXY(HMCDstPicosthCM,"HMCDstPicosthCM",20,-1.0001,1.0001,
	       "cos(#theta)*","");
  
    H2MCDstPiCMPvsTheta=new TH2F();
    SetHisto2D(H2MCDstPiCMPvsTheta,"H2MCDstPiCMPvsTheta",50,0,5,
	       "p* (GeV/c)",20,-1.0001,1.0001,"cos(#theta*)","");  

    HMCNDstPi=new TH1F();
    SetHistoXY(HMCNDstPi,"HMCNDstPi",11,-.5,10.5,
	       "nDstPi/event","Counts");
  }
  //////


  ///check how many candidates are removed by array size cut
  Int_t RemovedCands=0;
  Int_t InitialdCands=0;

  //Start the event loop;
  Long_t MaxNumberEvents=1000000000;
  if(RunInTestMode)MaxNumberEvents=10000;

  Int_t eventid=0;
  while(_fChain->GetEntry(eventid,0)>0&&eventid<MaxNumberEvents){   
    eventid++;
     
    if(eventid%5000==0)cout<<eventid<<" Events done.   With "<<RecoDstPiCounterTotal<<" Candidates saved."<<endl;    
      
    eventnumber=eventid;
     
    InitialdCands+=nDstPi;
    if(nDstPi>MAXNCANDS){
      cout<<"Too many cands at event "<<eventid<<" Only first "<<MAXNCANDS<<" of "<<nDstPi<<" will be used"<<endl;
      RemovedCands+=nDstPi-MAXNCANDS; 
      nDstPi=MAXNCANDS;      
    }

    ///Loop over the reconstructed
    RecoDstPiCounterPerEvent=0;      
    
    //------beam quantities
    TVector3 beamVtx(primVtxX,primVtxY,primVtxZ);


    for(DstPiIdx=0;DstPiIdx<nDstPi;DstPiIdx++){

      ////////////cut out the unconverged fits
      if(DstPiVtxStatus[DstPiIdx]!=0)continue;               


      ///determine the indexes for each particle
      DstarIdx=DstPid1Idx[DstPiIdx];
      SlowPiIdx=Dstard2Idx[DstarIdx];
      D0Idx=Dstard1Idx[DstarIdx];
      PiIdx=D0d2Idx[D0Idx];
      KIdx=D0d1Idx[D0Idx];
      Pi1Idx=DstPid2Idx[DstPiIdx];
      D0Pi2Idx=D0d3Idx[D0Idx];
      D0Pi3Idx=D0d4Idx[D0Idx];
          
      PitrkIdx=PiTrkIdx[PiIdx];
      KtrkIdx=KTrkIdx[KIdx];
      SlowPitrkIdx=PiTrkIdx[SlowPiIdx];
      Pi1trkIdx=PiTrkIdx[Pi1Idx];
      D0Pi2trkIdx=PiTrkIdx[D0Pi2Idx];
      D0Pi3trkIdx=PiTrkIdx[D0Pi3Idx];
       
      //////fill reduced ntuple variables    
      dstpimass=DstPiMass[DstPiIdx];
      dstpipstar=DstPip3CM[DstPiIdx];
      dstpicosstar=DstPicosthCM[DstPiIdx];
      dstpideltam=DstPiMass[DstPiIdx]-DstarMass[DstarIdx];  
      if(TMath::Prob(DstPiChi2[DstPiIdx],DstPinDof[DstPiIdx])>0)
	dstpilogvtxprob=log10(TMath::Prob(DstPiChi2[DstPiIdx],DstPinDof[DstPiIdx]));
      else dstpilogvtxprob=-100;
      //Determine D*pi combination: dstpicharge= -2=D*-pi- , -1=D*-pi+  , 1=D*+pi- , 2=D*+pi+
      dstpicharge=DstarLund[DstarIdx]/abs(DstarLund[DstarIdx])+PiLund[Pi1Idx]/abs(PiLund[Pi1Idx]);
      if(dstpicharge==0)dstpicharge=DstarLund[DstarIdx]/abs(DstarLund[DstarIdx]);
      dstpinDstPi=nDstPi;  
      dstpiIdx=DstPiIdx;

      //-------Dstar quantities
      dstarmass=DstarMass[DstarIdx];
      dstardeltam=DstarMass[DstarIdx]-D0Mass[D0Idx];
      if(DstarVtxStatus[DstarIdx]==0) dstarlogvtxprob=log10(TMath::Prob(DstarChi2[DstarIdx],DstarnDof[DstarIdx]));   
      else dstarlogvtxprob=0;
      dstarcostheta=ComputeDstarAngle();
      dstarpstar=Dstarp3CM[DstarIdx];
      dstarcharge=DstarLund[DstarIdx]/abs(DstarLund[DstarIdx]);

      //-------D0 quantities
      d0mass=D0Mass[D0Idx];
      if(TMath::Prob(D0Chi2[D0Idx],D0nDof[D0Idx])>0) d0logvtxprob = log10(TMath::Prob(D0Chi2[D0Idx],D0nDof[D0Idx]));
      else d0logvtxprob=0;
      d0pstar=D0p3CM[D0Idx];
      d0mode=0;
      if(D0Pi2Idx==-1&&D0Pi3Idx==-1) d0mode=1;
      if(D0Pi2Idx>=0&&D0Pi3Idx>=0) d0mode=2;
      if(d0mode==0)cout<<"Error d0mode=0"<<endl;
      d0charge=DstarLund[DstarIdx]/abs(DstarLund[DstarIdx]);
      //d0costheta=ComputeD0Angle();


      //track quantities
      kp3=Kp3[KIdx];
      kcharge=KLund[KIdx]/abs(KLund[KIdx]);
      //kcostheta=ComputeKAngle();

      pip3=Pip3[PiIdx];
      picharge=PiLund[PiIdx]/abs(PiLund[PiIdx]);

      d0pi2p3=0;d0pi3p3=0;d0pi2charge=0;d0pi3charge=0;
      if(d0mode==2){
	d0pi2p3=Pip3[D0Pi2Idx];      
	d0pi2charge=PiLund[D0Pi2Idx]/abs(PiLund[D0Pi2Idx]);      
	d0pi3p3=Pip3[D0Pi3Idx];      
	d0pi3charge=PiLund[D0Pi3Idx]/abs(PiLund[D0Pi3Idx]);		
      }
          	      
      slowpip3=Pip3[SlowPiIdx];
      slowpicharge=PiLund[SlowPiIdx]/abs(PiLund[SlowPiIdx]);

      pi1p3=Pip3[Pi1Idx];      
      pi1charge=PiLund[Pi1Idx]/abs(PiLund[Pi1Idx]);
 


      //fore MC determine if candidate was truthmatched
      dstpimctrue=1;
      dstarmctrue=1;
      d0mctrue=1;
      pimctrue=1;
      slowpimctrue=1;
      kmctrue=1;
      pi1mctrue=1;
      d0pi2mctrue=1;  
      d0pi3mctrue=1;      
      if(_TruthMatch){
	dstpimctrue=(DstPiMCIdx[DstPiIdx]>0);
	dstarmctrue=(DstarMCIdx[DstarIdx]>0);
	d0mctrue=(D0MCIdx[D0Idx]>0);
	pimctrue=(PiMCIdx[PiIdx]>0);
	slowpimctrue=(PiMCIdx[SlowPiIdx]>0);
	kmctrue=(KMCIdx[KIdx]>0);
	pi1mctrue=(PiMCIdx[Pi1Idx]>0);
	if(d0mode==2){
	  d0pi2mctrue=(PiMCIdx[D0Pi2Idx]>0);
	  d0pi3mctrue=(PiMCIdx[D0Pi3Idx]>0);
	}
      }

      //Determine the mass resolution for MC
      if(_TruthMatch&&dstpimctrue)      
	dstpidmres=dstpideltam-(mcmass[DstPiMCIdx[DstPiIdx]]-mcmass[DstarMCIdx[DstarIdx]]);
      else dstpidmres=100000;
      
      //Determine resolution from separate true D* and true pi 
      if(_TruthMatch)
	dstpigenmass=CalculateGenMass();
      else dstpigenmass=0;
          
      //apply some simple cuts to minimize file size
      if(dstarcostheta>.5||dstardeltam>.150||fabs(d0mass-1.865)>.02) continue;
     
      ReducedNtuple->Fill();	              
               
      RecoDstPiCounterTotal++;
           
   
    }//DstPi loop    
   
    
    ///-------------------------------
    ///Fill the Generated Quantities
    ///-----------------------------
    if(_TruthMatch){
      //now loop over the Generated MC
      MCDstPiCounterPerEvent=0; 
      Int_t mcid=-1;
      while(mcid<mcLen){
	mcid++;

	if(mcLund[mcid]==_MatterOrAntiMatter*MYDSTPILUND){
	  MCDstPiCounterPerEvent++; 
	  MCDstPiCounterTotal++;
		
	  HMCDstPiMass->Fill(mcmass[mcid]);
	  HMCDstPip3CM->Fill(mcp3CM[mcid]); 
	  HMCDstPicosthCM->Fill(mccosthCM[mcid]); 	
	  H2MCDstPiCMPvsTheta->Fill(mcp3CM[mcid],mccosthCM[mcid]);

	  //calculate deltaM   //mcmass[dauIdx[mcid]]=first daughter; mcmass[dauIdx[mcid] + 1] = second daughter ...	    
	  HMCDstPiDeltaM->Fill(mcmass[mcid]-mcmass[dauIdx[mcid]]);

	}
      }
      HMCNDstPi->Fill(MCDstPiCounterPerEvent);
    }

  }

  //print summary
  cout<<"--------Summary-------"<<endl;
  cout<<"Total events="<<eventid<<endl;
  cout<<"Total Generated="<<MCDstPiCounterTotal<<" Reconstructed="<<RecoDstPiCounterTotal<<endl;
  cout<<"Total candidates removed "<<RemovedCands<<" ( "<<(int)(100*RemovedCands/InitialdCands + .5)<<"%)"<<endl;
  cout<<"--------End Summary---"<<endl;

  ////Save the Ntuple and histograms
  cout<<"Going to save the ntuple and histograms"<<endl; 

  /*///////////Should not have to call TTree->Write(), TFile->Write() will doit
  if(ReducedNtuple->Write()){ cout<<"Ntuple written."<<endl;}
  else{ cout<<"Failed to write ntuple"<<endl;return 0;}
  delete  ReducedNtuple;   

  if(_TruthMatch){
    
    if(HMCDstPiMass->Write()&&
       HMCDstPiDeltaM->Write()&&
       HMCDstPip3CM->Write()&&
       HMCDstPicosthCM->Write()&&     
       H2MCDstPiCMPvsTheta->Write()&&     
       HMCNDstPi->Write()
       ){ 
      cout<<" Histograms have been written"<<endl;
    }
    else{
      cout<<"Failed to write Histos"<<endl;return 0;
    }

//////Should not have to do this, OutPutFile->Close() will do it.
//     delete  HMCDstPiMass;
//     delete  HMCDstPip3CM;
//     delete  HMCDstPicosthCM;     
//     delete  H2MCDstPiCMPvsTheta;   
//     delete  HMCNDstPi;        
//     delete  HMCDstPiDeltaM;
    
    cout<<"histos deleted."<<endl;

  }
  */
  
  OutPutFile->ls();
  OutPutFile->Write(); //necesary otherwise file is not closed, this will write all objects currently on memory
  cout<<OutPutFile->GetName()<<" has been written"<<endl;
  OutPutFile->ls();
  OutPutFile->Close(); //this will delete all objects created inside the file if they were not written
  cout<<OutPutFile->GetName()<<" has been closed."<<endl;

  delete OutPutFile;

  return 1;
}