Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:12:45

0001 #include "INTT_Calo_trkReco.h"
0002 
0003 // variables for tracking
0004 //
0005 // Variable used in FindInttMvtx()
0006 // They holds Mvtx hit candidates associated with an Intt pair.
0007 static vector<int>   vMvtx0Hit;
0008 static vector<int>   vMvtx1Hit;
0009 static vector<int>   vMvtx2Hit;
0010 
0011 void INTT_Calo_trkReco_Init(void) {
0012   hzgvtx = new TH1F("hzgvtx","global Zvtx",100,-50,50);
0013   hINTTdphi = new TH1F("hINTTdphi","INTT1phi - INTT0phi",100,-0.1,0.1);
0014   hINTTdZvtx = new TH1F("hINTTdZvtx","zvtx_intt - zgvtx",100,-50,50);
0015   hINTTdz0 = new TH1F("hINTTdz0","z0-z0proj",100,-25.,25.);
0016   hINTTdz1 = new TH1F("hINTTdz1","z1-z1proj",100,-25.,25.);
0017   hINTTdz0dz1 = new TH2F("hINTTdz0dz1","dz1 vs dz0",100,-25,25,100,-25,25);
0018   hINTTdz0dz1r = new TH2F("hINTTdz0dz1r","dz1 vs dz0 (rotate)",100,-25,25,100,-25,25);
0019   hINTTdz_r = new TH1F("hINTTdz_r"," dz (rotated)",100,-5,5);
0020   hInttPair_r = new TH1F("hInttPair_r","r of INTT pair",100,0.,500);
0021   hEmcIntt_dr = new TH1F("hEmcIntt_dr","rEmc-rIntt",100,-50,50);
0022   hEmcIntt_dr_Zcut = new TH1F("hEmcIntt_dr_Zcut","rEmc-rIntt w Zcut",100,-50,50);
0023   hEmcIntt_dr_Zvtx2 = new TH1F("hEmcIntt_dr_Zvtx2","rEmc-rIntt w Zvtx cut",100,-50,50);
0024   hEmcIntt_dr_Zvtx4 = new TH1F("hEmcIntt_dr_Zvtx4","rEmc-rIntt w Zvtx cut",100,-50,50);
0025   hEmcIntt_dr_Zvtx5 = new TH1F("hEmcIntt_dr_Zvtx5","rEmc-rIntt w Zvtx cut",100,-50,50);
0026   hdZe1 = new TH1F("hdZe1","Z_proj(rINTT1) - Z_INTT1",100,-10.,10);
0027   hdZe0 = new TH1F("hdZe0","Z_proj(rINTT0) - Z_INTT0",100,-10.,10);
0028 
0029   hTopEmc_dphi = new TH1F("hTopEmc_dphi","Top_phi - Emc_phi",100,-0.1,0.1);
0030   hTopEmc_deta = new TH1F("hTopEmc_deta","Top_eta - Emc_eta",100,-0.1,0.1);
0031 
0032   hTopEmc_dphi_1 = new TH1F("hTopEmc_dphi_1","Top_phi - Emc_phi (r<93.6)",100,-0.1,0.1);
0033   hTopEmc_dphi_2 = new TH1F("hTopEmc_dphi_2","Top_phi - Emc_phi (93.6<r<218)",100,-0.1,0.1);
0034   hTopEmc_dphi_3 = new TH1F("hTopEmc_dphi_3","Top_phi - Emc_phi (218<r)",100,-0.5,0.5);
0035 
0036   hTopEmc_deta_1 = new TH1F("hTopEmc_deta_1","Top_eta - Emc_eta (r<93.6)",100,-0.1,0.1);
0037   hTopEmc_deta_2 = new TH1F("hTopEmc_deta_2","Top_eta - Emc_eta (93.6<r<218)",100,-0.1,0.1);
0038   hTopEmc_deta_3 = new TH1F("hTopEmc_deta_3","Top_eta - Emc_eta (218<r)",100,-0.5,0.5);
0039 
0040   hZvtxTrk  = new TH1F("hZvtxTrk","Zvtx projection of INTT_Calo track",100,-50,50);
0041   hdZvtxTrk = new TH1F("hdZvtxTrk","zgvtx - ZvtxTrk",200,-25,25);
0042   hZvtxTrk2  = new TH1F("hZvtxTrk2","Zvtx projection of INTT_Calo track",100,-50,50);
0043   hdZvtxTrk2 = new TH1F("hdZvtxTrk2","zgvtx - ZvtxTrk",200,-25,25);
0044   hZvtxTrk3  = new TH1F("hZvtxTrk3","Zvtx projection of INTT_Calo track",100,-50,50);
0045   hdZvtxTrk3 = new TH1F("hdZvtxTrk3","zgvtx - ZvtxTrk",200,-25,25);
0046   hZvtxTrk4  = new TH1F("hZvtxTrk4","Zvtx projection of INTT_Calo track",100,-50,50);
0047   hdZvtxTrk4 = new TH1F("hdZvtxTrk4","zgvtx - ZvtxTrk",200,-25,25);
0048 
0049   hTopE     = new TH1F("hTopE"," Energy of TopoCluster",100.,0,10.0);
0050   hp_Trk    = new TH1F("hp_Trk","p of INTT_Calo track",100,0.,10.);
0051   hptTrk    = new TH1F("hptTrk","pt of INTT_Calo track",100,0.,10.);
0052   hTopE_p   = new TH1F("hTopE_p","E(Top)/p(Trk)",120,-0.4,2.0);
0053   hEmcE_p   = new TH1F("hEmcE_p","E(Emc)/p(Trk)",120,-0.4,2.0);
0054 
0055   hTopE_p_Zvtx   = new TH1F("hTopE_p_Zvtx","E(Top)/p(Trk) w Zvtx cut",120,-0.4,2.0);
0056   hEmcE_p_Zvtx = new TH1F("hEmcE_p_Zvtx","E(Emc)/p(Trk) w Zvtx cut",120,-0.4,2.0);
0057 
0058   hrIntt_rsEmc  = new TH1F("hrIntt_rsEmc","rIntt/rsEmc",100,0.,2.0);
0059   hrIntt_rsEmc2 = new TH1F("hrIntt_rsEmc2","rIntt/rsEmc",100,0.,2.0);
0060   hrIntt_rsEmc3 = new TH1F("hrIntt_rsEmc3","rIntt/rsEmc",100,0.,2.0);
0061 
0062   hMvtx0_dr = new TH1F("hMvtx0_dr","rMvtx0 - rIntt",100,-0.25,0.25);
0063   hMvtx1_dr = new TH1F("hMvtx1_dr","rMvtx1 - rIntt",100,-0.25,0.25);
0064   hMvtx2_dr = new TH1F("hMvtx2_dr","rMvtx2 - rIntt",100,-0.25,0.25);
0065   hMvtx0_dz0 = new TH1F("hMvtx0_dz0","z0-zproj0",100,-10.,10.);
0066   hMvtx0_dz1 = new TH1F("hMvtx0_dz1","z1-zproj1",100,-10.,10.);
0067   hMvtx1_dz0 = new TH1F("hMvtx1_dz0","z0-zproj0",100,-10.,10.);
0068   hMvtx1_dz1 = new TH1F("hMvtx1_dz1","z1-zproj1",100,-10.,10.);  
0069   hMvtx2_dz0 = new TH1F("hMvtx2_dz0","z0-zproj0",100,-10.,10.);
0070   hMvtx2_dz1 = new TH1F("hMvtx2_dz1","z1-zproj1",100,-10.,10.);
0071 
0072   hMvtx0_dr2 = new TH1F("hMvtx0_dr2","rMvtx0 - rIntt (dz cut)",100,-0.25,0.25);
0073   hMvtx1_dr2 = new TH1F("hMvtx1_dr2","rMvtx1 - rIntt (dz cut)",100,-0.25,0.25);
0074   hMvtx2_dr2 = new TH1F("hMvtx2_dr2","rMvtx2 - rIntt (dz cut)",100,-0.25,0.25);
0075 
0076   hdphi_ij = new TH1F("hdphi_ij","dphi_i-dphi_j",160,-0.04,0.04);
0077   hdzvtx_ij = new TH1F("hdzvtx_ij","zvtx_i-zvtx_j",100,-10,10);
0078   hdphi_ij2 = new TH1F("hdphi_ij2","dphi_i-dphi_j(w dzvtx cut)",160,-0.04,0.04);
0079 }
0080 
0081 void INTT_Calo_trkReco_End(void) {
0082   hzgvtx->Write();
0083   hINTTdphi->Write();
0084   hINTTdZvtx->Write();
0085   hINTTdz0->Write();
0086   hINTTdz1->Write();
0087   hINTTdz0dz1->Write();
0088   hINTTdz0dz1r->Write();
0089   hINTTdz_r->Write();
0090   hInttPair_r->Write();
0091   hEmcIntt_dr->Write();
0092   hEmcIntt_dr_Zcut->Write();
0093   hEmcIntt_dr_Zvtx2->Write();
0094   hEmcIntt_dr_Zvtx4->Write();
0095   hEmcIntt_dr_Zvtx5->Write();
0096   hdZe1->Write();
0097   hdZe0->Write();
0098 
0099   hTopEmc_dphi->Write();
0100   hTopEmc_deta->Write();
0101   hTopEmc_dphi_1->Write();
0102   hTopEmc_dphi_2->Write();
0103   hTopEmc_dphi_3->Write();
0104   hTopEmc_deta_1->Write();
0105   hTopEmc_deta_2->Write();
0106   hTopEmc_deta_3->Write();
0107 
0108   hZvtxTrk->Write();
0109   hdZvtxTrk->Write();
0110   hZvtxTrk2->Write();
0111   hdZvtxTrk2->Write();
0112   hZvtxTrk3->Write();
0113   hdZvtxTrk3->Write();
0114   hZvtxTrk4->Write();
0115   hdZvtxTrk4->Write();
0116 
0117   hTopE->Write();
0118   hp_Trk->Write();
0119   hptTrk->Write();
0120   hTopE_p->Write();
0121   hEmcE_p->Write();
0122   
0123   hTopE_p_Zvtx->Write();
0124   hEmcE_p_Zvtx->Write();
0125 
0126   hrIntt_rsEmc->Write();
0127   hrIntt_rsEmc2->Write();
0128   hrIntt_rsEmc3->Write();
0129 
0130   hMvtx0_dr->Write();
0131   hMvtx1_dr->Write();
0132   hMvtx2_dr->Write();
0133 
0134   hMvtx0_dz0->Write();
0135   hMvtx0_dz1->Write();  
0136   hMvtx1_dz0->Write();
0137   hMvtx1_dz1->Write();  
0138   hMvtx2_dz0->Write();
0139   hMvtx2_dz1->Write();  
0140   
0141   hMvtx0_dr2->Write();
0142   hMvtx1_dr2->Write();
0143   hMvtx2_dr2->Write();
0144 
0145   hdphi_ij->Write();
0146   hdzvtx_ij->Write();
0147   hdphi_ij2->Write();
0148 }
0149 
0150 void INTT_Calo_trkReco(void) {
0151   hzgvtx->Fill(zgvtx);
0152 
0153   LoadTrackerData();
0154 
0155   Connect_Topo_and_Emc();
0156   
0157   FindInttPair();
0158   if(imode == 2) PrintInttPair();
0159   
0160   FindCaloIntt();
0161     
0162   FindInttMvtx();
0163   
0164   FindCaloInttMvtx();
0165 
0166 }
0167 
0168 //
0169 // support functions
0170 //
0171 bool Is_Hot_Emc(int iemc) {
0172   float phiEMC = emc_phi->at(iemc);
0173   float zEMC = emc_z->at(iemc);
0174   if( (2.4 < phiEMC && phiEMC < 2.7) && (zEMC < 0)) return true;
0175   else return false;
0176 }
0177 
0178 float rz2eta(float r,float z) {
0179   if(z>=0) {
0180     return log((sqrt(r*r+z*z)+z)/r);
0181   } else {
0182     return -log((sqrt(r*r+z*z)-z)/r);
0183   }
0184 }
0185 
0186 //
0187 // Major functions in INTT_Calo_trkReco()
0188 //
0189 void LoadTrackerData(void) {
0190   // clear vectors of the hits
0191   vEmc_r.clear();
0192   vEmc_phi.clear();
0193   vEmc_eta.clear();
0194   vEmc_z.clear();
0195   vEmc_e.clear();
0196 
0197   vTop_r.clear();
0198   vTop_phi.clear();
0199   vTop_eta.clear();
0200   vTop_z.clear();
0201   vTop_e.clear();
0202   vTop_emc_e.clear();
0203   vTop_ihc_e.clear();
0204   vTop_ohc_e.clear();
0205 
0206   vTop_emc_r.clear();
0207   vTop_emc_phi.clear();
0208   vTop_emc_eta.clear();
0209   vTop_emc_z.clear();
0210   vTop_emc_emc_e.clear();
0211 
0212   vINTT0r.clear();
0213   vINTT0phi.clear();
0214   vINTT0z.clear();
0215   
0216   vINTT1r.clear();
0217   vINTT1phi.clear();
0218   vINTT1z.clear();
0219 
0220   vMvtx0r.clear();
0221   vMvtx0phi.clear();
0222   vMvtx0z.clear();
0223 
0224   vMvtx1r.clear();
0225   vMvtx1phi.clear();
0226   vMvtx1z.clear();
0227 
0228   vMvtx2r.clear();
0229   vMvtx2phi.clear();
0230   vMvtx2z.clear();
0231 
0232   int nEmc = emc_r->size();
0233   int nTop = top_r->size();
0234   int nSiAll = a_layer->size();
0235   // store hits in the vectors with correction of (xBC, yBC)
0236 
0237   if(nEmc>0) {
0238     for(int iemc=0;iemc<nEmc;iemc++) {
0239       if(!Is_Hot_Emc(iemc)) {
0240     //  vEmc_r.push_back(emc_r->at(iemc));
0241     vEmc_r.push_back(R_Emc);
0242     vEmc_phi.push_back(emc_phi->at(iemc));
0243     vEmc_eta.push_back(emc_eta->at(iemc));
0244     vEmc_z.push_back(emc_z->at(iemc));
0245     vEmc_e.push_back(energy->at(iemc));
0246       }//if(!Is_Hot_Emc)
0247     }//for(iemc)
0248   }// if(nEmc)
0249 
0250   if(nTop>0) {
0251     for(int itop=0; itop < nTop ;itop++) {
0252       vTop_r.push_back(top_r->at(itop));
0253       vTop_phi.push_back(top_phi->at(itop));
0254       vTop_eta.push_back(top_eta->at(itop));
0255       vTop_z.push_back(top_z->at(itop));
0256       vTop_e.push_back(top_e->at(itop));
0257       vTop_emc_e.push_back(emc_e->at(itop));
0258       vTop_ihc_e.push_back(ihc_e->at(itop));
0259       vTop_ohc_e.push_back(ohc_e->at(itop));
0260     }//for(itop)
0261   }//if(nTop)
0262 
0263   if(nSiAll>0) {
0264     for(int is = 0; is< nSiAll ;is++) {
0265       int layer = a_layer->at(is);
0266       float xhit = a_si_x->at(is)-xBC;
0267       float yhit = a_si_y->at(is)-yBC;
0268       float zhit = a_si_z->at(is);
0269       float thit = a_si_t->at(is);
0270       float phi_hit = atan2(yhit,xhit);
0271       float rhit = sqrt(xhit*xhit+yhit*yhit);
0272       
0273       if(layer == 0) {
0274     vMvtx0r.push_back(rhit);
0275     vMvtx0phi.push_back(phi_hit);
0276     vMvtx0z.push_back(zhit);
0277     vMvtx0t.push_back(thit);
0278       } else if(layer == 1) {
0279     vMvtx1r.push_back(rhit);
0280     vMvtx1phi.push_back(phi_hit);
0281     vMvtx1z.push_back(zhit);
0282     vMvtx1t.push_back(thit);
0283       } else if(layer == 2) {
0284     vMvtx2r.push_back(rhit);
0285     vMvtx2phi.push_back(phi_hit);
0286     vMvtx2z.push_back(zhit);
0287     vMvtx2t.push_back(thit);
0288       } else if(layer == 3|| layer==4) {
0289     vINTT0r.push_back(rhit);
0290     vINTT0phi.push_back(phi_hit);
0291     vINTT0z.push_back(zhit);
0292     vINTT0t.push_back(thit);
0293       } else {
0294     vINTT1r.push_back(rhit);
0295     vINTT1phi.push_back(phi_hit);
0296     vINTT1z.push_back(zhit);
0297     vINTT1t.push_back(thit);
0298       }
0299     }//for(is)
0300   }//if(nSiAll)
0301 }
0302 
0303 
0304 void Connect_Topo_and_Emc(void) {
0305   // Connect TopoCluster and EmcCulser
0306   // In Topo Cluster, there are 4 energies:
0307   // e (total) = emcal_e + ihcal_e + ohcal_e
0308   //
0309   // Topocluser position is Top_r, Top_phi, Top_z
0310   // if ihcal_e = ohcal_e =0, then Top_r = R_emc_front
0311   // if emcal_e = ihcal_e =0, then Top_r = R_ohcal_front
0312   //
0313   
0314   const float R_emc_front = 93.55;  //R of front surface of Emcal
0315   const float R_ohcal_front = 218;  //R of front surface of oHCal
0316 
0317   const float sigma_dphi1 = 0.0036;
0318   const float sigma_deta1 = 0.0050;
0319   const float sigma_dphi2 = 0.0039;
0320   const float sigma_deta2 = 0.0053;
0321 
0322   int nTop = vTop_r.size();
0323   int nEmc = vEmc_r.size();
0324   /*
0325   if(imode==2) {
0326     cout << "nTop = "<<nTop<<endl;
0327     for(int it=0;it<nTop;it++) {
0328       cout << it <<": e="<<vTop_e.at(it);
0329       cout <<" emc_e="<<vTop_emc_e.at(it);
0330       cout <<" r= "<<vTop_r.at(it);
0331       cout << " phi= "<<vTop_phi.at(it);
0332       cout << " eta= "<<vTop_eta.at(it)<<endl; 
0333     }
0334     cout << "nEmc = "<<nEmc<<endl;
0335     for(int ie=0;ie<nEmc;ie++) {
0336       cout << ie <<": E="<<vEmc_e.at(ie);
0337       cout <<" r= "<<vEmc_r.at(ie);
0338       cout << " phi= "<<vEmc_phi.at(ie);
0339       cout << " eta= "<<vEmc_eta.at(ie)<<endl; 
0340     }    
0341   }
0342   */
0343   if(nTop>0) {
0344     for(int it=0;it<nTop;it++) {
0345       float Top_e = vTop_e.at(it);
0346       float Top_emc_e = vTop_emc_e.at(it);
0347       float Top_r = vTop_r.at(it);
0348       float Top_phi = vTop_phi.at(it);
0349       float Top_eta = vTop_eta.at(it);
0350 
0351       vTop_emc_r.push_back(-99);    //mark as empty
0352       vTop_emc_phi.push_back(-99);  //mark as empty
0353       vTop_emc_eta.push_back(-99);  //mark as empty
0354       vTop_emc_z.push_back(-99);    //mark as empty
0355       vTop_emc_emc_e.push_back(-99);//mark as empty
0356 
0357       if(Top_e > Top_E_min) {
0358     int iemc_match= -1;
0359     float sdr_min = 1000;
0360 
0361     if(nEmc>0) {
0362       //      if(imode==2) cout << "search for a Emc cluster for this Topo"<<endl;
0363       for(int ie=0;ie<nEmc;ie++) {
0364         float Emc_e = vEmc_e.at(ie);
0365 
0366         float Emc_r = vEmc_r.at(ie);
0367         float Emc_phi = vEmc_phi.at(ie);
0368         float Emc_eta = vEmc_eta.at(ie);
0369         float TopEmc_dphi = Top_phi - Emc_phi;
0370         float TopEmc_deta = Top_eta - Emc_eta;
0371         
0372         hTopEmc_dphi->Fill(TopEmc_dphi);
0373         hTopEmc_deta->Fill(TopEmc_deta);
0374         
0375         // find emc cluster that is closest to this Topo cluster
0376         if(abs(Top_phi-Emc_phi)<0.15 && abs(Top_eta-Emc_eta)<0.15&& Top_emc_e>0.18) {
0377           if(Top_r < R_emc_front) {
0378         //      if(imode == 2) cout << " r<93.5" <<endl;
0379         hTopEmc_dphi_1->Fill(TopEmc_dphi);
0380         hTopEmc_deta_1->Fill(TopEmc_deta);
0381         
0382         float sdphi = TopEmc_dphi/sigma_dphi1;
0383         float sdeta = TopEmc_deta/sigma_deta1;
0384         float sdr = sqrt(sdphi*sdphi+sdeta*sdeta);
0385         if(sdr < sdr_min) {
0386           iemc_match = ie;
0387           sdr_min = sdr;
0388         }
0389           } else if(Top_r < R_ohcal_front) {
0390         //      if(imode == 2) cout << " 93.5 < r < 218" <<endl;
0391         hTopEmc_dphi_2->Fill(TopEmc_dphi);
0392         hTopEmc_deta_2->Fill(TopEmc_deta);
0393         
0394         float sdphi = TopEmc_dphi/sigma_dphi2;
0395         float sdeta = TopEmc_deta/sigma_deta2;
0396         float sdr = sqrt(sdphi*sdphi+sdeta*sdeta);
0397         if(sdr < sdr_min) {
0398           iemc_match = ie;
0399           sdr_min = sdr;
0400         }
0401           } else {
0402         // in this case, there is no energy in emcal
0403         // So this TopoCLuster has no associated EMC cluser
0404         hTopEmc_dphi_3->Fill(TopEmc_dphi);
0405         hTopEmc_deta_3->Fill(TopEmc_deta);
0406           }//if(Top_r)  
0407         }//for(ie)
0408         // store closest Emc cluster info
0409         if(iemc_match>=0) {
0410           //if(imode==2) cout <<" Emc hit found: it="<<it<<" iemc= "<<iemc_match<<endl;
0411           vTop_emc_r.at(it)  = vEmc_r.at(iemc_match);
0412           vTop_emc_phi.at(it)= vEmc_phi.at(iemc_match);
0413           vTop_emc_eta.at(it)= vEmc_eta.at(iemc_match);
0414           vTop_emc_z.at(it)  = vEmc_z.at(iemc_match);
0415           vTop_emc_emc_e.at(it) = vEmc_e.at(iemc_match);
0416         }
0417       }//if(abs(Emc_e - Top_emc_e))
0418     }//if(nEmc)
0419       }//if( Top_E_min)
0420     }//for(it)
0421   }//if(nTop)
0422 }
0423 
0424 void FindInttPair(void) {
0425   const float dPhiMax = 0.05;  // dPhi cut to form Pair
0426   const float R_min = 60;     // minimum circle radius of INTTpair tracklet (cm)
0427                                // R_min=60 cm corresponds to pT>0.25 GeV/c
0428   const float dZvtx_max = 20.0;
0429 
0430   
0431   int nINTT1=vINTT1phi.size();
0432   int nINTT0=vINTT0phi.size();
0433 
0434   vInttPair.clear();
0435   if(nINTT0>0 && nINTT1>0) {
0436     for(int i1=0;i1<nINTT1;i1++){
0437       for(int i0=0;i0<nINTT0;i0++){
0438     float dphi = vINTT1phi.at(i1)-vINTT0phi.at(i0);
0439     if(abs(dphi)<0.1) hINTTdphi->Fill(dphi);
0440       
0441     if(abs(dphi)<dPhiMax) {
0442       // Get the hit position of INTT0 and INTT1
0443       float r0   = vINTT0r.at(i0);
0444       float phi0 = vINTT0phi.at(i0);
0445       float z0   = vINTT0z.at(i0);
0446       float r1   = vINTT1r.at(i1);
0447       float phi1 = vINTT1phi.at(i1);
0448       float z1   = vINTT1z.at(i1);
0449       float x0 = r0*cos(phi0);
0450       float y0 = r0*sin(phi0);
0451       float x1 = r1*cos(phi1);
0452       float y1 = r1*sin(phi1);
0453 
0454       // calculate the radius of the circle passing through
0455       // INTT1(x1,y1), INTT0(x0,y0), and the origin (0.,0.).
0456       // Note that the orign was shifted by (xBC, yBC) when
0457       // r0,phi0, r1, and phi1 are calculated. Therefore,
0458       // the circle passes through INTT1, INTT0, and (xBC, yBC)
0459       //
0460       float r;   // radius of the circle
0461       float xc;  // center of the circle (xc,yc)
0462       float yc;
0463       CalcCircle2(x1,y1,x0,y0,r,xc,yc);
0464       //
0465       // examine if the pair is caused by a track
0466       // coming from gzvtx
0467       //
0468       float dzdr = ((z0+z1)-2.0*gzvtx)/(r0+r1);
0469       float z0proj = zgvtx + r0*dzdr;
0470       float z1proj = zgvtx + r1*dzdr;
0471       float dzdr2 = (z1-z0)/(r1-r0);
0472       float zvtx_intt = z0-r0*dzdr2;
0473 
0474       const float alpha = 0.75;
0475       if(r > R_min) {
0476         hINTTdZvtx->Fill(zvtx_intt-zgvtx);
0477         if(abs(zvtx_intt-zgvtx)< dZvtx_max) {
0478           hINTTdz0->Fill(z0-z0proj);
0479           hINTTdz1->Fill(z1-z1proj);
0480           hINTTdz0dz1->Fill(z0-z0proj,z1-z1proj);
0481           hINTTdz0dz1r->Fill(z0-z0proj-alpha*(z1-z1proj),z1-z1proj);
0482           hINTTdz_r->Fill(z0-z0proj-alpha*(z1-z1proj));
0483       
0484           InttPair new_pair;
0485           new_pair.iINTT0 = i0;
0486           new_pair.iINTT1 = i1;
0487           new_pair.r = r;
0488           new_pair.xc = xc;
0489           new_pair.yc = yc;
0490           new_pair.z  = z0;
0491           new_pair.zvtx =  zvtx_intt;
0492           vInttPair.push_back(new_pair);
0493         }//if(dzvtx)
0494       }//if(Rmin)
0495     }//if(dphi)
0496       }//for(i0)
0497     }//for(i1)
0498     //
0499     // now INTT-Pair candidates are found. But some of them are caused
0500     // by the same charged track because both INTT0 and INTT1 has two
0501     // sub-layers. Remove those "duplicated pairs".
0502     //
0503     int npair_found = vInttPair.size();
0504     if(npair_found > 1) {
0505       for(int ipair=0; ipair<npair_found; ipair++) {
0506     InttPair pair_i = vInttPair.at(ipair);
0507     for(int jpair=ipair+1;jpair<npair_found; jpair++) {
0508       InttPair pair_j = vInttPair.at(jpair);
0509       RemoveDuplicatedPair(pair_i, pair_j);
0510     }//for(jpair)
0511       }//for(ipair)
0512     }//if(npair_found)
0513   }//if(nINTT0, nINTT1)
0514 }
0515 
0516 void RemoveDuplicatedPair(InttPair &pair_i, InttPair &pair_j) {
0517   // Determine if pair_i and pair_j are "the same", and if they are,
0518   // removed one of them.
0519   int INTT0_i = pair_i.iINTT0;
0520   int INTT1_i = pair_i.iINTT1;
0521   int INTT0_j = pair_j.iINTT0;
0522   int INTT1_j = pair_j.iINTT1;
0523 
0524   float dphi_i = vINTT1phi.at(INTT1_i) - vINTT0phi.at(INTT0_i);
0525   float dphi_j = vINTT1phi.at(INTT1_j) - vINTT0phi.at(INTT0_j);
0526   float zvtx_i = pair_i.zvtx;
0527   float zvtx_j = pair_j.zvtx;
0528 
0529   hdphi_ij->Fill(dphi_i - dphi_j);
0530   hdzvtx_ij->Fill(zvtx_i-zvtx_j);
0531   if(abs(zvtx_i-zvtx_j)<0.06) {
0532     hdphi_ij2->Fill(dphi_i - dphi_j);
0533     pair_j.r=-99;
0534   }
0535 }
0536 
0537 void PrintInttPair(void) {
0538   int nPair = vInttPair.size();
0539   if(nPair>0) {
0540     for(int i=0;i<nPair; i++) {
0541       InttPair pair = vInttPair.at(i);
0542       int i0=pair.iINTT0;
0543       int i1=pair.iINTT1;
0544       float r = pair.r;
0545       float phi0 = vINTT0phi.at(i0);
0546       float phi1 = vINTT1phi.at(i1);
0547     }//for(i)
0548   }//if(nPair)
0549 }
0550 
0551 void CalcCircle2(float x1,float y1,float x0, float y0,
0552          float &r, float &xc, float &yc) {
0553   float r0  = sqrt(x0*x0+y0*y0);
0554   float r01 =  sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
0555   float t = 0.5*x1/((y1-y0)/r01-y0/r0);
0556   xc = 0.5*x0 - t*y0/r0;
0557   yc = 0.5*y0 + t*x0/r0;
0558   r  = sqrt((x0-xc)*(x0-xc)+(y0-yc)*(y0-yc));
0559 }
0560 
0561 void CalcCircle(double xs0, double ys0, double xs1, double ys1,double xs2, double ys2,
0562         float &rs, float &xsc, float &ysc) {
0563   //
0564   // calclate the radius of the p0-p1-p2 circle. It is assumed that r0<r1<r2
0565   //
0566   
0567   double r12 = sqrt((xs2-xs1)*(xs2-xs1)+(ys2-ys1)*(ys2-ys1));
0568   double r01 = sqrt((xs1-xs0)*(xs1-xs0)+(ys1-ys0)*(ys1-ys0));
0569   double ts = 0.5*(xs2-xs0)/((ys2-ys1)/r12-(ys1-ys0)/r01);
0570   
0571   xsc = 0.5*(xs0+xs1)-ts*(ys1-ys0)/r01;
0572   ysc = 0.5*(ys0+ys1)+ts*(xs1-xs0)/r01;
0573   rs  = sqrt((xs0-xsc)*(xs0-xsc)+(ys0-ysc)*(ys0-ysc));
0574 }
0575 
0576 float Calc_Remc(float xe, float ye, float x1,float y1, float x0, float y0, float xc, float yc) {
0577   float xm = 0.5*(x1+x0);
0578   float ym = 0.5*(y1+y0);
0579   float ux = xm-xc;
0580   float uy = ym-yc;
0581   float ru = sqrt(ux*ux+uy*uy);
0582   float vx = x1-x0;
0583   float vy = y1-y0;
0584   float rv = sqrt(vx*vx+vy*vy);
0585   // normalize the u and v vector
0586   ux = ux/ru;
0587   uy = uy/ru;
0588   vx = vx/rv;
0589   vy = vy/rv;
0590 
0591   float h = vx*(xe-xc) + vy*(ye-yc);
0592   float d = ux*(xm-xe)+uy*(ym-ye);
0593 
0594   return 0.5*(d*d+h*h)/d;
0595 }
0596 
0597 void FindCaloIntt(void) {
0598   // find Topo Clusters that match the INTT pair tracklet
0599   //
0600   // analysis constants
0601   const float rIntt_min = 200.; //cm. 100cm corresponds to pT>0.84 GeV/c
0602   const float dRoffset = -1.0;
0603   const float dRcut = 18.0;
0604   const float dRcut_narrow = 10.0;
0605   const float dZvtxCut   = 1.2;
0606   const float dZvtx_narrow = 1.0;
0607 
0608   int nTop = vTop_r.size();
0609   int nPair= vInttPair.size();
0610 
0611   vCaloInttMvtx.clear();
0612   
0613   if(nTop>0 && nPair>0) {
0614     for(int ip=0;ip<nPair;ip++) {
0615       // For each of InttPair tracklet, search for TopClusters that is
0616       // close to the projection point of the tracklet.
0617       // if multiple Top Clusters are found in the search area, all of them
0618       // are added to the tracklet.
0619       InttPair pair=vInttPair.at(ip);
0620       float rIntt = pair.r;
0621       float xc = pair.xc;  //(xc,yc) is the center of the circule
0622       float yc = pair.yc;  // passing through INTT1,INTT0 and (xBC,yBC)
0623       
0624       if(rIntt > rIntt_min) {
0625     int i0=pair.iINTT0;
0626     int i1=pair.iINTT1;
0627     
0628     float r0   = vINTT0r.at(i0);
0629     float phi0 = vINTT0phi.at(i0);
0630     float Z0   = vINTT0z.at(i0);
0631     float r1   = vINTT1r.at(i1);
0632     float phi1 = vINTT1phi.at(i1);
0633     float Z1   = vINTT1z.at(i1);
0634     float x0   = r0*cos(phi0); //hit position (x0,y0) of INTT0
0635     float y0   = r0*sin(phi0);
0636     float x1   = r1*cos(phi1); //hit position (x1,y1) of INTT1
0637     float y1   = r1*sin(phi1);
0638     float xm   = x1/2.; // mid-point (xm,ym) of INTT1 and (0,0)
0639     float ym   = y1/2.;
0640     float r_cm = sqrt((xc-xm)*(xc-xm)+(yc-ym)*(yc-ym));
0641     float uxc  = (xc-xm)/r_cm; //(uxc,uyc) is the unit direction vector from
0642     float uyc  = (yc-ym)/r_cm; //(xm,ym) to (xc,yc)
0643     
0644     // Search for a TopoCluster that is close to the projection point of
0645     // the INTT_pair track.
0646     // vector of index of topoClusters that are in the search window.
0647     vector<int>   vTop_in_window;
0648     vector<float> vrsEmc;
0649     vector<float> vxsc;
0650     vector<float> vysc;
0651     vector<float> vZvtxTrk;
0652     vector<float> vptTrk;
0653     vector<float> vpzTrk;
0654     for(int it=0;it<nTop;it++) {
0655       if(vTop_e.at(it) > Top_E_min) {
0656         // Cut variables in R-phi space
0657         float Emc_emc_e = vTop_emc_emc_e.at(it);
0658         if(Emc_emc_e>0.1) { // an Emc cluster is associated with this Topo Cluster
0659           float total_e = vTop_e.at(it);
0660           float emcal_e = vTop_emc_e.at(it);
0661           float ihcal_e = vTop_ihc_e.at(it);
0662           float ohcal_e = vTop_ohc_e.at(it);
0663           float R_t = vTop_r.at(it);
0664               float R_e = vTop_emc_r.at(it);
0665           float phi_t = vTop_phi.at(it);
0666           float phi_e = vTop_emc_phi.at(it);
0667           float Z_t   = vTop_z.at(it);
0668           
0669           float xe = R_e*cos(phi_e);
0670           float ye = R_e*sin(phi_e);
0671           float ze = vTop_emc_z.at(it);
0672           float le = sqrt(xe*xe+ye*ye+ze*ze);
0673           
0674           float rEmc = sqrt((xe-xc)*(xe-xc)+(ye-yc)*(ye-yc));
0675 
0676           // Cut variables in RZ space
0677           //
0678           float Ze = vTop_emc_z.at(it);
0679           float Z1p = ((Ze-0.5*(Z0+Z1))/(R_e-0.5*(r0+r1)))*(r1-0.5*(r0+r1))+0.5*(Z0+Z1);
0680           float Z0p = ((Ze-0.5*(Z0+Z1))/(R_e-0.5*(r0+r1)))*(r0-0.5*(r0+r1))+0.5*(Z0+Z1);
0681           float ZvtxTrk = ((Ze-0.5*(Z0+Z1))/(R_e-0.5*(r0+r1)))*(-0.5*(r0+r1))+0.5*(Z0+Z1);
0682           float dZe1 = Z1p-Z1;
0683           float dZe0 = Z0p-Z0;
0684           float dZ1max = 1.1;
0685           float dZ0max = 1.1;
0686           if(abs(Z1)<12.9) dZ1max = 0.9;
0687           if(abs(Z0)<12.9) dZ0max = 0.9;
0688           
0689           hZvtxTrk->Fill(ZvtxTrk);
0690           hdZvtxTrk->Fill(zgvtx-ZvtxTrk);
0691           
0692           // Cuts in R-phi space
0693           if(abs(rEmc-rIntt - dRoffset) < dRcut) {
0694         //
0695         // a maching Topo cluster is found in Rphi plane.
0696         //
0697         hdZe1->Fill(dZe1);
0698         hdZe0->Fill(dZe0);
0699         hZvtxTrk2->Fill(ZvtxTrk);
0700         hdZvtxTrk2->Fill(zgvtx-ZvtxTrk);
0701 
0702         // Cuts in RZ space
0703         if(abs(dZe1)<dZ1max && abs(dZe0)<dZ0max) {
0704           //
0705           // Topo-INTT1-INTT0 is consisent with a straight line in RZ space
0706           //
0707           hZvtxTrk4->Fill(ZvtxTrk);
0708           hdZvtxTrk4->Fill(zgvtx-ZvtxTrk);
0709           if(abs(zgvtx-ZvtxTrk)<dZvtxCut) { // 
0710             //
0711             // A TopoCluster in the search window is found.
0712             //
0713             float rsEmc;
0714             float xsc;
0715             float ysc;
0716             // Calclualte the radius etc of the circle passing through
0717             // (0,0)-INTT0-Topo
0718             //
0719             CalcCircle(x0,y0,x1,y1,xe,ye, rsEmc, xsc, ysc);
0720             float ptTrk   = 0.0042*rsEmc;
0721             float p_Trk   = ptTrk*le/R_e;       
0722             float pzTrk   = ptTrk*(ze-ZvtxTrk)/R_e;
0723 
0724             // store the index of the topoCluter in the window and
0725             // the information of the Calo-INTT tracklet
0726             vTop_in_window.push_back(it);  // index of topocluster
0727             vrsEmc.push_back(rsEmc);    // radius of the circle orbit
0728             vxsc.push_back(xsc);        // (xsc,ysc) is center of the circle
0729             vysc.push_back(ysc);
0730             vZvtxTrk.push_back(ZvtxTrk);// Projected zvtx position of the track
0731             vptTrk.push_back(ptTrk);    // pT of the track
0732             vpzTrk.push_back(pzTrk);    // pz of the track
0733             //
0734             // the following part is to monitor the code. To be removed later
0735             //
0736             hrIntt_rsEmc->Fill(rIntt/rsEmc);
0737             if(abs(zgvtx-ZvtxTrk)<dZvtx_narrow) {
0738               hrIntt_rsEmc2->Fill(rIntt/rsEmc);
0739               if(abs(rEmc-rIntt - dRoffset) < dRcut_narrow) {
0740             hrIntt_rsEmc3->Fill(rIntt/rsEmc);
0741               }//if(dRcut_narrow)
0742             }//if(dZvtx_narrow)
0743             hptTrk->Fill(ptTrk);
0744             hTopE->Fill(total_e);
0745             hp_Trk->Fill(p_Trk);
0746             hTopE_p->Fill(total_e/p_Trk);
0747             hEmcE_p->Fill(emcal_e/p_Trk);
0748             hTopE_p_Zvtx->Fill(total_e/p_Trk);
0749             hEmcE_p_Zvtx->Fill(emcal_e/p_Trk);
0750           }//if(abs(zgvtx-ZvtxTrk)
0751         }//if(dZe1 && dZe0)
0752         //
0753         // the following part is to check the cut efficiency
0754         //
0755         if(abs(dZe1)<dZ1max && abs(dZe0)< dZ0max) {
0756           hEmcIntt_dr_Zvtx2->Fill(rEmc-rIntt);
0757         }
0758           }//if(abs()
0759           //
0760           // the following part is to check the cut efficiency
0761           //
0762           hEmcIntt_dr->Fill(rEmc-rIntt);
0763           if(abs(dZe1)<dZ1max && abs(dZe0)<dZ0max) {
0764         hEmcIntt_dr_Zcut->Fill(rEmc-rIntt);
0765         hZvtxTrk3->Fill(ZvtxTrk);
0766         hdZvtxTrk3->Fill(zgvtx-ZvtxTrk);
0767         if(abs(zgvtx-ZvtxTrk)<dZvtxCut) {
0768           hEmcIntt_dr_Zvtx4->Fill(rEmc-rIntt);
0769         }
0770         if(abs(zgvtx-ZvtxTrk)<dZvtx_narrow) {
0771           hEmcIntt_dr_Zvtx5->Fill(rEmc-rIntt);
0772         }
0773           }
0774         }// if(Emc_emc_e)
0775       }// if(Top_E_min)
0776     }// for(it) 
0777     int ntop_found = vTop_in_window.size();
0778     
0779     if(ntop_found > 0) {
0780       // this INTT_pair tracklet is associated with at least one
0781       // Emc hit. So Calo-INTT track is formed.
0782       // store the information of the track
0783       //
0784       // if more than 1 cluster is associated with the tracklet
0785       // the cluster that is closest to the original INTT-Pair track
0786       // is chosen.
0787       int i_dr_min = 0;
0788       float dr_min = abs(vrsEmc.at(0)-rIntt);  //difference of r_emc_intt and r_intt
0789       
0790       for(int i = 0; i < ntop_found; i++) {
0791         if(abs(vrsEmc.at(i)-rIntt)< dr_min) {
0792           i_dr_min = i;
0793           dr_min = abs(vrsEmc.at(i)-rIntt);
0794         }//if
0795       }//for(i)
0796       // cluster with largest emcal_e is selected. Store the data
0797       //
0798       int sign=1;
0799       if(phi1>phi0) sign = -1;
0800 
0801       // create a CaloInttMvtx track and fill its "Calo-INTT" part
0802       int itop = vTop_in_window.at(i_dr_min);
0803       float r_emc = vTop_emc_r.at(itop);
0804       float phi_emc = vTop_emc_phi.at(itop);
0805       float xemc = r_emc*cos(phi_emc);
0806       float yemc = r_emc*sin(phi_emc);
0807       
0808       a_CaloInttMvtx.iTop = itop;
0809       a_CaloInttMvtx.iINTT0 = i0;
0810       a_CaloInttMvtx.iINTT1 = i1;
0811       a_CaloInttMvtx.iMvtx0 = -99;
0812       a_CaloInttMvtx.iMvtx1 = -99;
0813       a_CaloInttMvtx.iMvtx2 = -99;
0814       a_CaloInttMvtx.sign   = sign;
0815       a_CaloInttMvtx.r_intt  = pair.r;  //=rIntt
0816       a_CaloInttMvtx.xc_intt = pair.xc; //=xc
0817       a_CaloInttMvtx.yc_intt = pair.yc; //=yc
0818       a_CaloInttMvtx.z_intt  = pair.z;  //=Z0
0819       a_CaloInttMvtx.zvtx_intt   = pair.zvtx;
0820       a_CaloInttMvtx.r_emc_intt  = vrsEmc.at(i_dr_min);
0821       a_CaloInttMvtx.xc_emc_intt = vxsc.at(i_dr_min);
0822       a_CaloInttMvtx.yc_emc_intt = vysc.at(i_dr_min);
0823       a_CaloInttMvtx.zvtx_emc_intt = vZvtxTrk.at(i_dr_min);
0824       a_CaloInttMvtx.r_intt_mvtx    = -99;
0825       a_CaloInttMvtx.xc_intt_mvtx   = -99;
0826       a_CaloInttMvtx.yc_intt_mvtx   = -99;
0827       a_CaloInttMvtx.zvtx_intt_mvtx = -99;
0828       a_CaloInttMvtx.xemc = xemc;
0829       a_CaloInttMvtx.yemc = yemc;
0830       a_CaloInttMvtx.zemc = vTop_emc_z.at(itop);
0831       a_CaloInttMvtx.total_e = vTop_e.at(itop);
0832       a_CaloInttMvtx.emcal_e = vTop_emc_e.at(itop);
0833       a_CaloInttMvtx.ihcal_e = vTop_ihc_e.at(itop);
0834       a_CaloInttMvtx.ohcal_e = vTop_ohc_e.at(itop);
0835       a_CaloInttMvtx.emc_e   = vTop_emc_emc_e.at(itop);
0836       a_CaloInttMvtx.BDT_e   = -99;  // not calucalted yet
0837       a_CaloInttMvtx.x0e   = 0.0;
0838       a_CaloInttMvtx.y0e   = 0.0;
0839       a_CaloInttMvtx.z0e   = vZvtxTrk.at(i_dr_min);
0840       a_CaloInttMvtx.pt0e  = vptTrk.at(i_dr_min);
0841       a_CaloInttMvtx.phi0e = phi0 + sign*r0/vrsEmc.at(i_dr_min);
0842       a_CaloInttMvtx.pz0e  = vpzTrk.at(i_dr_min);
0843       a_CaloInttMvtx.x0m   = -99;
0844       a_CaloInttMvtx.y0m   = -99;
0845       a_CaloInttMvtx.z0m   = -99;
0846       a_CaloInttMvtx.pt0m  = -99;
0847       a_CaloInttMvtx.phi0m = -99;
0848       a_CaloInttMvtx.pz0m  = -99;
0849 
0850       vCaloInttMvtx.push_back(a_CaloInttMvtx);
0851     }//if(ntop_found)
0852       }// if(rIntt)
0853     }// for(ip)
0854   }//if(nTop, nPair)
0855   int ntrk_found = vCaloInttMvtx.size();
0856   //  if(ntrk_found>0) cout << i_event << ": ntrk_found = "<<ntrk_found<<endl;
0857 }
0858 
0859 void FormInttMvtxTrk(float r0, float phi0, float z0,float r1, float phi1,float z1,
0860          int iMvtx0,int iMvtx1,int iMvtx2,
0861          float &r_intt_mvtx, float &xc_intt_mvtx, float &yc_intt_mvtx,
0862          float& zvtx_intt_mvtx,
0863          float &x0m, float &y0m, float &z0m, float &pt0m,float& phi0m, float &pz0m) {
0864   float xs0;  //INTT0 (x,y)
0865   float ys0;
0866   float xs1;  //The outermost Mvtx hit
0867   float ys1;
0868   float xs2;  //The innermost Mvtx hit or the origin
0869   float ys2;
0870   float xsc;
0871   float ysc;
0872 
0873   if(imode == 2) {
0874     cout << "FormInttMvtxTrk (old)"<<endl;
0875     cout << "iMvtx0 = "<<iMvtx0<<" iMvtx1 = "<<iMvtx1<<" iMvtx2 = "<<iMvtx2<<endl;
0876   }
0877   // Create a INTT0-Mvtx track
0878   //
0879   // (xs0,ys0) is (x,y) of INTT0
0880   //
0881   xs0 = r0*cos(phi0);
0882   ys0 = r0*sin(phi0);
0883   
0884   float rs0 = sqrt(xs0*xs0+ys0*ys0);
0885   // (xs1,ys1) -- The outer-most Mvts hit.
0886   // Note that actual hit is indicated by non-negative index.
0887   // From outside (Mvtx2) to inside (Mvtx0), look for a hit.
0888   float rs1;
0889   float phis1;
0890   float zs1;
0891   
0892   if(iMvtx2>=0) { // Mvtx2 has a hit.
0893     rs1   = vMvtx2r.at(iMvtx2);
0894     phis1 = vMvtx2phi.at(iMvtx2);
0895     zs1   = vMvtx2z.at(iMvtx2);
0896   } else if(iMvtx1>=0) {
0897     rs1   = vMvtx1r.at(iMvtx1);
0898     phis1 = vMvtx1phi.at(iMvtx1);
0899     zs1   = vMvtx1z.at(iMvtx1);   
0900   } else {
0901     rs1   = vMvtx0r.at(iMvtx0);
0902     phis1 = vMvtx0phi.at(iMvtx0);
0903     zs1   = vMvtx0z.at(iMvtx0);
0904   }
0905   xs1 = rs1*cos(phis1);
0906   ys1 = rs1*sin(phis1);
0907   
0908   // (xs2,ys2) -- The inner-most Mvtx hit or (0,0) if only one Mvtx hit
0909   float rs2;
0910   float phis2;
0911   float zs2;
0912   float dzdr;
0913   if(iMvtx0>=0) {//Mvtx0 is the inner-most hit
0914     if(iMvtx1<0 && iMvtx2 <0) {//Mvtx0 is the only hit
0915       rs2=0;
0916     } else {
0917       rs2=vMvtx0r.at(iMvtx0);
0918     }
0919     phis2=vMvtx0phi.at(iMvtx0);
0920     zs2=vMvtx0z.at(iMvtx0);
0921   } else if(iMvtx1>=0) {// Mvtx1 is the inner-most hit
0922     if(iMvtx2<0) {
0923       rs2=0;
0924     } else {
0925       rs2=vMvtx1r.at(iMvtx1);
0926     }
0927     phis2=vMvtx1phi.at(iMvtx1);
0928     zs2=vMvtx1z.at(iMvtx1);
0929   } else {//this means that Mvtx2 is the only hit
0930     rs2=0;
0931     phis2=vMvtx2phi.at(iMvtx2);
0932     zs2=vMvtx2z.at(iMvtx2);
0933   }
0934 
0935   if(rs2==0) {//there is only one Mvtx hit
0936     xs2=0;
0937     ys2=0;
0938     float rintt = 0.5*(r0+r1);
0939     float zintt = 0.5*(z0+z1);
0940     float rmvtx = rs1;
0941     float zmvtx = zs1;
0942     dzdr = (zintt-zmvtx)/(rintt-rmvtx);
0943     zvtx_intt_mvtx = zmvtx - dzdr*rmvtx;
0944   } else {
0945     // there are at least two Mvtx hit.
0946     // Outermost hit is (rs1,phis1,zs1)
0947     // Innermost hit is (rs2,phis2,zs2)
0948     xs2=rs2*cos(phis2);
0949     ys2=rs2*sin(phis2);
0950     float r_out = rs1;
0951     float r_in  = rs2;
0952     float z_out = zs1;
0953     float z_in  = zs2;
0954     dzdr  = (z_out - z_in)/(r_out - r_in);
0955     zvtx_intt_mvtx = z_in - dzdr*r_in;
0956   }
0957 
0958   // Draw a circle passing through (xs0,ys0)-(xs1,ys1)-(xs2,ys2)
0959   // and get its radius (r_intt_mvtx) and the center (xs2,ys2) 
0960   //    CalcCircle(xs0,ys0,xs1,ys1,xs2,ys2,
0961   CalcCircle(xs2,ys2,xs1,ys1,xs0,ys0,
0962          r_intt_mvtx, xc_intt_mvtx, yc_intt_mvtx);
0963   //
0964   x0m= xs2;
0965   y0m= ys2;
0966   z0m= zs2;
0967   pt0m= 0.0042*r_intt_mvtx;
0968   phi0m=phis2;
0969   pz0m= dzdr*pt0m;
0970 }
0971 
0972 void FormInttMvtxTrk(float r0, float phi0, float z0,float r1, float phi1,float z1,
0973              vector<int> &vMvtx0Hit, vector<int> &vMvtx1Hit,vector<int> &vMvtx2Hit,
0974              int &iMvtx0, int & iMvtx1, int &iMvtx2,
0975              float &r_intt_mvtx, float &xc_intt_mvtx, float &yc_intt_mvtx,
0976              float& zvtx_intt_mvtx,
0977              float &x0m, float &y0m, float &z0m, float &pt0m,float& phi0m, float &pz0m) {
0978   int nMvtx0 = vMvtx0Hit.size();
0979   int nMvtx1 = vMvtx1Hit.size();
0980   int nMvtx2 = vMvtx2Hit.size();
0981 
0982   float x0 = r0*cos(phi0);
0983   float y0 = r0*sin(phi0);
0984   float x1 = r1*cos(phi1);
0985   float y1 = r1*sin(phi1);
0986 
0987   if(imode == 2) {
0988     cout << "nMvtx0="<<nMvtx0<<" nMvtx1= "<<nMvtx1<<" nMvtx2="<<nMvtx2<<endl;
0989   }
0990   // Case 1: one Mvtx layer has associated hits
0991   if(nMvtx0>1 && nMvtx1 ==0 && nMvtx2 == 0) {
0992     FormInttMvtxTrk1(x0,y0,z0,x1,y1,z1,vMvtx0Hit,
0993              vMvtx0r,vMvtx0phi,vMvtx0z,
0994              iMvtx0,
0995              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
0996              zvtx_intt_mvtx,
0997              x0m, y0m, z0m, pt0m, phi0m, pz0m);
0998   }
0999 
1000   if(nMvtx0==0 && nMvtx1 > 0 && nMvtx2 == 0) {
1001     FormInttMvtxTrk1(x0,y0,z0,x1,y1,z1,vMvtx1Hit,
1002              vMvtx1r,vMvtx1phi,vMvtx1z,
1003              iMvtx1,
1004              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1005              zvtx_intt_mvtx,
1006              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1007   }
1008   
1009   if(nMvtx0 == 0 && nMvtx1 ==0 && nMvtx2 > 0) {
1010     FormInttMvtxTrk1(x0,y0,z0,x1,y1,z1,vMvtx2Hit,
1011              vMvtx2r,vMvtx2phi,vMvtx2z,
1012              iMvtx2,
1013              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1014              zvtx_intt_mvtx,
1015              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1016   }
1017 
1018   // Case 2: two Mvtx layers have associated hits
1019   if(nMvtx0>1 && nMvtx1 >0 && nMvtx2 == 0) {
1020     FormInttMvtxTrk2(x0,y0,z0,x1,y1,z1,vMvtx0Hit,vMvtx1Hit,
1021              vMvtx0r,vMvtx0phi,vMvtx0z,
1022              vMvtx1r,vMvtx1phi,vMvtx1z,
1023              iMvtx0, iMvtx1,
1024              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1025              zvtx_intt_mvtx,
1026              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1027   }
1028 
1029   if(nMvtx0>1 && nMvtx1 ==0 && nMvtx2 > 0) {
1030     FormInttMvtxTrk2(x0,y0,z0,x1,y1,z1,vMvtx0Hit,vMvtx2Hit,
1031              vMvtx0r,vMvtx0phi,vMvtx0z,
1032              vMvtx2r,vMvtx2phi,vMvtx2z,
1033              iMvtx0, iMvtx2,
1034              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1035              zvtx_intt_mvtx,
1036              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1037   }
1038 
1039   if(nMvtx0 == 0 && nMvtx1 >0 && nMvtx2 > 0) {
1040     FormInttMvtxTrk2(x0,y0,z0,x1,y1,z1,vMvtx1Hit,vMvtx2Hit,
1041              vMvtx1r,vMvtx1phi,vMvtx1z,
1042              vMvtx2r,vMvtx2phi,vMvtx2z,
1043              iMvtx1, iMvtx2,
1044              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1045              zvtx_intt_mvtx,
1046              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1047   }
1048 
1049   // Case 3: all three Mvtx layers have associated hits
1050   if(nMvtx0 > 0 && nMvtx1 >0 && nMvtx2 > 0) {
1051     FormInttMvtxTrk3(x0,y0,z0,x1,y1,z1,vMvtx0Hit,vMvtx1Hit,vMvtx2Hit,
1052              iMvtx0,iMvtx1,iMvtx2,
1053              r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1054              zvtx_intt_mvtx,
1055              x0m, y0m, z0m, pt0m, phi0m, pz0m);
1056   }    
1057 }
1058 
1059 void FormInttMvtxTrk1(float x0, float y0, float z0,float x1, float y1,float z1,
1060               vector<int> &vMvtxHit,
1061               vector<float> &vMvtx_r, vector<float> &vMvtx_phi, vector<float> &vMvtx_z,
1062               int &iMvtxHit,
1063               float &rc_intt_mvtx, float &xc_intt_mvtx, float &yc_intt_mvtx,
1064               float& zvtx_intt_mvtx,
1065               float &x0m, float &y0m, float &z0m, float &pt0m,float& phi0m, float &pz0m) {
1066   //There is only one Mvtx layer that has associated hits.
1067   //Form a track of (INTT1-INTT0-Mvtx-BC) and select the best hit in Mvtx.
1068   int nMvtx = vMvtxHit.size();
1069   float dr2_min = 100000;
1070   int   im_min = -1;
1071   float rc_min = 100000;
1072   float xc_min = 100000;
1073   float yc_min = 100000;
1074 
1075   if(imode == 2) {
1076     cout << "FormTrk1"<<endl;
1077     cout << "nMvtx="<<nMvtx<<endl;
1078   }
1079 
1080   for(int im=0;im<nMvtx;im++) {
1081     float r_m  = vMvtx_r.at(vMvtxHit.at(im));
1082     float phi_m= vMvtx_phi.at(vMvtxHit.at(im));
1083     float xm= r_m*cos(phi_m);
1084     float ym= r_m*sin(phi_m);
1085     float zm= vMvtx_z.at(vMvtxHit.at(im));
1086     float r1;
1087     float xc1;
1088     float yc1;
1089     float r2;
1090     float xc2;
1091     float yc2;
1092   
1093   // Mvtx-INTT0-INTT1 Circle
1094     CalcCircle(xm,ym,x0,y0,x1,y1, r1,xc1,yc1);
1095   
1096   // BC(0,0)-Mvtx-INTT0 Circle
1097     CalcCircle( 0, 0,xm,ym,x0,y0, r2,xc2,yc2);
1098 
1099     float xc = 0.5*(xc1+xc2);
1100     float yc = 0.5*(yc1+yc2);
1101 
1102     float rc1= sqrt(xc*xc+yc*yc);
1103     float rc2= sqrt((xm-xc)*(xm-xc) + (ym-yc)*(ym-yc));
1104     float rc3= sqrt((x0-xc)*(x0-xc) + (y0-yc)*(y0-yc));
1105     float rc4= sqrt((x1-xc)*(x1-xc) + (y1-yc)*(y1-yc));
1106     float rc = 0.25*(rc1+rc2+rc3+rc4);
1107     float dr2 = (rc1-rc)*(rc1-rc)+(rc2-rc)*(rc2-rc)+(rc3-rc)*(rc3-rc)+(rc4-rc)*(rc4-rc);
1108 
1109     if(dr2<dr2_min) {
1110       dr2_min = dr2;
1111       im_min = im;
1112       rc_min = rc;
1113       xc_min = xc;
1114       yc_min = yc;
1115     }
1116   }//for(iMvtx)
1117   iMvtxHit = vMvtxHit.at(im_min);
1118   rc_intt_mvtx = rc_min;
1119   xc_intt_mvtx = xc_min;
1120   yc_intt_mvtx = yc_min;
1121   float rm  = vMvtx_r.at(iMvtxHit);
1122   float phim= vMvtx_phi.at(iMvtxHit);
1123   float r0 = sqrt(x0*x0+y0*y0);
1124   float phi0 = atan2(y0,x0);
1125 
1126   x0m= rm*cos(phim);
1127   y0m= rm*sin(phim);
1128   z0m= vMvtx_z.at(iMvtxHit);
1129   float dzdr = (z0-z0m)/(r0-rm);  
1130   zvtx_intt_mvtx= z0-dzdr*rm;  
1131   pt0m=0.0042*rc_intt_mvtx;
1132   phi0m=phim + (phi0-phim)*rm/(r0-rm);
1133   pz0m=dzdr*pt0m;
1134 }
1135 
1136 void FormInttMvtxTrk2(float x0, float y0, float z0,float x1, float y1,float z1,
1137               vector<int> &vMvtxHit_I, vector<int> &vMvtxHit_O,
1138               vector<float> &vMvtxI_r, vector<float> &vMvtxI_phi, vector<float> &vMvtxI_z,
1139               vector<float> &vMvtxO_r, vector<float> &vMvtxO_phi, vector<float> &vMvtxO_z,
1140               int &iMvtx_I, int &iMvtx_O,
1141               float &rc_intt_mvtx, float &xc_intt_mvtx, float &yc_intt_mvtx,
1142               float& zvtx_intt_mvtx,
1143               float &x0m, float &y0m, float &z0m, float &pt0m,float& phi0m, float &pz0m) {
1144   // There are two Mvtx layers that have associated hits.
1145   // They are Mvtx_O (outer layer) and  Mvtx_I (inner layer)
1146   // Form a track of (INTT1-INTT0-Mvtx_O-Mvtx_I)
1147 
1148   int nMvtxO = vMvtxHit_O.size();
1149   int nMvtxI = vMvtxHit_I.size();
1150   float dr2_min = 100000;
1151   int iO_min = -1;
1152   int iI_min = -1;
1153   float rc_min = 100000;
1154   float xc_min = 100000;
1155   float yc_min = 100000;
1156 
1157   if(imode == 2) {
1158     cout << "Trk2" << endl;
1159     cout << "nMvtxO="<<nMvtxO<<" nMvtxI="<<nMvtxI<<endl;
1160   }
1161   for(int iO=0;iO<nMvtxO;iO++) {
1162     float rO_m   = vMvtxO_r.at(vMvtxHit_O.at(iO));
1163     float phiO_m = vMvtxO_phi.at(vMvtxHit_O.at(iO));
1164     float xOm = rO_m*cos(phiO_m);
1165     float yOm = rO_m*sin(phiO_m);
1166     float zOm = vMvtxO_z.at(vMvtxHit_O.at(iO));
1167     
1168     for(int iI=0;iI<nMvtxI;iI++) {
1169       float rI_m   = vMvtxI_r.at(vMvtxHit_I.at(iI));
1170       float phiI_m = vMvtxI_phi.at(vMvtxHit_I.at(iI));
1171       float xIm = rI_m*cos(phiI_m);
1172       float yIm = rI_m*sin(phiI_m);
1173       float zIm = vMvtxI_z.at(vMvtxHit_I.at(iI));
1174       
1175       float r1;
1176       float xc1;
1177       float yc1;
1178       float r2;
1179       float xc2;
1180       float yc2;
1181       
1182   // MvtxO-INTT0-INTT1 Circle
1183       CalcCircle(xOm,yOm,x0,y0,x1,y1, r1,xc1,yc1);
1184   
1185   // MvtxI-MvtxO-INTT1 Circle
1186       CalcCircle(xIm,yIm,xOm,yOm,x1,y1, r2,xc2,yc2);
1187 
1188       float xc = 0.5*(xc1+xc2);
1189       float yc = 0.5*(yc1+yc2);
1190 
1191       float rc1= sqrt((xIm-xc)*(xIm-xc) + (yIm-yc)*(yIm-yc));
1192       float rc2= sqrt((xOm-xc)*(xOm-xc) + (yOm-yc)*(yOm-yc));
1193       float rc3= sqrt((x0-xc)*(x0-xc)   + (y0-yc)*(y0-yc));
1194       float rc4= sqrt((x1-xc)*(x1-xc)   + (y1-yc)*(y1-yc));
1195       float rc = 0.25*(rc1+rc2+rc3+rc4);
1196       float dr2 = (rc1-rc)*(rc1-rc)+(rc2-rc)*(rc2-rc)+(rc3-rc)*(rc3-rc)+(rc4-rc)*(rc4-rc);
1197       
1198       if(dr2<dr2_min) {
1199     dr2_min = dr2;
1200     iO_min = iO;
1201     iI_min = iI;
1202     rc_min = rc;
1203     xc_min = xc;
1204     yc_min = yc;
1205       }
1206     }//for(iMvtxI)
1207   }//for(iMvtxO)
1208   iMvtx_O = vMvtxHit_O.at(iO_min);
1209   iMvtx_I = vMvtxHit_I.at(iI_min);
1210   rc_intt_mvtx = rc_min;
1211   xc_intt_mvtx = xc_min;
1212   yc_intt_mvtx = yc_min;
1213   
1214   float rIm  = vMvtxI_r.at(iMvtx_I);
1215   float phiIm= vMvtxI_phi.at(iMvtx_I);
1216   float zIm  = vMvtxI_z.at(iMvtx_I);
1217 
1218   float rOm  = vMvtxO_r.at(iMvtx_O);
1219   float phiOm= vMvtxO_phi.at(iMvtx_O);
1220   float zOm  = vMvtxO_z.at(iMvtx_O);
1221 
1222   float dzdr = (zOm-zIm)/(rOm-rIm);
1223   
1224   x0m= rIm*cos(phiIm);
1225   y0m= rIm*sin(phiIm);
1226   z0m= zIm;
1227   
1228   zvtx_intt_mvtx= zIm-dzdr*rIm;  
1229 
1230   pt0m=0.0042*rc_intt_mvtx;
1231   phi0m=phiIm + (phiOm - phiIm)*rIm/(rOm-rIm);
1232   pz0m=dzdr*pt0m;
1233 
1234 }
1235 
1236 void FormInttMvtxTrk3(float x0, float y0, float z0,float x1, float y1,float z1,
1237               vector<int> &vMvtx0Hit, vector<int> &vMvtx1Hit,vector<int> &vMvtx2Hit,
1238               int &iMvtx0, int &iMvtx1, int &iMvtx2,
1239               float &rc_intt_mvtx, float &xc_intt_mvtx, float &yc_intt_mvtx,
1240               float& zvtx_intt_mvtx,
1241               float &x0m, float &y0m, float &z0m, float &pt0m,float& phi0m, float &pz0m) {
1242   // All three Mvtx layers have associated hits.
1243   // Form a track of (INTT0-Mvtx2-Mvtx1-Mvtx0)
1244   
1245   int nMvtx0 = vMvtx0Hit.size();
1246   int nMvtx1 = vMvtx1Hit.size();
1247   int nMvtx2 = vMvtx2Hit.size();
1248   float dr2_min = 100000;
1249   int iMvtx0_min = -1;
1250   int iMvtx1_min = -1;
1251   int iMvtx2_min = -1;
1252   float rc_min = 100000;
1253   float xc_min = 100000;
1254   float yc_min = 100000;
1255   
1256   if(imode == 2) {
1257     cout << "Trk3" << endl;
1258     cout << "nMvtx0="<<nMvtx0<<" nMvtx1="<<nMvtx1<<" nMvtx2="<<nMvtx2<<endl;
1259   }
1260   for(int im0=0;im0<nMvtx0;im0++) {
1261     float r0_m   = vMvtx0r.at(vMvtx0Hit.at(im0));
1262     float phi0_m = vMvtx0phi.at(vMvtx0Hit.at(im0));
1263     float x0_m = r0_m*cos(phi0_m);
1264     float y0_m = r0_m*sin(phi0_m);
1265     float z0_m = vMvtx0z.at(vMvtx0Hit.at(im0));
1266     
1267     for(int im1=0;im1<nMvtx1;im1++) {
1268       float r1_m   = vMvtx1r.at(vMvtx1Hit.at(im1));
1269       float phi1_m = vMvtx1phi.at(vMvtx1Hit.at(im1));
1270       float x1_m = r1_m*cos(phi1_m);
1271       float y1_m = r1_m*sin(phi1_m);
1272       float z1_m = vMvtx1z.at(vMvtx1Hit.at(im1));
1273       
1274       for(int im2=0;im2<nMvtx2;im2++) {
1275     float r2_m   = vMvtx2r.at(vMvtx2Hit.at(im2));
1276     float phi2_m = vMvtx2phi.at(vMvtx2Hit.at(im2));
1277     float x2_m = r2_m*cos(phi2_m);
1278     float y2_m = r2_m*sin(phi2_m);
1279     float z2_m = vMvtx2z.at(vMvtx2Hit.at(im2));
1280       
1281     float r1;
1282     float xc1;
1283     float yc1;
1284     float r2;
1285     float xc2;
1286     float yc2;
1287     float r3;
1288     float xc3;
1289     float yc3;
1290     
1291     // Mvtx0-Mvtx2-INTT1 Circle
1292     CalcCircle(x0_m,y0_m,x2_m,y2_m,x1,y1, r1,xc1,yc1);
1293   
1294     // Mvtx0-Mvtx1-INTT1 Circle
1295     CalcCircle(x0_m,y0_m,x1_m,y1_m,x1,y1, r2,xc2,yc2);
1296 
1297     float xc = (xc1+xc2)/2.0;
1298     float yc = (yc1+yc2)/2.0;
1299     
1300     float rc1= sqrt((x0_m-xc)*(x0_m-xc) + (y0_m-yc)*(y0_m-yc));
1301     float rc2= sqrt((x1_m-xc)*(x1_m-xc) + (y1_m-yc)*(y1_m-yc));
1302     float rc3= sqrt((x2_m-xc)*(x2_m-xc) + (y2_m-yc)*(y2_m-yc));
1303     float rc4= sqrt((x1-xc)*(x1-xc)     + (y1-yc)*(y1-yc));
1304     float rc = (rc1+rc2+rc3+rc4)/4.0;
1305     float dr2 = (rc1-rc)*(rc1-rc)+(rc2-rc)*(rc2-rc)+(rc3-rc)*(rc3-rc)+(rc4-rc)*(rc4-rc);
1306     
1307     if(dr2<dr2_min) {
1308       dr2_min = dr2;
1309       iMvtx0_min = vMvtx0Hit.at(im0);
1310       iMvtx1_min = vMvtx1Hit.at(im1);
1311       iMvtx2_min = vMvtx2Hit.at(im2);
1312       rc_min = rc;
1313       xc_min = xc;
1314       yc_min = yc;
1315     }
1316       }//for(im2)
1317     }//for(im1)
1318   }//for(im0)
1319   iMvtx0 = iMvtx0_min;
1320   iMvtx1 = iMvtx1_min;
1321   iMvtx2 = iMvtx2_min;
1322   rc_intt_mvtx = rc_min;
1323   xc_intt_mvtx = xc_min;
1324   yc_intt_mvtx = yc_min;
1325   float rIm  = vMvtx0r.at(iMvtx0);
1326   float phiIm= vMvtx0phi.at(iMvtx0);
1327   float zIm  = vMvtx0z.at(iMvtx0);
1328 
1329   float rOm  = vMvtx1r.at(iMvtx1);
1330   float phiOm= vMvtx1phi.at(iMvtx1);
1331   float zOm  = vMvtx1z.at(iMvtx1);
1332 
1333   float dzdr = (zOm-zIm)/(rOm-rIm);
1334   
1335   x0m= rIm*cos(phiIm);
1336   y0m= rIm*sin(phiIm);
1337   z0m= zIm;
1338   
1339   zvtx_intt_mvtx= zIm-dzdr*rIm;  
1340 
1341   pt0m=0.0042*rc_intt_mvtx;
1342   phi0m=phiIm + (phiOm - phiIm)*rIm/(rOm-rIm);
1343   pz0m=dzdr*pt0m;
1344 }
1345 
1346 void FindInttMvtx(void) {
1347   // find Mvtx clusters that match the INTT-pair tracklet
1348   //
1349   int nPair = vInttPair.size();
1350   if(imode == 2) {
1351     cout << "nPair = "<<nPair<<endl;
1352   }
1353   if(nPair > 0) {
1354     for(int ip=0;ip<nPair;ip++) {
1355       InttPair pair = vInttPair.at(ip);
1356       int i0=pair.iINTT0;
1357       int i1=pair.iINTT1;
1358       float rIntt = pair.r;
1359       float xc = pair.xc;  //(xc,yc) is the center of the circule
1360       float yc = pair.yc;  // passing through INTT1,INTT0 and (xBC,yBC)
1361       float r0   = vINTT0r.at(i0);
1362       float r1   = vINTT1r.at(i1);
1363       float phi0 = vINTT0phi.at(i0);
1364       float phi1 = vINTT1phi.at(i1);
1365       float z0   = vINTT0z.at(i0);
1366       float z1   = vINTT1z.at(i1);
1367       float zvtx = pair.zvtx;
1368       int sign = 1;
1369       if(phi1>phi0) sign = -1;
1370       
1371       int iMvtx0 = FindMvtxHit(0,rIntt,xc,yc,zvtx,r0,r1,z0,z1,vMvtx0Hit);
1372       int iMvtx1 = FindMvtxHit(1,rIntt,xc,yc,zvtx,r0,r1,z0,z1,vMvtx1Hit);
1373       int iMvtx2 = FindMvtxHit(2,rIntt,xc,yc,zvtx,r0,r1,z0,z1,vMvtx2Hit);
1374 
1375       if(iMvtx0 >=0 || iMvtx1 >=0 || iMvtx2 >=0) {
1376     // at least one layer has associated hit.
1377     // Case 1: if there is a Calo-INTT track in vCaloInttMvtx that is based on
1378     //         the same InttPair, add the Mvtx hits to the track
1379     // Case 2: if this InttPair is not vCaloInttMvtx, create a new CaloInttMvtx
1380     //         track and add it i
1381     //
1382     // calculate the InttPair-Mvtx track parameters
1383     float r_intt_mvtx;
1384     float xc_intt_mvtx;
1385     float yc_intt_mvtx;
1386     float zvtx_intt_mvtx;
1387     float x0m;
1388     float y0m;
1389     float z0m;
1390     float pt0m;
1391     float phi0m;
1392     float pz0m;
1393     
1394     /*
1395     FormInttMvtxTrk(r0,phi0,z0,r1,phi1,z1,iMvtx0,iMvtx1,iMvtx2,
1396             r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1397             zvtx_intt_mvtx,
1398             x0m, y0m, z0m, pt0m, phi0m, pz0m);
1399     */
1400     FormInttMvtxTrk(r0,phi0,z0,r1,phi1,z1,vMvtx0Hit,vMvtx1Hit,vMvtx2Hit,
1401             iMvtx0,iMvtx1,iMvtx2,
1402             r_intt_mvtx,xc_intt_mvtx,yc_intt_mvtx,
1403             zvtx_intt_mvtx,
1404             x0m, y0m, z0m, pt0m, phi0m, pz0m);
1405 
1406     // Now an INTT-Mvtx track is formed
1407     // There are two cases:
1408     // CASE 1: The same track is already formed as an Emc-Intt track
1409     // CASE 2: This is new Intt-Mvtx track
1410     //
1411     // search vCaloInttMvtx for the same InttPair as this track
1412     // If found, it is CASE 1. Otherwise CASE2.
1413     int itrk=0;
1414     int ntrk = vCaloInttMvtx.size();
1415     while(itrk<ntrk) {
1416       int iINTT0 = (vCaloInttMvtx.at(itrk)).iINTT0;
1417       int iINTT1 = (vCaloInttMvtx.at(itrk)).iINTT1;
1418 
1419       if(iINTT0 == i0 && iINTT1 == i1) break;
1420       itrk++;
1421     }
1422 
1423     if(itrk < ntrk) {
1424       // This means it is CASE 1.
1425       // Add the Intt-Mvtx part of the existing EmcIntt track
1426       if(imode==2) {
1427         cout << "CASE 1: add to existing track" <<endl;
1428       }
1429       (vCaloInttMvtx.at(itrk)).iMvtx0 = iMvtx0;
1430       (vCaloInttMvtx.at(itrk)).iMvtx1 = iMvtx1;
1431       (vCaloInttMvtx.at(itrk)).iMvtx2 = iMvtx2;
1432       (vCaloInttMvtx.at(itrk)).r_intt_mvtx = r_intt_mvtx;
1433       (vCaloInttMvtx.at(itrk)).xc_intt_mvtx = xc_intt_mvtx;
1434       (vCaloInttMvtx.at(itrk)).yc_intt_mvtx = yc_intt_mvtx;
1435       (vCaloInttMvtx.at(itrk)).zvtx_intt_mvtx  = zvtx_intt_mvtx;
1436       (vCaloInttMvtx.at(itrk)).x0m  = x0m;
1437       (vCaloInttMvtx.at(itrk)).y0m  = y0m;
1438       (vCaloInttMvtx.at(itrk)).z0m  = z0m;
1439       (vCaloInttMvtx.at(itrk)).pt0m  = pt0m;
1440       (vCaloInttMvtx.at(itrk)).phi0m = phi0m;
1441       (vCaloInttMvtx.at(itrk)).pz0m  = pz0m;
1442     } else {
1443       //the same InttPair is not found, i.e., CASE 2.
1444       // Add a new CIMtrack.
1445       if(imode==2) {
1446         cout << "CASE 2: create a new track" <<endl;
1447       }
1448       CaloInttMvtx a_CaloInttMvtx;
1449       a_CaloInttMvtx.iTop = -99;
1450       a_CaloInttMvtx.iINTT0 = i0;
1451       a_CaloInttMvtx.iINTT1 = i1;
1452       a_CaloInttMvtx.iMvtx0 = iMvtx0;
1453       a_CaloInttMvtx.iMvtx1 = iMvtx1;
1454       a_CaloInttMvtx.iMvtx2 = iMvtx2;
1455       a_CaloInttMvtx.sign   = sign;
1456       a_CaloInttMvtx.r_intt =  pair.r;
1457       a_CaloInttMvtx.xc_intt = pair.xc;
1458       a_CaloInttMvtx.yc_intt = pair.yc;
1459       a_CaloInttMvtx.z_intt    = z0;
1460       a_CaloInttMvtx.zvtx_intt = zvtx;
1461       a_CaloInttMvtx.r_emc_intt = -99;
1462       a_CaloInttMvtx.xc_emc_intt = -99;
1463       a_CaloInttMvtx.yc_emc_intt = -99;
1464       a_CaloInttMvtx.zvtx_emc_intt = -99;
1465       a_CaloInttMvtx.r_intt_mvtx    = r_intt_mvtx;
1466       a_CaloInttMvtx.xc_intt_mvtx   = xc_intt_mvtx;
1467       a_CaloInttMvtx.yc_intt_mvtx   = yc_intt_mvtx;
1468       a_CaloInttMvtx.zvtx_intt_mvtx = zvtx_intt_mvtx;
1469       a_CaloInttMvtx.xemc = -99;
1470       a_CaloInttMvtx.yemc = -99;
1471       a_CaloInttMvtx.zemc = -99;
1472       a_CaloInttMvtx.total_e = -99;
1473       a_CaloInttMvtx.emcal_e = -99;
1474       a_CaloInttMvtx.ihcal_e = -99;
1475       a_CaloInttMvtx.ohcal_e = -99;
1476       a_CaloInttMvtx.emc_e   = -99;
1477       a_CaloInttMvtx.BDT_e   = -99;
1478       a_CaloInttMvtx.x0e   = -99;
1479       a_CaloInttMvtx.y0e   = -99;
1480       a_CaloInttMvtx.z0e   = -99;
1481       a_CaloInttMvtx.pt0e  = -99;
1482       a_CaloInttMvtx.phi0e = -99;
1483       a_CaloInttMvtx.pz0e  = -99;
1484       a_CaloInttMvtx.x0m   = x0m;
1485       a_CaloInttMvtx.y0m   = y0m;
1486       a_CaloInttMvtx.z0m   = z0m;
1487       a_CaloInttMvtx.pt0m  = pt0m;
1488       a_CaloInttMvtx.phi0m = phi0m;
1489       a_CaloInttMvtx.pz0m  = pz0m;
1490 
1491       vCaloInttMvtx.push_back(a_CaloInttMvtx);
1492     }//if(itrk)
1493       }//if(iMvtx0,iMvtx1,iMvtx2)
1494     }//for(ip)
1495   }//if(nPair)
1496 }
1497 
1498 int FindMvtxHit(int layer, float rIntt, float xc, float yc,
1499         float zvtx, float r0, float r1, float z0, float z1,
1500         vector<int>   &vMvtxHit) {
1501   // constants for the analysis
1502   const float InttMvtx_dr_cut = 0.03;
1503   const float InttMvtx_dz_cut = 1.0;
1504 
1505   static vector<float> vMvtx_dr;
1506   static vector<float> vMvtx_dz0;
1507   static vector<float> vMvtx_dz1;
1508 
1509   vector<float> *pvMvtx_r;
1510   vector<float> *pvMvtx_phi;
1511   vector<float> *pvMvtx_z;
1512   TH1F *hMvtx_dz0;
1513   TH1F *hMvtx_dz1;
1514   TH1F *hMvtx_dr;
1515   TH1F *hMvtx_dr2;
1516 
1517   vMvtxHit.clear();
1518   vMvtx_dr.clear();
1519   vMvtx_dz0.clear();
1520   vMvtx_dz1.clear();
1521 
1522   if(layer == 2) {
1523     pvMvtx_r   = &vMvtx2r;
1524     pvMvtx_phi = &vMvtx2phi;
1525     pvMvtx_z   = &vMvtx2z;
1526     
1527     hMvtx_dz0 = hMvtx2_dz0;
1528     hMvtx_dz1 = hMvtx2_dz1;
1529     hMvtx_dr  = hMvtx2_dr;
1530     hMvtx_dr2 = hMvtx2_dr2;
1531   } else if(layer == 1) {
1532     pvMvtx_r   = &vMvtx1r;
1533     pvMvtx_phi = &vMvtx1phi;
1534     pvMvtx_z   = &vMvtx1z;
1535     
1536     hMvtx_dz0 = hMvtx1_dz0;
1537     hMvtx_dz1 = hMvtx1_dz1;
1538     hMvtx_dr  = hMvtx1_dr;
1539     hMvtx_dr2 = hMvtx1_dr2;
1540   } else if(layer == 0) {
1541     pvMvtx_r   = &vMvtx0r;
1542     pvMvtx_phi = &vMvtx0phi;
1543     pvMvtx_z   = &vMvtx0z;
1544     
1545     hMvtx_dz0 = hMvtx0_dz0;
1546     hMvtx_dz1 = hMvtx0_dz1;
1547     hMvtx_dr  = hMvtx0_dr;
1548     hMvtx_dr2 = hMvtx0_dr2;
1549   }
1550   
1551   int nMvtx = pvMvtx_r->size();
1552   // search for hits of Mvt in the window
1553   int i=0;
1554   while(i<nMvtx) {
1555     float r   = pvMvtx_r->at(i);
1556     float phi = pvMvtx_phi->at(i);
1557     float z = pvMvtx_z->at(i);
1558     
1559     float x = r*cos(phi);
1560     float y = r*sin(phi);
1561     float rmvtx = sqrt((x-xc)*(x-xc)+(y-yc)*(y-yc));
1562     float dzdr = (z-zgvtx)/r;
1563     float zproj0 = zgvtx+dzdr*r0;
1564     float zproj1 = zgvtx+dzdr*r1;
1565     hMvtx_dr->Fill(rmvtx-rIntt);
1566     if(abs(rmvtx-rIntt)< InttMvtx_dr_cut) {
1567       hMvtx_dz0->Fill(z0-zproj0);
1568       hMvtx_dz1->Fill(z1-zproj1);
1569       if(abs(z0-zproj0) < InttMvtx_dz_cut  &&
1570      abs(z1-zproj1) < InttMvtx_dz_cut ) {
1571     // A Mvtx hit is found in the window. store it.
1572     vMvtxHit.push_back(i);
1573     vMvtx_dr.push_back(rmvtx-rIntt);
1574     vMvtx_dz0.push_back(z0-zproj0);
1575     vMvtx_dz1.push_back(z1-zproj1);
1576       }
1577     }//if(abs(rmvtx...)
1578     // This part is to see the S/N of the associated hit
1579     if(abs(z0-zproj0) < InttMvtx_dz_cut &&
1580        abs(z1-zproj1) < InttMvtx_dz_cut ) {
1581       hMvtx_dr2->Fill(rmvtx-rIntt);
1582     }//if(abs(z0-zproj0)...
1583     i++;
1584   }//while(i)
1585   // Now Mvtx(layer) hits that can associated with
1586   // this InttPair track are found.
1587   // If there are more than one hits are found, chose
1588   // the best one.
1589   if(vMvtxHit.size()==0) return -99;
1590   else return SelectBestMvtxHit(vMvtxHit, vMvtx_dr, vMvtx_dz0, vMvtx_dz1);
1591 }      
1592 
1593 int SelectBestMvtxHit(vector<int> &vMvtxhit, vector<float> &vMvtx_dr,
1594               vector<float> &vMvtx_dz0, vector<float> &vMvtx_dz1) {
1595   int nhit = vMvtxhit.size();
1596   int ihit=0;
1597   float drmin=100;
1598   int i_min;
1599   while(ihit<nhit) {
1600     float dr = abs(vMvtx_dr.at(ihit));
1601     if(dr < drmin) {
1602       drmin = dr;
1603       i_min = ihit;
1604     }
1605     ihit++;
1606   }
1607   return vMvtxhit.at(i_min);
1608 }
1609 
1610 int SelectBestTopHit(vector<int> &vTop_near_trk) {
1611   return vTop_near_trk.at(0);
1612 }
1613 
1614 void FindCaloInttMvtx(void) {
1615   // For Intt-Mvtx tracklet, find an Emc hit
1616   //  if(imode==2) cout << "FindCaloInttMvtx()"<<endl;
1617   int ntrk = vCaloInttMvtx.size();
1618   if(ntrk > 0) {
1619     for(int itrk=0;itrk<ntrk;itrk++) {
1620       CaloInttMvtx *pCIMtrack = &(vCaloInttMvtx.at(itrk));
1621       float pt_emc_intt  = pCIMtrack->pt0e;
1622       float pt_intt_mvtx = pCIMtrack->pt0m;
1623       float emc_e = pCIMtrack->emc_e;
1624       float emcal_e = pCIMtrack->emcal_e;
1625       float total_e = pCIMtrack->total_e;
1626       float phi0 = pCIMtrack->phi0e;
1627       float z0   = pCIMtrack->z0e;
1628       int Intt0_t = vINTT0t.at(pCIMtrack->iINTT0);
1629       int Intt1_t = vINTT1t.at(pCIMtrack->iINTT1);
1630 
1631       int iMvtx0 = pCIMtrack->iMvtx0;
1632       int iMvtx1 = pCIMtrack->iMvtx1;
1633       int iMvtx2 = pCIMtrack->iMvtx2;
1634 
1635       int nMvtxHits = 0;
1636       if( iMvtx2 >=0) nMvtxHits++;
1637       if( iMvtx1 >=0) nMvtxHits++;
1638       if( iMvtx0 >=0) nMvtxHits++;
1639       
1640       if(nMvtxHits>=2) {
1641     // at least two Mvt layers has a hit for this track
1642     // thus an Intt-Mvtx track is formed and its track parameters
1643     // at the origin (x0m,y0m,z0m,pt0m,phi0m,pz0m) are well defined
1644     //
1645     int ntop = vTop_r.size();
1646     vector<int> vTop_near_trk;
1647     if(ntop>0) {
1648       for(int itop=0;itop<ntop;itop++) {
1649         if(vTop_emc_emc_e.at(itop) > 0) {// Emc Hit in the topocluster
1650           float emc_r   = vTop_emc_r.at(itop);
1651           float emc_phi = vTop_emc_phi.at(itop);
1652           float zemc = vTop_emc_z.at(itop);
1653           float xemc = emc_r*cos(emc_phi);
1654           float yemc = emc_r*sin(emc_phi);
1655           float x0m = pCIMtrack->x0m;
1656           float y0m = pCIMtrack->y0m;
1657           float z0m = pCIMtrack->z0m;
1658           float pt0m = pCIMtrack->pt0m;
1659           float phi0m = pCIMtrack->phi0m;
1660           float pz0m  = pCIMtrack->pz0m;
1661           float rc = pCIMtrack->r_intt_mvtx;
1662           float xc = pCIMtrack->xc_intt_mvtx;
1663           float yc = pCIMtrack->yc_intt_mvtx;
1664           float rcEmc = sqrt((xemc-xc)*(xemc-xc)+(yemc-yc)*(yemc-yc));
1665           float dzdr = pz0m/pt0m;
1666           float zproj = z0m + dzdr*emc_r;
1667           if(abs(rcEmc-rc)<20 && abs(zemc-zproj)<8) {
1668         //Emc hit that matches to the track is found.
1669         vTop_near_trk.push_back(itop);
1670           }
1671         }//if(vTop_emc_emc_e)
1672       }//for(itop)
1673     }//if(ntop>0)
1674 
1675     //  if(imode==2) cout << "top found:"<<vTop_near_trk.size()<<endl;
1676     if(vTop_near_trk.size()>0) {
1677       int itop_best = SelectBestTopHit(vTop_near_trk);
1678       float emc_r   = vTop_emc_r.at(itop_best);
1679       float emc_phi = vTop_emc_phi.at(itop_best);
1680       float xemc = emc_r*cos(emc_phi);
1681       float yemc = emc_r*sin(emc_phi);
1682 
1683       float r_emc_intt;
1684       float xc_emc_intt;
1685       float yc_emc_intt;
1686       int iINTT0 = pCIMtrack->iINTT0;
1687       float r_intt0   =  vINTT0r.at(iINTT0);
1688       float phi_intt0 =  vINTT0phi.at(iINTT0);
1689       float x_intt0 = r_intt0*cos(phi_intt0);
1690       float y_intt0 = r_intt0*sin(phi_intt0);
1691       // Draw a circle passing through (xemc,yemc)-INTT0-(0,0)
1692       //CalcCircle(xemc,yemc,x_intt0,y_intt0,0.0,0.0,
1693       CalcCircle(0.0,0.0,x_intt0,y_intt0,xemc,yemc,
1694              r_emc_intt,xc_emc_intt,yc_emc_intt);
1695       //      if(imode==2) cout << "r_emc_intt = "<<r_emc_intt<<endl;
1696 
1697       // This track is connected to Intt-Mvtx track. So the starting point
1698       // is the same
1699       float x0e  = pCIMtrack->x0m;
1700       float y0e  = pCIMtrack->y0m;
1701       float z0e  = pCIMtrack->z0m;
1702       float phi0e= pCIMtrack->phi0m;
1703       
1704       // pT is determined by EmcIntt part of the track
1705       float pt0m = pCIMtrack->pt0m;
1706       float pz0m = pCIMtrack->pz0m;
1707       float pt0e = 0.0042*r_emc_intt;
1708       float pz0e = pt0e*(pz0m/pt0m);
1709 
1710       pCIMtrack->iTop = itop_best;
1711       pCIMtrack->r_emc_intt = r_emc_intt;
1712       pCIMtrack->xc_emc_intt = xc_emc_intt;
1713       pCIMtrack->yc_emc_intt = yc_emc_intt;
1714       pCIMtrack->zvtx_emc_intt = pCIMtrack->zvtx_intt_mvtx;
1715       pCIMtrack->xemc = xemc;
1716       pCIMtrack->yemc = yemc;
1717       pCIMtrack->zemc = vTop_emc_z.at(itop_best);
1718       pCIMtrack->total_e = vTop_e.at(itop_best);
1719       pCIMtrack->emcal_e = vTop_emc_e.at(itop_best);
1720       pCIMtrack->ihcal_e = vTop_ihc_e.at(itop_best);
1721       pCIMtrack->ohcal_e = vTop_ohc_e.at(itop_best);
1722       pCIMtrack->emc_e = vTop_emc_emc_e.at(itop_best);
1723       pCIMtrack->BDT_e = 0;
1724       pCIMtrack->x0e = x0e;
1725       pCIMtrack->y0e = y0e;
1726       pCIMtrack->z0e = z0e;
1727       pCIMtrack->pt0e = pt0e;
1728       pCIMtrack->phi0e = phi0e;
1729       pCIMtrack->pz0e = pz0e;     
1730     }
1731       }//if(nMvtxHits>=2)
1732     }//for(itrk)
1733   }//if(ntrk>0)
1734 }