// $Id$ // // File: DTrackTimeBased_factory.cc // Created: Thu Sep 4 14:02:44 EDT 2008 // Creator: davidl (on Darwin harriet.jlab.org 8.11.1 i386) // #include #include #include #include using namespace std; #define TOF_SIGMA 0.080 // TOF resolution in ns #include #include "DTrackTimeBased_factory.h" #include #include #include #include using namespace jana; // count_common_members //------------------ template static unsigned int count_common_members(vector &a, vector &b) { unsigned int n=0; for(unsigned int i=0; iSetDefaultParameter("TRKFIT:DEBUG_HISTS", DEBUG_HISTS); gPARMS->SetDefaultParameter("TRKFIT:DEBUG_LEVEL", DEBUG_LEVEL); gPARMS->SetDefaultParameter("TRKFIT:MOMENTUM_CUT_FOR_DEDX",MOMENTUM_CUT_FOR_DEDX); gPARMS->SetDefaultParameter("TRKFIT:MOMENTUM_CUT_FOR_PROTON_ID",MOMENTUM_CUT_FOR_PROTON_ID); return NOERROR; } //------------------ // brun //------------------ jerror_t DTrackTimeBased_factory::brun(jana::JEventLoop *loop, int runnumber) { // Get the geometry DApplication* dapp=dynamic_cast(loop->GetJApplication()); geom = dapp->GetDGeometry(runnumber); // Get pointer to TrackFitter object that actually fits a track vector fitters; loop->Get(fitters); if(fitters.size()<1){ _DBG_<<"Unable to get a DTrackFitter object! NO Charged track fitting will be done!"<(fitters[0]); // Warn user if something happened that caused us NOT to get a fitter object pointer if(!fitter){ _DBG_<<"Unable to get a DTrackFitter object! NO Charged track fitting will be done!"<Lock(); // Histograms may already exist. (Another thread may have created them) // Try and get pointers to the existing ones. fom_tdiff_bcal = (TH1F*)gROOT->FindObject("fom_tdiff_bcal"); fom_tdiff_tof = (TH1F*)gROOT->FindObject("fom_tdiff_tof"); fom_chi2_trk = (TH1F*)gROOT->FindObject("fom_chi2_trk"); fom_chi2_dedx = (TH1F*)gROOT->FindObject("fom_chi2_dedx"); fom_chi2_tof = (TH1F*)gROOT->FindObject("fom_chi2_tof"); fom_chi2_bcal = (TH1F*)gROOT->FindObject("fom_chi2_bcal"); if(!fom_tdiff_bcal)fom_tdiff_bcal = new TH1F("fom_tdiff_bcal","PID FOM: BCAL time difference", 2000, -10.0, 10.0); if(!fom_tdiff_tof)fom_tdiff_tof = new TH1F("fom_tdiff_tof","PID FOM: TOF time difference", 2000, -10.0, 10.0); if(!fom_chi2_trk)fom_chi2_trk = new TH1F("fom_chi2_trk","PID FOM: #chi^{2}/Ndf from tracking", 1000, 0.0, 100.0); if(!fom_chi2_dedx)fom_chi2_dedx = new TH1F("fom_chi2_dedx","PID FOM: #chi^{2}/Ndf from dE/dx", 1000, 0.0, 100.0); if(!fom_chi2_tof)fom_chi2_tof = new TH1F("fom_chi2_tof","PID FOM: #chi^{2}/Ndf from TOF", 1000, 0.0, 100.0); if(!fom_chi2_bcal)fom_chi2_bcal = new TH1F("fom_chi2_bcal","PID FOM: #chi^{2}/Ndf from BCAL", 1000, 0.0, 100.0); dapp->Unlock(); } return NOERROR; } //------------------ // evnt //------------------ jerror_t DTrackTimeBased_factory::evnt(JEventLoop *loop, int eventnumber) { if(!fitter)return NOERROR; // Get candidates and hits vector tracks; loop->Get(tracks); if (tracks.size()==0) return NOERROR; // Get TOF points vector tof_points; eventLoop->Get(tof_points); // Get BCAL and FCAL clusters vectorbcal_clusters; eventLoop->Get(bcal_clusters); vectorfcal_clusters; //eventLoop->Get(fcal_clusters); //Temporary mStartTime=0.; mStartDetector=SYS_NULL; // Loop over candidates for(unsigned int i=0; iGetDMagneticFieldMap())); DReferenceTrajectory *rt = rtv[_data.size()]; rt->SetMass(track->mass()); rt->SetDGeometry(geom); if(DEBUG_LEVEL>1){_DBG__;_DBG_<<"---- Starting time based fit with mass: "<< track->mass()<SetFitType(DTrackFitter::kTimeBased); DTrackFitter::fit_status_t status = fitter->FindHitsAndFitTrack(*track, rt, loop, track->mass()); // Check the status value from the fit switch(status){ case DTrackFitter::kFitNotDone: _DBG_<<"Fitter returned kFitNotDone. This should never happen!!"<GetDMagneticFieldMap())); DReferenceTrajectory *rt = rtv[_data.size()]; // Create a new time-based track object DTrackTimeBased *timebased_track = new DTrackTimeBased; // Copy over DKinematicData part DKinematicData *track_kd = timebased_track; *track_kd = fitter->GetFitParameters(); rt->SetMass(track_kd->mass()); rt->SetDGeometry(geom); rt->Swim(timebased_track->position(), timebased_track->momentum(), timebased_track->charge()); timebased_track->rt = rt; timebased_track->chisq = fitter->GetChisq(); timebased_track->Ndof = fitter->GetNdof(); timebased_track->pulls = fitter->GetPulls(); timebased_track->trackid = track->id; timebased_track->candidateid=track->candidateid; // Set the start time timebased_track->setT0(mStartTime,0.,mStartDetector); // Add hits used as associated objects const vector &cdchits = fitter->GetCDCFitHits(); const vector &fdchits = fitter->GetFDCFitHits(); for(unsigned int i=0; iAddAssociatedObject(cdchits[i]); for(unsigned int i=0; iAddAssociatedObject(fdchits[i]); // Add DTrack object as associate object timebased_track->AddAssociatedObject(track); // Add figure-of-merit based on chi2, dEdx and matching to outer // detectors timebased_track->FOM=GetFOM(timebased_track,bcal_clusters, fcal_clusters,tof_points); _data.push_back(timebased_track); break; } default: break; } } // Filter out duplicate tracks FilterDuplicates(); return NOERROR; } //------------------ // erun //------------------ jerror_t DTrackTimeBased_factory::erun(void) { return NOERROR; } //------------------ // fini //------------------ jerror_t DTrackTimeBased_factory::fini(void) { for(unsigned int i=0; ibcal_clusters, vectorfcal_clusters, vectortof_points) { // For high momentum, the likelihood that the particle is a proton is small. // For now, assign a figure-of-merit of zero for particles with the proton // mass hypothesis that exceed some momentum cut. /* if (dtrack->mass()>0.9 && dtrack->momentum().Mag()>MOMENTUM_CUT_FOR_PROTON_ID) return 0.; */ // First ingredient is chi2 from the fit double trk_chi2=dtrack->chisq; unsigned int ndof=dtrack->Ndof; double chi2_sum = trk_chi2; // Next compute dEdx in the chambers for this track double mean_path_length=0.,p_avg=0.; // Get the dEdx info from the CDC/FDC hits in a list vectordEdx_list; fitter->GetdEdx(dtrack->rt,dEdx_list); // Truncated mean: loop over a subset of this list, throwing away a // number of the highest dE/dx values. Since the list is sorted according // to dEdx values, with smaller values being earlier in the list, we need // only loop over a fraction of the total number of hits. double dEdx=0.,dEdx_diff=0.; double N=0.; double mass=dtrack->rt->GetMass(); for (unsigned int i=0;i 0.0020)break; // cut off end of tail of distribution // Get the expected (most probable) dE/dx for a particle with this mass // and momentum for this hit double dEdx_mp=fitter->GetdEdx(p,mass,dx); dEdx+=my_dedx; dEdx_diff+=my_dedx-dEdx_mp; p_avg+=p; mean_path_length+=dx; N+=1.; } dEdx/=N; dtrack->setdEdx(dEdx); dEdx_diff/=N; mean_path_length/=N; p_avg/=N; double dEdx_sigma=fitter->GetdEdxSigma(N,p_avg,mass,mean_path_length); // Chi2 for dedx measurement double dedx_chi2=dEdx_diff*dEdx_diff/dEdx_sigma/dEdx_sigma; chi2_sum+=dedx_chi2; ndof++; // Next match to outer detectors double tof_chi2=MatchToTOF(dtrack,tof_points); double bcal_chi2=MatchToBCAL(dtrack,bcal_clusters); if (tof_chi2>-1.){ chi2_sum+=tof_chi2; ndof++; } if (bcal_chi2>-1.){ chi2_sum+=bcal_chi2; ndof++; } if(DEBUG_HISTS){ fom_chi2_trk->Fill(trk_chi2); fom_chi2_dedx->Fill(dedx_chi2); fom_chi2_tof->Fill(tof_chi2); fom_chi2_bcal->Fill(bcal_chi2); } //_DBG_<<"FOM="< indexes_to_delete; for(unsigned int i=0; i<_data.size()-1; i++){ DTrackTimeBased *dtrack1 = _data[i]; vector cdchits1; vector fdchits1; dtrack1->Get(cdchits1); dtrack1->Get(fdchits1); JObject::oid_t cand1=dtrack1->candidateid; for(unsigned int j=i+1; j<_data.size(); j++){ DTrackTimeBased *dtrack2 = _data[j]; if (dtrack2->candidateid==cand1) continue; if (dtrack2->mass() != dtrack1->mass())continue; vector cdchits2; vector fdchits2; dtrack2->Get(cdchits2); dtrack2->Get(fdchits2); // Count number of cdc and fdc hits in common unsigned int Ncdc = count_common_members(cdchits1, cdchits2); unsigned int Nfdc = count_common_members(fdchits1, fdchits2); if(Ncdc!=cdchits1.size() && Ncdc!=cdchits2.size())continue; if(Nfdc!=fdchits1.size() && Nfdc!=fdchits2.size())continue; unsigned int total = Ncdc + Nfdc; unsigned int total1 = cdchits1.size()+fdchits1.size(); unsigned int total2 = cdchits2.size()+fdchits2.size(); if(total!=total1 && total!=total2)continue; if(total12)_DBG_<<"Found "< new_data; for(unsigned int i=0; i<_data.size(); i++){ if(indexes_to_delete.find(i)==indexes_to_delete.end()){ new_data.push_back(_data[i]); }else{ delete _data[i]; if(DEBUG_LEVEL>1)_DBG_<<"Deleting clone time-based track "<