int PHG4GenFitTrackProjection::process_event(PHCompositeNode *topNode) { if (verbosity > 1) cout << "PHG4GenFitTrackProjection::process_event -- entered" << endl; //--------------------------------- // Get Objects off of the Node Tree //--------------------------------- // Pull the reconstructed track information off the node tree... SvtxTrackMap* _g4tracks = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap"); if (!_g4tracks) { cerr << PHWHERE << " ERROR: Can't find SvtxTrackMap." << endl; return Fun4AllReturnCodes::ABORTRUN; } for (int i = 0; i < _num_cal_layers; ++i) { if (std::isnan(_cal_radii[i])) continue; if (verbosity > 1) cout << "Projecting tracks into: " << _cal_names[i] << endl; // pull the tower geometry string towergeonodename = "TOWERGEOM_" + _cal_names[i]; RawTowerGeomContainer *towergeo = findNode::getClass< RawTowerGeomContainer>(topNode, towergeonodename.c_str()); if (!towergeo) { cerr << PHWHERE << " ERROR: Can't find node " << towergeonodename << endl; return Fun4AllReturnCodes::ABORTRUN; } // pull the towers string towernodename = "TOWER_CALIB_" + _cal_names[i]; RawTowerContainer *towerList = findNode::getClass<RawTowerContainer>( topNode, towernodename.c_str()); if (!towerList) { cerr << PHWHERE << " ERROR: Can't find node " << towernodename << endl; return Fun4AllReturnCodes::ABORTRUN; } // pull the clusters string clusternodename = "CLUSTER_" + _cal_names[i]; RawClusterContainer *clusterList = findNode::getClass< RawClusterContainer>(topNode, clusternodename.c_str()); if (!clusterList) { cerr << PHWHERE << " ERROR: Can't find node " << clusternodename << endl; return Fun4AllReturnCodes::ABORTRUN; } // loop over all tracks for (SvtxTrackMap::Iter iter = _g4tracks->begin(); iter != _g4tracks->end(); ++iter) { SvtxTrack *track = iter->second; #ifdef DEBUG cout <<__LINE__ <<": track->get_charge(): "<<track->get_charge() <<endl; #endif if(!track) { if(verbosity >= 2) LogWarning("!track"); continue; } if (verbosity > 1) cout << "projecting track id " << track->get_id() << endl; if (verbosity > 1) { cout << " track pt = " << track->get_pt() << endl; } std::vector<double> point; point.assign(3, -9999.); auto last_state_iter = --track->end_states(); SvtxTrackState * trackstate = last_state_iter->second; if(!trackstate) { if(verbosity >= 2) LogWarning("!trackstate"); continue; } auto pdg = unique_ptr<TDatabasePDG> (TDatabasePDG::Instance()); int reco_charge = track->get_charge(); int gues_charge = pdg->GetParticle(_pid_guess)->Charge(); if(reco_charge*gues_charge<0) _pid_guess *= -1; #ifdef DEBUG cout <<__LINE__ <<": guess charge: " << gues_charge <<": reco charge: " << reco_charge <<": pid: " << _pid_guess <<": pT: " << sqrt(trackstate->get_px()*trackstate->get_px() + trackstate->get_py()*trackstate->get_py()) <<endl; #endif auto rep = unique_ptr<genfit::AbsTrackRep> (new genfit::RKTrackRep(_pid_guess)); unique_ptr<genfit::MeasuredStateOnPlane> msop80 = nullptr; { TVector3 pos(trackstate->get_x(), trackstate->get_y(), trackstate->get_z()); //pos.SetXYZ(0.01,0,0); TVector3 mom(trackstate->get_px(), trackstate->get_py(), trackstate->get_pz()); //mom.SetXYZ(1,0,0); TMatrixDSym cov(6); for (int i = 0; i < 6; ++i) { for (int j = 0; j < 6; ++j) { cov[i][j] = trackstate->get_error(i, j); } } msop80 = unique_ptr<genfit::MeasuredStateOnPlane> (new genfit::MeasuredStateOnPlane(rep.get())); msop80->setPosMomCov(pos, mom, cov); } #ifdef DEBUG { double x = msop80->getPos().X(); double y = msop80->getPos().Y(); double z = msop80->getPos().Z(); // double px = msop80->getMom().X(); // double py = msop80->getMom().Y(); double pz = msop80->getMom().Z(); genfit::FieldManager *field_mgr = genfit::FieldManager::getInstance(); double Bx=0, By=0, Bz=0; field_mgr->getFieldVal(x,y,z,Bx,By,Bz); cout << __LINE__ << ": { " << msop80->getPos().Perp() << ", " << msop80->getPos().Phi() << ", " << msop80->getPos().Eta() << "} @ " //<< "{ " << Bx << ", " << By << ", " << Bz << "}" << "{ " << msop80->getMom().Perp() << ", " << msop80->getMom().Phi() << ", " << pz << "} " <<endl; //msop80->Print(); } #endif try { rep->extrapolateToCylinder(*msop80, _cal_radii[i], TVector3(0,0,0), TVector3(0,0,1)); //rep->extrapolateToCylinder(*msop80, 5., TVector3(0,0,0), TVector3(0,0,1)); } catch (...) { if(verbosity >= 2) LogWarning("extrapolateToCylinder failed"); continue; } #ifdef DEBUG { cout<<__LINE__<<endl; //msop80->Print(); double x = msop80->getPos().X(); double y = msop80->getPos().Y(); double z = msop80->getPos().Z(); // double px = msop80->getMom().X(); // double py = msop80->getMom().Y(); double pz = msop80->getMom().Z(); genfit::FieldManager *field_mgr = genfit::FieldManager::getInstance(); double Bx=0, By=0, Bz=0; field_mgr->getFieldVal(x,y,z,Bx,By,Bz); cout << __LINE__ << ": { " << msop80->getPos().Perp() << ", " << msop80->getPos().Phi() << ", " << msop80->getPos().Eta() << "} @ " //<< "{ " << Bx << ", " << By << ", " << Bz << "}" << "{ " << msop80->getMom().Perp() << ", " << msop80->getMom().Phi() << ", " << pz << "} " <<endl; } #endif point[0] = msop80->getPos().X(); point[1] = msop80->getPos().Y(); point[2] = msop80->getPos().Z(); #ifdef DEBUG cout <<__LINE__ <<": GenFit: {" << point[0] <<", " << point[1] <<", " << point[2] <<" }" <<endl; #endif if (std::isnan(point[0])) continue; if (std::isnan(point[1])) continue; if (std::isnan(point[2])) continue; double x = point[0]; double y = point[1]; double z = point[2]; double phi = atan2(y, x); double eta = asinh(z / sqrt(x * x + y * y)); if (verbosity > 1) { cout << " initial track phi = " << track->get_phi(); cout << ", eta = " << track->get_eta() << endl; cout << " calorimeter phi = " << phi << ", eta = " << eta << endl; } // projection is outside the detector extent // TODO towergeo doesn't make this easy to extract, but this should be // fetched from the node tree instead of hardcoded if (fabs(eta) >= 1.0) continue; // calculate 3x3 tower energy int binphi = towergeo->get_phibin(phi); int bineta = towergeo->get_etabin(eta); double energy_3x3 = 0.0; double energy_5x5 = 0.0; for (int iphi = binphi - 2; iphi <= binphi + 2; ++iphi) { for (int ieta = bineta - 2; ieta <= bineta + 2; ++ieta) { // wrap around int wrapphi = iphi; if (wrapphi < 0) { wrapphi = towergeo->get_phibins() + wrapphi; } if (wrapphi >= towergeo->get_phibins()) { wrapphi = wrapphi - towergeo->get_phibins(); } // edges if (ieta < 0) continue; if (ieta >= towergeo->get_etabins()) continue; RawTower* tower = towerList->getTower(ieta, wrapphi); if (tower) { energy_5x5 += tower->get_energy(); if (abs(iphi - binphi) <= 1 and abs(ieta - bineta) <= 1) energy_3x3 += tower->get_energy(); if (verbosity > 1) cout << " tower " << ieta << " " << wrapphi << " energy = " << tower->get_energy() << endl; } } } track->set_cal_energy_3x3(_cal_types[i], energy_3x3); track->set_cal_energy_5x5(_cal_types[i], energy_5x5); // loop over all clusters and find nearest double min_r = DBL_MAX; double min_index = -9999; double min_dphi = NAN; double min_deta = NAN; double min_e = NAN; #ifdef DEBUG double min_cluster_phi = NAN; #endif for (unsigned int k = 0; k < clusterList->size(); ++k) { RawCluster *cluster = clusterList->getCluster(k); double dphi = atan2(sin(phi - cluster->get_phi()), cos(phi - cluster->get_phi())); double deta = eta - cluster->get_eta(); double r = sqrt(pow(dphi, 2) + pow(deta, 2)); if (r < min_r) { min_index = k; min_r = r; min_dphi = dphi; min_deta = deta; min_e = cluster->get_energy(); #ifdef DEBUG min_cluster_phi = cluster->get_phi(); #endif } } if (min_index != -9999) { track->set_cal_dphi(_cal_types[i], min_dphi); track->set_cal_deta(_cal_types[i], min_deta); track->set_cal_cluster_id(_cal_types[i], min_index); track->set_cal_cluster_e(_cal_types[i], min_e); #ifdef DEBUG cout <<__LINE__ <<": min_cluster_phi: "<<min_cluster_phi <<endl; #endif if (verbosity > 1) { cout << " nearest cluster dphi = " << min_dphi << " deta = " << min_deta << " e = " << min_e << endl; } } } // end track loop } // end calorimeter layer loop if (verbosity > 1) cout << "PHG4GenFitTrackProjection::process_event -- exited" << endl; return Fun4AllReturnCodes::EVENT_OK; }
SvtxTrack* TrackProjectionTools::FindClosestTrack( RawCluster* cluster, float& best_track_dr ) { /* best matching track */ SvtxTrack* best_track = NULL; best_track_dr = NAN; /* find name of calorimeter for this cluster */ string caloname = "NONE"; /* C++11 range loop */ for (auto& towit : cluster->get_towermap() ) { caloname = RawTowerDefs::convert_caloid_to_name( RawTowerDefs::decode_caloid(towit.first) ); break; } /* Get track collection with all tracks in this event */ SvtxTrackMap* trackmap = findNode::getClass<SvtxTrackMap>(_topNode,"SvtxTrackMap_FastSim"); if (!trackmap) { cout << PHWHERE << "SvtxTrackMap node not found on node tree" << endl; } /* Loop over all tracks from BARREL tracking and see if one points to the same * cluster as the reference clusters (i.e. matching ID in the same calorimeter) */ /* for (SvtxTrackMap::ConstIter track_itr = trackmap->begin(); track_itr != trackmap->end(); track_itr++) { SvtxTrack* track = dynamic_cast<SvtxTrack*>(track_itr->second); if ( caloname == "CEMC" && track->get_cal_cluster_id(SvtxTrack::CEMC) == cluster->get_id() ) { best_track = track; } } */ /* If track found with barrel tracking, return it here- if not, proceed with forward tracking below. */ if ( best_track ) return best_track; /* Cluster / track matching for barrel calorimeters and tracking */ float max_dr = 10; /* cluster position for easy reference */ float cx = cluster->get_x(); float cy = cluster->get_y(); /* If track map found: Loop over all tracks to find best match for cluster (forward calorimeters)*/ if ( trackmap && ( caloname == "FEMC" || caloname == "EEMC" ) ) { for (SvtxTrackMap::ConstIter track_itr = trackmap->begin(); track_itr != trackmap->end(); track_itr++) { /* get pointer to track */ SvtxTrack* track = dynamic_cast<SvtxTrack*>(track_itr->second); /* distance between track and cluster */ float dr = NAN; /* loop over track states (projections) sotred for this track */ for (SvtxTrack::ConstStateIter state_itr = track->begin_states(); state_itr != track->end_states(); state_itr++) { /* get pointer to current track state */ SvtxTrackState *temp = dynamic_cast<SvtxTrackState*>(state_itr->second); /* check if track state projection name matches calorimeter where cluster was found */ if( (temp->get_name()==caloname) ) { dr = sqrt( pow( cx - temp->get_x(), 2 ) + pow( cy - temp->get_y(), 2 ) ); break; } } /* check dr and update best_track and best_track_dr if this track is closest to cluster */ if ( ( best_track_dr != best_track_dr ) || ( dr < max_dr && dr < best_track_dr ) ) { best_track = track; best_track_dr = dr; } } } /* If track found with barrel tracking, return it here- if not, proceed with alternative barrel cluster-track matching below. */ if ( best_track ) return best_track; /* Cluster / track matching for barrel calorimeters and tracking */ float max_dr_barrel = 10; float ctheta = atan2( cluster->get_r() , cluster->get_z() ); float ceta = -log( tan( ctheta / 2.0 ) ); float cphi = cluster->get_phi(); /* If track map found: Loop over all tracks to find best match for cluster (barrel calorimeters)*/ if ( trackmap && ( caloname == "CEMC" ) ) { for (SvtxTrackMap::ConstIter track_itr = trackmap->begin(); track_itr != trackmap->end(); track_itr++) { /* get pointer to track */ SvtxTrack* track = dynamic_cast<SvtxTrack*>(track_itr->second); /* distance between track and cluster */ float dr = NAN; /* loop over track states (projections) sotred for this track */ for (SvtxTrack::ConstStateIter state_itr = track->begin_states(); state_itr != track->end_states(); state_itr++) { /* get pointer to current track state */ SvtxTrackState *temp = dynamic_cast<SvtxTrackState*>(state_itr->second); /* check if track state projection name matches calorimeter where cluster was found */ if( (temp->get_name()==caloname) ) { dr = sqrt( pow( ceta - temp->get_eta(), 2 ) + pow( cphi - temp->get_phi(), 2 ) ); break; } } /* check dr and update best_track and best_track_dr if this track is closest to cluster */ if ( ( best_track_dr != best_track_dr ) || (dr < max_dr_barrel && dr < best_track_dr) ) { best_track = track; best_track_dr = dr; } } } return best_track; }