// $Id: DEventProcessor_trackeff_hists2.cc 2774 2007-07-19 15:59:02Z davidl $ // // File: DEventProcessor_trackeff_hists2.cc // Created: Sun Apr 24 06:45:21 EDT 2005 // Creator: davidl (on Darwin Harriet.local 7.8.0 powerpc) // #include #include using namespace std; #include #include #include "DEventProcessor_trackeff_hists2.h" #include "DTrackingResolutionGEANT.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Routine used to create our DEventProcessor extern "C"{ void InitPlugin(JApplication *app){ InitJANAPlugin(app); app->AddProcessor(new DEventProcessor_trackeff_hists2()); } } // "C" //------------------ // DEventProcessor_trackeff_hists2 //------------------ DEventProcessor_trackeff_hists2::DEventProcessor_trackeff_hists2() { trk_ptr = &trk; //trkres = new DTrackingResolutionGEANT(); pthread_mutex_init(&mutex, NULL); } //------------------ // ~DEventProcessor_trackeff_hists2 //------------------ DEventProcessor_trackeff_hists2::~DEventProcessor_trackeff_hists2() { } //------------------ // init //------------------ jerror_t DEventProcessor_trackeff_hists2::init(void) { // Create TRACKING directory TDirectory *dir = (TDirectory*)gROOT->FindObject("TRACKING"); if(!dir)dir = new TDirectoryFile("TRACKING","TRACKING"); dir->cd(); // Create Trees trkeff = new TTree("trkeff2","Tracking Efficiency"); trkeff->Branch("E","track2",&trk_ptr); dir->cd("../"); JParameterManager *parms = app->GetJParameterManager(); DEBUG = 1; parms->SetDefaultParameter("TRKEFF:DEBUG", DEBUG); return NOERROR; } //------------------ // brun //------------------ jerror_t DEventProcessor_trackeff_hists2::brun(JEventLoop *loop, int runnumber) { DApplication *dapp = dynamic_cast(loop->GetJApplication()); const DGeometry *dgeom = dapp->GetDGeometry(runnumber); rt_thrown = new DReferenceTrajectory(dgeom->GetBfield()); double dz, rmin, rmax; dgeom->GetCDCEndplate(CDCZmax, dz, rmin, rmax); double cdc_axial_length; dgeom->GetCDCAxialLength(cdc_axial_length); CDCZmin = CDCZmax-cdc_axial_length; return NOERROR; } //------------------ // erun //------------------ jerror_t DEventProcessor_trackeff_hists2::erun(void) { return NOERROR; } //------------------ // fini //------------------ jerror_t DEventProcessor_trackeff_hists2::fini(void) { return NOERROR; } //------------------ // evnt //------------------ jerror_t DEventProcessor_trackeff_hists2::evnt(JEventLoop *loop, int eventnumber) { vector cdctrackhits; vector fdchits; vector particles; vector mcthrowns; vector mctrajpoints; // Bail quick on events with too many or too few CDC hits loop->Get(cdctrackhits); //if(cdctrackhits.size()>30 || cdctrackhits.size()<6)return NOERROR; // Bail quick on events with too many FDC hits loop->Get(fdchits); //if(fdchits.size()>30)return NOERROR; loop->Get(particles); loop->Get(mcthrowns); loop->Get(mctrajpoints); // Lock mutex pthread_mutex_lock(&mutex); // Get hit list for all throwns for(unsigned int i=0; iSwim(mcthrown->position(), mcthrown->momentum(), mcthrown->charge()); // if this isn't a charged track, then skip it if(fabs(mcthrowns[i]->charge())==0.0)continue; // Momentum of thrown particle DVector3 pthrown = mcthrown->momentum(); trk.pthrown = pthrown; // Initialize with the "not found" values trk.pfit.SetXYZ(0,0,0); trk.pfit_wire.SetXYZ(0,0,0); trk.pcan.SetXYZ(0,0,0); trk.trk_chisq=1.0E20; trk.trk_Ndof=1; trk.trk_chisq_wb=1.0E20; trk.trk_Ndof_wb=1; trk.delta_pt_over_pt=1.0E20; trk.delta_theta=1.0E20; trk.delta_phi=1.0E20; trk.isreconstructable = isReconstructable(mcthrown, mctrajpoints); trk.Nstereo = 0; trk.Ncdc = 0; trk.Nfdc = 0; trk.NLR_bad_stereo = 0; trk.NLR_bad = 0; trk.event = eventnumber; double fom_best = 1.0E8; // Loop over found/fit tracks for(unsigned int j=0; j tracks; particle->Get(tracks); const DTrackWireBased *track = tracks.size()==1 ? tracks[0]:NULL; vector trackcandidates; if(track)track->Get(trackcandidates); const DTrackCandidate *trackcandidate = trackcandidates.size()==1 ? trackcandidates[0]:NULL; // Copy momentum vectors to convenient local variables DVector3 pfit = particle->momentum(); DVector3 pfit_wire = track ? track->momentum():DVector3(0,0,0); DVector3 pcan = trackcandidate ? trackcandidate->momentum():DVector3(0,0,0); // Calculate residuals from momentum parameters from DParticle double delta_pt_over_pt = (pfit.Perp() - pthrown.Perp())/pthrown.Perp(); double delta_theta = (pfit.Theta() - pthrown.Theta())*1000.0; double delta_phi = (pfit.Phi() - pthrown.Phi())*1000.0; // Formulate a figure of merit to decide if this fit track is closer to // the thrown track than the best one we found so far. We hardwire // dpt/pt=2%, dtheta=20mrad and dphi=20mrad for now. double fom = pow(delta_pt_over_pt/0.02, 2.0) + pow(delta_theta/20.0, 2.0) + pow(delta_phi/20.0, 2.0); if(fomchisq; trk.trk_Ndof = particle->Ndof; trk.trk_chisq_wb = track!=NULL ? track->chisq:1.0E6; trk.trk_Ndof_wb = track!=NULL ? track->Ndof:0; trk.delta_pt_over_pt = delta_pt_over_pt; trk.delta_theta = delta_theta; trk.delta_phi = delta_phi; // Get Nstereo, Ncdc, and Nfdc vector cdchits; particle->Get(cdchits); trk.Nstereo = 0; for(unsigned int k=0; kwire->stereo!=0.0)trk.Nstereo++; trk.Ncdc = cdchits.size(); vector fdchits; particle->Get(fdchits); trk.Nfdc = fdchits.size(); // Get the number LR signs for all hits used on this track. We have to // do this for the thrown track here so we get the list for the same hits // used in fitting this track. vector LRthrown; vector LRfit; vector wires; for(unsigned int k=0; kwire); for(unsigned int k=0; kwire); if(use_rt_thrown){ FindLR(wires, rt_thrown, LRthrown); }else{ FindLR(wires, mctrajpoints, LRthrown); } FindLR(wires, particle->rt, LRfit); // Make sure the number of entries is the same for both LR vectors if(LRfit.size()!=LRthrown.size() || LRfit.size()!=wires.size()){ _DBG_<<"LR vector sizes do not match! LRfit.size()="<track != mcthrown->myid)continue; if(mctraj->primary_track != mcthrown->myid)continue; // redundant? if(mctraj_first==NULL)mctraj_first = mctraj; mctraj_last = mctraj; } if(mctraj_last!=NULL){ double r = sqrt(pow((double)mctraj_last->x,2.0) + pow((double)mctraj_last->y,2.0)); if(r>45.0)return true; if(mctraj_last->z<17.0)return true; if(mctraj_last->z<17.0)return true; } return false; } //------------------ // FindLR //------------------ void DEventProcessor_trackeff_hists2::FindLR(vector &wires, const DReferenceTrajectory *crt, vector &LRhits) { /// Fill the vector LRhits with +1 or -1 values indicating the side of each wire in the "wires" /// vector the given reference trajectory passed on. LRhits.clear(); // This first bit is shameful. In order to use the DistToRT methods of the reference trajectory, // we have to cast away the const qualifier since those methods must modify the object DReferenceTrajectory *rt = const_cast(crt); for(unsigned int i=0; iDistToRT(wire); rt->GetLastDOCAPoint(pos_doca, mom_doca); DVector3 shift = wire->udir.Cross(mom_doca); double u = rt->GetLastDistAlongWire(); DVector3 pos_wire = wire->origin + u*wire->udir; DVector3 pos_diff = pos_doca-pos_wire; LRhits.push_back(shift.Dot(pos_diff)<0.0 ? -1:1); } } //------------------ // FindLR //------------------ void DEventProcessor_trackeff_hists2::FindLR(vector &wires, vector &trajpoints, vector &LRhits) { /// Fill the vector LRhits with +1 or -1 values indicating the side of each wire in the "wires" /// vector the particle swum by GEANT passed on according to the closest DMCTrajectoryPoint. }