// $Id$ // // File: DTrackHitSelectorALT2.cc // Created: Fri Feb 6 08:22:58 EST 2009 // Creator: davidl (on Darwin harriet.jlab.org 9.6.0 i386) // #include #include #include "DTrackHitSelectorALT2.h" #ifndef ansi_escape #define ansi_escape ((char)0x1b) #define ansi_bold ansi_escape<<"[1m" #define ansi_normal ansi_escape<<"[0m" #define ansi_red ansi_escape<<"[31m" #define ansi_green ansi_escape<<"[32m" #define ansi_blue ansi_escape<<"[34m" #endif // ansi_escape #define ONE_OVER_SQRT12 0.288675 bool static DTrackHitSelector_cdchit_cmp(paira, pairb){ if (a.second->wire->ring!=b.second->wire->ring) return (a.second->wire->ring>b.second->wire->ring); return (a.first>b.first); } bool static DTrackHitSelector_fdchit_cmp(paira, pairb){ if (a.second->wire->layer!=b.second->wire->layer) return (a.second->wire->layer>b.second->wire->layer); return (a.first>b.first); } //--------------------------------- // DTrackHitSelectorALT2 (Constructor) //--------------------------------- DTrackHitSelectorALT2::DTrackHitSelectorALT2(jana::JEventLoop *loop):DTrackHitSelector(loop) { HS_DEBUG_LEVEL = 0; MAKE_DEBUG_TREES = false; MIN_HIT_PROB_CDC = 0.05; MIN_HIT_PROB_FDC = 0.05; MIN_FDC_SIGMA_ANODE_CANDIDATE = 0.1000; MIN_FDC_SIGMA_CATHODE_CANDIDATE = 0.1000; MIN_FDC_SIGMA_ANODE_WIREBASED = 0.0100; MIN_FDC_SIGMA_CATHODE_WIREBASED = 0.0100; gPARMS->SetDefaultParameter("TRKFIT:HS_DEBUG_LEVEL", HS_DEBUG_LEVEL, "Debug verbosity level for hit selector used in track fitting (0=no debug messages)"); gPARMS->SetDefaultParameter("TRKFIT:MAKE_DEBUG_TREES", MAKE_DEBUG_TREES, "Create a TTree with debugging info on hit selection for the FDC and CDC"); gPARMS->SetDefaultParameter("TRKFIT:MIN_HIT_PROB_CDC", MIN_HIT_PROB_CDC, "Minimum probability a CDC hit may have to be associated with a track to be included in list passed to fitter"); gPARMS->SetDefaultParameter("TRKFIT:MIN_HIT_PROB_FDC", MIN_HIT_PROB_FDC, "Minimum probability a FDC hit may have to be associated with a track to be included in list passed to fitter"); gPARMS->SetDefaultParameter("TRKFIT:MIN_FDC_SIGMA_ANODE_CANDIDATE", MIN_FDC_SIGMA_ANODE_CANDIDATE, "Minimum sigma used for FDC anode hits on track candidates"); gPARMS->SetDefaultParameter("TRKFIT:MIN_FDC_SIGMA_CATHODE_CANDIDATE", MIN_FDC_SIGMA_CATHODE_CANDIDATE, "Minimum sigma used for FDC cathode hits on track candidates"); gPARMS->SetDefaultParameter("TRKFIT:MIN_FDC_SIGMA_ANODE_WIREBASED", MIN_FDC_SIGMA_ANODE_WIREBASED, "Minimum sigma used for FDC anode hits on wire-based tracks"); gPARMS->SetDefaultParameter("TRKFIT:MIN_FDC_SIGMA_CATHODE_WIREBASED", MIN_FDC_SIGMA_CATHODE_WIREBASED, "Minimum sigma used for FDC cathode hits on wire-based tracks"); cdchitsel = NULL; fdchitsel = NULL; if(MAKE_DEBUG_TREES){ loop->GetJApplication()->Lock(); cdchitsel= (TTree*)gROOT->FindObject("cdchitsel"); if(!cdchitsel){ cdchitsel = new TTree("cdchitsel", "CDC Hit Selector"); cdchitsel->Branch("H", &cdchitdbg, "fit_type/I:p/F:theta:mass:sigma:mom_factor:x:y:z:s:s_factor:itheta02:itheta02s:itheta02s2:dist:doca:resi:sigma_total:chisq:prob"); }else{ _DBG__; jerr<<" !!! WARNING !!!"<FindObject("fdchitsel"); if(!fdchitsel){ fdchitsel = new TTree("fdchitsel", "FDC Hit Selector"); fdchitsel->Branch("H", &fdchitdbg, "fit_type/I:hit_cdc_endplate:p/F:theta:mass:sigma_anode:sigma_cathode:mom_factor_anode:mom_factor_cathode:x:y:z:s:s_factor_anode:s_factor_cathode:itheta02:itheta02s:itheta02s2:dist:doca:resi:u:u_cathodes:resic:sigma_anode_total:sigma_cathode_total:chisq:prob:prob_anode:prob_cathode:pull_anode:pull_cathode"); }else{ _DBG__; jerr<<" !!! WARNING !!!"<GetJApplication()->Unlock(); } // Calibration constants correction_parms_t &cp0 = correction_parms[0]; // miss endplate, helical correction_parms_t &cp1 = correction_parms[1]; // miss endplate, wire-based correction_parms_t &cp2 = correction_parms[2]; // hit endplate, helical correction_parms_t &cp3 = correction_parms[3]; // hit endplate, wire-based // These values come from macros fitting single track data. // The macros have names like "s_factor_candidates_anodes.C" // This is temporary and these will eventually need to be moved // to the CCDB one the technique is proven. // 1/31/2011 DL cp0.s1_anode=1.61482; cp0.s2_anode=0.572955; cp0.s1_cathode=1.59351; cp0.s2_cathode=0.513831; cp1.s1_anode=1.35426; cp1.s2_anode=0.594413; cp1.s1_cathode=0.188271; cp1.s2_cathode=0.21525; cp2.s1_anode=0.108834; cp2.s2_anode=0.373974; cp2.s1_cathode=0.257157; cp2.s2_cathode=0.357933; cp3.s1_anode=-0.152481; cp3.s2_anode=0.556112; cp3.s1_cathode=-0.856589; cp3.s2_cathode=0.0705065; } //--------------------------------- // ~DTrackHitSelectorALT2 (Destructor) //--------------------------------- DTrackHitSelectorALT2::~DTrackHitSelectorALT2() { } //--------------------------------- // GetCDCHits //--------------------------------- void DTrackHitSelectorALT2::GetCDCHits(fit_type_t fit_type, DReferenceTrajectory *rt, const vector &cdchits_in, vector &cdchits_out) const { // Vector of pairs storing the hit with the probability it is on the track vector >cdchits_tmp; /// Determine the probability that for each CDC hit that it came from the /// track with the given trajectory. /// /// This will calculate a probability for each CDC hit that /// it came from the track represented by the given /// DReference trajectory. The probability is based on /// the residual between the distance of closest approach /// of the trajectory to the wire and the drift time for /// time-based tracks and the distance to the wire for /// wire-based tracks. // Calculate beta of particle. double my_mass=rt->GetMass(); double one_over_beta =sqrt(1.0+my_mass*my_mass/rt->swim_steps[0].mom.Mag2()); // The error on the residual. This will be different based on the // quality of the track and whether MULS is on or not etc. // In principle, this could also depend on the momentum parameters // of the track. double sigma; switch(fit_type){ case kTimeBased: sigma = 0.8*ONE_OVER_SQRT12; break; case kWireBased: sigma = 1.6*ONE_OVER_SQRT12; break; case kHelical: default: sigma = 8.0*ONE_OVER_SQRT12; } // Loop over hits double MIN_HIT_PROB = 0.05; vector::const_iterator iter; for(iter=cdchits_in.begin(); iter!=cdchits_in.end(); iter++){ const DCDCTrackHit *hit = *iter; // Find the DOCA to this wire double s; double doca = rt->DistToRT(hit->wire, &s); if(!finite(s)) s = -999.0; const DReferenceTrajectory::swim_step_t *last_step = rt->GetLastSwimStep(); double itheta02s2 = last_step->itheta02s2; // Get "measured" distance to wire. For time-based tracks // this is calculated from the drift time. For all other // tracks, this is assumed to be half a cell size double dist; if(fit_type == kTimeBased){ // Distance using drift time // NOTE: Right now we assume pions for the TOF // and a constant drift velocity of 55um/ns double tof = s*one_over_beta/29.98; dist = (hit->tdrift - tof)*55E-4; }else{ dist = 0.4; // =0.8/2.0; half cell-size } // remove residual momentum dependance double p = rt->swim_steps[0].mom.Mag(); double mom_factor = 0.809 + 0.0225*p; // For time-based and wire-based tracks, the fit was // weighted for multiple scattering by material times // angle giving preference to the begining of the // track. Take this into account here by enhancing the // error for hits further from the vertex double s_factor = 1.0; switch(fit_type){ case kWireBased: s_factor = 0.474 + itheta02s2*14.23; break; case kHelical: s_factor = 0.107 + itheta02s2*6.13; break; default: break; } double sigma_total = sigma*s_factor*mom_factor; // Residual double resi = dist - doca; //double chisq = pow(resi/sigma_total, 2.0); double chisq=resi*resi/(sigma_total*sigma_total); // Use chi-sq probability function with Ndof=1 to calculate probability double probability = TMath::Prob(chisq, 1); if(probability>=MIN_HIT_PROB_CDC){ pairmyhit; myhit.first=probability; myhit.second=hit; cdchits_tmp.push_back(myhit); } // Optionally fill debug tree if(cdchitsel){ DVector3 pos = rt->GetLastDOCAPoint(); cdchitdbg.fit_type = fit_type; cdchitdbg.p = p; cdchitdbg.theta = rt->swim_steps[0].mom.Theta(); cdchitdbg.mass = my_mass; cdchitdbg.sigma = sigma; cdchitdbg.mom_factor = mom_factor; cdchitdbg.x = pos.X(); cdchitdbg.y = pos.Y(); cdchitdbg.z = pos.Z(); cdchitdbg.s = s; cdchitdbg.s_factor = s_factor; cdchitdbg.itheta02 = last_step->itheta02; cdchitdbg.itheta02s = last_step->itheta02s; cdchitdbg.itheta02s2 = last_step->itheta02s2; cdchitdbg.dist = dist; cdchitdbg.doca = doca; cdchitdbg.resi = resi; cdchitdbg.sigma_total = sigma_total; cdchitdbg.chisq = chisq; cdchitdbg.prob = probability; cdchitsel->Fill(); static bool printed_first = false; if(!printed_first){ _DBG_<<"=== Printing first entry for CDC hit selector debug tree ==="<time - tof)*55E-4; }else{ dist = 0.25; //= 0.5/2.0; half cell-size } // Anode Residual double resi = dist - doca; // Cathode Residual double u=rt->GetLastDistAlongWire(); double u_cathodes = hit->s; double resic = u - u_cathodes; // Calculate sigma for both anode and cathode hits (imposing lower limit) double sigma_anode_total = sigma_anode*mom_factor_anode*s_factor_anode; double sigma_cathode_total = sigma_cathode*mom_factor_cathode*s_factor_cathode; if(sigma_anode_total=MIN_HIT_PROB_FDC){ pairmyhit; myhit.first=probability; myhit.second=hit; fdchits_tmp.push_back(myhit); } // Optionally fill debug tree if(fdchitsel){ DVector3 pos = rt->GetLastDOCAPoint(); fdchitdbg.fit_type = fit_type; fdchitdbg.hit_cdc_endplate = hit_cdc_endplate; fdchitdbg.p = p; fdchitdbg.theta = rt->swim_steps[0].mom.Theta(); fdchitdbg.mass = my_mass; fdchitdbg.sigma_anode = sigma_anode; fdchitdbg.sigma_cathode = sigma_cathode; fdchitdbg.mom_factor_anode = mom_factor_anode; fdchitdbg.mom_factor_cathode = mom_factor_cathode; fdchitdbg.x = pos.X(); fdchitdbg.y = pos.Y(); fdchitdbg.z = pos.Z(); fdchitdbg.s = s; fdchitdbg.s_factor_anode = s_factor_anode; fdchitdbg.s_factor_cathode = s_factor_cathode; fdchitdbg.itheta02 = last_step->itheta02; fdchitdbg.itheta02s = last_step->itheta02s; fdchitdbg.itheta02s2 = last_step->itheta02s2; fdchitdbg.dist = dist; fdchitdbg.doca = doca; fdchitdbg.resi = resi; fdchitdbg.u = u; fdchitdbg.u_cathodes = u_cathodes; fdchitdbg.resic = resic; fdchitdbg.sigma_anode_total = sigma_anode_total; fdchitdbg.sigma_cathode_total = sigma_cathode_total; fdchitdbg.chisq = chisq; fdchitdbg.prob = probability; fdchitdbg.prob_anode = TMath::Prob(pull_anode*pull_anode, 1); fdchitdbg.prob_cathode = TMath::Prob(pull_cathode*pull_cathode, 1); fdchitdbg.pull_anode = pull_anode; fdchitdbg.pull_cathode = pull_cathode; fdchitsel->Fill(); } if(HS_DEBUG_LEVEL>10){ _DBG_; if(probability>=MIN_HIT_PROB_FDC)jerr<