/**
@SYMTestCaseID PIM-CONVERTERTEST-0001
*/	
void doMainL()
	{
	test.Start(KTest1);

	RFs fs;
	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);
	TBufC<11> targetFile(_L("target file"));

//========================================================
//path
	TBuf<17> path(_L(":\\testHtml\\*.*"));
//single file
	TBuf<25> sourceFile;
	_LIT(KFileName, "test1.txt");
//========================================================
	if(getPathL(path, fs))
		{
		//CONVERT PATH
		TBuf<17> pathName(path);
		pathName.SetLength(pathName.Length()-3);

		convertPathL(path, pathName, fs, targetFile);

		//CONVERT SINGLE FILE

		sourceFile.Copy(pathName);
		sourceFile.Append(KFileName);

		synchronousL(sourceFile, targetFile);
//		asynchronousL(sourceFile, targetFile);

		//OOM TESTS
//		oomSynchronousL(sourceFile, targetFile);
//		oomAsynchronousL(sourceFile, targetFile);
		}
//========================================================

	CleanupStack::PopAndDestroy(); // fs
	
	REComSession::FinalClose(); //needed, otherwise you will get a memory leak
	
	test.End();
	test.Close();
	}
void AnaGenPartonAndFFNtuplizer(bool save=false, 
				bool applyQ = false,
				double fractQ = 0.3, 
				double constQ = 30.0, 
				double fractLogQ = 0.1, 
				double fractLogQ_P2 = 1, 
				bool fixedFracLogQ = true, 
				float fractLogQ_low = 1.5, 
				float fractLogQ_hig = 2.5, 
				bool phiDepELoss = false, 
				float ellipse_a = 7.0, 
				float ellipse_b = 10.0){

   // variables
   bool debug = false;

   /*
   bool applyQ = false;

   double fractQ = 0.3;
   double constQ = 30.0;   // 10, 20, 30
   double fractLogQ = 0.1;
   double fractLogQ_P2 = 1;  // 1 = does nothing
   
   fractQ = -1;
   constQ = -1;
   fractLogQ = 2.0;
   fractLogQ_P2 = 1;

   bool fixedFracLogQ = true;
   float fractLogQ_low = 1.5;
   float fractLogQ_hig = 2.5;

   bool phiDepELoss = true;
   float ellipse_a = 7.0;  // short path length
   float ellipse_b = 10.0; // long path length
   */

   //TString infdir = "/net/hisrv0001/home/y_alive/scratch1/ana/jetquenching/pythia";
   //TString infile = "spectAnaGEN_March26_PtAll_numEvents5000_proq20_FullExt_v3_VariedN.root";

   TString infdir = "/net/hisrv0001/home/y_alive/scratch1/ana/jetquenching/pythia/proq20";    
   TString infile = "spectAnaGEN_March26_PtAll_Ntot24M_proq20_FullExt_Large_VariedN";
   //TString infile = "spectAnaGEN_March26_PtAll_Ntot17M_proq20_FullExt_Large_VariedN";
   //TString infile = "spectAnaGEN_March26_PtAll_Ntot8M_proq20_FullExt_Large_VariedN";
   //TString infile = "spectAnaGEN_March26_PtAll_Ntot400K_proq20_FullExt_Large_VariedN";
   //TString infile = "spectAnaGEN_March26_PtAll_numEvents5000_proq20_FullExt_v5_VariedN";

   //TString infdir = "/net/hisrv0001/home/y_alive/cmssw_new/CMSSW_443_JetQuenchingAna/src/SpectraAna/GenPartonAndFFNtuplizer/test";
   //TString infile = "spectAnaGEN_numEvent500.root";


   TString outdir = "./root_output";
   TString outfile;
   outfile.Append(Form("ANA_%s",infile.Data()));
   if(applyQ) {
      outfile.Append("_jetQ");
      if(fractQ>0) outfile.Append(Form("_fract%1.2f",fractQ));
      if(constQ>0) outfile.Append(Form("_const%1.2f",constQ));
      if(fractLogQ>0) {
	 if(!fixedFracLogQ) {  // if parameter is not fixed
	    outfile.Append(Form("_fractLog%1.2fto%1.2f",fractLogQ_low,fractLogQ_hig));
	 }else{
	    outfile.Append(Form("_fractLog%1.2f",fractLogQ));
	 }
	 if(fractLogQ_P2!=1) outfile.Append(Form("_sp%1.2f",fractLogQ_P2));
      }
      if(phiDepELoss){
	 outfile.Append(Form("_phidep_a%1.2f_b%1.2f",ellipse_a,ellipse_b));
      }
   }
   
   cout<<"Check Parameters = "<<outfile.Data()<<endl;


   TFile *f1 = TFile::Open(Form("%s/%s.root",infdir.Data(),infile.Data()));

   if(!f1) {
      Error("<Input File Reading>","File is NULL");
      return;
   }
   

   f1->cd("genSpectAna");
   TTree *nt = (TTree*) f1->FindObjectAny("SpectraStudyTree");
   if(!nt) {
      Error("<Input Tree Reading>","Tree is NULL");
      return;
   }

   gSystem->Load("/net/hisrv0001/home/y_alive/cmssw_new/CMSSW_443_JetQuenchingAna/lib/slc5_amd64_gcc434/pluginSpectraAnaGenPartonAndFFNtuplizer.so");

   SpectraStudyTreeClass stree;

   TClonesArray *asstrk = new TClonesArray("GenParticleInfo");
   TClonesArray *alltrk = new TClonesArray("GenParticleInfo");

   nt->SetBranchAddress("fPthat",&stree.fPthat);
   nt->SetBranchAddress("fCrossx",&stree.fCrossx);
   nt->SetBranchAddress("isMinPtHat",&stree.isMinPtHat);
   nt->SetBranchAddress("nNumEvt",&stree.nNumEvt);

   nt->SetBranchAddress("nJets",&stree.nJets);
   nt->SetBranchAddress("nTrks",stree.nTrks);
   nt->SetBranchAddress("fJPt",stree.fJPt);
   nt->SetBranchAddress("fJEt",stree.fJEt);
   nt->SetBranchAddress("fJEta",stree.fJEta);
   nt->SetBranchAddress("fJPhi",stree.fJPhi);

   nt->SetBranchAddress("AssParticles",&asstrk);
   nt->SetBranchAddress("AllParticles",&alltrk);

   // prepare histograms
   prepareHist();

   int totN = 0;

   for (int i=0;i<nt->GetEntries();i++){

      nt->GetEntry(i);
      
      float nevt = (float) stree.nNumEvt;

      //if(i>10000) break;

      if (i%50000==0) {
	 cout<<"Cross-section = "<<stree.fCrossx<<" pTHat = "<<stree.fPthat
	     <<" number of events = "<<nevt
	     <<" number of jets = "<<stree.nJets<<" number of total tracks = "<<alltrk->GetEntriesFast()<<endl;
      }

      int ntotTrk = 0;
      dPtHat->Fill(stree.fPthat);
      
      /* Event-by-event Quenching Parameter Determination */
      double pFracQ = 0.0;
      if(fixedFracLogQ){
	 pFracQ = fractLogQ;
      }else{
	 pFracQ = gRandom->Uniform(fractLogQ_low,fractLogQ_hig);
      }
      dPar1stFracLogQ->Fill(gRandom->Uniform(fractLogQ_low,fractLogQ_hig));

      
      // 0. Parton/Jet and Associated Tracks ------------------------------------
      for (int j=0; j<stree.nJets; ++j) {

	 float jet  = stree.fJEt[j];
	 float jpt  = stree.fJPt[j];
	 float jeta = stree.fJEta[j];
	 float jphi = stree.fJPhi[j];
	 int ntrk = stree.nTrks[j];

	 float pathLength = 0.0;
	 float pPhiFracQ = 0.0;

	 // Without this cut, slightly more fragmented tracks in 4-5 GeV/c 
	 if(fabs(jeta)>2.0) continue; // eta cut 

	 if(debug) {
	    cout<<" Found Jet (et,pt,  eta,phi) = ("<<jet<<","<<jpt<<",  "<<jeta<<","<<jphi
		<<") with "<<ntrk<<" associated charged tracks"<<endl;
	 }

	 /* Apply quenching scenarios  */ 
	 
	 if(applyQ){
	    if(fractQ>0){
	       /* fractional eloss: */
	       jet = jet*(1. - fractQ);
	    }else if(constQ>0){
	       /* constant eloss: */
	       jet = jet - constQ; 
	    }else if(!phiDepELoss && fractLogQ>0){
	       /* e-dependent fractional eloss: */
	       jet = jet*(1. - pFracQ*(log(fractLogQ_P2*jet)/jet));
	       //}else if(phiDepELoss && fractLogQ>0){
	    }else if(phiDepELoss){  
	       float pathLength = 0.0;
	       float pPhiFracQ = 0.0;

	       pathLength = getPathL(jphi,ellipse_a,ellipse_b);
	       pPhiFracQ = getPar1stLinearPathL(pathLength,ellipse_a,ellipse_b);
	       
	       jet = jet*(1. - pPhiFracQ*(log(fractLogQ_P2*jet)/jet));

	       dPathL->Fill(pathLength,stree.fCrossx);
	       dPhidPathL->Fill(jphi,pathLength,stree.fCrossx);
	       dPhidPathL2->Fill(jphi,pathLength*pathLength,stree.fCrossx);
	       dPar1stdPhi->Fill(pPhiFracQ,jphi,stree.fCrossx);
	       dPar1stVsPhi->Fill(pPhiFracQ*cos(jphi),pPhiFracQ*sin(jphi),stree.fCrossx);
	       dPathLVsPhi->Fill(pathLength*cos(jphi),pathLength*sin(jphi),stree.fCrossx);
	       dPathLVsPhiWPar1st->Fill(pathLength*cos(jphi),pathLength*sin(jphi),pPhiFracQ*stree.fCrossx); // sure?

	    }
	    // THIS IS IMPORTANT --> JUSTIFIED?
	    // THIS IS NOT NEEDED SINCE JET<0 FILLED IN UNDERFLOW BIN ANYWAY
	    // if(jet<0) continue;

	 } // end of apply jetQ
	 
	 // HIST FILLING 
	 
	 dJetPhi->Fill(jphi,stree.fCrossx);
	 dNJetdEt->Fill(jet,stree.fCrossx);
	 dNJetdEtdPhi->Fill(jet,jphi,stree.fCrossx);
	 dNJetdEtdCos2Phi->Fill(jet,cos(2.*jphi),stree.fCrossx); // v2 = <cos2(phi-psi)>
	 dNJetdEtwCos2Phi->Fill(jet,stree.fCrossx*cos(2.*jphi)); // v2 =  dNJetdEtwCos2Phi/dNJetdEtwNonePhi
	 dNJetdEtwNonePhi->Fill(jet,stree.fCrossx*1.0);
	 dNJetdEtdPtHat->Fill(jet,stree.fPthat,stree.fCrossx); 
	 dNJetdEtdPtHat_FF->Fill(jet,stree.fPthat,stree.fCrossx);
	 
	 // associated track loop 
	 for (int k=0; k<ntrk; ++k) {

	    GenParticleInfo *AssParticles = (GenParticleInfo*)asstrk->At(ntotTrk);  
	    ntotTrk++;  // ntotTrk = sum of ntrk_{i}
	    
	    float trkpt  = AssParticles->fPt;
	    float trketa = AssParticles->fEta;
	    float trkphi = AssParticles->fPhi;

	    float trkz = (jet>0) ? trkpt/jet : 100.0;

	    if(fabs(trketa)>1.0) continue; // eta cut

	    if(debug) {
	       cout<<"    Associated Tracks (pt,eta,phi) = ("<<trkpt<<","<<trketa<<","<<trkphi
		   <<") and z = trkpt/jetet = "<<trkpt/jpt<<endl; 
	    }


	    // HIST FILLING
	    dNTrkdPtdPtHat->Fill(trkpt,stree.fPthat,stree.fCrossx);  // weighted by cross section
	    dNTrkdPtdJetEt->Fill(trkpt,jpt,stree.fCrossx);
	    dNTrkdZdJetEt->Fill(trkz,jpt,stree.fCrossx);
	    dNTrkdPtdPhi->Fill(trkpt,trkphi,stree.fCrossx);
	    //dNTrkdPtdPhi->Fill(trkpt,trkphi,stree.fCrossx*(1.+applyCos(trkphi))); // ARTIFICAL V2

	    dNTrkdPtdJetEtdPhi->Fill(trkpt,jpt,trkphi,stree.fCrossx);

	    dNTrkdPtdPtHatdJetEt->Fill(trkpt,stree.fPthat,jpt,stree.fCrossx);
	    dNTrkdZdPtHatdJetEt->Fill(trkz,stree.fPthat,jpt,stree.fCrossx);
	    
	    //ntotTrk++;
	 } // end of tracks

      } // end of nJets


      // 1. All Charged Tracks ----------------------------------------
      for (int l=0; l<alltrk->GetEntriesFast(); ++l) {
	 GenParticleInfo *AllParticles = (GenParticleInfo*)alltrk->At(l);

	 float alltrkpt  = AllParticles->fPt;
	 float alltrketa = AllParticles->fEta;
	 float alltrkphi = AllParticles->fPhi;


	 if(fabs(alltrketa)>1.0) continue; // eta cut     

	 // HIST FILLING
	 dNAllTrkdPtdPtHat->Fill(alltrkpt,stree.fPthat,stree.fCrossx);
	 dNAllTrkdPtdPhi->Fill(alltrkpt,alltrkphi,stree.fCrossx);

      }


      if(stree.isMinPtHat==1) dNevtMinPtHat->Fill(1.1);
      totN++;

   } // end of all entries

   cout<<"Number of events = "<<totN<<endl;

   // Fragmentation Function Generator
   if(saveFF){
      for(int j=0;j<dNTrkdPtdPtHatdJetEt->GetNbinsZ();j++){
	 
	 //double dsigma = hdjetet_ff->GetBinContent(j+1);
	 //if(dsigma<1E-22) continue; // no jet ET bins 
	 double etmin = dNTrkdPtdPtHatdJetEt->GetZaxis()->GetBinLowEdge(j+1);
	 double etmax = dNTrkdPtdPtHatdJetEt->GetZaxis()->GetBinUpEdge(j+1);
	 
	 // Fragmentation Function (Be carefull not [j+1,j+2]) 
	 TH1D *hddtrkdpt_ff = (TH1D*) dNTrkdPtdPtHatdJetEt->ProjectionX("",0,-1,j+1,j+1,"e");
	 hddtrkdpt_ff->SetName(Form("hddTrkdPt_FF_et%1.0fto%1.0f",etmin,etmax));
	 hFF.push_back(hddtrkdpt_ff);
      }
   }

   // Save histograms in a root file
   if(save){
      cout<<"Output file = "<<Form("%s/%s.root",outdir.Data(),outfile.Data())<<endl;
      TFile *outputFile = new TFile(Form("%s/%s.root",outdir.Data(),outfile.Data()),"recreate");
      saveHistRoot();
   }

}