diff --git a/Reconstruction/SiliconTracking/CMakeLists.txt b/Reconstruction/SiliconTracking/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f76fb016d2ffc54c7c2bfc183013669f1aa6786 --- /dev/null +++ b/Reconstruction/SiliconTracking/CMakeLists.txt @@ -0,0 +1,21 @@ +gaudi_subdir(SiliconTracking v0r0) + +find_package(GEAR REQUIRED) +find_package(GSL REQUIRED ) +find_package(LCIO REQUIRED ) +find_package(EDM4HEP REQUIRED ) + +gaudi_depends_on_subdirs( + Service/GearSvc + Service/EventSeeder + Service/TrackSystemSvc + Utilities/DataHelper +) + +set(SiliconTracking_srcs src/*.cpp) + +# Modules +gaudi_add_module(SiliconTracking ${SiliconTracking_srcs} + INCLUDE_DIRS GaudiKernel FWCore gear ${GSLx_INCLUDE_DIRS} ${LCIOx_INCLUDE_DIRS} + LINK_LIBRARIES TrackSystemSvcLib DataHelperLib GaudiKernel FWCore $ENV{GEAR}/lib/libgearsurf.so ${GSL_LIBRARIES} ${LCIO_LIBRARIES} +) diff --git a/Reconstruction/SiliconTracking/CMakeLists.txt~ b/Reconstruction/SiliconTracking/CMakeLists.txt~ new file mode 100644 index 0000000000000000000000000000000000000000..49e8a2a273939f18b7d7a91e3fffc5910b8703b7 --- /dev/null +++ b/Reconstruction/SiliconTracking/CMakeLists.txt~ @@ -0,0 +1,21 @@ +gaudi_subdir(SiliconTracking v0r0) + +find_package(GEAR REQUIRED) +find_package(GSL REQUIRED ) +find_package(LCIO REQUIRED ) +find_package(EDM4HEP REQUIRED ) + +gaudi_depends_on_subdirs( + Service/GearSvc + Service/EventSeeder + Service/TrackSystemSvc + Utilities/DataHelper +) + +set(SiliconTracking_srcs src/*.cpp) + +# Modules +gaudi_add_module(SiliconTracking ${SiliconTracking_srcs} + INCLUDE_DIRS GaudiKernel FWCore gear ${GSLx_INCLUDE_DIRS} ${LCIOx_INCLUDE_DIRS} + LINK_LIBRARIES TrackSystemSvcLib DataHelper GaudiKernel FWCore $ENV{GEAR}/lib/libgearsurf.so ${GSL_LIBRARIES} ${LCIO_LIBRARIES} +) diff --git a/Reconstruction/SiliconTracking/src/SiliconTracking.cpp~ b/Reconstruction/SiliconTracking/src/SiliconTracking.cpp~ new file mode 100644 index 0000000000000000000000000000000000000000..7c22fc853a96a13ac71ee59cbc5e7ebb3501c7f1 --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTracking.cpp~ @@ -0,0 +1,3084 @@ +#include "SiliconTracking.h" +#include "GearSvc/IGearSvc.h" +#include "EventSeeder/IEventSeeder.h" +#include "TrackSystemSvc/ITrackSystemSvc.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/TrackerHit.h" +//#include "edm4hep/TrackerHitPlane.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackState.h" + +#include <iostream> +#include <algorithm> +#include <cmath> +#include <climits> + +#include <gear/GEAR.h> +#include <gear/GearMgr.h> +#include <gear/GearParameters.h> +#include <gear/VXDLayerLayout.h> +#include <gear/VXDParameters.h> +#include "gear/FTDLayerLayout.h" +#include "gear/FTDParameters.h" + +#include <gear/BField.h> + +#include <UTIL/BitField64.h> +#include <UTIL/BitSet32.h> +#include <UTIL/ILDConf.h> + +#include "TrackSystemSvc/MarlinTrkUtils.h" +#include "TrackSystemSvc/HelixTrack.h" +#include "TrackSystemSvc/HelixFit.h" +#include "TrackSystemSvc/IMarlinTrack.h" +//#include "MarlinTrk/Factory.h" + +//#include "TrackSystemSvc/MarlinTrkDiagnostics.h" +//#ifdef MARLINTRK_DIAGNOSTICS_ON +//#include "TrackSystemSvc/DiagnosticsController.h" +//#endif + +//#include "MarlinCED.h" + +//#include "marlin/AIDAProcessor.h" + +//---- ROOT ----- +#include "TH1F.h" +#include "TH2F.h" + +using namespace edm4hep ; +//using namespace marlin ; +using namespace MarlinTrk ; + +using std::min; +using std::max; +using std::abs; + +const int SiliconTracking::_output_track_col_quality_GOOD = 1; +const int SiliconTracking::_output_track_col_quality_FAIR = 2; +const int SiliconTracking::_output_track_col_quality_POOR = 3; + +const double SiliconTracking::TWOPI = 2*M_PI; + +DECLARE_COMPONENT( SiliconTracking ) + +SiliconTracking::SiliconTracking(const std::string& name, ISvcLocator* svcLoc) +: GaudiAlgorithm(name, svcLoc) { + + //_description = "Pattern recognition in silicon trackers"; + + _fastfitter = new MarlinTrk::HelixFit(); + + _encoder = new UTIL::BitField64(lcio::ILDCellID0::encoder_string); + + _petalBasedFTDWithOverlaps = false; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Input Collections + // ^^^^^^^^^^^^^^^^^ + declareProperty("HeaderCol", _headerColHdl); + declareProperty("MCParticleCollection", _inMCColHdl, "Handle of the Input MCParticle collection"); + declareProperty("VTXHitCollection", _inVTXColHdl, "Handle of the Input VTX TrackerHits collection"); + declareProperty("FTDPixelHitCollection", _inFTDPixelColHdl, "Handle of the Input FTD TrackerHits collection"); + declareProperty("FTDSpacePointCollection", _inFTDSpacePointColHdl, "Handle of the Input FTD SpacePoints collection"); + declareProperty("SITHitCollection", _inSITColHdl, "Handle of the Input SIT TrackerHits collection"); + + // Output Collections + // ^^^^^^^^^^^^^^^^^^ + declareProperty("SiTrackCollection", _outColHdl, "Handle of the SiTrack output collection"); + //declareProperty("TrkHitRelCollection", _outRelColHdl, "Handle of TrackerHit Track relation collection"); + // Steering parameters + // ^^^^^^^^^^^^^^^^^^^ + + _output_track_col_quality = _output_track_col_quality_GOOD; + +} + + + +StatusCode SiliconTracking::initialize() { + + _nRun = -1 ; + _nEvt = 0 ; + //printParameters() ; + + // set up the geometery needed by KalTest + //FIXME: for now do KalTest only - make this a steering parameter to use other fitters + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return StatusCode::FAILURE; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return StatusCode::FAILURE; + } + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + std::cout << "fucd ==============" << _trksystem << std::endl; +#ifdef MARLINTRK_DIAGNOSTICS_ON + + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->init(_MarlinTrkDiagnosticsName,_MarlinTrkDiagnosticsName, _runMarlinTrkDiagnostics); + +#endif + + if(setupGearGeom()==StatusCode::FAILURE) return StatusCode::FAILURE; + + if (_useSIT == 0) + _nLayers = _nLayersVTX; + else + _nLayers = _nLayersVTX + _nLayersSIT; + + // initialise the container to have separate vectors for up to _nHitsChi2 hits. + _tracksWithNHitsContainer.resize(_nHitsChi2); + + _dPhi = TWOPI/_nDivisionsInPhi; + _dTheta = 2.0/_nDivisionsInTheta; + _dPhiFTD = TWOPI/_nPhiFTD; + // I leave this for the moment, but 0.3 is c/1e9. + // For the cut it does not make too much of a difference + double cutOnR = _cutOnPt/(0.3*_bField); + cutOnR = 1000.*cutOnR; + _cutOnOmega = 1/cutOnR; + + _output_track_col_quality = 0; + + return GaudiAlgorithm::initialize(); +} + +StatusCode SiliconTracking::execute(){ + + //_current_event = evt; + //_allHits.reserve(1000); + + _output_track_col_quality = _output_track_col_quality_GOOD; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Clearing the working containers from the previous event + // FIXME: partly done at the end of the event, in CleanUp. Make it consistent. + //_tracksWithNHitsContainer.clear(); + //_trackImplVec.clear(); + + //_colTrackerHits.clear(); + //_colNamesTrackerHits.clear(); + //auto header = _headerColHdl.get()->at(0); + //int evtNo = header.getEventNumber(); + //int runNo = header.getRunNumber(); + //debug() << "Processing Run[" << runNo << "]::Event[" << evtNo << "]" << endmsg; + + _trackImplVec.reserve(100); + _allHits.reserve(1000); + + int successVTX = InitialiseVTX(); + int successFTD = 0; + //int successFTD = InitialiseFTD(); + if (successVTX == 1) { + + debug() << " phi theta layer nh o : m : i :: o*m*i " << endmsg; + + for (int iPhi=0; iPhi<_nDivisionsInPhi; ++iPhi) { + for (int iTheta=0; iTheta<_nDivisionsInTheta;++iTheta) { + ProcessOneSector(iPhi,iTheta); // Process one VXD sector + } + } + + debug() << "End of Processing VXD and SIT sectors" << endmsg; + + } + + if (successFTD == 1) { + debug() << " phi side layer nh o : m : i :: o*m*i " << endmsg; + TrackingInFTD(); // Perform tracking in the FTD + debug() << "End of Processing FTD sectors" << endmsg; + } + + //if(0){ + if (successVTX == 1 || successFTD == 1) { + //if (successVTX == 1 ) { + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + Sorting( _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ) ); + + } + debug() << "End of Sorting " << endmsg; + + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + + TrackExtendedVec &tracksWithNHits = _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ); + for (TrackExtendedVec::iterator trackIter = tracksWithNHits.begin(); + trackIter < tracksWithNHits.end(); trackIter++) { + CreateTrack( *trackIter ); + } + debug() << "End of creating "<< nHits << " hits tracks " << endmsg; + } + + if (_attachFast == 0) { + if(successVTX) AttachRemainingVTXHitsSlow(); + if(successFTD) AttachRemainingFTDHitsSlow(); + } + else { + if(successVTX) AttachRemainingVTXHitsFast(); + if(successFTD) AttachRemainingFTDHitsFast(); + } + + debug() << "End of picking up remaining hits " << endmsg; + + //edm4hep::TrackCollection* trkCol = nullptr; + //edm4hep::LCRelationCollection* relCol = nullptr; + auto trkCol = _outColHdl.createAndPut(); + //auto relCol = _outRelColHdl.createAndPut(); + //std::cout << "fucd------------------" << std::endl; + /* + LCCollectionVec * trkCol = new LCCollectionVec(LCIO::TRACK); + // if we want to point back to the hits we need to set the flag + LCFlagImpl trkFlag(0) ; + trkFlag.setBit( LCIO::TRBIT_HITS ) ; + trkCol->setFlag( trkFlag.getFlag() ) ; + + LCCollectionVec * relCol = NULL; + */ + //FinalRefit(trkCol, relCol); + FinalRefit(trkCol); + //std::cout << "fucd------------------" << std::endl; + // set the quality of the output collection + switch (_output_track_col_quality) { + + case _output_track_col_quality_FAIR: + //trkCol->parameters().setValue( "QualityCode" , "Fair" ) ; + break; + + case _output_track_col_quality_POOR: + //trkCol->parameters().setValue( "QualityCode" , "Poor" ) ; + break; + + default: + //trkCol->parameters().setValue( "QualityCode" , "Good" ) ; + break; + } + /* + if (_UseEventDisplay) { + this->drawEvent(); + } + */ + } + + // fill event based histogram + /* + if (_createDiagnosticsHistograms) { + + // triplet histos + _histos->fill1D(DiagnosticsHistograms::hntriplets, _ntriplets); + _histos->fill1D(DiagnosticsHistograms::hntriplets_good, _ntriplets_good); + _histos->fill1D(DiagnosticsHistograms::hntriplets_2MCP, _ntriplets_2MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_3MCP, _ntriplets_3MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_1MCP_Bad, _ntriplets_1MCP_Bad); + _histos->fill1D(DiagnosticsHistograms::hntriplets_bad, _ntriplets_bad); + + } + */ + /* + const edm4hep::MCParticleCollection* mcCol = nullptr; + try{ + mcCol =_inMCColHdl.get(); + } + catch(...){ + } + if(mcCol){ + int id = 0; + for(auto mcP : *mcCol){ + float pos[3]; + float mom[3]; + pos[0] = mcP.vertex()[0]; + pos[1] = mcP.vertex()[1]; + pos[2] = mcP.vertex()[2]; + mom[0] = mcP.momentum()[0]; + mom[1] = mcP.momentum()[1]; + mom[2] = mcP.momentum()[2]; + float charge = mcP.getCharge(); + HelixClass helix; + helix.Initialize_VP(pos,mom,charge,_bField); + float d0 = helix.getD0(); + float z0 = helix.getZ0(); + float omega = helix.getOmega(); + float phi0 = helix.getPhi0(); + float tanLambda = helix.getTanLambda(); + std::cout <<"MCParticle: " << evtNo << " " << id << " " << sqrt(mom[0]*mom[0]+mom[1]*mom[1]) << " " << acos(mom[2]/sqrt(mom[0]*mom[0]+mom[1]*mom[1]+mom[2]*mom[2])) + << " " << atan2(mom[1],mom[0]) + << " " << d0 << " " << phi0 << " " << omega << " " << z0 << " " << tanLambda << " " << mcP.vertex() << std::endl; + id++; + } + } + + const edm4hep::TrackCollection* trkCol = nullptr; + try{ + trkCol = _outColHdl.get(); + } + catch(...){ + } + if(trkCol){ + int id = 0; + for(auto track : *trkCol){ + int nstate = track->trackStates_size(); + for(int i=0;i<nstate;i++){ + edm4hep::TrackState trkState = track->getTrackStates(i); + if(trkState.location != 1) continue; + HelixClass helix_final; + helix_final.Initialize_Canonical(trkState.phi,trkState.D0,trkState.Z0,trkState.omega,trkState.tanLambda,_bField); + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkPt = sqrt(trkPx*trkPx+trkPy*trkPy); + std::cout << "Track parameter: " << evtNo << " " << id << " " << trkPt << " " << acos(trkPz/sqrt(trkPt*trkPt+trkPz*trkPz)) << " " << atan2(trkPy,trkPx) + << " " << trkState.D0 << " " << trkState.phi << " " << trkState.omega << " " << trkState.Z0 << " " << trkState.tanLambda + << " " << sqrt(trkState.covMatrix[0]) << " " << sqrt(trkState.covMatrix[2]) << " " << sqrt(trkState.covMatrix[5]) + << " " << sqrt(trkState.covMatrix[9]) << " " << sqrt(trkState.covMatrix[14]) << " " << std::endl; + id++; + break; + } + } + } + */ + CleanUp(); + debug() << "Event is done " << endmsg; + _nEvt++; + return StatusCode::SUCCESS; +} + + +void SiliconTracking::CleanUp() { + + _tracksWithNHitsContainer.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + unsigned int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + + if( iCode >= _sectors.size()){ + error() << "iCode index out of range: iCode = " << iCode << " _sectors.size() = " << _sectors.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + unsigned int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + + if( iCode >= _sectorsFTD.size()){ + //error() << "iCode index out of range: iCode = " << iCode << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + _trackImplVec.clear(); + _allHits.clear(); +} + +int SiliconTracking::InitialiseFTD() { + + int success = 1; + + _nTotalFTDHits = 0; + _sectorsFTD.clear(); + _sectorsFTD.resize(2*_nlayersFTD*_nPhiFTD); + + // Reading in FTD Pixel Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDPixelCol = nullptr; + try { + hitFTDPixelCol = _inFTDPixelColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDPixelColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDPixelCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDPixelHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDPixelHitCollection; + // _colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDPixelCol->size(); + + debug() << "Number of FTD Pixel Hits = " << nelem << endmsg; + _nTotalFTDHits = nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDPixelCol){ + // edm4hep::TrackerHit* hit = hitFTDPixelCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended( hit ); + + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(V.dot(Z)) > eps ) { + error() << "SiliconTracking: VXD Hit measurment vectors V is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTracking: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // SJA:FIXME Here dU and dV are almost certainly dX and dY ... should test ... + //double point_res_rphi = sqrt( hit->getdU()*hit->getdU() + hit->getdV()*hit->getdV() ); + double point_res_rphi = sqrt( hit.getCovMatrix()[2]*hit.getCovMatrix()[2] + hit.getCovMatrix()[5]*hit.getCovMatrix()[5] ); + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTracking => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD Pixel Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + } + } + // Reading out FTD SpacePoint Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDSpacePointCol = nullptr; + try { + hitFTDSpacePointCol = _inFTDSpacePointColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDSpacePointColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDSpacePointCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDSpacePointCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDSpacePointCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDSpacePointCol->size(); + + debug() << "Number of FTD SpacePoints = " << nelem << endmsg; + _nTotalFTDHits += nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDSpacePointCol){ + //edm4hep::TrackerHit* hit = hitFTDSpacePointCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + double point_res_rphi = 2 * sqrt( hit.getCovMatrix()[0] + hit.getCovMatrix()[2] ); + + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTracking => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD SpacePoint Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + for (unsigned i=0; i<_sectorsFTD.size(); ++i) { + int nhits = _sectorsFTD[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in FTD Sector " << i << " = " << _sectorsFTD[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectorsFTD[i].size(); ++ihit) { + delete _sectorsFTD[i][ihit]; + } + _sectorsFTD[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in FTD Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + + } + + } + debug() << "FTD initialized" << endmsg; + return success; +} + +int SiliconTracking::InitialiseVTX() { + //std::cout << "fucd================" << std::endl; + _nTotalVTXHits = 0; + _nTotalSITHits = 0; + _sectors.clear(); + _sectors.resize(_nLayers*_nDivisionsInPhi*_nDivisionsInTheta); + //std::cout << "fucd================" << std::endl; + int success = 1; + // Reading out VTX Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitVTXCol = nullptr; + try { + hitVTXCol = _inVTXColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inVTXColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitVTXCol){ + //LCCollection * hitCollection = evt->getCollection(_VTXHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _VTXHitCollection; + //_colTrackerHits.push_back(hitCollection); + //std::cout << "fucd================1" << std::endl; + int nelem = hitVTXCol->size(); + //std::cout << "fucd================2" << std::endl; + debug() << "Number of VTX hits = " << nelem << endmsg; + _nTotalVTXHits = nelem; + + for (int ielem=0; ielem<nelem; ++ielem) { + //for(auto hit : *hitVTXCol){ + edm4hep::TrackerHit hit = hitVTXCol->at(ielem); + //_allHits.push_back(hit); + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + //debug() << "covMatrix : " << hit->getCovMatrix()[0] << " " << hit->getCovMatrix()[1] << endmsg; + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTracking: VXD Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTracking: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + //std::cout << "fucd: " << &hit << " " << &_allHits.back() << std::endl; + //TrackerHitExtended * hitExt = new TrackerHitExtended( &_allHits.back() ); + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + std::cout << "Saved TrackerHit pointer in TrackerHitExtended " << ielem << ": " << hitExt->getTrackerHit() << std::endl; + //std::cout << (&_allHits.back())->getPosition()[0] << " " << hit.getCovMatrix()[2] << " " << hit.getCovMatrix()[5] << std::endl; + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(hit.getCovMatrix()[2]); + hitExt->setResolutionZ(hit.getCovMatrix()[5]); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + int layer = getLayerID(&hit); + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTracking => fatal error in VTX : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " VXD Hit " << hit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + if (_useSIT > 0 ) { + const edm4hep::TrackerHitCollection* hitSITCol = nullptr; + try { + hitSITCol = _inSITColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inSITColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitSITCol){ + //LCCollection *hitCollection = evt->getCollection(_SITHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _SITHitCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitSITCol->size(); + + debug() << "Number of SIT hits = " << nelem << endmsg; + _nTotalSITHits = nelem; + + //TrackerHit* trkhit = 0; + //TrackerHitPlane* trkhit_P = 0; + //TrackerHitZCylinder* trkhit_C = 0; + + double drphi(NAN); + double dz(NAN); + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto trkhit : *hitSITCol){ + // hit could be of the following type + // 1) TrackerHit, either ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT or just standard TrackerHit + // 2) TrackerHitPlane, either 1D or 2D + // 3) TrackerHitZCylinder, if coming from a simple cylinder design as in the LOI + + // Establish which of these it is in the following order of likelyhood + // i) ILDTrkHitTypeBit::ONE_DIMENSIONAL (TrackerHitPlane) Should Never Happen: SpacePoints Must be Used Instead + // ii) ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT (TrackerHit) + // iii) TrackerHitPlane (Two dimentional) + // iv) TrackerHitZCylinder + // v) Must be standard TrackerHit + + //const edm4hep::TrackerHit* trkhit = hitSITCol->at(ielem); + + int layer = getLayerID(&trkhit); + + // VXD and SIT are treated as one system so SIT layers start from _nLayersVTX + layer = layer + _nLayersVTX; + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTracking => fatal error in SIT : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + // first check that we have not been given 1D hits by mistake, as they won't work here + if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL ] ) { + + error() << "SiliconTracking: SIT Hit cannot be of type UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL COMPOSITE SPACEPOINTS must be use instead. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + + } + // most likely case: COMPOSITE_SPACEPOINT hits formed from stereo strip hits + else if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ) { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // or a PIXEL based SIT, using 2D TrackerHitPlane like the VXD above + // by fucd + //else if ( ( trkhit_P = dynamic_cast<TrackerHitPlane*>( hitCollection->getElementAt( ielem ) ) ) ) { + else if( UTIL::BitSet32( trkhit.getType() )[ 31 ]){ + // first we need to check if the measurement vectors are aligned with the global coordinates + //gear::Vector3D U(1.0,trkhit_P->getU()[1],trkhit_P->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,trkhit_P->getV()[1],trkhit_P->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,trkhit.getCovMatrix()[1],trkhit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,trkhit.getCovMatrix()[4],trkhit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTracking: PIXEL SIT Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // U must be normal to the global z axis + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTracking: PIXEL SIT Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + //drphi = trkhit_P->getdU(); + //dz = trkhit_P->getdV(); + drphi = trkhit.getCovMatrix()[2]; + dz = trkhit.getCovMatrix()[5]; + } + + // or a simple cylindrical design, as used in the LOI + /* by fucd + else if ( ( trkhit_C = dynamic_cast<TrackerHitZCylinder*>( hitCollection->getElementAt( ielem ) ) ) ) { + + drphi = trkhit_C->getdRPhi(); + dz = trkhit_C->getdZ(); + + } + */ + // this would be very unlikely, but who knows ... just an ordinary TrackerHit, which is not a COMPOSITE_SPACEPOINT + else { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // now that the hit type has been established carry on and create a + + TrackerHitExtended * hitExt = new TrackerHitExtended(trkhit); + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(drphi); + hitExt->setResolutionZ(dz); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = trkhit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " SIT Hit " << trkhit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + } + + + for (unsigned i=0; i<_sectors.size(); ++i) { + int nhits = _sectors[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in VXD/SIT Sector " << i << " = " << _sectors[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectors[i].size(); ++ihit) { + delete _sectors[i][ihit]; + } + _sectors[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in VXD/SIT Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + } + } + debug() << "VXD initialized" << endmsg; + return success; +} + +StatusCode SiliconTracking::finalize(){ + + delete _fastfitter ; _fastfitter = 0; + delete _encoder ; _encoder = 0; + //delete _trksystem ; _trksystem = 0; + //delete _histos ; _histos = 0; + info() << "Processed " << _nEvt << " events " << endmsg; + return GaudiAlgorithm::finalize(); +} + + +void SiliconTracking::ProcessOneSector(int iPhi, int iTheta) { + + int counter = 0 ; + + int iPhi_Up = iPhi + 1; + int iPhi_Low = iPhi - 1; + int iTheta_Up = iTheta + 1; + int iTheta_Low = iTheta - 1; + if (iTheta_Low < 0) iTheta_Low = 0; + if (iTheta_Up >= _nDivisionsInTheta) iTheta_Up = _nDivisionsInTheta-1; + + int nComb = int( _Combinations.size() / 3 ); // number of triplet combinations + // std::cout << iPhi << " " << iTheta << " " << _nEvt << endmsg; + int iNC = 0; + + for (int iComb=0; iComb < nComb; ++iComb) { // loop over triplets + + int nLR[3]; + + for (int iS=0; iS<3; ++iS) { + nLR[iS] = _Combinations[iNC]; + iNC++; + } + + //std::cout << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " " << std::endl; + + // index of theta-phi bin of outer most layer + int iCode = nLR[0] + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + + //std::cout << "size of vector = " << _sectors.size() << " iCode = " << iCode << std::endl; + + // get the all the hits in the outer most theta-phi bin + + TrackerHitExtendedVec& hitVecOuter = _sectors[iCode]; + + int nHitsOuter = int(hitVecOuter.size()); + if (nHitsOuter > 0) { + + //std::cout << " " << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " size of vector = " << hitVecOuter.size() << std::endl; + + for (int ipMiddle=iPhi_Low; ipMiddle<iPhi_Up+1;ipMiddle++) { // loop over phi in the Middle + + for (int itMiddle=iTheta_Low; itMiddle<iTheta_Up+1;itMiddle++) { // loop over theta in the Middle + + int iPhiMiddle = ipMiddle; + + // catch wrap-around + if (ipMiddle < 0) iPhiMiddle = _nDivisionsInPhi-1; + if (ipMiddle >= _nDivisionsInPhi) iPhiMiddle = ipMiddle - _nDivisionsInPhi; + + // index of current theta-phi bin of middle layer + iCode = nLR[1] + _nLayers*iPhiMiddle + _nLayers*_nDivisionsInPhi*itMiddle; + + // get the all the hits in the current middle theta-phi bin + TrackerHitExtendedVec& hitVecMiddle = _sectors[iCode]; + + int nHitsMiddle = int(hitVecMiddle.size()); + + // determine which inner theta-phi bins to look in + + int iPhiLowInner = iPhi_Low; + int iPhiUpInner = iPhi_Up; + int iThetaLowInner = iTheta_Low; + int iThetaUpInner = iTheta_Up; + + // test to see if this is the core bin of the current search + // if so, look into the neigboring bins in the inner layer + if (ipMiddle == iPhi && itMiddle==iTheta) { + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + else { + int difP = abs(ipMiddle-iPhi); // number of phi bins from core: can only be 1 or 0 due to hard coded 1 above + int difT = abs(itMiddle-iTheta);// number of theta bins from core: can only be 1 or 0 due to hard coded 1 above + int minP = min(ipMiddle,iPhi); // min phi: core bin or current phi bin middle + int minT = min(itMiddle,iTheta); // min theta: core bin or current theta bin middle + int maxP = max(ipMiddle,iPhi); // max phi: core bin or current phi bin middle + int maxT = max(itMiddle,iTheta); // max theta: core bin or current theta bin middle + + if (difP==1 && difT==1) { // if the diffence is a single bin in both phi and theta : only look in the bin adjacent to the core bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difP==0) { // must be +/-1 theta : only look in bins adjacent to the middle bin + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difT==0) { // must be +/-1 phi : only look in bins adjacent to the middle bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + } + if (nHitsMiddle > 0) { // look into inner bins + + for (int ipInner=iPhiLowInner; ipInner<iPhiUpInner+1;ipInner++) { // loop over phi in the Inner + + for (int itInner=iThetaLowInner; itInner<iThetaUpInner+1;itInner++) { // loop over theta in the Inner + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + iCode = nLR[2] + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get hit for inner bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + if (nHitsInner > 0) { + + debug() << " " + << std::setw(3) << iPhi << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iTheta << " " << std::setw(3) << itMiddle << " " << std::setw(3) << itInner << " " + << std::setw(3) << nLR[0] << " " << std::setw(3) << nLR[1] << " " << std::setw(3) << nLR[2] << " " + << std::setw(3) << nHitsOuter << " : " << std::setw(3) << nHitsMiddle << " : " << std::setw(3) << nHitsInner << " :: " + << std::setw(3) << nHitsOuter*nHitsMiddle* nHitsInner << endmsg; + + // test all triplets + + for (int iOuter=0; iOuter<nHitsOuter; ++iOuter) { // loop over hits in the outer sector + TrackerHitExtended * outerHit = hitVecOuter[iOuter]; + for (int iMiddle=0;iMiddle<nHitsMiddle;iMiddle++) { // loop over hits in the middle sector + TrackerHitExtended * middleHit = hitVecMiddle[iMiddle]; + for (int iInner=0;iInner<nHitsInner;iInner++) { // loop over hits in the inner sector + TrackerHitExtended * innerHit = hitVecInner[iInner]; + HelixClass helix; + //std::cout <<"fucd++++++++++++++++++++++1" << std::endl; + // test fit to triplet + TrackExtended * trackAR = TestTriplet(outerHit,middleHit,innerHit,helix); + //std::cout <<"fucd++++++++++++++++++++++2" << std::endl; + if ( trackAR != NULL ) { + int nHits = BuildTrack(outerHit,middleHit,innerHit,helix,nLR[2], + iPhiLowInner,iPhiUpInner, + iThetaLowInner,iThetaUpInner,trackAR); + + _tracksWithNHitsContainer.getTracksWithNHitsVec(nHits).push_back(trackAR); + + counter ++ ; + } + //std::cout <<"fucd++++++++++++++++++++++3" << std::endl; + } // endloop over hits in the inner sector + } // endloop over hits in the middle sector + } // endloop over hits in the outer sector + } // endif nHitsInner > 0 + } // endloop over theta in the Inner + } // endloop over phi in the Inner + } // endif nHitsMiddle > 0 + } // endloop over theta in the Middle + } // endloop over phi in the Middle + } // endif nHitsOuter > 0 + } // endloop over triplets + + //debug() << " process one sectector theta,phi " << iTheta << ", " << iPhi << " number of loops : " << counter << endmsg ; +} + +TrackExtended * SiliconTracking::TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix) { + /* + Methods checks if the triplet of hits satisfies helix hypothesis + */ + //std::cout << "fucd================1" << std::endl; + // get the tracks already associated with the triplet + TrackExtendedVec& trackOuterVec = outerHit->getTrackExtendedVec(); + TrackExtendedVec& trackMiddleVec = middleHit->getTrackExtendedVec(); + TrackExtendedVec& trackInnerVec = innerHit->getTrackExtendedVec(); + + //std::cout << "fucd================2" << std::endl; + // check if all the hits are already assigned to a track + if ( (!trackOuterVec.empty()) && (!trackMiddleVec.empty()) && (!trackInnerVec.empty())) { + + TrackExtendedVec::const_iterator middleEndIter = trackMiddleVec.end(); + TrackExtendedVec::const_iterator outerEndIter = trackOuterVec.end(); + TrackExtendedVec::const_iterator innerEndIter = trackInnerVec.end(); + TrackExtendedVec::const_iterator outerBeginIter = trackOuterVec.begin(); + TrackExtendedVec::const_iterator innerBeginIter = trackInnerVec.begin(); + + // loop over the tracks from the middle hit + for (TrackExtendedVec::const_iterator middleIter = trackMiddleVec.begin(); + middleIter < middleEndIter; + ++middleIter) { + + // loop over the track from the outer hit + for (TrackExtendedVec::const_iterator outerIter = outerBeginIter; + outerIter < outerEndIter; + ++outerIter) { + + // if track from the outer and middle are not the same progress + if ( *outerIter != *middleIter ) continue; + + // loop over the tracks from the inner hit + for (TrackExtendedVec::const_iterator innerIter = innerBeginIter; + innerIter < innerEndIter; + ++innerIter) { + + // no need to check against middle, it is idendical to outer here + if ( *outerIter == *innerIter ) { + // an existing track already contains all three hits + // return a null pointer + debug() << " TestTriplet: track " << *outerIter << " already contains all three hits: Do not create new track from these hits " << endmsg ; + return 0; + } + + }// for inner + }// for outer + }// for middle + }// if all vectors are not empty + //std::cout << "fucd================3" << std::endl; + + // float dZ = FastTripletCheck(innerHit, middleHit, outerHit); + + // if (fabs(dZ) > _minDistCutAttach) + // return trackAR; + + + // increase triplet count + ++_ntriplets; + + // get the hit coordinates and errors + double xh[3]; + double yh[3]; + float zh[3]; + double wrh[3]; + float wzh[3]; + float rh[3]; + float ph[3]; + + float par[5]; + float epar[15]; + /*fucd + for(int i=0;i<_allHits.size();i++){ + std::cout << &_allHits.at(i) << std::endl; + } + */ + // first hit + xh[0] = outerHit->getTrackerHit()->getPosition()[0]; + yh[0] = outerHit->getTrackerHit()->getPosition()[1]; + zh[0] = float(outerHit->getTrackerHit()->getPosition()[2]); + wrh[0] = double(1.0/(outerHit->getResolutionRPhi()*outerHit->getResolutionRPhi())); + wzh[0] = 1.0/(outerHit->getResolutionZ()*outerHit->getResolutionZ()); + // second hit + xh[1] = middleHit->getTrackerHit()->getPosition()[0]; + yh[1] = middleHit->getTrackerHit()->getPosition()[1]; + zh[1] = float(middleHit->getTrackerHit()->getPosition()[2]); + wrh[1] = double(1.0/(middleHit->getResolutionRPhi()*middleHit->getResolutionRPhi())); + wzh[1] = 1.0/(middleHit->getResolutionZ()*middleHit->getResolutionZ()); + // third hit + xh[2] = innerHit->getTrackerHit()->getPosition()[0]; + yh[2] = innerHit->getTrackerHit()->getPosition()[1]; + zh[2] = float(innerHit->getTrackerHit()->getPosition()[2]); + wrh[2] = double(1.0/(innerHit->getResolutionRPhi()*innerHit->getResolutionRPhi())); + wzh[2] = 1.0/(innerHit->getResolutionZ()*innerHit->getResolutionZ()); + // calculate r and phi for all hits + for (int ih=0; ih<3; ih++) { + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = atan2(yh[ih],xh[ih]); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + + int NPT = 3; + int iopt = 2; + float chi2RPhi; + float chi2Z; + + debug() << " TestTriplet: Use fastHelixFit " << endmsg ; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + // get helix parameters + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + // chi2 is weighted here by a factor for both rphi and z + float Chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + int ndf = 2*NPT-5; + + + // check the truth information for the triplet + + // define these outside of the ifdef so that we don't need to keep repeating it. + //std::vector<TrackerHit*> hit_list; + //std::vector<MCParticle*> mcps_imo; + //std::vector<MCParticle*> mcp_s; + int triplet_code = 0; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + + int nmcps = 0; + int nbadHits = 0; + + int layer = 9 ; + int size = 3 ; + int marker = 1 ; + int ml = 0 ; + // float helix_max_r = 0; + float helix_max_z = 0; + int color = 0; + + // use the MCTruth4HitExt to get the MCPs + + hit_list.push_back(innerHit->getTrackerHit()); + hit_list.push_back(middleHit->getTrackerHit()); + hit_list.push_back(outerHit->getTrackerHit()); + + EVENT::MCParticle* mcp_i = 0; + EVENT::MCParticle* mcp_m = 0; + EVENT::MCParticle* mcp_o = 0; + + for (unsigned ihit = 0; ihit < hit_list.size(); ++ihit) { + + EVENT::TrackerHit* trkhit = hit_list[ihit]; + std::vector<MCParticle*> mcps; + + MarlinTrk::getMCParticlesForTrackerHit(trkhit, mcps); + + if (mcps.size() == 1) { + mcps_imo.push_back(mcps[0]); + ++nmcps; + } else { + mcps_imo.push_back(0); + ++nbadHits; + } + + } + + mcp_i = mcps_imo[0]; + mcp_m = mcps_imo[1]; + mcp_o = mcps_imo[2]; + + debug() + << "\n mcp_i = " << mcp_i + << "\n mcp_m = " << mcp_m + << "\n mcp_o = " << mcp_o + << endmsg; + + if( mcp_i ) { + mcp_s.push_back(mcp_i) ; + } + + if( mcp_m && mcp_m != mcp_i ) { + mcp_s.push_back(mcp_m); + } + + if( mcp_o && mcp_o != mcp_m && mcp_o != mcp_i ){ + mcp_s.push_back(mcp_o); + } + + nmcps = mcp_s.size(); + + if (_UseEventDisplay) { + // display this triplet and the MCPs from which it is formed + + MarlinCED::newEvent(this , _detector_model_for_drawing ) ; + + // CEDPickingHandler &pHandler=CEDPickingHandler::getInstance(); + // + // pHandler.update(_current_event); + + for (unsigned imcp = 0; imcp < mcp_s.size(); ++imcp) { + + MCParticle* mcp = mcp_s[imcp]; + + helix_max_z = fabsf(mcp->getEndpoint()[2]); + + + info() << "Draw MCParticle : " << *mcp <<endmsg; + + MarlinCED::add_layer_description("MCParticle_For_Fit", layer); + + MarlinCED::drawHelix( _bField , mcp->getCharge(), mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2], + mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2], layer , size , 0x7af774 , + 0.0, _helix_max_r , + helix_max_z, mcp->id() ) ; + + } + + const std::string colName = "Hits_For_Fit"; + + + size = 10 ; + layer = 11 ; + // ml = marker | ( layer << CED_LAYER_SHIFT ) ; + + //ced_describe_layer( colName.c_str() ,layer); + MarlinCED::add_layer_description(colName, layer); + + + color = 0xFFFFFF; + + for( std::vector<TrackerHit* >::const_iterator it = hit_list.begin(); it != hit_list.end() ; it++ ) { + + TrackerHit* trkhit = *it; + + ced_hit_ID(trkhit->getPosition()[0], + trkhit->getPosition()[1], + trkhit->getPosition()[2], + marker, layer, size , color, trkhit->id() ) ; + + } // hits + + } + + if (_createDiagnosticsHistograms) { + + // if no bad hits are present triplet_code = nmcps; + triplet_code = nmcps + nbadHits * 3 ; + + _histos->fill1D(DiagnosticsHistograms::htriplets, triplet_code); + + double pt = (2.99792458E-4*_bField) / omega ; // for r in mm, p in GeV and Bz in Tesla + + if (triplet_code == 1) { + ++_ntriplets_good; + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_good, pt, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_good, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_good, pt ); + } else { + + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_bad, pt, Chi2); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_bad, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_bad, pt ); + + if(triplet_code == 2) { + ++_ntriplets_2MCP; + } else if (triplet_code == 3) { + ++_ntriplets_3MCP; + } else if (triplet_code == 4) { + ++_ntriplets_1MCP_Bad; + } else { + ++_ntriplets_bad; + } + } + + } + +#endif + */ + + // Check if track satisfies all conditions + + + // std::cout << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + // std::cout << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + // std::cout << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + // std::cout << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + + // if ( Chi2/float(ndf) > _chi2FitCut || fabs(d0) > _cutOnD0 || fabs(z0) > _cutOnZ0 || fabs(omega)>_cutOnOmega) + // return a null pointer + // return 0; + + bool failed = false; + + int quality_code = triplet_code * 10 ; + + if ( Chi2/float(ndf) > _chi2FitCut ) { + debug() << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + failed = true; + quality_code += 1; + } else if (fabs(d0) > _cutOnD0 ) { + debug() << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + failed = true; + quality_code += 2; + } else if (fabs(z0) > _cutOnZ0 ) { + debug() << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + failed = true; + quality_code += 3; + } else if ( fabs(omega)>_cutOnOmega) { + debug() << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + failed = true; + quality_code += 4; + } else { + debug() << "Success !!!!!!!" << endmsg; + } + /* + if (_createDiagnosticsHistograms) _histos->fill1D(DiagnosticsHistograms::htriplets, quality_code); + + if (_UseEventDisplay) { + drawEvent(); + } + */ + + if( failed ) { + // return a null pointer + return 0; + } + + + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + + TrackExtended * trackAR = new TrackExtended(); + trackAR->addTrackerHitExtended(outerHit); + trackAR->addTrackerHitExtended(middleHit); + trackAR->addTrackerHitExtended(innerHit); + outerHit->addTrackExtended(trackAR); + middleHit->addTrackExtended(trackAR); + innerHit->addTrackExtended(trackAR); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix(epar); + + + return trackAR; + +} + +int SiliconTracking::BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerLayer, + int iPhiLow, int iPhiUp, + int iThetaLow, int iThetaUp, + TrackExtended * trackAR) { + /** + Method for building up track in the VXD. Method starts from the found triplet and performs + sequential attachment of hits in other layers, which have hits within the search window. + Only searches inwards. + Given that we know we are now jumping over layers due to the doublet nature of the VXD, we + could optimise this to look for the hits in interleaving layers as well. + Currently a fast fit is being done for each additional hit, it could be more efficient to try and use kaltest? + + */ + + debug() << " BuildTrack starting " << endmsg; + + for (int layer = innerLayer-1; layer>=0; layer--) { // loop over remaining layers + float distMin = 1.0e+20; + TrackerHitExtended * assignedhit = NULL; + //std::cout << "fucd---------------------1" << std::endl; + // loop over phi in the Inner region + for (int ipInner=iPhiLow; ipInner<iPhiUp+1;ipInner++) { + + // loop over theta in the Inner region + for (int itInner=iThetaLow; itInner<iThetaUp+1;itInner++) { + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + // get the index of the theta-phi bin to search + int iCode = layer + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get the hits from this bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + // loop over hits in the Inner sector + for (int iInner=0;iInner<nHitsInner;iInner++) { + + TrackerHitExtended * currentHit = hitVecInner[iInner]; + + // get the position of the hit to test + float pos[3]; + float distance[3]; + + for (int i=0; i<3; ++i) { + pos[i] = float(currentHit->getTrackerHit()->getPosition()[i]); + } + + // get the distance of closest approach and distance s traversed to the POCA + float time = helix.getDistanceToPoint(pos,distance); + + // sanity check on s + if (time < 1.0e+10) { + + // check if this is the closest hit yet + if (distance[2] < distMin) { // distance[2] = sqrt( d0*d0 + z0*z0 ) + + // if yes store hit and distance + distMin = distance[2]; + assignedhit = currentHit; + } + } + } // endloop over hits in the Inner sector + } // endloop over theta in the Inner region + } // endloop over phi in the Inner region + //std::cout << "fucd---------------------2" << std::endl; + // check if closest hit fulfills the min distance cut + if (distMin < _minDistCutAttach) { + + // if yes try to include it in the fit + + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hvec.size()); + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hvec[ih]->getTrackerHit(); + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(hvec[ih]->getResolutionRPhi()*hvec[ih]->getResolutionRPhi())); + wzh[ih] = 1.0/(hvec[ih]->getResolutionZ()*hvec[ih]->getResolutionZ()); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + edm4hep::TrackerHit * assignedTrkHit = assignedhit->getTrackerHit(); + xh[nHits] = assignedTrkHit->getPosition()[0]; + yh[nHits] = assignedTrkHit->getPosition()[1]; + zh[nHits] = float(assignedTrkHit->getPosition()[2]); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + if (ph[nHits] < 0.) + ph[nHits] = TWOPI + ph[nHits]; + wrh[nHits] = double(1.0/(assignedhit->getResolutionRPhi()*assignedhit->getResolutionRPhi())); + wzh[nHits] = 1.0/(assignedhit->getResolutionZ()*assignedhit->getResolutionZ()); + + int NPT = nHits + 1; + int iopt = 2; + float chi2RPhi; + float chi2Z; + +// std::cout << "######## number of hits to fit with _fastfitter = " << NPT << endmsg; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + bool validCombination = 0; + float Chi2 = FLT_MAX; + + if ((nHits+1) == 4) { + Chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if ((nHits+1) >= 5) { + Chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + int ndf = 2*NPT-5; + + // check if this is valid combination based on the chi2/ndf + validCombination = Chi2/float(ndf) < _chi2FitCut; + + if ( validCombination ) { + // assign hit to track and track to hit, update the track parameters + trackAR->addTrackerHitExtended(assignedhit); + assignedhit->addTrackExtended(trackAR); + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setCovMatrix(epar); + trackAR->setNDF( ndf ); + } + + } + } // endloop over remaining layers + //std::cout << "fucd---------------------3" << std::endl; + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nTotalHits = int(hvec.size()); + +// std::cout << "######## number of hits to return = " << nTotalHits << endmsg; + + return nTotalHits; + +} + + +void SiliconTracking::Sorting(TrackExtendedVec & trackVec) { + /** + Sorting of Track Vector in ascending order of chi2/ndf + */ + + std::sort(trackVec.begin(), trackVec.end(), compare_TrackExtended() ); + + // also clean up? what does this do here? + for (size_t i=0, sizeOfVector=trackVec.size(); i<sizeOfVector; ++i) { + + TrackerHitExtendedVec& hitVec = trackVec[i]->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int ih=0;ih<nHits;ih++) { + hitVec[ih]->clearTrackVec(); + } + } + +} + +void SiliconTracking::CreateTrack(TrackExtended * trackAR ) { + + /** + Method which creates Track out of TrackExtended objects. Checks for possible + track splitting (separate track segments in VXD and FTD). + */ + + + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int i=0; i<nHits; ++i) { + TrackExtendedVec& trackVec = hitVec[i]->getTrackExtendedVec(); + if (trackVec.size() != 0) + return ; + } + + // First check if the current track is piece of the split one + // look for matching track segment + + int found = 0; + + int nTrk = int(_trackImplVec.size()); + + for (int itrk=0; itrk<nTrk; ++itrk) { + TrackExtended * trackOld = _trackImplVec[itrk]; + TrackerHitExtendedVec& hitVecOld = trackOld->getTrackerHitExtendedVec(); + + float phiNew = trackAR->getPhi(); + float phiOld = trackOld->getPhi(); + float thetaNew = M_PI_2 - atan(trackAR->getTanLambda()); + float thetaOld = M_PI_2 - atan(trackOld->getTanLambda()); + + float angle = (cos(phiNew)*cos(phiOld)+sin(phiNew)*sin(phiOld))*sin(thetaNew)*sin(thetaOld)+cos(thetaNew)*cos(thetaOld); + angle = acos(angle); + + if (angle < _angleCutForMerging) { + int nHitsOld = int(hitVecOld.size()); + int nTotHits = nHits + nHitsOld; + double * xh = new double[nTotHits]; + double * yh = new double[nTotHits]; + float * zh = new float[nTotHits]; + double * wrh = new double[nTotHits]; + float * wzh = new float[nTotHits]; + float * rh = new float[nTotHits]; + float * ph = new float[nTotHits]; + float par[5]; + float epar[15]; + float refPoint[3] = {0.,0.,0.}; + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hitVec[ih]->getTrackerHit(); + float rR = hitVec[ih]->getResolutionRPhi(); + float rZ = hitVec[ih]->getResolutionZ(); + if (int(hitVec[ih]->getTrackExtendedVec().size()) != 0) + debug() << "WARNING : HIT POINTS TO TRACK " << endmsg; + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(rR*rR)); + wzh[ih] = 1.0/(rZ*rZ); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + } + for (int ih=0;ih<nHitsOld;++ih) { + edm4hep::TrackerHit * trkHit = hitVecOld[ih]->getTrackerHit(); + xh[ih+nHits] = trkHit->getPosition()[0]; + yh[ih+nHits] = trkHit->getPosition()[1]; + zh[ih+nHits] = float(trkHit->getPosition()[2]); + float rR = hitVecOld[ih]->getResolutionRPhi(); + float rZ = hitVecOld[ih]->getResolutionZ(); + wrh[ih+nHits] = double(1.0/(rR*rR)); + wzh[ih+nHits] = 1.0/(rZ*rZ); + rh[ih+nHits] = float(sqrt(xh[ih+nHits]*xh[ih+nHits]+yh[ih+nHits]*yh[ih+nHits])); + ph[ih+nHits] = float(atan2(yh[ih+nHits],xh[ih+nHits])); + + } + int NPT = nTotHits; + int iopt = 2; + float chi2RPhi; + float chi2Z; + int ndf = 2*NPT - 5; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + float eparmin[15]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + + float refPointMin[3]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + + float chi2Min = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Min = chi2Min/float(ndf); + + float chi2MinRPhi = chi2RPhi; + float chi2MinZ = chi2Z; + + int iBad = -1; + if (chi2Min < _chi2FitCut) { + found = 1; + } + else { // SJA:FIXME: UH What is going on here? setting weights to 0 and refitting? + float * wzhOld = new float[nTotHits]; + double * wrhOld = new double[nTotHits]; + for (int i=0;i<nTotHits;++i) { + wzhOld[i] = wzh[i]; + wrhOld[i] = wrh[i]; + } + for (int i=0; i<nTotHits; ++i) { + for (int j=0;j<nTotHits;++j) { + if (i == j) { + wrh[j] = 0.0; + wzh[j] = 0.0; + } + else { + wrh[j] = wrhOld[j]; + wzh[j] = wzhOld[j]; + } + } + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float chi2Cur = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Cur = chi2Cur/float(ndf); + + if (chi2Cur < chi2Min) { + chi2Min = chi2Cur; + chi2MinRPhi = chi2RPhi; + chi2MinZ = chi2Z; + omega = par[0]; + tanlambda = par[1]; + phi0 = par[2]; + d0 = par[3]; + z0 = par[4]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + iBad = i; + } + } + if (chi2Min < _chi2FitCut) { + found = 1; + } + delete[] wzhOld; + delete[] wrhOld; + } + + // Split track is found. + // Attach hits belonging to the current track segment to + // the track already created + if (found == 1) { + trackOld->ClearTrackerHitExtendedVec(); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * trkHit = hitVec[i]; + trkHit->clearTrackVec(); + if (i == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + for (int i=0;i<nHitsOld;++i) { + int icur = i+nHits; + TrackerHitExtended * trkHit = hitVecOld[i]; + trkHit->clearTrackVec(); + if (icur == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + trackOld->setOmega(omega); + trackOld->setTanLambda(tanlambda); + trackOld->setPhi(phi0); + trackOld->setD0(d0); + trackOld->setZ0(z0); + + // std::cout << "Split track found " << d0 << " " << z0 << endmsg; + + // killeb: In the original SiliconTracking this was in the NOT simple helix branch. + // The rest of the code uses the simple helix branch, where ndf_D is never set. + // In fact it has never been initialised or used anywhere. I think this line should not be executed. + // ndf = ndf_D; + + trackOld->setChi2(chi2Min*float(ndf)); + trackOld->setNDF(ndf); + trackOld->setCovMatrix(eparmin); + // trackOld->setReferencePoint(refPointMin); + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + } + if (found == 1) + break; + } + + // Candidate is a unique track + // No other segments are found + if (found == 0 ) { + _trackImplVec.push_back(trackAR); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * hit = hitVec[i]; + hit->addTrackExtended( trackAR ); + } + } + + +} + +void SiliconTracking::AttachRemainingVTXHitsFast() { + + std::vector<TrackerHitExtendedVec> nonAttachedHits; + nonAttachedHits.resize(_nDivisionsInPhi*_nDivisionsInTheta); + std::vector<TrackExtendedVec> trackVector; + trackVector.resize(_nDivisionsInPhi*_nDivisionsInTheta); + int nTracks = int(_trackImplVec.size()); + + for (int iTrk=0;iTrk<nTracks;++iTrk) { + TrackExtended * track = _trackImplVec[iTrk]; + double Phi = double(track->getPhi()); + if (Phi < 0) + Phi = Phi + TWOPI; + float tanlambda = track->getTanLambda(); + double cosTheta = double(tanlambda/sqrt(1+tanlambda*tanlambda)); + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = iPhi + _nDivisionsInPhi*iTheta; + trackVector[iCode].push_back( track ); + } + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hitExt = hitVec[iH]; + TrackExtendedVec& trackVec = hitExt->getTrackExtendedVec(); + if (trackVec.size()==0) { + edm4hep::TrackerHit * hit = hitExt->getTrackerHit(); + double pos[3]; + double radius = 0; + for (int i=0; i<3; ++i) { + pos[i] = hit->getPosition()[i]; + radius += pos[i]*pos[i]; + } + radius = sqrt(radius); + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + iCode = iPhi + _nDivisionsInPhi*iTheta; + nonAttachedHits[iCode].push_back( hitExt ); + } + } + } + } + } + + for (int iT=0; iT<_nDivisionsInTheta; ++iT) { + for (int iP=0; iP<_nDivisionsInPhi; ++iP) { + int iCode = iP + _nDivisionsInPhi*iT; + int nHits = int(nonAttachedHits[iCode].size()); + int iT1 = iT - 1; + int iT2 = iT + 1; + if (iT == 0) { + iT1 = iT; + iT2 = iT1 + 1; + } + if (iT == _nDivisionsInTheta - 1) { + iT2 = iT; + iT1 = iT2 - 1; + } + int iPHI[3]; + iPHI[0] = iP - 1; + iPHI[1] = iP; + iPHI[2] = iP + 1; + if (iP == 0) + iPHI[0] = _nDivisionsInPhi - 1; + if (iP == _nDivisionsInPhi - 1 ) + iPHI[2] = 0; + + for (int ihit = 0; ihit<nHits; ++ihit) { + + TrackerHitExtended * hit = nonAttachedHits[iCode][ihit]; + TrackExtended * trackToAttach = NULL; + float minDist = 1.0e+6; + + for (int iTheta = iT1; iTheta <iT2+1; ++iTheta) { + for (int indexP=0;indexP<3;++indexP) { + int iPhi = iPHI[indexP]; + int iCodeForTrack = iPhi + _nDivisionsInPhi*iTheta; + int nTrk = int(trackVector[iCodeForTrack].size()); + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = trackVector[iCodeForTrack][iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + break; + } + } + } + } + if (consider) { + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + HelixClass helix; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int layer = getLayerID(hit->getTrackerHit()); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } + } + } +} + +void SiliconTracking::AttachRemainingVTXHitsSlow() { + + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + // if (trackVec.size()==0) + // nonAttachedHits.push_back( hit ); + //-- allow hits that are only used in triplets to be re-attached + unsigned int maxTrackSize = 0; + for(unsigned int itrack = 0;itrack < trackVec.size();itrack++){ + TrackerHitExtendedVec hitVec_tmp= trackVec[itrack]->getTrackerHitExtendedVec(); + unsigned int isize = hitVec_tmp.size(); + if(isize>maxTrackSize)maxTrackSize = isize; + } + if (maxTrackSize<=3) { + debug() << " Add non attached hit to list: id = " << hit->getTrackerHit()->id() << endmsg; + nonAttachedHits.push_back( hit ); + } + + + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + debug() << " Try hit: id = " << hit->getTrackerHit()->id() << endmsg; + int layer = getLayerID( hit->getTrackerHit() ); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + debug() << " hit: id = " << hit->getTrackerHit()->id() << " condsidered delta together with hit " << trkhit2->id() << endmsg; + break; + } + } + } + } + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " : try attachement"<< endmsg; + AttachHitToTrack(trackToAttach,hit,iopt); + } else { + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " rejected due to distance cut of " <<_minDistCutAttach<< " min distance = " << minDist << endmsg; + } + } + } +} + +void SiliconTracking::AttachRemainingFTDHitsSlow() { + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + if (trackVec.size()==0) + nonAttachedHits.push_back( hit ); + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + + consider = false; + break; + } + } + + + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + if (tanlambda*float(getSideID(hit->getTrackerHit())) > 0) { + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } +} + + +void SiliconTracking::AttachRemainingFTDHitsFast() { + int nTrk = _trackImplVec.size(); + + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int iSemiSphere = 0; + if (tanlambda > 0) + iSemiSphere = 1; + float ref[3]; + for (int i=0;i<3;++i) + ref[i] = helix.getReferencePoint()[i]; + // Start loop over FTD layers + for (unsigned int layer=0;layer<_nlayersFTD;layer++) { + float ZL = _zLayerFTD[layer]; + if (iSemiSphere == 0) + ZL = - ZL; + float point[3]; + helix.getPointInZ(ZL,ref,point); + float Phi = atan2(point[1],point[0]); + if (Phi < 0) + Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+10; + TrackerHitExtended * attachedHit = NULL; + for (int iP=iPhi-1;iP<=iPhi+1;++iP) { + int iPP = iP; + if (iP < 0) + iPP = iP + _nPhiFTD; + if (iP >= _nPhiFTD) + iPP = iP - _nPhiFTD; + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPP; + int nHits = int(_sectorsFTD[iCode].size()); + for (int iHit=0;iHit<nHits;++iHit) { + TrackerHitExtended * hit = _sectorsFTD[iCode][iHit]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + for (int IHIT=0;IHIT<NHITS;++IHIT) { + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + consider = false; + break; + } + } + + + if (consider) { + float pos[3]; + for (int i=0;i<3;++i) { + pos[i] = hit->getTrackerHit()->getPosition()[i]; + } + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + } + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack(trackAR,attachedHit, iopt); + } + } + } +} + +void SiliconTracking::TrackingInFTD() { + + int nComb = int(_CombinationsFTD.size()) / 3; + + for (int iComb=0;iComb<nComb;++iComb) { + + int nLS[3]; + nLS[0] = _CombinationsFTD[3*iComb]; + nLS[1] = _CombinationsFTD[3*iComb+1]; + nLS[2] = _CombinationsFTD[3*iComb+2]; + + for (int iS=0;iS<2;++iS) { // loop over +z and -z + + // std::cout << "Combinations : " << iS << " " << nLS[0] << " " << nLS[1] << " " << nLS[2] << endmsg; + // int iC = iS + 2*nLS[0]; + // TrackerHitExtendedVec& hitVec = _sectorsFTD[iC]; + // int nO = int(hitVec.size()); + // iC = iS + 2*nLS[1]; + // hitVec = _sectorsFTD[iC]; + // int nM = int(hitVec.size()); + // iC = iS + 2*nLS[2]; + // hitVec = _sectorsFTD[iC]; + // int nI = int(hitVec.size()); + // std::cout << nO << " " << nM << " " << nI << endmsg; + + for (int ipOuter=0;ipOuter<_nPhiFTD;++ipOuter) { + + int ipMiddleLow = ipOuter - 1; + int ipMiddleUp = ipOuter + 1; + + unsigned int iCodeOuter = iS + 2*nLS[0] + 2*_nlayersFTD*ipOuter; + + if( iCodeOuter >= _sectorsFTD.size()){ + error() << "iCodeOuter index out of range: iCodeOuter = " << iCodeOuter << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + exit(1); + } + + TrackerHitExtendedVec& hitVecOuter = _sectorsFTD[iCodeOuter]; + + int nOuter = int(hitVecOuter.size()); + + for (int iOuter=0;iOuter<nOuter;++iOuter) { + + TrackerHitExtended * hitOuter = hitVecOuter[iOuter]; + + for (int ipMiddle=ipMiddleLow;ipMiddle<=ipMiddleUp;++ipMiddle) { + //for(int ipMiddle=0;ipMiddle<_nPhiFTD;++ipMiddle) { + int ipM = ipMiddle; + if (ipM < 0) + ipM = ipMiddle + _nPhiFTD; + if (ipM >= _nPhiFTD) + ipM = ipMiddle - _nPhiFTD; + int iCodeMiddle = iS + 2*nLS[1] + 2*_nlayersFTD*ipM; + + TrackerHitExtendedVec& hitVecMiddle = _sectorsFTD[iCodeMiddle]; + int ipInnerLow,ipInnerUp; + ipInnerLow = ipMiddle - 1; + ipInnerUp = ipMiddle + 1; + + int nMiddle = int(hitVecMiddle.size()); + + for (int iMiddle=0;iMiddle<nMiddle;++iMiddle) { + TrackerHitExtended * hitMiddle = hitVecMiddle[iMiddle]; + for (int ipInner=ipInnerLow;ipInner<=ipInnerUp;++ipInner) { + //for (int ipInner=0;ipInner<_nPhiFTD;++ipInner) { + int ipI = ipInner; + if (ipI < 0) + ipI = ipInner + _nPhiFTD; + if (ipI >= _nPhiFTD) + ipI = ipInner - _nPhiFTD; + int iCodeInner = iS + 2*nLS[2] + 2*_nlayersFTD*ipI; + TrackerHitExtendedVec& hitVecInner = _sectorsFTD[iCodeInner]; + + int nInner = int(hitVecInner.size()); + + for (int iInner=0;iInner<nInner;++iInner) { + + TrackerHitExtended * hitInner = hitVecInner[iInner]; + HelixClass helix; + // std::cout << endmsg; + // std::cout << "Outer Hit Type " << hitOuter->getTrackerHit()->getType() << " z = " << hitOuter->getTrackerHit()->getPosition()[2] + // << "\nMiddle Hit Type "<< hitMiddle->getTrackerHit()->getType() << " z = " << hitMiddle->getTrackerHit()->getPosition()[2] + // << "\nInner Hit Type "<< hitInner->getTrackerHit()->getType() << " z = " << hitInner->getTrackerHit()->getPosition()[2] << endmsg; + + debug() << " " + << std::setw(3) << ipOuter << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iS << " " + << std::setw(3) << nLS[0] << " " << std::setw(3) << nLS[1] << " " << std::setw(3) << nLS[2] << " " + << std::setw(3) << nOuter << " : " << std::setw(3) << nMiddle << " : " << std::setw(3) << nInner << " :: " + << std::setw(3) << nOuter*nMiddle* nInner << endmsg; + + + TrackExtended * trackAR = TestTriplet(hitOuter,hitMiddle,hitInner,helix); + if (trackAR != NULL) { + // std::cout << "FTD triplet found" << endmsg; + int nHits = BuildTrackFTD(trackAR,nLS,iS); + + _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ).push_back( trackAR ); + } + } + } + } + } + } + } + } + } +} + + +int SiliconTracking::BuildTrackFTD(TrackExtended * trackAR, int * nLR, int iS) { + // std::cout << "BuildTrackFTD: Layers = " << nLR[0] << " " << nLR[1] << " " << nLR[2] << endmsg; + + // initialise a helix from the track + HelixClass helix; + const float d0 = trackAR->getD0(); + const float z0 = trackAR->getZ0(); + const float phi0 = trackAR->getPhi(); + const float tanlambda = trackAR->getTanLambda(); + const float omega = trackAR->getOmega(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float ref[3] = {helix.getReferencePoint()[0], + helix.getReferencePoint()[1], + helix.getReferencePoint()[2]}; + + for (int iL=0; iL < static_cast<int>(_nlayersFTD); ++iL) { + if (iL != nLR[0] && iL != nLR[1] && iL != nLR[2]) { + float point[3]; + float ZL = _zLayerFTD[iL]; + if (iS == 0) + ZL = - ZL; + helix.getPointInZ(ZL,ref,point); + // float Phi = atan2(point[1],point[0]); + // int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+6; + TrackerHitExtended * attachedHit = NULL; + for (int ip=0;ip<=_nPhiFTD;++ip) { + int iP = ip; + if (iP < 0) + iP = ip + _nPhiFTD; + if (iP >= _nPhiFTD) + iP = ip - _nPhiFTD; + int iCode = iS + 2*iL + 2*_nlayersFTD*iP; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + float pos[3]; + for (int i=0;i<3;++i) + pos[i] = float(trkHit->getPosition()[i]); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + // std::cout << "Layer = " << iL << " distMin = " << distMin << endmsg; + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack( trackAR, attachedHit, iopt); + } + } + } + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nH = int (hitVec.size()); + return nH; +} + +int SiliconTracking::AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt) { + + int attached = 0; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int i=0; i<nHits; ++i) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + xh[i] = double(trkHit->getPosition()[0]); + yh[i] = double(trkHit->getPosition()[1]); + zh[i] = float(trkHit->getPosition()[2]); + ph[i] = float(atan2(yh[i],xh[i])); + rh[i] = float(sqrt(xh[i]*xh[i]+yh[i]*yh[i])); + float rR = hitVec[i]->getResolutionRPhi(); + float rZ = hitVec[i]->getResolutionZ(); + wrh[i] = double(1.0/(rR*rR)); + wzh[i] = 1.0/(rZ*rZ); + } + + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + xh[nHits] = double(trkHit->getPosition()[0]); + yh[nHits] = double(trkHit->getPosition()[1]); + zh[nHits] = float(trkHit->getPosition()[2]); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + + float rR = hit->getResolutionRPhi(); + float rZ = hit->getResolutionZ(); + wrh[nHits] = double(1.0/(rR*rR)); + wzh[nHits] = 1.0/(rZ*rZ); + + + int NPT = nHits + 1; + + // SJA:FIXME the newtonian part is giving crazy results for FTD so just use iopt 2 for simply attaching hits + // using SIT and VXD doesn't seem to give any problems, so make it a function parameter and let the caller decide + // int iopt = 3; + + float chi2RPhi = 0 ; + float chi2Z = 0 ; + + + int error = _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + float chi2 = FLT_MAX; + int ndf = INT_MAX; + + if (NPT == 3) { + chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + } + if (NPT == 4) { + chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if (NPT > 4) { + chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + ndf = 2*NPT-5; + + + if ( error == 0 && chi2/float(ndf) < _chi2FitCut ) { + trackAR->addTrackerHitExtended(hit); + hit->addTrackExtended( trackAR ); + trackAR->setChi2( chi2 ); + trackAR->setOmega( omega ); + trackAR->setTanLambda( tanlambda ); + trackAR->setD0( d0 ); + trackAR->setZ0( z0 ); + trackAR->setPhi( phi0 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix( epar ); + attached = 1; + debug() << "Attachement succeeded chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } else { + debug() << "Attachement failed chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + return attached; + + +} + +void SiliconTracking::FinalRefit(edm4hep::TrackCollection* trk_col) { + + int nTracks = int(_trackImplVec.size()); + + int nSiSegments = 0; + float eTot = 0.; + float pxTot = 0.; + float pyTot = 0.; + float pzTot = 0.; + std::cout << "fucd============" << nTracks << std::endl; + for (int iTrk=0;iTrk<nTracks;++iTrk) { + + TrackExtended * trackAR = _trackImplVec[iTrk]; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + + int nHits = int(hitVec.size()); + std::cout << "fucd-------------" << iTrk << ": " << nHits << std::endl; + if( nHits >= _minimalHits) { + // int * lh = new int[nHits]; + std::vector<int> lh; + lh.resize(nHits); + + for (int i=0; i<nHits; ++i) { + lh[i]=0; + } + + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + float phi0 = trackAR->getPhi(); + + HelixClass * helix = new HelixClass(); + helix->Initialize_Canonical(phi0, d0, z0, omega, + tanlambda, _bField); + + + // get the point of closest approach to the reference point + // here it is implicitly assumed that the reference point is the origin + float Pos[3]; + Pos[0] = -d0*sin(phi0); + Pos[1] = d0*cos(phi0); + Pos[2] = z0; + + std::cout << "fucd------------------1" << std::endl; + // at this point is is possible to have hits from the same layer ... + // so a check is made to ensure that the hit with the smallest distance to the + // current helix hypothosis is used, the other hit has lh set to 0 + + // start loop over the hits to + for (int ihit=0;ihit<nHits;++ihit) { + + lh[ihit] = 1; // only hits which have lh=1 will be used for the fit + + // get the pointer to the lcio trackerhit for this hit + edm4hep::TrackerHit * trkHit = hitVec[ihit]->getTrackerHit(); + + int det = getDetectorID(trkHit); + + if (det == lcio::ILDDetID::VXD || det == lcio::ILDDetID::FTD || det == lcio::ILDDetID::SIT) { // only accept VXD, FTD or SIT + + + // int layer = getLayerID(trkHit); + // int moduleIndex = getModuleID(trkHit); + + // start a double loop over the hits which have already been checked + for (int lhit=0;lhit<ihit;++lhit) { + + // get the pointer to the lcio trackerhit for the previously checked hit + edm4hep::TrackerHit * trkHitS = hitVec[lhit]->getTrackerHit(); + + + // int layerS = getLayerID(trkHitS); + // int moduleIndexS = getModuleID(trkHitS); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if they are on the same layer and the previously checked hits has been declared good for fitting + // if ((trkHitS->getType() == trkHit->getType()) && (lh[lhit] == 1)) { + // check if the hits have the same layer and petal number + // hitVec[ihit]-> + // if ((layer == layerS) && (moduleIndex==moduleIndexS) && (lh[lhit] == 1)) { + if ( (trkHit->getCellID() == trkHitS->getCellID()) && (lh[lhit] == 1)) { + + // get the position of the hits + float xP[3]; + float xPS[3]; + for (int iC=0;iC<3;++iC) { + xP[iC] = float(trkHit->getPosition()[iC]); + xPS[iC] = float(trkHitS->getPosition()[iC]); + } + + // get the intersection of the helix with the either the cylinder or plane containing the hit + float Point[6]; + float PointS[6]; + + if (det == lcio::ILDDetID::FTD) { + + float time = helix->getPointInZ(xP[2],Pos,Point); + time = helix->getPointInZ(xPS[2],Pos,PointS); + + } else { + + float RAD = sqrt(xP[0]*xP[0]+xP[1]*xP[1]); + float RADS = sqrt(xPS[0]*xPS[0]+xPS[1]*xPS[1]); + float time = helix->getPointOnCircle(RAD,Pos,Point); + time = helix->getPointOnCircle(RADS,Pos,PointS); + + } + + float DIST = 0; + float DISTS = 0; + + // get the euclidean distance between the hit and the point of intersection + for (int iC=0;iC<3;++iC) { + DIST += (Point[iC]-xP[iC])*(Point[iC]-xP[iC]); + DISTS += (PointS[iC]-xPS[iC])*(PointS[iC]-xPS[iC]); + } + if (DIST < DISTS) { + lh[lhit] = 0; + } + else { + lh[ihit] = 0; + } + break; + } + } + } + } + + delete helix; + + std::vector<TrackerHit*> trkHits; + std::vector<TrackerHit*> trkHits_used_inFit; + + int nFit = 0; + for (int i=0; i<nHits; ++i) { + // check if the hit has been rejected as being on the same layer and further from the helix lh==0 + if (lh[i] == 1) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + nFit++; + if(trkHit) { + trkHits.push_back(trkHit); + } + else{ + throw EVENT::Exception( std::string("SiliconTracking::FinalRefit: TrackerHit pointer == NULL ") ) ; + } + } + else { // reject hit + // SJA:FIXME missuse of type find a better way to signal rejected hits + hitVec[i]->setType(int(0)); + } + } + + if( trkHits.size() < 3 ) { + debug() << "SiliconTracking::FinalRefit: Cannot fit less than 3 hits. Number of hits = " << trkHits.size() << endmsg; + continue ; + } + std::cout << "fucd------------------2" << std::endl; + //TrackImpl* Track = new TrackImpl ; + auto track = trk_col->create(); + //fucd + //edm4hep::Track track;// = new edm4hep::Track; + std::cout << "fucd------------------3" << std::endl; + // setup initial dummy covariance matrix + //std::vector<float> covMatrix; + //covMatrix.resize(15); + std::array<float,15> covMatrix; + + for (unsigned icov = 0; icov<covMatrix.size(); ++icov) { + covMatrix[icov] = 0; + } + + covMatrix[0] = ( _initialTrackError_d0 ); //sigma_d0^2 + covMatrix[2] = ( _initialTrackError_phi0 ); //sigma_phi0^2 + covMatrix[5] = ( _initialTrackError_omega ); //sigma_omega^2 + covMatrix[9] = ( _initialTrackError_z0 ); //sigma_z0^2 + covMatrix[14] = ( _initialTrackError_tanL ); //sigma_tanl^2 + + + std::vector< std::pair<float, edm4hep::TrackerHit*> > r2_values; + r2_values.reserve(trkHits.size()); + + for (std::vector<edm4hep::TrackerHit*>::iterator it=trkHits.begin(); it!=trkHits.end(); ++it) { + edm4hep::TrackerHit* h = *it; + float r2 = h->getPosition()[0]*h->getPosition()[0]+h->getPosition()[1]*h->getPosition()[1]; + r2_values.push_back(std::make_pair(r2, *it)); + } + + sort(r2_values.begin(),r2_values.end()); + //std::cout << "fucd------------------3" << std::endl; + trkHits.clear(); + trkHits.reserve(r2_values.size()); + + for (std::vector< std::pair<float, edm4hep::TrackerHit*> >::iterator it=r2_values.begin(); it!=r2_values.end(); ++it) { + trkHits.push_back(it->second); + } + //std::cout << "fucd------------------3 " << _trksystem << std::endl; + //for (unsigned ihit_indx=0 ; ihit_indx < trkHits.size(); ++ihit_indx) { + // std::cout << "fucd trk hit " << *trkHits[ihit_indx] << " " << trkHits[ihit_indx]->getCovMatrix()[0] + // << " " << BitSet32(trkHits[ihit_indx]->getType())[ ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] << endmsg; + //} + /* + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return; + } + debug() << "_trksystem pointer " << _trksystem << endmsg; + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + */ + bool fit_backwards = IMarlinTrack::backward; + + MarlinTrk::IMarlinTrack* marlinTrk = nullptr; + try{ + marlinTrk = _trksystem->createTrack(); + } + catch(...){ + error() << "Cannot create MarlinTrack ! " << endmsg; + return; + } + + int status = 0; + std::cout << "fucd------------------3" << std::endl; + try { + status = MarlinTrk::createFinalisedLCIOTrack(marlinTrk, trkHits, &track, fit_backwards, covMatrix, _bField, _maxChi2PerHit); + } catch (...) { + + // delete Track; + // delete marlinTrk; + error() << "MarlinTrk::createFinalisedLCIOTrack " << endmsg; + throw ; + + } + std::cout << "fucd------------------4" << std::endl; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + if ( status != IMarlinTrack::success && _runMarlinTrkDiagnostics ) { + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->skip_current_track(); + } +#endif + */ + + std::vector<std::pair<edm4hep::TrackerHit* , double> > hits_in_fit ; + std::vector<std::pair<edm4hep::TrackerHit* , double> > outliers ; + std::vector<edm4hep::TrackerHit*> all_hits; + all_hits.reserve(300); + + marlinTrk->getHitsInFit(hits_in_fit); + + for ( unsigned ihit = 0; ihit < hits_in_fit.size(); ++ihit) { + all_hits.push_back(hits_in_fit[ihit].first); + } + + UTIL::BitField64 cellID_encoder( lcio::ILDCellID0::encoder_string ) ; + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, true, cellID_encoder); + + marlinTrk->getOutliers(outliers); + + for ( unsigned ihit = 0; ihit < outliers.size(); ++ihit) { + all_hits.push_back(outliers[ihit].first); + } + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, false, cellID_encoder); + + delete marlinTrk; + + int nhits_in_vxd = track.getSubDetectorHitNumbers(0); + int nhits_in_ftd = track.getSubDetectorHitNumbers(1); + int nhits_in_sit = track.getSubDetectorHitNumbers(2); + + //debug() << " Hit numbers for Track "<< track->id() << ": " + debug() << " Hit numbers for Track "<< iTrk <<": " + << " vxd hits = " << nhits_in_vxd + << " ftd hits = " << nhits_in_ftd + << " sit hits = " << nhits_in_sit + << endmsg; + + //if (nhits_in_vxd > 0) Track->setTypeBit( lcio::ILDDetID::VXD ) ; + //if (nhits_in_ftd > 0) Track->setTypeBit( lcio::ILDDetID::FTD ) ; + //if (nhits_in_sit > 0) Track->setTypeBit( lcio::ILDDetID::SIT ) ; + + + + if( status != IMarlinTrack::success ) { + + //delete track; + debug() << "SiliconTracking::FinalRefit: Track fit failed with error code " << status << " track dropped. Number of hits = "<< trkHits.size() << endmsg; + continue ; + } + + if( track.getNdf() < 0) { + //delete track; + debug() << "SiliconTracking::FinalRefit: Track fit returns " << track.getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + //delete track; + continue ; + } + + //trk_col->addElement(Track); + //fucd + //trk_col->push_back(track); + for(int i=0;i<track.trackStates_size();i++){ + // 1 = lcio::EVENT::TrackState::AtIP + edm4hep::TrackState trkStateIP = track.getTrackStates(i); + if(trkStateIP.location !=1) continue; + /* + if (trkStateIP == 0) { + debug() << "SiliconTracking::FinalRefit: Track fit returns " << track->getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + throw EVENT::Exception( std::string("SiliconTracking::FinalRefit: trkStateIP pointer == NULL ") ) ; + } + */ + // note trackAR which is of type TrackExtended, only takes fits set for ref point = 0,0,0 + trackAR->setOmega(trkStateIP.omega); + trackAR->setTanLambda(trkStateIP.tanLambda); + trackAR->setPhi(trkStateIP.phi); + trackAR->setD0(trkStateIP.D0); + trackAR->setZ0(trkStateIP.Z0); + + float cov[15]; + + for (int i = 0 ; i<15 ; ++i) { + cov[i] = trkStateIP.covMatrix.operator[](i); + } + + trackAR->setCovMatrix(cov); + trackAR->setChi2(track.getChi2()); + trackAR->setNDF(track.getNdf()); + + nSiSegments++; + + HelixClass helix_final; + + helix_final.Initialize_Canonical(trkStateIP.phi,trkStateIP.D0,trkStateIP.Z0,trkStateIP.omega,trkStateIP.tanLambda,_bField); + + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkP = sqrt(trkPx*trkPx+trkPy*trkPy+trkPz*trkPz); + eTot += trkP; + pxTot += trkPx; + pyTot += trkPy; + pzTot += trkPz; + } + } + } + + debug() << "SiliconTracking -> run " << _nRun + << " event " << _nEvt << endmsg; + debug() << "Number of Si tracks = " << nSiSegments << endmsg; + debug() << "Total 4-momentum of Si Tracks : E = " << eTot + << " Px = " << pxTot + << " Py = " << pyTot + << " Pz = " << pzTot << endmsg; + + +} + + +StatusCode SiliconTracking::setupGearGeom(){ + auto _gear = service<IGearSvc>("GearSvc"); + if ( !_gear ) { + error() << "Failed to find GearSvc ..." << endmsg; + return StatusCode::FAILURE; + } + gear::GearMgr* gearMgr = _gear->getGearMgr(); + _bField = gearMgr->getBField().at( gear::Vector3D( 0.,0.,0.) ).z() ; + debug() << "Field " << _bField << endmsg; + //-- VXD Parameters-- + _nLayersVTX = 0 ; + const gear::VXDParameters* pVXDDetMain = 0; + const gear::VXDLayerLayout* pVXDLayerLayout = 0; + + try{ + + debug() << " filling VXD parameters from gear::SITParameters " << endmsg ; + + pVXDDetMain = &gearMgr->getVXDParameters(); + pVXDLayerLayout = &(pVXDDetMain->getVXDLayerLayout()); + _nLayersVTX = pVXDLayerLayout->getNLayers(); + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::VXDParameters Not Present in GEAR FILE" << endmsg ; + + } + + + + //-- SIT Parameters-- + _nLayersSIT = 0 ; + const gear::ZPlanarParameters* pSITDetMain = 0; + const gear::ZPlanarLayerLayout* pSITLayerLayout = 0; + + try{ + + debug() << " filling SIT parameters from gear::SITParameters " << endmsg ; + + pSITDetMain = &gearMgr->getSITParameters(); + pSITLayerLayout = &(pSITDetMain->getZPlanarLayerLayout()); + _nLayersSIT = pSITLayerLayout->getNLayers(); + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SITParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nLayersSIT == 0 ){ + // try the old LOI style key value pairs as defined in the SSit03 Mokka drive + try{ + + info() << " SiliconTracking - Simple Cylinder Based SIT using parameters defined by SSit03 Mokka driver " << endmsg ; + + // SIT + + const gear::GearParameters& pSIT = gearMgr->getGearParameters("SIT"); + + const std::vector<double>& SIT_r = pSIT.getDoubleVals("SITLayerRadius" ) ; + const std::vector<double>& SIT_hl = pSIT.getDoubleVals("SITSupportLayerHalfLength" ) ; + + _nLayersSIT = SIT_r.size() ; + + if (_nLayersSIT != SIT_r.size() || _nLayersSIT != SIT_hl.size()) { + + error() << "ILDSITCylinderKalDetector miss-match between DoubleVec and nlayers exit(1) called from file " << __FILE__ << " line " << __LINE__ << endmsg ; + exit(1); + + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SIT Parameters from as defined in SSit03 Not Present in GEAR FILE" << endmsg ; + + } + + } + + + + //-- FTD Parameters-- + _petalBasedFTDWithOverlaps = false; + _nlayersFTD = 0; + + try{ + + debug() << " filling FTD parameters from gear::FTDParameters " << endmsg ; + + const gear::FTDParameters& pFTD = gearMgr->getFTDParameters(); + const gear::FTDLayerLayout& ftdlayers = pFTD.getFTDLayerLayout() ; + + _nlayersFTD = ftdlayers.getNLayers() ; + + for (unsigned int disk=0; disk < _nlayersFTD; ++disk) { + + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 0, 1) ); // front petal even numbered + + if ( ftdlayers.getNPetals(disk) > 0) { + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 1, 1) ); // front petal odd numbered + _petalBasedFTDWithOverlaps = true; + } + + } + + // SJA: Here we increase the size of _nlayersFTD as we are treating the + _nlayersFTD =_zLayerFTD.size() ; + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTDParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nlayersFTD == 0 ){ + + // FTD + try{ + + info() << " SiliconTracking - Simple Disc Based FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + const gear::GearParameters& pFTD = gearMgr->getGearParameters("FTD"); + + const std::vector<double>* pFTD_z = NULL; + + info() << " For FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + pFTD_z = &pFTD.getDoubleVals("FTDZCoordinate" ) ; + + _nlayersFTD = pFTD_z->size(); + + for (unsigned int i = 0; i<_nlayersFTD; ++i) { + _zLayerFTD.push_back((*pFTD_z)[i]); + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTD Parameters as defined in SFtd05 Not Present in GEAR FILE" << endmsg ; + + } + } + return StatusCode::SUCCESS; +} + +void SiliconTracking::TracksWithNHitsContainer::clear() +{ + for (std::vector< TrackExtendedVec >::iterator trackVecIter = _tracksNHits.begin(); + trackVecIter < _tracksNHits.end(); trackVecIter++) + { + for (TrackExtendedVec::iterator trackIter = trackVecIter->begin(); + trackIter < trackVecIter->end(); trackIter++) + { + delete *trackIter; + } + + trackVecIter->clear(); + } +} + diff --git a/Reconstruction/SiliconTracking/src/SiliconTracking.h~ b/Reconstruction/SiliconTracking/src/SiliconTracking.h~ new file mode 100644 index 0000000000000000000000000000000000000000..86190002b98883556b62eccdeb6be4aabc0db257 --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTracking.h~ @@ -0,0 +1,426 @@ +#ifndef SiliconTracking_h +#define SiliconTracking_h + +//#include "marlin/Processor.h" +//#include <marlin/Global.h> +#include "FWCore/DataHandle.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/TrackCollection.h" +//#include "edm4hep/LCRelationCollection.h" + +//#include "lcio.h" +#include <string> +#include <vector> +#include <cmath> +//#include <IMPL/TrackImpl.h> +#include "ClusterExtended.h" +#include "TrackExtended.h" +#include "TrackerHitExtended.h" +#include "HelixClass.h" + +#include "TrackSystemSvc/IMarlinTrack.h" + +#include <UTIL/BitField64.h> +#include <UTIL/ILDConf.h> + +using namespace edm4hep ; + +namespace gear{ + class GearMgr ; +} + +namespace MarlinTrk { + class HelixFit; + class IMarlinTrkSystem ; +} + +namespace UTIL{ + class LCRelationNavigator ; +} + + +/** === Silicon Tracking Processor === <br> + * Processor performing stand-alone pattern recognition + * in the vertex detector (VTX), forward tracking disks and SIT. <br> + * The procedure consists of three steps : <br> + * 1) Tracking in VTX and SIT ; <br> + * 2) Tracking in FTD ; <br> + * 3) Merging compatible track segments reconstructed in VTX and FTD <br> + * STEP 1 : TRACKING IN VTX and SIT <br> + * Algorithm starts with finding of hit triplets satisfying helix hypothesis <br> + * in three different layers. Two layers of SIT are effectively considered as outermost <br> + * layers of the vertex detector. To accelerate procedure, the 4-pi solid angle + * is divided in NDivisionsInTheta and NDivisionsInPhi sectors in cosQ and Phi, + * respectively. Triplets are looked for in 2x2 window of adjacent sectors. + * Once triplet is found, attempt is made to associate additional hits to + * track. Combinatin of hits is accepted for further analysis if the Chi2 + * of the fit is less than certain predefined threshold. All accepted + * combinations are sorted in ascending order of their Chi2. First track candidate + * in the sorted array is automatically accepted. The hits belonging to this track are + * marked as used, and track candidates sharing these hits are discarded. + * The procedure proceeds with increasing index of track candidate in the sorted + * array until all track candidate have been output or discarded. <br> + * STEP 2 : TRACKING IN FTD <br> + * In the next step tracking in FTD is performed. The strategy of tracking in the FTD + * is the same as used for tracking in the VTX+SIT. <br> + * STEP 3 : MERGING TRACK SEGMENTS FOUND IN FTD AND VTX+SIT <br> + * In the last step, track segments reconstructed in the FTD and VTX+SIT, belonging to the + * same track are identified and merged into one track. All possible + * pairings are tested for their compatibility. + * The number of pairings considered is Ntrk_VTX_SIT*Ntrk_FTD, where Ntrk_VTX_SIT is the number of + * track segments reconstructed in the first step in VTX+SIT (segments containing solely VTX and SIT hits) and + * Ntrk_FTD is the number of track segments reconstructed in the second step + * (segments containing solely FTD hits). + * Pair of segments is accepted for further examination if the angle between track segments and + * than certain specified threshold. + * Pairing satisfying this condition is subjected for + * addtitional test. The fit is performed on unified array of hits belonging to both segments. + * If the chi2 of the fit does not exceed predefined cut value two segments are unified into + * one track. + * <h4>Input collections and prerequisites</h4> + * Processor requires collection of digitized vertex, sit and ftd tracker hits. <br> + * If such a collections with the user specified names do not exist + * processor takes no action. <br> + * <h4>Output</h4> + * Processor produces an LCIO collection of the Tracks. Each track is characterised by + * five parameters : Omega (signed curvuture), Tan(lambda) where + * lambda is the dip angle, Phi (azimuthal angle @ point of closest approach), D0 (signed impact parameter), + * Z0 (displacement along z axis at the point of closest approach to IP). Covariance matrix for these parameters is also provided. + * Only lower left corner of the covariance matrix is stored. The sequence of the covariance matrix elements + * assigned to track is the following: <br> + * (Omega,Omega) <br> + * (Omega,TanLambda), (TanLambda,TanLambda) <br> + * (Omega,Phi), (TanLamda,Phi), (Phi,Phi) <br> + * (Omega,D0), (TanLambda,D0), (Phi,D0), (D0,D0) <br> + * (Omega,Z0), (TanLambda,Z0), (Phi,Z0), (D0,Z0), (Z0,Z0) <br> + * The number of hits in the different subdetectors associated + * with each track can be accessed via method Track::getSubdetectorHitNumbers(). + * This method returns vector of integers : <br> + * number of VTX hits in track is the first element in this vector + * (Track::getSubdetectorHitNumbers()[0]) <br> + * number of FTD hits in track is the second element in this vector + * (Track::getSubdetectorHitNumbers()[1]) <br> + * number of SIT hits in track is the third element in this vector + * (Track::getSubdetectorHitNumbers()[2]) <br> + * Output track collection has a name "SiTracks". <br> + * @param VTXHitCollectionName name of input VTX TrackerHit collection <br> + * (default parameter value : "VTXTrackerHits") <br> + * @param FTDHitCollectionName name of input FTD TrackerHit collection <br> + * (default parameter value : "FTDTrackerHits") <br> + * @param SITHitCollectionName name of input SIT TrackerHit collection <br> + * (default parameter value : "SITTrackerHits") <br> + * @param SiTrackCollectionName name of the output Silicon track collection <br> + * (default parameter value : "SiTracks") <br> + * @param LayerCombinations combinations of layers used to search for hit triplets in VTX+SIT <br> + * (default parameters : 6 4 3 6 4 2 6 3 2 5 4 3 5 4 2 5 3 2 4 3 2 4 3 1 4 2 1 3 2 1) <br> + * Note that in the VTX+SIT system the first and the second layers of SIT have indicies nLayerVTX and nLayerVTX+1. + * Combination given above means that triplets are looked first in layers 6 4 3, and then + * in 6 4 2; 5 4 3; 6 3 2 etc. NOTE THAT LAYER INDEXING STARTS FROM 0. + * LAYER 0 is the innermost layer <br> + * @param LayerCombinationsFTD combinations of layers used to search for hit triplets in FTD <br> + * (default parameters 6 5 4 5 4 3 5 4 2 5 4 1 5 3 2 5 3 1 5 2 1 4 3 2 4 3 1 + * 4 3 0 4 2 1 4 2 0 4 1 0 3 2 1 3 2 0 3 1 0 2 1 0). + * NOTE THAT TRACKS IN FTD ARE SEARCHED ONLY IN ONE HEMISPHERE. TRACK IS NOT + * ALLOWED TO HAVE HITS BOTH IN BACKWARD AND FORWARD PARTS OF FTD SIMULTANEOUSLY. + * @param NDivisionsInPhi Number of divisions in Phi for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInTheta Number of divisions in cosQ for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInPhiFTD Number of divisions in Phi for tracking in FTD <br> + * (default value is 3) <br> + * @param Chi2WRphiTriplet weight on chi2 in R-Phi plane for track with 3 hits <br> + * (default value is 1) <br> + * @param Chi2WZTriplet weight on chi2 in S-Z plane for track with 3 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiQuartet weight on chi2 in R-Phi plane to accept track with 4 hits <br> + * (default value is 1) <br> + * @param Chi2WZQuartet weight on chi2 in S-Z plane for track with 4 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiSeptet weight on chi2 in R-Phi plane for track with 5 and more hits <br> + * (default value is 1) <br> + * @param Chi2WZSeptet Cut on chi2 in S-Z plane for track with 5 and more hits <br> + * (default value is 0.5) <br> + * @param Chi2FitCut Cut on chi2/ndf to accept track candidate <br> + * (default value is 100.) <br> + * @param AngleCutForMerging cut on the angle between two track segments. + * If the angle is greater than this cut, segments are not allowed to be merged. <br> + * (default value is 0.1) <br> + * @param MinDistCutAttach cut on the distance (in mm) from hit to the helix. This parameter is used + * to decide whether hit can be attached to the track. If the distance is less than + * cut value. The track is refitted with a given hit being added to the list of hits already + * assigned for the track. Additional hit is assigned if chi2 of the new fit has good chi2. <br> + * (default value is 2 ) <br> + * @param MinLayerToAttach the minimal layer index to attach VTX hits to the found hit triplets <br> + * (default value is -1) <br> + * @param CutOnZ0 cut on Z0 parameter of track (in mm). If abs(Z0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnD0 cut on D0 parameter of track (in mm). If abs(D0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnPt cut on Pt (GeV/c). If Pt is less than this cut, track is discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 0.1) <br> + * @param MinimalHits minimal number of hits in track required <br> + * (default value is 3) <br> + * @param NHitsChi2 Maximal number of hits for which a track with n hits is aways better than one with n-1 hits. + * For tracks with equal or more than NHitsChi2 the track with the lower \f$\chi^2\f$ is better. + * (default value is 5) <br> + * @param FastAttachment if this flag is set to 1, less accurate but fast procedure to merge additional hits to tracks is used <br> + * if set to 0, a more accurate, but slower procedure is invoked <br> + * (default value is 0) <br> + * @param UseSIT When this flag is set to 1, SIT is included in pattern recognition. When this flag is set + * to 0, SIT is excluded from the procedure of pattern recognition <br> + * (default value is 1) <br> + * <br> + * @author A. Raspereza (MPI Munich)<br> + */ +class SiliconTracking : public GaudiAlgorithm { + public: + + SiliconTracking(const std::string& name, ISvcLocator* svcLoc); + + virtual StatusCode initialize() ; + + virtual StatusCode execute() ; + + virtual StatusCode finalize() ; + +protected: + + int _nRun ; + int _nEvt ; + //EVENT::LCEvent* _current_event; + int _nLayers; + unsigned int _nLayersVTX; + unsigned int _nLayersSIT; + int _ntriplets, _ntriplets_good, _ntriplets_2MCP, _ntriplets_3MCP, _ntriplets_1MCP_Bad, _ntriplets_bad; + + MarlinTrk::HelixFit* _fastfitter; + gear::GearMgr* _GEAR; + /** pointer to the IMarlinTrkSystem instance + */ + MarlinTrk::IMarlinTrkSystem* _trksystem ; + //bool _runMarlinTrkDiagnostics; + //std::string _MarlinTrkDiagnosticsName; + typedef std::vector<int> IntVec; + + Gaudi::Property<IntVec> _Combinations{this, "LayerCombinations", {8,6,5, 8,6,4, 8,6,3, 8,6,2, 8,5,3, 8,5,2, 8,4,3, 8,4,2, 6,5,3, 6,5,2, 6,4,3, 6,4,2, 6,3,1, 6,3,0, 6,2,1, 6,2,0, + 5,3,1, 5,3,0, 5,2,1, 5,2,0, 4,3,1, 4,3,0, 4,2,1, 4,2,0}}; + Gaudi::Property<IntVec> _CombinationsFTD{this, "LayerCombinationsFTD", {4,3,2, 4,3,1, 4,3,0, 4,2,1, 4,2,0, 4,1,0, 3,2,1, 3,2,0, 3,1,0, 2,1,0, + 9,8,7, 9,8,6, 9,8,5, 9,7,6, 9,7,5, 9,6,5, 8,7,6, 8,7,5, 8,6,5, 7,6,5}}; + Gaudi::Property<int> _nDivisionsInPhi{this, "NDivisionsInPhi", 80}; + Gaudi::Property<int> _nDivisionsInPhiFTD{this, "NDivisionsInPhiFTD", 30}; + Gaudi::Property<int> _nDivisionsInTheta{this, "NDivisionsInTheta", 80}; + Gaudi::Property<float> _chi2WRPhiTriplet{this, "Chi2WRphiTriplet", 1.}; + Gaudi::Property<float> _chi2WRPhiQuartet{this, "Chi2WRphiQuartet", 1.}; + Gaudi::Property<float> _chi2WRPhiSeptet{this, "Chi2WRphiSeptet", 1.}; + Gaudi::Property<float> _chi2WZTriplet{this, "Chi2WZTriplet", 0.5}; + Gaudi::Property<float> _chi2WZQuartet{this, "Chi2WZQuartet", 0.5}; + Gaudi::Property<float> _chi2WZSeptet{this, "Chi2WZSeptet", 0.5}; + Gaudi::Property<float> _chi2FitCut{this, "Chi2FitCut", 120.}; + Gaudi::Property<float> _angleCutForMerging{this, "AngleCutForMerging", 0.1}; + Gaudi::Property<float> _minDistCutAttach{this, "MinDistCutAttach", 2.5}; + Gaudi::Property<float> _minimalLayerToAttach{this, "MinLayerToAttach", -1}; + Gaudi::Property<float> _cutOnD0{this, "CutOnD0", 100.0}; + Gaudi::Property<float> _cutOnZ0{this, "CutOnZ0", 100.0}; + Gaudi::Property<float> _cutOnPt{this, "CutOnPt", 0.05}; + Gaudi::Property<int> _minimalHits{this, "MinimalHits",3}; + Gaudi::Property<int> _nHitsChi2{this, "NHitsChi2", 5}; + Gaudi::Property<int> _max_hits_per_sector{this, "MaxHitsPerSector", 100}; + Gaudi::Property<int> _attachFast{this, "FastAttachment", 0}; + Gaudi::Property<bool> _useSIT{this, "UseSIT", true}; + Gaudi::Property<float> _initialTrackError_d0{this, "InitialTrackErrorD0",1e6}; + Gaudi::Property<float> _initialTrackError_phi0{this, "InitialTrackErrorPhi0",1e2}; + Gaudi::Property<float> _initialTrackError_omega{this, "InitialTrackErrorOmega",1e-4}; + Gaudi::Property<float> _initialTrackError_z0{this, "InitialTrackErrorZ0",1e6}; + Gaudi::Property<float> _initialTrackError_tanL{this, "InitialTrackErrorTanL",1e2}; + Gaudi::Property<float> _maxChi2PerHit{this, "MaxChi2PerHit", 1e2}; + Gaudi::Property<int> _checkForDelta{this, "CheckForDelta", 1}; + Gaudi::Property<float> _minDistToDelta{this, "MinDistToDelta", 0.25}; + Gaudi::Property<bool> _MSOn{this, "MultipleScatteringOn", true}; + Gaudi::Property<bool> _ElossOn{this, "EnergyLossOn", true}; + Gaudi::Property<bool> _SmoothOn{this, "SmoothOn", true}; + Gaudi::Property<float> _helix_max_r{this, "HelixMaxR", 2000.}; + + //std::vector<int> _colours; + + /** helper function to get collection using try catch block */ + //LCCollection* GetCollection( LCEvent * evt, std::string colName ) ; + + /** helper function to get relations using try catch block */ + //LCRelationNavigator* GetRelations( LCEvent * evt, std::string RelName ) ; + + /** input MCParticle collection and threshold used for Drawing + */ + //Gaudi::Property<Float> _MCpThreshold{this, "MCpThreshold", 0.1}; + //std::string _colNameMCParticles; + + /// Compare tracks according to their chi2/ndf + struct compare_TrackExtended{ + // n.b.: a and b should be TrackExtended const *, but the getters are not const :-( + bool operator()(TrackExtended *a, TrackExtended *b) const { + if ( a == b ) return false; + return (a->getChi2()/a->getNDF() < b->getChi2()/b->getNDF() ); + } + }; + + + //std::string _VTXHitCollection; + //std::string _FTDPixelHitCollection; + //std::string _FTDSpacePointCollection; + //std::string _SITHitCollection; + //std::string _siTrkCollection; + + //std::vector< LCCollection* > _colTrackerHits; + //std::map< LCCollection*, std::string > _colNamesTrackerHits; + + // Input collections + DataHandle<edm4hep::EventHeaderCollection> _headerColHdl{"EventHeaderCol", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::MCParticleCollection> _inMCColHdl{"MCParticle", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inVTXColHdl{"VXDCollection", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inFTDPixelColHdl{"FTDPixelCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inVTXColHdl{"VXDTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDPixelColHdl{"FTDPixelTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDSpacePointColHdl{"FTDSpacePoints", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inSITColHdl{"SITTrackerHits", Gaudi::DataHandle::Reader, this}; + // Output collections + DataHandle<edm4hep::TrackCollection> _outColHdl{"SiTracks", Gaudi::DataHandle::Writer, this}; + //DataHandle<edm4hep::LCRelationCollection> _outRelColHdl{"TrackerHitRelations", Gaudi::DataHandle::Reader, this}; + + std::vector<TrackerHitExtendedVec> _sectors; + std::vector<TrackerHitExtendedVec> _sectorsFTD; + + /** + * A helper class to allow good code readability by accessing tracks with N hits. + * As the smalest valid track contains three hits, but the first index in a vector is 0, + * this class hides the index-3 calculation. As the vector access is inline there should be + * no performance penalty. + */ + class TracksWithNHitsContainer { + public: + /// Empty all the vectors and delete the tracks contained in it. + void clear(); + + /// Set the size to allow a maximum of maxHit hits. + inline void resize(size_t maxHits) { + _tracksNHits.resize(maxHits-2); + _maxIndex=(maxHits-3); + } + + // Sort all track vectors according to chi2/nDof + // void sort(); + + /// Returns the TrackExtendedVec for track with n hits. + /// In case n is larger than the maximal number the vector with the largest n ist returned. + /// \attention The smallest valid number is three! For + /// performance reasons there is no safety check! + inline TrackExtendedVec & getTracksWithNHitsVec( size_t nHits ) { + //return _tracksNHits[ std::min(nHits-3, _maxIndex) ]; + // for debugging: with boundary check + return _tracksNHits.at(std::min(nHits-3, _maxIndex)); + } + + protected: + std::vector< TrackExtendedVec > _tracksNHits; + size_t _maxIndex; /// local cache variable to avoid calculation overhead + }; + + TracksWithNHitsContainer _tracksWithNHitsContainer; + + int InitialiseVTX(); + int InitialiseFTD(); + void ProcessOneSector(int iSectorPhi, int iSectorTheta); + void CleanUp(); + TrackExtended * TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix); + + int BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerlayer, + int iPhiLow, int iPhiUp, + int iTheta, int iThetaUp, + TrackExtended * trackAR); + + void Sorting( TrackExtendedVec & trackVec); + void CreateTrack(TrackExtended * trackAR ); + void AttachRemainingVTXHitsSlow(); + void AttachRemainingFTDHitsSlow(); + void AttachRemainingVTXHitsFast(); + void AttachRemainingFTDHitsFast(); + void TrackingInFTD(); + int BuildTrackFTD(TrackExtended* trackAR, int* nLR, int iS); + int AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt); + + void FinalRefit(edm4hep::TrackCollection*);//, edm4hep::LCRelationCollection*); + + float _bField; + + // two pi is not a constant in cmath. Calculate it, once! + static const double TWOPI; + + double _dPhi; + double _dTheta; + double _dPhiFTD; + + float _resolutionRPhiVTX; + float _resolutionZVTX; + + float _resolutionRPhiFTD; + float _resolutionZFTD; + + float _resolutionRPhiSIT; + float _resolutionZSIT; + + float _phiCutForMerging; + float _tanlambdaCutForMerging; + //float _angleCutForMerging; + + float _distRPhi; + float _distZ; + + float _cutOnOmega; + + TrackExtendedVec _trackImplVec; + + int _nTotalVTXHits,_nTotalFTDHits,_nTotalSITHits; + + // int _createMap; + + UTIL::BitField64* _encoder; + int getDetectorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::subdet]; } + int getSideID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::side]; }; + int getLayerID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::layer]; }; + int getModuleID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::module]; }; + int getSensorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::sensor]; }; + + StatusCode setupGearGeom() ; + + std::vector<float> _zLayerFTD; + + unsigned int _nlayersFTD; + bool _petalBasedFTDWithOverlaps; + int _nPhiFTD; + + int _output_track_col_quality; + static const int _output_track_col_quality_GOOD; + static const int _output_track_col_quality_FAIR; + static const int _output_track_col_quality_POOR; + + std::vector<edm4hep::TrackerHit> _allHits; +} ; + +#endif + + + diff --git a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..156d9afde64c18fd7dfcc23558f0133d653f4027 --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp @@ -0,0 +1,3083 @@ +#include "SiliconTrackingAlg.h" +#include "GearSvc/IGearSvc.h" +#include "EventSeeder/IEventSeeder.h" +#include "TrackSystemSvc/ITrackSystemSvc.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/TrackerHit.h" +//#include "edm4hep/TrackerHitPlane.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackState.h" + +#include <iostream> +#include <algorithm> +#include <cmath> +#include <climits> + +#include <gear/GEAR.h> +#include <gear/GearMgr.h> +#include <gear/GearParameters.h> +#include <gear/VXDLayerLayout.h> +#include <gear/VXDParameters.h> +#include "gear/FTDLayerLayout.h" +#include "gear/FTDParameters.h" + +#include <gear/BField.h> + +#include <UTIL/BitField64.h> +#include <UTIL/BitSet32.h> +#include <UTIL/ILDConf.h> + +#include "TrackSystemSvc/MarlinTrkUtils.h" +#include "TrackSystemSvc/HelixTrack.h" +#include "TrackSystemSvc/HelixFit.h" +#include "TrackSystemSvc/IMarlinTrack.h" + +//#include "TrackSystemSvc/MarlinTrkDiagnostics.h" +//#ifdef MARLINTRK_DIAGNOSTICS_ON +//#include "TrackSystemSvc/DiagnosticsController.h" +//#endif + +//#include "MarlinCED.h" + +//#include "marlin/AIDAProcessor.h" + +//---- ROOT ----- +#include "TH1F.h" +#include "TH2F.h" + +using namespace edm4hep ; +//using namespace marlin ; +using namespace MarlinTrk ; + +using std::min; +using std::max; +using std::abs; + +const int SiliconTrackingAlg::_output_track_col_quality_GOOD = 1; +const int SiliconTrackingAlg::_output_track_col_quality_FAIR = 2; +const int SiliconTrackingAlg::_output_track_col_quality_POOR = 3; + +const double SiliconTrackingAlg::TWOPI = 2*M_PI; + +DECLARE_COMPONENT( SiliconTrackingAlg ) + +SiliconTrackingAlg::SiliconTrackingAlg(const std::string& name, ISvcLocator* svcLoc) +: GaudiAlgorithm(name, svcLoc) { + + //_description = "Pattern recognition in silicon trackers"; + + _fastfitter = new MarlinTrk::HelixFit(); + + _encoder = new UTIL::BitField64(lcio::ILDCellID0::encoder_string); + + _petalBasedFTDWithOverlaps = false; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Input Collections + // ^^^^^^^^^^^^^^^^^ + declareProperty("HeaderCol", _headerColHdl); + declareProperty("MCParticleCollection", _inMCColHdl, "Handle of the Input MCParticle collection"); + declareProperty("VTXHitCollection", _inVTXColHdl, "Handle of the Input VTX TrackerHits collection"); + declareProperty("FTDPixelHitCollection", _inFTDPixelColHdl, "Handle of the Input FTD TrackerHits collection"); + declareProperty("FTDSpacePointCollection", _inFTDSpacePointColHdl, "Handle of the Input FTD SpacePoints collection"); + declareProperty("SITHitCollection", _inSITColHdl, "Handle of the Input SIT TrackerHits collection"); + + // Output Collections + // ^^^^^^^^^^^^^^^^^^ + declareProperty("SiTrackCollection", _outColHdl, "Handle of the SiTrack output collection"); + //declareProperty("TrkHitRelCollection", _outRelColHdl, "Handle of TrackerHit Track relation collection"); + // Steering parameters + // ^^^^^^^^^^^^^^^^^^^ + + _output_track_col_quality = _output_track_col_quality_GOOD; + +} + + + +StatusCode SiliconTrackingAlg::initialize() { + + _nRun = -1 ; + _nEvt = 0 ; + //printParameters() ; + + // set up the geometery needed by KalTest + //FIXME: for now do KalTest only - make this a steering parameter to use other fitters + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return StatusCode::FAILURE; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return StatusCode::FAILURE; + } + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + std::cout << "fucd ==============" << _trksystem << std::endl; +#ifdef MARLINTRK_DIAGNOSTICS_ON + + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->init(_MarlinTrkDiagnosticsName,_MarlinTrkDiagnosticsName, _runMarlinTrkDiagnostics); + +#endif + + if(setupGearGeom()==StatusCode::FAILURE) return StatusCode::FAILURE; + + if (_useSIT == 0) + _nLayers = _nLayersVTX; + else + _nLayers = _nLayersVTX + _nLayersSIT; + + // initialise the container to have separate vectors for up to _nHitsChi2 hits. + _tracksWithNHitsContainer.resize(_nHitsChi2); + + _dPhi = TWOPI/_nDivisionsInPhi; + _dTheta = 2.0/_nDivisionsInTheta; + _dPhiFTD = TWOPI/_nPhiFTD; + // I leave this for the moment, but 0.3 is c/1e9. + // For the cut it does not make too much of a difference + double cutOnR = _cutOnPt/(0.3*_bField); + cutOnR = 1000.*cutOnR; + _cutOnOmega = 1/cutOnR; + + _output_track_col_quality = 0; + + return GaudiAlgorithm::initialize(); +} + +StatusCode SiliconTrackingAlg::execute(){ + + //_current_event = evt; + //_allHits.reserve(1000); + + _output_track_col_quality = _output_track_col_quality_GOOD; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Clearing the working containers from the previous event + // FIXME: partly done at the end of the event, in CleanUp. Make it consistent. + //_tracksWithNHitsContainer.clear(); + //_trackImplVec.clear(); + + //_colTrackerHits.clear(); + //_colNamesTrackerHits.clear(); + //auto header = _headerColHdl.get()->at(0); + //int evtNo = header.getEventNumber(); + //int runNo = header.getRunNumber(); + //debug() << "Processing Run[" << runNo << "]::Event[" << evtNo << "]" << endmsg; + + _trackImplVec.reserve(100); + _allHits.reserve(1000); + + int successVTX = InitialiseVTX(); + int successFTD = 0; + //int successFTD = InitialiseFTD(); + if (successVTX == 1) { + + debug() << " phi theta layer nh o : m : i :: o*m*i " << endmsg; + + for (int iPhi=0; iPhi<_nDivisionsInPhi; ++iPhi) { + for (int iTheta=0; iTheta<_nDivisionsInTheta;++iTheta) { + ProcessOneSector(iPhi,iTheta); // Process one VXD sector + } + } + + debug() << "End of Processing VXD and SIT sectors" << endmsg; + + } + + if (successFTD == 1) { + debug() << " phi side layer nh o : m : i :: o*m*i " << endmsg; + TrackingInFTD(); // Perform tracking in the FTD + debug() << "End of Processing FTD sectors" << endmsg; + } + + //if(0){ + if (successVTX == 1 || successFTD == 1) { + //if (successVTX == 1 ) { + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + Sorting( _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ) ); + + } + debug() << "End of Sorting " << endmsg; + + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + + TrackExtendedVec &tracksWithNHits = _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ); + for (TrackExtendedVec::iterator trackIter = tracksWithNHits.begin(); + trackIter < tracksWithNHits.end(); trackIter++) { + CreateTrack( *trackIter ); + } + debug() << "End of creating "<< nHits << " hits tracks " << endmsg; + } + + if (_attachFast == 0) { + if(successVTX) AttachRemainingVTXHitsSlow(); + if(successFTD) AttachRemainingFTDHitsSlow(); + } + else { + if(successVTX) AttachRemainingVTXHitsFast(); + if(successFTD) AttachRemainingFTDHitsFast(); + } + + debug() << "End of picking up remaining hits " << endmsg; + + //edm4hep::TrackCollection* trkCol = nullptr; + //edm4hep::LCRelationCollection* relCol = nullptr; + auto trkCol = _outColHdl.createAndPut(); + //auto relCol = _outRelColHdl.createAndPut(); + //std::cout << "fucd------------------" << std::endl; + /* + LCCollectionVec * trkCol = new LCCollectionVec(LCIO::TRACK); + // if we want to point back to the hits we need to set the flag + LCFlagImpl trkFlag(0) ; + trkFlag.setBit( LCIO::TRBIT_HITS ) ; + trkCol->setFlag( trkFlag.getFlag() ) ; + + LCCollectionVec * relCol = NULL; + */ + //FinalRefit(trkCol, relCol); + FinalRefit(trkCol); + //std::cout << "fucd------------------" << std::endl; + // set the quality of the output collection + switch (_output_track_col_quality) { + + case _output_track_col_quality_FAIR: + //trkCol->parameters().setValue( "QualityCode" , "Fair" ) ; + break; + + case _output_track_col_quality_POOR: + //trkCol->parameters().setValue( "QualityCode" , "Poor" ) ; + break; + + default: + //trkCol->parameters().setValue( "QualityCode" , "Good" ) ; + break; + } + /* + if (_UseEventDisplay) { + this->drawEvent(); + } + */ + } + + // fill event based histogram + /* + if (_createDiagnosticsHistograms) { + + // triplet histos + _histos->fill1D(DiagnosticsHistograms::hntriplets, _ntriplets); + _histos->fill1D(DiagnosticsHistograms::hntriplets_good, _ntriplets_good); + _histos->fill1D(DiagnosticsHistograms::hntriplets_2MCP, _ntriplets_2MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_3MCP, _ntriplets_3MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_1MCP_Bad, _ntriplets_1MCP_Bad); + _histos->fill1D(DiagnosticsHistograms::hntriplets_bad, _ntriplets_bad); + + } + */ + /* + const edm4hep::MCParticleCollection* mcCol = nullptr; + try{ + mcCol =_inMCColHdl.get(); + } + catch(...){ + } + if(mcCol){ + int id = 0; + for(auto mcP : *mcCol){ + float pos[3]; + float mom[3]; + pos[0] = mcP.vertex()[0]; + pos[1] = mcP.vertex()[1]; + pos[2] = mcP.vertex()[2]; + mom[0] = mcP.momentum()[0]; + mom[1] = mcP.momentum()[1]; + mom[2] = mcP.momentum()[2]; + float charge = mcP.getCharge(); + HelixClass helix; + helix.Initialize_VP(pos,mom,charge,_bField); + float d0 = helix.getD0(); + float z0 = helix.getZ0(); + float omega = helix.getOmega(); + float phi0 = helix.getPhi0(); + float tanLambda = helix.getTanLambda(); + std::cout <<"MCParticle: " << evtNo << " " << id << " " << sqrt(mom[0]*mom[0]+mom[1]*mom[1]) << " " << acos(mom[2]/sqrt(mom[0]*mom[0]+mom[1]*mom[1]+mom[2]*mom[2])) + << " " << atan2(mom[1],mom[0]) + << " " << d0 << " " << phi0 << " " << omega << " " << z0 << " " << tanLambda << " " << mcP.vertex() << std::endl; + id++; + } + } + + const edm4hep::TrackCollection* trkCol = nullptr; + try{ + trkCol = _outColHdl.get(); + } + catch(...){ + } + if(trkCol){ + int id = 0; + for(auto track : *trkCol){ + int nstate = track->trackStates_size(); + for(int i=0;i<nstate;i++){ + edm4hep::TrackState trkState = track->getTrackStates(i); + if(trkState.location != 1) continue; + HelixClass helix_final; + helix_final.Initialize_Canonical(trkState.phi,trkState.D0,trkState.Z0,trkState.omega,trkState.tanLambda,_bField); + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkPt = sqrt(trkPx*trkPx+trkPy*trkPy); + std::cout << "Track parameter: " << evtNo << " " << id << " " << trkPt << " " << acos(trkPz/sqrt(trkPt*trkPt+trkPz*trkPz)) << " " << atan2(trkPy,trkPx) + << " " << trkState.D0 << " " << trkState.phi << " " << trkState.omega << " " << trkState.Z0 << " " << trkState.tanLambda + << " " << sqrt(trkState.covMatrix[0]) << " " << sqrt(trkState.covMatrix[2]) << " " << sqrt(trkState.covMatrix[5]) + << " " << sqrt(trkState.covMatrix[9]) << " " << sqrt(trkState.covMatrix[14]) << " " << std::endl; + id++; + break; + } + } + } + */ + CleanUp(); + debug() << "Event is done " << endmsg; + _nEvt++; + return StatusCode::SUCCESS; +} + + +void SiliconTrackingAlg::CleanUp() { + + _tracksWithNHitsContainer.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + unsigned int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + + if( iCode >= _sectors.size()){ + error() << "iCode index out of range: iCode = " << iCode << " _sectors.size() = " << _sectors.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + unsigned int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + + if( iCode >= _sectorsFTD.size()){ + //error() << "iCode index out of range: iCode = " << iCode << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + _trackImplVec.clear(); + _allHits.clear(); +} + +int SiliconTrackingAlg::InitialiseFTD() { + + int success = 1; + + _nTotalFTDHits = 0; + _sectorsFTD.clear(); + _sectorsFTD.resize(2*_nlayersFTD*_nPhiFTD); + + // Reading in FTD Pixel Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDPixelCol = nullptr; + try { + hitFTDPixelCol = _inFTDPixelColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDPixelColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDPixelCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDPixelHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDPixelHitCollection; + // _colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDPixelCol->size(); + + debug() << "Number of FTD Pixel Hits = " << nelem << endmsg; + _nTotalFTDHits = nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDPixelCol){ + // edm4hep::TrackerHit* hit = hitFTDPixelCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended( hit ); + + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors V is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // SJA:FIXME Here dU and dV are almost certainly dX and dY ... should test ... + //double point_res_rphi = sqrt( hit->getdU()*hit->getdU() + hit->getdV()*hit->getdV() ); + double point_res_rphi = sqrt( hit.getCovMatrix()[2]*hit.getCovMatrix()[2] + hit.getCovMatrix()[5]*hit.getCovMatrix()[5] ); + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTrackingAlg => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD Pixel Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + } + } + // Reading out FTD SpacePoint Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDSpacePointCol = nullptr; + try { + hitFTDSpacePointCol = _inFTDSpacePointColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDSpacePointColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDSpacePointCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDSpacePointCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDSpacePointCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDSpacePointCol->size(); + + debug() << "Number of FTD SpacePoints = " << nelem << endmsg; + _nTotalFTDHits += nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDSpacePointCol){ + //edm4hep::TrackerHit* hit = hitFTDSpacePointCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + double point_res_rphi = 2 * sqrt( hit.getCovMatrix()[0] + hit.getCovMatrix()[2] ); + + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTrackingAlg => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD SpacePoint Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + for (unsigned i=0; i<_sectorsFTD.size(); ++i) { + int nhits = _sectorsFTD[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in FTD Sector " << i << " = " << _sectorsFTD[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectorsFTD[i].size(); ++ihit) { + delete _sectorsFTD[i][ihit]; + } + _sectorsFTD[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in FTD Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + + } + + } + debug() << "FTD initialized" << endmsg; + return success; +} + +int SiliconTrackingAlg::InitialiseVTX() { + //std::cout << "fucd================" << std::endl; + _nTotalVTXHits = 0; + _nTotalSITHits = 0; + _sectors.clear(); + _sectors.resize(_nLayers*_nDivisionsInPhi*_nDivisionsInTheta); + //std::cout << "fucd================" << std::endl; + int success = 1; + // Reading out VTX Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitVTXCol = nullptr; + try { + hitVTXCol = _inVTXColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inVTXColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitVTXCol){ + //LCCollection * hitCollection = evt->getCollection(_VTXHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _VTXHitCollection; + //_colTrackerHits.push_back(hitCollection); + //std::cout << "fucd================1" << std::endl; + int nelem = hitVTXCol->size(); + //std::cout << "fucd================2" << std::endl; + debug() << "Number of VTX hits = " << nelem << endmsg; + _nTotalVTXHits = nelem; + + for (int ielem=0; ielem<nelem; ++ielem) { + //for(auto hit : *hitVTXCol){ + edm4hep::TrackerHit hit = hitVTXCol->at(ielem); + //_allHits.push_back(hit); + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + //debug() << "covMatrix : " << hit->getCovMatrix()[0] << " " << hit->getCovMatrix()[1] << endmsg; + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + //std::cout << "fucd: " << &hit << " " << &_allHits.back() << std::endl; + //TrackerHitExtended * hitExt = new TrackerHitExtended( &_allHits.back() ); + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + std::cout << "Saved TrackerHit pointer in TrackerHitExtended " << ielem << ": " << hitExt->getTrackerHit() << std::endl; + //std::cout << (&_allHits.back())->getPosition()[0] << " " << hit.getCovMatrix()[2] << " " << hit.getCovMatrix()[5] << std::endl; + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(hit.getCovMatrix()[2]); + hitExt->setResolutionZ(hit.getCovMatrix()[5]); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + int layer = getLayerID(&hit); + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTrackingAlg => fatal error in VTX : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " VXD Hit " << hit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + if (_useSIT > 0 ) { + const edm4hep::TrackerHitCollection* hitSITCol = nullptr; + try { + hitSITCol = _inSITColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inSITColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitSITCol){ + //LCCollection *hitCollection = evt->getCollection(_SITHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _SITHitCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitSITCol->size(); + + debug() << "Number of SIT hits = " << nelem << endmsg; + _nTotalSITHits = nelem; + + //TrackerHit* trkhit = 0; + //TrackerHitPlane* trkhit_P = 0; + //TrackerHitZCylinder* trkhit_C = 0; + + double drphi(NAN); + double dz(NAN); + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto trkhit : *hitSITCol){ + // hit could be of the following type + // 1) TrackerHit, either ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT or just standard TrackerHit + // 2) TrackerHitPlane, either 1D or 2D + // 3) TrackerHitZCylinder, if coming from a simple cylinder design as in the LOI + + // Establish which of these it is in the following order of likelyhood + // i) ILDTrkHitTypeBit::ONE_DIMENSIONAL (TrackerHitPlane) Should Never Happen: SpacePoints Must be Used Instead + // ii) ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT (TrackerHit) + // iii) TrackerHitPlane (Two dimentional) + // iv) TrackerHitZCylinder + // v) Must be standard TrackerHit + + //const edm4hep::TrackerHit* trkhit = hitSITCol->at(ielem); + + int layer = getLayerID(&trkhit); + + // VXD and SIT are treated as one system so SIT layers start from _nLayersVTX + layer = layer + _nLayersVTX; + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTrackingAlg => fatal error in SIT : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + // first check that we have not been given 1D hits by mistake, as they won't work here + if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL ] ) { + + error() << "SiliconTrackingAlg: SIT Hit cannot be of type UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL COMPOSITE SPACEPOINTS must be use instead. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + + } + // most likely case: COMPOSITE_SPACEPOINT hits formed from stereo strip hits + else if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ) { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // or a PIXEL based SIT, using 2D TrackerHitPlane like the VXD above + // by fucd + //else if ( ( trkhit_P = dynamic_cast<TrackerHitPlane*>( hitCollection->getElementAt( ielem ) ) ) ) { + else if( UTIL::BitSet32( trkhit.getType() )[ 31 ]){ + // first we need to check if the measurement vectors are aligned with the global coordinates + //gear::Vector3D U(1.0,trkhit_P->getU()[1],trkhit_P->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,trkhit_P->getV()[1],trkhit_P->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,trkhit.getCovMatrix()[1],trkhit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,trkhit.getCovMatrix()[4],trkhit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: PIXEL SIT Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // U must be normal to the global z axis + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: PIXEL SIT Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + //drphi = trkhit_P->getdU(); + //dz = trkhit_P->getdV(); + drphi = trkhit.getCovMatrix()[2]; + dz = trkhit.getCovMatrix()[5]; + } + + // or a simple cylindrical design, as used in the LOI + /* by fucd + else if ( ( trkhit_C = dynamic_cast<TrackerHitZCylinder*>( hitCollection->getElementAt( ielem ) ) ) ) { + + drphi = trkhit_C->getdRPhi(); + dz = trkhit_C->getdZ(); + + } + */ + // this would be very unlikely, but who knows ... just an ordinary TrackerHit, which is not a COMPOSITE_SPACEPOINT + else { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // now that the hit type has been established carry on and create a + + TrackerHitExtended * hitExt = new TrackerHitExtended(trkhit); + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(drphi); + hitExt->setResolutionZ(dz); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = trkhit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " SIT Hit " << trkhit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + } + + + for (unsigned i=0; i<_sectors.size(); ++i) { + int nhits = _sectors[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in VXD/SIT Sector " << i << " = " << _sectors[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectors[i].size(); ++ihit) { + delete _sectors[i][ihit]; + } + _sectors[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in VXD/SIT Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + } + } + debug() << "VXD initialized" << endmsg; + return success; +} + +StatusCode SiliconTrackingAlg::finalize(){ + + delete _fastfitter ; _fastfitter = 0; + delete _encoder ; _encoder = 0; + //delete _trksystem ; _trksystem = 0; + //delete _histos ; _histos = 0; + info() << "Processed " << _nEvt << " events " << endmsg; + return GaudiAlgorithm::finalize(); +} + + +void SiliconTrackingAlg::ProcessOneSector(int iPhi, int iTheta) { + + int counter = 0 ; + + int iPhi_Up = iPhi + 1; + int iPhi_Low = iPhi - 1; + int iTheta_Up = iTheta + 1; + int iTheta_Low = iTheta - 1; + if (iTheta_Low < 0) iTheta_Low = 0; + if (iTheta_Up >= _nDivisionsInTheta) iTheta_Up = _nDivisionsInTheta-1; + + int nComb = int( _Combinations.size() / 3 ); // number of triplet combinations + // std::cout << iPhi << " " << iTheta << " " << _nEvt << endmsg; + int iNC = 0; + + for (int iComb=0; iComb < nComb; ++iComb) { // loop over triplets + + int nLR[3]; + + for (int iS=0; iS<3; ++iS) { + nLR[iS] = _Combinations[iNC]; + iNC++; + } + + //std::cout << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " " << std::endl; + + // index of theta-phi bin of outer most layer + int iCode = nLR[0] + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + + //std::cout << "size of vector = " << _sectors.size() << " iCode = " << iCode << std::endl; + + // get the all the hits in the outer most theta-phi bin + + TrackerHitExtendedVec& hitVecOuter = _sectors[iCode]; + + int nHitsOuter = int(hitVecOuter.size()); + if (nHitsOuter > 0) { + + //std::cout << " " << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " size of vector = " << hitVecOuter.size() << std::endl; + + for (int ipMiddle=iPhi_Low; ipMiddle<iPhi_Up+1;ipMiddle++) { // loop over phi in the Middle + + for (int itMiddle=iTheta_Low; itMiddle<iTheta_Up+1;itMiddle++) { // loop over theta in the Middle + + int iPhiMiddle = ipMiddle; + + // catch wrap-around + if (ipMiddle < 0) iPhiMiddle = _nDivisionsInPhi-1; + if (ipMiddle >= _nDivisionsInPhi) iPhiMiddle = ipMiddle - _nDivisionsInPhi; + + // index of current theta-phi bin of middle layer + iCode = nLR[1] + _nLayers*iPhiMiddle + _nLayers*_nDivisionsInPhi*itMiddle; + + // get the all the hits in the current middle theta-phi bin + TrackerHitExtendedVec& hitVecMiddle = _sectors[iCode]; + + int nHitsMiddle = int(hitVecMiddle.size()); + + // determine which inner theta-phi bins to look in + + int iPhiLowInner = iPhi_Low; + int iPhiUpInner = iPhi_Up; + int iThetaLowInner = iTheta_Low; + int iThetaUpInner = iTheta_Up; + + // test to see if this is the core bin of the current search + // if so, look into the neigboring bins in the inner layer + if (ipMiddle == iPhi && itMiddle==iTheta) { + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + else { + int difP = abs(ipMiddle-iPhi); // number of phi bins from core: can only be 1 or 0 due to hard coded 1 above + int difT = abs(itMiddle-iTheta);// number of theta bins from core: can only be 1 or 0 due to hard coded 1 above + int minP = min(ipMiddle,iPhi); // min phi: core bin or current phi bin middle + int minT = min(itMiddle,iTheta); // min theta: core bin or current theta bin middle + int maxP = max(ipMiddle,iPhi); // max phi: core bin or current phi bin middle + int maxT = max(itMiddle,iTheta); // max theta: core bin or current theta bin middle + + if (difP==1 && difT==1) { // if the diffence is a single bin in both phi and theta : only look in the bin adjacent to the core bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difP==0) { // must be +/-1 theta : only look in bins adjacent to the middle bin + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difT==0) { // must be +/-1 phi : only look in bins adjacent to the middle bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + } + if (nHitsMiddle > 0) { // look into inner bins + + for (int ipInner=iPhiLowInner; ipInner<iPhiUpInner+1;ipInner++) { // loop over phi in the Inner + + for (int itInner=iThetaLowInner; itInner<iThetaUpInner+1;itInner++) { // loop over theta in the Inner + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + iCode = nLR[2] + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get hit for inner bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + if (nHitsInner > 0) { + + debug() << " " + << std::setw(3) << iPhi << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iTheta << " " << std::setw(3) << itMiddle << " " << std::setw(3) << itInner << " " + << std::setw(3) << nLR[0] << " " << std::setw(3) << nLR[1] << " " << std::setw(3) << nLR[2] << " " + << std::setw(3) << nHitsOuter << " : " << std::setw(3) << nHitsMiddle << " : " << std::setw(3) << nHitsInner << " :: " + << std::setw(3) << nHitsOuter*nHitsMiddle* nHitsInner << endmsg; + + // test all triplets + + for (int iOuter=0; iOuter<nHitsOuter; ++iOuter) { // loop over hits in the outer sector + TrackerHitExtended * outerHit = hitVecOuter[iOuter]; + for (int iMiddle=0;iMiddle<nHitsMiddle;iMiddle++) { // loop over hits in the middle sector + TrackerHitExtended * middleHit = hitVecMiddle[iMiddle]; + for (int iInner=0;iInner<nHitsInner;iInner++) { // loop over hits in the inner sector + TrackerHitExtended * innerHit = hitVecInner[iInner]; + HelixClass helix; + //std::cout <<"fucd++++++++++++++++++++++1" << std::endl; + // test fit to triplet + TrackExtended * trackAR = TestTriplet(outerHit,middleHit,innerHit,helix); + //std::cout <<"fucd++++++++++++++++++++++2" << std::endl; + if ( trackAR != NULL ) { + int nHits = BuildTrack(outerHit,middleHit,innerHit,helix,nLR[2], + iPhiLowInner,iPhiUpInner, + iThetaLowInner,iThetaUpInner,trackAR); + + _tracksWithNHitsContainer.getTracksWithNHitsVec(nHits).push_back(trackAR); + + counter ++ ; + } + //std::cout <<"fucd++++++++++++++++++++++3" << std::endl; + } // endloop over hits in the inner sector + } // endloop over hits in the middle sector + } // endloop over hits in the outer sector + } // endif nHitsInner > 0 + } // endloop over theta in the Inner + } // endloop over phi in the Inner + } // endif nHitsMiddle > 0 + } // endloop over theta in the Middle + } // endloop over phi in the Middle + } // endif nHitsOuter > 0 + } // endloop over triplets + + //debug() << " process one sectector theta,phi " << iTheta << ", " << iPhi << " number of loops : " << counter << endmsg ; +} + +TrackExtended * SiliconTrackingAlg::TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix) { + /* + Methods checks if the triplet of hits satisfies helix hypothesis + */ + //std::cout << "fucd================1" << std::endl; + // get the tracks already associated with the triplet + TrackExtendedVec& trackOuterVec = outerHit->getTrackExtendedVec(); + TrackExtendedVec& trackMiddleVec = middleHit->getTrackExtendedVec(); + TrackExtendedVec& trackInnerVec = innerHit->getTrackExtendedVec(); + + //std::cout << "fucd================2" << std::endl; + // check if all the hits are already assigned to a track + if ( (!trackOuterVec.empty()) && (!trackMiddleVec.empty()) && (!trackInnerVec.empty())) { + + TrackExtendedVec::const_iterator middleEndIter = trackMiddleVec.end(); + TrackExtendedVec::const_iterator outerEndIter = trackOuterVec.end(); + TrackExtendedVec::const_iterator innerEndIter = trackInnerVec.end(); + TrackExtendedVec::const_iterator outerBeginIter = trackOuterVec.begin(); + TrackExtendedVec::const_iterator innerBeginIter = trackInnerVec.begin(); + + // loop over the tracks from the middle hit + for (TrackExtendedVec::const_iterator middleIter = trackMiddleVec.begin(); + middleIter < middleEndIter; + ++middleIter) { + + // loop over the track from the outer hit + for (TrackExtendedVec::const_iterator outerIter = outerBeginIter; + outerIter < outerEndIter; + ++outerIter) { + + // if track from the outer and middle are not the same progress + if ( *outerIter != *middleIter ) continue; + + // loop over the tracks from the inner hit + for (TrackExtendedVec::const_iterator innerIter = innerBeginIter; + innerIter < innerEndIter; + ++innerIter) { + + // no need to check against middle, it is idendical to outer here + if ( *outerIter == *innerIter ) { + // an existing track already contains all three hits + // return a null pointer + debug() << " TestTriplet: track " << *outerIter << " already contains all three hits: Do not create new track from these hits " << endmsg ; + return 0; + } + + }// for inner + }// for outer + }// for middle + }// if all vectors are not empty + //std::cout << "fucd================3" << std::endl; + + // float dZ = FastTripletCheck(innerHit, middleHit, outerHit); + + // if (fabs(dZ) > _minDistCutAttach) + // return trackAR; + + + // increase triplet count + ++_ntriplets; + + // get the hit coordinates and errors + double xh[3]; + double yh[3]; + float zh[3]; + double wrh[3]; + float wzh[3]; + float rh[3]; + float ph[3]; + + float par[5]; + float epar[15]; + /*fucd + for(int i=0;i<_allHits.size();i++){ + std::cout << &_allHits.at(i) << std::endl; + } + */ + // first hit + xh[0] = outerHit->getTrackerHit()->getPosition()[0]; + yh[0] = outerHit->getTrackerHit()->getPosition()[1]; + zh[0] = float(outerHit->getTrackerHit()->getPosition()[2]); + wrh[0] = double(1.0/(outerHit->getResolutionRPhi()*outerHit->getResolutionRPhi())); + wzh[0] = 1.0/(outerHit->getResolutionZ()*outerHit->getResolutionZ()); + // second hit + xh[1] = middleHit->getTrackerHit()->getPosition()[0]; + yh[1] = middleHit->getTrackerHit()->getPosition()[1]; + zh[1] = float(middleHit->getTrackerHit()->getPosition()[2]); + wrh[1] = double(1.0/(middleHit->getResolutionRPhi()*middleHit->getResolutionRPhi())); + wzh[1] = 1.0/(middleHit->getResolutionZ()*middleHit->getResolutionZ()); + // third hit + xh[2] = innerHit->getTrackerHit()->getPosition()[0]; + yh[2] = innerHit->getTrackerHit()->getPosition()[1]; + zh[2] = float(innerHit->getTrackerHit()->getPosition()[2]); + wrh[2] = double(1.0/(innerHit->getResolutionRPhi()*innerHit->getResolutionRPhi())); + wzh[2] = 1.0/(innerHit->getResolutionZ()*innerHit->getResolutionZ()); + // calculate r and phi for all hits + for (int ih=0; ih<3; ih++) { + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = atan2(yh[ih],xh[ih]); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + + int NPT = 3; + int iopt = 2; + float chi2RPhi; + float chi2Z; + + debug() << " TestTriplet: Use fastHelixFit " << endmsg ; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + // get helix parameters + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + // chi2 is weighted here by a factor for both rphi and z + float Chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + int ndf = 2*NPT-5; + + + // check the truth information for the triplet + + // define these outside of the ifdef so that we don't need to keep repeating it. + //std::vector<TrackerHit*> hit_list; + //std::vector<MCParticle*> mcps_imo; + //std::vector<MCParticle*> mcp_s; + int triplet_code = 0; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + + int nmcps = 0; + int nbadHits = 0; + + int layer = 9 ; + int size = 3 ; + int marker = 1 ; + int ml = 0 ; + // float helix_max_r = 0; + float helix_max_z = 0; + int color = 0; + + // use the MCTruth4HitExt to get the MCPs + + hit_list.push_back(innerHit->getTrackerHit()); + hit_list.push_back(middleHit->getTrackerHit()); + hit_list.push_back(outerHit->getTrackerHit()); + + EVENT::MCParticle* mcp_i = 0; + EVENT::MCParticle* mcp_m = 0; + EVENT::MCParticle* mcp_o = 0; + + for (unsigned ihit = 0; ihit < hit_list.size(); ++ihit) { + + EVENT::TrackerHit* trkhit = hit_list[ihit]; + std::vector<MCParticle*> mcps; + + MarlinTrk::getMCParticlesForTrackerHit(trkhit, mcps); + + if (mcps.size() == 1) { + mcps_imo.push_back(mcps[0]); + ++nmcps; + } else { + mcps_imo.push_back(0); + ++nbadHits; + } + + } + + mcp_i = mcps_imo[0]; + mcp_m = mcps_imo[1]; + mcp_o = mcps_imo[2]; + + debug() + << "\n mcp_i = " << mcp_i + << "\n mcp_m = " << mcp_m + << "\n mcp_o = " << mcp_o + << endmsg; + + if( mcp_i ) { + mcp_s.push_back(mcp_i) ; + } + + if( mcp_m && mcp_m != mcp_i ) { + mcp_s.push_back(mcp_m); + } + + if( mcp_o && mcp_o != mcp_m && mcp_o != mcp_i ){ + mcp_s.push_back(mcp_o); + } + + nmcps = mcp_s.size(); + + if (_UseEventDisplay) { + // display this triplet and the MCPs from which it is formed + + MarlinCED::newEvent(this , _detector_model_for_drawing ) ; + + // CEDPickingHandler &pHandler=CEDPickingHandler::getInstance(); + // + // pHandler.update(_current_event); + + for (unsigned imcp = 0; imcp < mcp_s.size(); ++imcp) { + + MCParticle* mcp = mcp_s[imcp]; + + helix_max_z = fabsf(mcp->getEndpoint()[2]); + + + info() << "Draw MCParticle : " << *mcp <<endmsg; + + MarlinCED::add_layer_description("MCParticle_For_Fit", layer); + + MarlinCED::drawHelix( _bField , mcp->getCharge(), mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2], + mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2], layer , size , 0x7af774 , + 0.0, _helix_max_r , + helix_max_z, mcp->id() ) ; + + } + + const std::string colName = "Hits_For_Fit"; + + + size = 10 ; + layer = 11 ; + // ml = marker | ( layer << CED_LAYER_SHIFT ) ; + + //ced_describe_layer( colName.c_str() ,layer); + MarlinCED::add_layer_description(colName, layer); + + + color = 0xFFFFFF; + + for( std::vector<TrackerHit* >::const_iterator it = hit_list.begin(); it != hit_list.end() ; it++ ) { + + TrackerHit* trkhit = *it; + + ced_hit_ID(trkhit->getPosition()[0], + trkhit->getPosition()[1], + trkhit->getPosition()[2], + marker, layer, size , color, trkhit->id() ) ; + + } // hits + + } + + if (_createDiagnosticsHistograms) { + + // if no bad hits are present triplet_code = nmcps; + triplet_code = nmcps + nbadHits * 3 ; + + _histos->fill1D(DiagnosticsHistograms::htriplets, triplet_code); + + double pt = (2.99792458E-4*_bField) / omega ; // for r in mm, p in GeV and Bz in Tesla + + if (triplet_code == 1) { + ++_ntriplets_good; + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_good, pt, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_good, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_good, pt ); + } else { + + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_bad, pt, Chi2); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_bad, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_bad, pt ); + + if(triplet_code == 2) { + ++_ntriplets_2MCP; + } else if (triplet_code == 3) { + ++_ntriplets_3MCP; + } else if (triplet_code == 4) { + ++_ntriplets_1MCP_Bad; + } else { + ++_ntriplets_bad; + } + } + + } + +#endif + */ + + // Check if track satisfies all conditions + + + // std::cout << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + // std::cout << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + // std::cout << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + // std::cout << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + + // if ( Chi2/float(ndf) > _chi2FitCut || fabs(d0) > _cutOnD0 || fabs(z0) > _cutOnZ0 || fabs(omega)>_cutOnOmega) + // return a null pointer + // return 0; + + bool failed = false; + + int quality_code = triplet_code * 10 ; + + if ( Chi2/float(ndf) > _chi2FitCut ) { + debug() << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + failed = true; + quality_code += 1; + } else if (fabs(d0) > _cutOnD0 ) { + debug() << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + failed = true; + quality_code += 2; + } else if (fabs(z0) > _cutOnZ0 ) { + debug() << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + failed = true; + quality_code += 3; + } else if ( fabs(omega)>_cutOnOmega) { + debug() << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + failed = true; + quality_code += 4; + } else { + debug() << "Success !!!!!!!" << endmsg; + } + /* + if (_createDiagnosticsHistograms) _histos->fill1D(DiagnosticsHistograms::htriplets, quality_code); + + if (_UseEventDisplay) { + drawEvent(); + } + */ + + if( failed ) { + // return a null pointer + return 0; + } + + + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + + TrackExtended * trackAR = new TrackExtended(); + trackAR->addTrackerHitExtended(outerHit); + trackAR->addTrackerHitExtended(middleHit); + trackAR->addTrackerHitExtended(innerHit); + outerHit->addTrackExtended(trackAR); + middleHit->addTrackExtended(trackAR); + innerHit->addTrackExtended(trackAR); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix(epar); + + + return trackAR; + +} + +int SiliconTrackingAlg::BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerLayer, + int iPhiLow, int iPhiUp, + int iThetaLow, int iThetaUp, + TrackExtended * trackAR) { + /** + Method for building up track in the VXD. Method starts from the found triplet and performs + sequential attachment of hits in other layers, which have hits within the search window. + Only searches inwards. + Given that we know we are now jumping over layers due to the doublet nature of the VXD, we + could optimise this to look for the hits in interleaving layers as well. + Currently a fast fit is being done for each additional hit, it could be more efficient to try and use kaltest? + + */ + + debug() << " BuildTrack starting " << endmsg; + + for (int layer = innerLayer-1; layer>=0; layer--) { // loop over remaining layers + float distMin = 1.0e+20; + TrackerHitExtended * assignedhit = NULL; + //std::cout << "fucd---------------------1" << std::endl; + // loop over phi in the Inner region + for (int ipInner=iPhiLow; ipInner<iPhiUp+1;ipInner++) { + + // loop over theta in the Inner region + for (int itInner=iThetaLow; itInner<iThetaUp+1;itInner++) { + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + // get the index of the theta-phi bin to search + int iCode = layer + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get the hits from this bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + // loop over hits in the Inner sector + for (int iInner=0;iInner<nHitsInner;iInner++) { + + TrackerHitExtended * currentHit = hitVecInner[iInner]; + + // get the position of the hit to test + float pos[3]; + float distance[3]; + + for (int i=0; i<3; ++i) { + pos[i] = float(currentHit->getTrackerHit()->getPosition()[i]); + } + + // get the distance of closest approach and distance s traversed to the POCA + float time = helix.getDistanceToPoint(pos,distance); + + // sanity check on s + if (time < 1.0e+10) { + + // check if this is the closest hit yet + if (distance[2] < distMin) { // distance[2] = sqrt( d0*d0 + z0*z0 ) + + // if yes store hit and distance + distMin = distance[2]; + assignedhit = currentHit; + } + } + } // endloop over hits in the Inner sector + } // endloop over theta in the Inner region + } // endloop over phi in the Inner region + //std::cout << "fucd---------------------2" << std::endl; + // check if closest hit fulfills the min distance cut + if (distMin < _minDistCutAttach) { + + // if yes try to include it in the fit + + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hvec.size()); + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hvec[ih]->getTrackerHit(); + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(hvec[ih]->getResolutionRPhi()*hvec[ih]->getResolutionRPhi())); + wzh[ih] = 1.0/(hvec[ih]->getResolutionZ()*hvec[ih]->getResolutionZ()); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + edm4hep::TrackerHit * assignedTrkHit = assignedhit->getTrackerHit(); + xh[nHits] = assignedTrkHit->getPosition()[0]; + yh[nHits] = assignedTrkHit->getPosition()[1]; + zh[nHits] = float(assignedTrkHit->getPosition()[2]); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + if (ph[nHits] < 0.) + ph[nHits] = TWOPI + ph[nHits]; + wrh[nHits] = double(1.0/(assignedhit->getResolutionRPhi()*assignedhit->getResolutionRPhi())); + wzh[nHits] = 1.0/(assignedhit->getResolutionZ()*assignedhit->getResolutionZ()); + + int NPT = nHits + 1; + int iopt = 2; + float chi2RPhi; + float chi2Z; + +// std::cout << "######## number of hits to fit with _fastfitter = " << NPT << endmsg; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + bool validCombination = 0; + float Chi2 = FLT_MAX; + + if ((nHits+1) == 4) { + Chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if ((nHits+1) >= 5) { + Chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + int ndf = 2*NPT-5; + + // check if this is valid combination based on the chi2/ndf + validCombination = Chi2/float(ndf) < _chi2FitCut; + + if ( validCombination ) { + // assign hit to track and track to hit, update the track parameters + trackAR->addTrackerHitExtended(assignedhit); + assignedhit->addTrackExtended(trackAR); + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setCovMatrix(epar); + trackAR->setNDF( ndf ); + } + + } + } // endloop over remaining layers + //std::cout << "fucd---------------------3" << std::endl; + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nTotalHits = int(hvec.size()); + +// std::cout << "######## number of hits to return = " << nTotalHits << endmsg; + + return nTotalHits; + +} + + +void SiliconTrackingAlg::Sorting(TrackExtendedVec & trackVec) { + /** + Sorting of Track Vector in ascending order of chi2/ndf + */ + + std::sort(trackVec.begin(), trackVec.end(), compare_TrackExtended() ); + + // also clean up? what does this do here? + for (size_t i=0, sizeOfVector=trackVec.size(); i<sizeOfVector; ++i) { + + TrackerHitExtendedVec& hitVec = trackVec[i]->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int ih=0;ih<nHits;ih++) { + hitVec[ih]->clearTrackVec(); + } + } + +} + +void SiliconTrackingAlg::CreateTrack(TrackExtended * trackAR ) { + + /** + Method which creates Track out of TrackExtended objects. Checks for possible + track splitting (separate track segments in VXD and FTD). + */ + + + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int i=0; i<nHits; ++i) { + TrackExtendedVec& trackVec = hitVec[i]->getTrackExtendedVec(); + if (trackVec.size() != 0) + return ; + } + + // First check if the current track is piece of the split one + // look for matching track segment + + int found = 0; + + int nTrk = int(_trackImplVec.size()); + + for (int itrk=0; itrk<nTrk; ++itrk) { + TrackExtended * trackOld = _trackImplVec[itrk]; + TrackerHitExtendedVec& hitVecOld = trackOld->getTrackerHitExtendedVec(); + + float phiNew = trackAR->getPhi(); + float phiOld = trackOld->getPhi(); + float thetaNew = M_PI_2 - atan(trackAR->getTanLambda()); + float thetaOld = M_PI_2 - atan(trackOld->getTanLambda()); + + float angle = (cos(phiNew)*cos(phiOld)+sin(phiNew)*sin(phiOld))*sin(thetaNew)*sin(thetaOld)+cos(thetaNew)*cos(thetaOld); + angle = acos(angle); + + if (angle < _angleCutForMerging) { + int nHitsOld = int(hitVecOld.size()); + int nTotHits = nHits + nHitsOld; + double * xh = new double[nTotHits]; + double * yh = new double[nTotHits]; + float * zh = new float[nTotHits]; + double * wrh = new double[nTotHits]; + float * wzh = new float[nTotHits]; + float * rh = new float[nTotHits]; + float * ph = new float[nTotHits]; + float par[5]; + float epar[15]; + float refPoint[3] = {0.,0.,0.}; + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hitVec[ih]->getTrackerHit(); + float rR = hitVec[ih]->getResolutionRPhi(); + float rZ = hitVec[ih]->getResolutionZ(); + if (int(hitVec[ih]->getTrackExtendedVec().size()) != 0) + debug() << "WARNING : HIT POINTS TO TRACK " << endmsg; + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(rR*rR)); + wzh[ih] = 1.0/(rZ*rZ); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + } + for (int ih=0;ih<nHitsOld;++ih) { + edm4hep::TrackerHit * trkHit = hitVecOld[ih]->getTrackerHit(); + xh[ih+nHits] = trkHit->getPosition()[0]; + yh[ih+nHits] = trkHit->getPosition()[1]; + zh[ih+nHits] = float(trkHit->getPosition()[2]); + float rR = hitVecOld[ih]->getResolutionRPhi(); + float rZ = hitVecOld[ih]->getResolutionZ(); + wrh[ih+nHits] = double(1.0/(rR*rR)); + wzh[ih+nHits] = 1.0/(rZ*rZ); + rh[ih+nHits] = float(sqrt(xh[ih+nHits]*xh[ih+nHits]+yh[ih+nHits]*yh[ih+nHits])); + ph[ih+nHits] = float(atan2(yh[ih+nHits],xh[ih+nHits])); + + } + int NPT = nTotHits; + int iopt = 2; + float chi2RPhi; + float chi2Z; + int ndf = 2*NPT - 5; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + float eparmin[15]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + + float refPointMin[3]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + + float chi2Min = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Min = chi2Min/float(ndf); + + float chi2MinRPhi = chi2RPhi; + float chi2MinZ = chi2Z; + + int iBad = -1; + if (chi2Min < _chi2FitCut) { + found = 1; + } + else { // SJA:FIXME: UH What is going on here? setting weights to 0 and refitting? + float * wzhOld = new float[nTotHits]; + double * wrhOld = new double[nTotHits]; + for (int i=0;i<nTotHits;++i) { + wzhOld[i] = wzh[i]; + wrhOld[i] = wrh[i]; + } + for (int i=0; i<nTotHits; ++i) { + for (int j=0;j<nTotHits;++j) { + if (i == j) { + wrh[j] = 0.0; + wzh[j] = 0.0; + } + else { + wrh[j] = wrhOld[j]; + wzh[j] = wzhOld[j]; + } + } + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float chi2Cur = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Cur = chi2Cur/float(ndf); + + if (chi2Cur < chi2Min) { + chi2Min = chi2Cur; + chi2MinRPhi = chi2RPhi; + chi2MinZ = chi2Z; + omega = par[0]; + tanlambda = par[1]; + phi0 = par[2]; + d0 = par[3]; + z0 = par[4]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + iBad = i; + } + } + if (chi2Min < _chi2FitCut) { + found = 1; + } + delete[] wzhOld; + delete[] wrhOld; + } + + // Split track is found. + // Attach hits belonging to the current track segment to + // the track already created + if (found == 1) { + trackOld->ClearTrackerHitExtendedVec(); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * trkHit = hitVec[i]; + trkHit->clearTrackVec(); + if (i == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + for (int i=0;i<nHitsOld;++i) { + int icur = i+nHits; + TrackerHitExtended * trkHit = hitVecOld[i]; + trkHit->clearTrackVec(); + if (icur == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + trackOld->setOmega(omega); + trackOld->setTanLambda(tanlambda); + trackOld->setPhi(phi0); + trackOld->setD0(d0); + trackOld->setZ0(z0); + + // std::cout << "Split track found " << d0 << " " << z0 << endmsg; + + // killeb: In the original SiliconTrackingAlg this was in the NOT simple helix branch. + // The rest of the code uses the simple helix branch, where ndf_D is never set. + // In fact it has never been initialised or used anywhere. I think this line should not be executed. + // ndf = ndf_D; + + trackOld->setChi2(chi2Min*float(ndf)); + trackOld->setNDF(ndf); + trackOld->setCovMatrix(eparmin); + // trackOld->setReferencePoint(refPointMin); + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + } + if (found == 1) + break; + } + + // Candidate is a unique track + // No other segments are found + if (found == 0 ) { + _trackImplVec.push_back(trackAR); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * hit = hitVec[i]; + hit->addTrackExtended( trackAR ); + } + } + + +} + +void SiliconTrackingAlg::AttachRemainingVTXHitsFast() { + + std::vector<TrackerHitExtendedVec> nonAttachedHits; + nonAttachedHits.resize(_nDivisionsInPhi*_nDivisionsInTheta); + std::vector<TrackExtendedVec> trackVector; + trackVector.resize(_nDivisionsInPhi*_nDivisionsInTheta); + int nTracks = int(_trackImplVec.size()); + + for (int iTrk=0;iTrk<nTracks;++iTrk) { + TrackExtended * track = _trackImplVec[iTrk]; + double Phi = double(track->getPhi()); + if (Phi < 0) + Phi = Phi + TWOPI; + float tanlambda = track->getTanLambda(); + double cosTheta = double(tanlambda/sqrt(1+tanlambda*tanlambda)); + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = iPhi + _nDivisionsInPhi*iTheta; + trackVector[iCode].push_back( track ); + } + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hitExt = hitVec[iH]; + TrackExtendedVec& trackVec = hitExt->getTrackExtendedVec(); + if (trackVec.size()==0) { + edm4hep::TrackerHit * hit = hitExt->getTrackerHit(); + double pos[3]; + double radius = 0; + for (int i=0; i<3; ++i) { + pos[i] = hit->getPosition()[i]; + radius += pos[i]*pos[i]; + } + radius = sqrt(radius); + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + iCode = iPhi + _nDivisionsInPhi*iTheta; + nonAttachedHits[iCode].push_back( hitExt ); + } + } + } + } + } + + for (int iT=0; iT<_nDivisionsInTheta; ++iT) { + for (int iP=0; iP<_nDivisionsInPhi; ++iP) { + int iCode = iP + _nDivisionsInPhi*iT; + int nHits = int(nonAttachedHits[iCode].size()); + int iT1 = iT - 1; + int iT2 = iT + 1; + if (iT == 0) { + iT1 = iT; + iT2 = iT1 + 1; + } + if (iT == _nDivisionsInTheta - 1) { + iT2 = iT; + iT1 = iT2 - 1; + } + int iPHI[3]; + iPHI[0] = iP - 1; + iPHI[1] = iP; + iPHI[2] = iP + 1; + if (iP == 0) + iPHI[0] = _nDivisionsInPhi - 1; + if (iP == _nDivisionsInPhi - 1 ) + iPHI[2] = 0; + + for (int ihit = 0; ihit<nHits; ++ihit) { + + TrackerHitExtended * hit = nonAttachedHits[iCode][ihit]; + TrackExtended * trackToAttach = NULL; + float minDist = 1.0e+6; + + for (int iTheta = iT1; iTheta <iT2+1; ++iTheta) { + for (int indexP=0;indexP<3;++indexP) { + int iPhi = iPHI[indexP]; + int iCodeForTrack = iPhi + _nDivisionsInPhi*iTheta; + int nTrk = int(trackVector[iCodeForTrack].size()); + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = trackVector[iCodeForTrack][iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + break; + } + } + } + } + if (consider) { + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + HelixClass helix; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int layer = getLayerID(hit->getTrackerHit()); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } + } + } +} + +void SiliconTrackingAlg::AttachRemainingVTXHitsSlow() { + + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + // if (trackVec.size()==0) + // nonAttachedHits.push_back( hit ); + //-- allow hits that are only used in triplets to be re-attached + unsigned int maxTrackSize = 0; + for(unsigned int itrack = 0;itrack < trackVec.size();itrack++){ + TrackerHitExtendedVec hitVec_tmp= trackVec[itrack]->getTrackerHitExtendedVec(); + unsigned int isize = hitVec_tmp.size(); + if(isize>maxTrackSize)maxTrackSize = isize; + } + if (maxTrackSize<=3) { + debug() << " Add non attached hit to list: id = " << hit->getTrackerHit()->id() << endmsg; + nonAttachedHits.push_back( hit ); + } + + + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + debug() << " Try hit: id = " << hit->getTrackerHit()->id() << endmsg; + int layer = getLayerID( hit->getTrackerHit() ); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + debug() << " hit: id = " << hit->getTrackerHit()->id() << " condsidered delta together with hit " << trkhit2->id() << endmsg; + break; + } + } + } + } + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " : try attachement"<< endmsg; + AttachHitToTrack(trackToAttach,hit,iopt); + } else { + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " rejected due to distance cut of " <<_minDistCutAttach<< " min distance = " << minDist << endmsg; + } + } + } +} + +void SiliconTrackingAlg::AttachRemainingFTDHitsSlow() { + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + if (trackVec.size()==0) + nonAttachedHits.push_back( hit ); + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + + consider = false; + break; + } + } + + + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + if (tanlambda*float(getSideID(hit->getTrackerHit())) > 0) { + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } +} + + +void SiliconTrackingAlg::AttachRemainingFTDHitsFast() { + int nTrk = _trackImplVec.size(); + + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int iSemiSphere = 0; + if (tanlambda > 0) + iSemiSphere = 1; + float ref[3]; + for (int i=0;i<3;++i) + ref[i] = helix.getReferencePoint()[i]; + // Start loop over FTD layers + for (unsigned int layer=0;layer<_nlayersFTD;layer++) { + float ZL = _zLayerFTD[layer]; + if (iSemiSphere == 0) + ZL = - ZL; + float point[3]; + helix.getPointInZ(ZL,ref,point); + float Phi = atan2(point[1],point[0]); + if (Phi < 0) + Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+10; + TrackerHitExtended * attachedHit = NULL; + for (int iP=iPhi-1;iP<=iPhi+1;++iP) { + int iPP = iP; + if (iP < 0) + iPP = iP + _nPhiFTD; + if (iP >= _nPhiFTD) + iPP = iP - _nPhiFTD; + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPP; + int nHits = int(_sectorsFTD[iCode].size()); + for (int iHit=0;iHit<nHits;++iHit) { + TrackerHitExtended * hit = _sectorsFTD[iCode][iHit]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + for (int IHIT=0;IHIT<NHITS;++IHIT) { + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + consider = false; + break; + } + } + + + if (consider) { + float pos[3]; + for (int i=0;i<3;++i) { + pos[i] = hit->getTrackerHit()->getPosition()[i]; + } + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + } + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack(trackAR,attachedHit, iopt); + } + } + } +} + +void SiliconTrackingAlg::TrackingInFTD() { + + int nComb = int(_CombinationsFTD.size()) / 3; + + for (int iComb=0;iComb<nComb;++iComb) { + + int nLS[3]; + nLS[0] = _CombinationsFTD[3*iComb]; + nLS[1] = _CombinationsFTD[3*iComb+1]; + nLS[2] = _CombinationsFTD[3*iComb+2]; + + for (int iS=0;iS<2;++iS) { // loop over +z and -z + + // std::cout << "Combinations : " << iS << " " << nLS[0] << " " << nLS[1] << " " << nLS[2] << endmsg; + // int iC = iS + 2*nLS[0]; + // TrackerHitExtendedVec& hitVec = _sectorsFTD[iC]; + // int nO = int(hitVec.size()); + // iC = iS + 2*nLS[1]; + // hitVec = _sectorsFTD[iC]; + // int nM = int(hitVec.size()); + // iC = iS + 2*nLS[2]; + // hitVec = _sectorsFTD[iC]; + // int nI = int(hitVec.size()); + // std::cout << nO << " " << nM << " " << nI << endmsg; + + for (int ipOuter=0;ipOuter<_nPhiFTD;++ipOuter) { + + int ipMiddleLow = ipOuter - 1; + int ipMiddleUp = ipOuter + 1; + + unsigned int iCodeOuter = iS + 2*nLS[0] + 2*_nlayersFTD*ipOuter; + + if( iCodeOuter >= _sectorsFTD.size()){ + error() << "iCodeOuter index out of range: iCodeOuter = " << iCodeOuter << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + exit(1); + } + + TrackerHitExtendedVec& hitVecOuter = _sectorsFTD[iCodeOuter]; + + int nOuter = int(hitVecOuter.size()); + + for (int iOuter=0;iOuter<nOuter;++iOuter) { + + TrackerHitExtended * hitOuter = hitVecOuter[iOuter]; + + for (int ipMiddle=ipMiddleLow;ipMiddle<=ipMiddleUp;++ipMiddle) { + //for(int ipMiddle=0;ipMiddle<_nPhiFTD;++ipMiddle) { + int ipM = ipMiddle; + if (ipM < 0) + ipM = ipMiddle + _nPhiFTD; + if (ipM >= _nPhiFTD) + ipM = ipMiddle - _nPhiFTD; + int iCodeMiddle = iS + 2*nLS[1] + 2*_nlayersFTD*ipM; + + TrackerHitExtendedVec& hitVecMiddle = _sectorsFTD[iCodeMiddle]; + int ipInnerLow,ipInnerUp; + ipInnerLow = ipMiddle - 1; + ipInnerUp = ipMiddle + 1; + + int nMiddle = int(hitVecMiddle.size()); + + for (int iMiddle=0;iMiddle<nMiddle;++iMiddle) { + TrackerHitExtended * hitMiddle = hitVecMiddle[iMiddle]; + for (int ipInner=ipInnerLow;ipInner<=ipInnerUp;++ipInner) { + //for (int ipInner=0;ipInner<_nPhiFTD;++ipInner) { + int ipI = ipInner; + if (ipI < 0) + ipI = ipInner + _nPhiFTD; + if (ipI >= _nPhiFTD) + ipI = ipInner - _nPhiFTD; + int iCodeInner = iS + 2*nLS[2] + 2*_nlayersFTD*ipI; + TrackerHitExtendedVec& hitVecInner = _sectorsFTD[iCodeInner]; + + int nInner = int(hitVecInner.size()); + + for (int iInner=0;iInner<nInner;++iInner) { + + TrackerHitExtended * hitInner = hitVecInner[iInner]; + HelixClass helix; + // std::cout << endmsg; + // std::cout << "Outer Hit Type " << hitOuter->getTrackerHit()->getType() << " z = " << hitOuter->getTrackerHit()->getPosition()[2] + // << "\nMiddle Hit Type "<< hitMiddle->getTrackerHit()->getType() << " z = " << hitMiddle->getTrackerHit()->getPosition()[2] + // << "\nInner Hit Type "<< hitInner->getTrackerHit()->getType() << " z = " << hitInner->getTrackerHit()->getPosition()[2] << endmsg; + + debug() << " " + << std::setw(3) << ipOuter << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iS << " " + << std::setw(3) << nLS[0] << " " << std::setw(3) << nLS[1] << " " << std::setw(3) << nLS[2] << " " + << std::setw(3) << nOuter << " : " << std::setw(3) << nMiddle << " : " << std::setw(3) << nInner << " :: " + << std::setw(3) << nOuter*nMiddle* nInner << endmsg; + + + TrackExtended * trackAR = TestTriplet(hitOuter,hitMiddle,hitInner,helix); + if (trackAR != NULL) { + // std::cout << "FTD triplet found" << endmsg; + int nHits = BuildTrackFTD(trackAR,nLS,iS); + + _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ).push_back( trackAR ); + } + } + } + } + } + } + } + } + } +} + + +int SiliconTrackingAlg::BuildTrackFTD(TrackExtended * trackAR, int * nLR, int iS) { + // std::cout << "BuildTrackFTD: Layers = " << nLR[0] << " " << nLR[1] << " " << nLR[2] << endmsg; + + // initialise a helix from the track + HelixClass helix; + const float d0 = trackAR->getD0(); + const float z0 = trackAR->getZ0(); + const float phi0 = trackAR->getPhi(); + const float tanlambda = trackAR->getTanLambda(); + const float omega = trackAR->getOmega(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float ref[3] = {helix.getReferencePoint()[0], + helix.getReferencePoint()[1], + helix.getReferencePoint()[2]}; + + for (int iL=0; iL < static_cast<int>(_nlayersFTD); ++iL) { + if (iL != nLR[0] && iL != nLR[1] && iL != nLR[2]) { + float point[3]; + float ZL = _zLayerFTD[iL]; + if (iS == 0) + ZL = - ZL; + helix.getPointInZ(ZL,ref,point); + // float Phi = atan2(point[1],point[0]); + // int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+6; + TrackerHitExtended * attachedHit = NULL; + for (int ip=0;ip<=_nPhiFTD;++ip) { + int iP = ip; + if (iP < 0) + iP = ip + _nPhiFTD; + if (iP >= _nPhiFTD) + iP = ip - _nPhiFTD; + int iCode = iS + 2*iL + 2*_nlayersFTD*iP; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + float pos[3]; + for (int i=0;i<3;++i) + pos[i] = float(trkHit->getPosition()[i]); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + // std::cout << "Layer = " << iL << " distMin = " << distMin << endmsg; + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack( trackAR, attachedHit, iopt); + } + } + } + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nH = int (hitVec.size()); + return nH; +} + +int SiliconTrackingAlg::AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt) { + + int attached = 0; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int i=0; i<nHits; ++i) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + xh[i] = double(trkHit->getPosition()[0]); + yh[i] = double(trkHit->getPosition()[1]); + zh[i] = float(trkHit->getPosition()[2]); + ph[i] = float(atan2(yh[i],xh[i])); + rh[i] = float(sqrt(xh[i]*xh[i]+yh[i]*yh[i])); + float rR = hitVec[i]->getResolutionRPhi(); + float rZ = hitVec[i]->getResolutionZ(); + wrh[i] = double(1.0/(rR*rR)); + wzh[i] = 1.0/(rZ*rZ); + } + + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + xh[nHits] = double(trkHit->getPosition()[0]); + yh[nHits] = double(trkHit->getPosition()[1]); + zh[nHits] = float(trkHit->getPosition()[2]); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + + float rR = hit->getResolutionRPhi(); + float rZ = hit->getResolutionZ(); + wrh[nHits] = double(1.0/(rR*rR)); + wzh[nHits] = 1.0/(rZ*rZ); + + + int NPT = nHits + 1; + + // SJA:FIXME the newtonian part is giving crazy results for FTD so just use iopt 2 for simply attaching hits + // using SIT and VXD doesn't seem to give any problems, so make it a function parameter and let the caller decide + // int iopt = 3; + + float chi2RPhi = 0 ; + float chi2Z = 0 ; + + + int error = _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + float chi2 = FLT_MAX; + int ndf = INT_MAX; + + if (NPT == 3) { + chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + } + if (NPT == 4) { + chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if (NPT > 4) { + chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + ndf = 2*NPT-5; + + + if ( error == 0 && chi2/float(ndf) < _chi2FitCut ) { + trackAR->addTrackerHitExtended(hit); + hit->addTrackExtended( trackAR ); + trackAR->setChi2( chi2 ); + trackAR->setOmega( omega ); + trackAR->setTanLambda( tanlambda ); + trackAR->setD0( d0 ); + trackAR->setZ0( z0 ); + trackAR->setPhi( phi0 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix( epar ); + attached = 1; + debug() << "Attachement succeeded chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } else { + debug() << "Attachement failed chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + return attached; + + +} + +void SiliconTrackingAlg::FinalRefit(edm4hep::TrackCollection* trk_col) { + + int nTracks = int(_trackImplVec.size()); + + int nSiSegments = 0; + float eTot = 0.; + float pxTot = 0.; + float pyTot = 0.; + float pzTot = 0.; + std::cout << "fucd============" << nTracks << std::endl; + for (int iTrk=0;iTrk<nTracks;++iTrk) { + + TrackExtended * trackAR = _trackImplVec[iTrk]; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + + int nHits = int(hitVec.size()); + std::cout << "fucd-------------" << iTrk << ": " << nHits << std::endl; + if( nHits >= _minimalHits) { + // int * lh = new int[nHits]; + std::vector<int> lh; + lh.resize(nHits); + + for (int i=0; i<nHits; ++i) { + lh[i]=0; + } + + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + float phi0 = trackAR->getPhi(); + + HelixClass * helix = new HelixClass(); + helix->Initialize_Canonical(phi0, d0, z0, omega, + tanlambda, _bField); + + + // get the point of closest approach to the reference point + // here it is implicitly assumed that the reference point is the origin + float Pos[3]; + Pos[0] = -d0*sin(phi0); + Pos[1] = d0*cos(phi0); + Pos[2] = z0; + + std::cout << "fucd------------------1" << std::endl; + // at this point is is possible to have hits from the same layer ... + // so a check is made to ensure that the hit with the smallest distance to the + // current helix hypothosis is used, the other hit has lh set to 0 + + // start loop over the hits to + for (int ihit=0;ihit<nHits;++ihit) { + + lh[ihit] = 1; // only hits which have lh=1 will be used for the fit + + // get the pointer to the lcio trackerhit for this hit + edm4hep::TrackerHit * trkHit = hitVec[ihit]->getTrackerHit(); + + int det = getDetectorID(trkHit); + + if (det == lcio::ILDDetID::VXD || det == lcio::ILDDetID::FTD || det == lcio::ILDDetID::SIT) { // only accept VXD, FTD or SIT + + + // int layer = getLayerID(trkHit); + // int moduleIndex = getModuleID(trkHit); + + // start a double loop over the hits which have already been checked + for (int lhit=0;lhit<ihit;++lhit) { + + // get the pointer to the lcio trackerhit for the previously checked hit + edm4hep::TrackerHit * trkHitS = hitVec[lhit]->getTrackerHit(); + + + // int layerS = getLayerID(trkHitS); + // int moduleIndexS = getModuleID(trkHitS); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if they are on the same layer and the previously checked hits has been declared good for fitting + // if ((trkHitS->getType() == trkHit->getType()) && (lh[lhit] == 1)) { + // check if the hits have the same layer and petal number + // hitVec[ihit]-> + // if ((layer == layerS) && (moduleIndex==moduleIndexS) && (lh[lhit] == 1)) { + if ( (trkHit->getCellID() == trkHitS->getCellID()) && (lh[lhit] == 1)) { + + // get the position of the hits + float xP[3]; + float xPS[3]; + for (int iC=0;iC<3;++iC) { + xP[iC] = float(trkHit->getPosition()[iC]); + xPS[iC] = float(trkHitS->getPosition()[iC]); + } + + // get the intersection of the helix with the either the cylinder or plane containing the hit + float Point[6]; + float PointS[6]; + + if (det == lcio::ILDDetID::FTD) { + + float time = helix->getPointInZ(xP[2],Pos,Point); + time = helix->getPointInZ(xPS[2],Pos,PointS); + + } else { + + float RAD = sqrt(xP[0]*xP[0]+xP[1]*xP[1]); + float RADS = sqrt(xPS[0]*xPS[0]+xPS[1]*xPS[1]); + float time = helix->getPointOnCircle(RAD,Pos,Point); + time = helix->getPointOnCircle(RADS,Pos,PointS); + + } + + float DIST = 0; + float DISTS = 0; + + // get the euclidean distance between the hit and the point of intersection + for (int iC=0;iC<3;++iC) { + DIST += (Point[iC]-xP[iC])*(Point[iC]-xP[iC]); + DISTS += (PointS[iC]-xPS[iC])*(PointS[iC]-xPS[iC]); + } + if (DIST < DISTS) { + lh[lhit] = 0; + } + else { + lh[ihit] = 0; + } + break; + } + } + } + } + + delete helix; + + std::vector<TrackerHit*> trkHits; + std::vector<TrackerHit*> trkHits_used_inFit; + + int nFit = 0; + for (int i=0; i<nHits; ++i) { + // check if the hit has been rejected as being on the same layer and further from the helix lh==0 + if (lh[i] == 1) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + nFit++; + if(trkHit) { + trkHits.push_back(trkHit); + } + else{ + throw EVENT::Exception( std::string("SiliconTrackingAlg::FinalRefit: TrackerHit pointer == NULL ") ) ; + } + } + else { // reject hit + // SJA:FIXME missuse of type find a better way to signal rejected hits + hitVec[i]->setType(int(0)); + } + } + + if( trkHits.size() < 3 ) { + debug() << "SiliconTrackingAlg::FinalRefit: Cannot fit less than 3 hits. Number of hits = " << trkHits.size() << endmsg; + continue ; + } + std::cout << "fucd------------------2" << std::endl; + //TrackImpl* Track = new TrackImpl ; + auto track = trk_col->create(); + //fucd + //edm4hep::Track track;// = new edm4hep::Track; + std::cout << "fucd------------------3" << std::endl; + // setup initial dummy covariance matrix + //std::vector<float> covMatrix; + //covMatrix.resize(15); + std::array<float,15> covMatrix; + + for (unsigned icov = 0; icov<covMatrix.size(); ++icov) { + covMatrix[icov] = 0; + } + + covMatrix[0] = ( _initialTrackError_d0 ); //sigma_d0^2 + covMatrix[2] = ( _initialTrackError_phi0 ); //sigma_phi0^2 + covMatrix[5] = ( _initialTrackError_omega ); //sigma_omega^2 + covMatrix[9] = ( _initialTrackError_z0 ); //sigma_z0^2 + covMatrix[14] = ( _initialTrackError_tanL ); //sigma_tanl^2 + + + std::vector< std::pair<float, edm4hep::TrackerHit*> > r2_values; + r2_values.reserve(trkHits.size()); + + for (std::vector<edm4hep::TrackerHit*>::iterator it=trkHits.begin(); it!=trkHits.end(); ++it) { + edm4hep::TrackerHit* h = *it; + float r2 = h->getPosition()[0]*h->getPosition()[0]+h->getPosition()[1]*h->getPosition()[1]; + r2_values.push_back(std::make_pair(r2, *it)); + } + + sort(r2_values.begin(),r2_values.end()); + //std::cout << "fucd------------------3" << std::endl; + trkHits.clear(); + trkHits.reserve(r2_values.size()); + + for (std::vector< std::pair<float, edm4hep::TrackerHit*> >::iterator it=r2_values.begin(); it!=r2_values.end(); ++it) { + trkHits.push_back(it->second); + } + //std::cout << "fucd------------------3 " << _trksystem << std::endl; + //for (unsigned ihit_indx=0 ; ihit_indx < trkHits.size(); ++ihit_indx) { + // std::cout << "fucd trk hit " << *trkHits[ihit_indx] << " " << trkHits[ihit_indx]->getCovMatrix()[0] + // << " " << BitSet32(trkHits[ihit_indx]->getType())[ ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] << endmsg; + //} + /* + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return; + } + debug() << "_trksystem pointer " << _trksystem << endmsg; + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + */ + bool fit_backwards = IMarlinTrack::backward; + + MarlinTrk::IMarlinTrack* marlinTrk = nullptr; + try{ + marlinTrk = _trksystem->createTrack(); + } + catch(...){ + error() << "Cannot create MarlinTrack ! " << endmsg; + return; + } + + int status = 0; + std::cout << "fucd------------------3" << std::endl; + try { + status = MarlinTrk::createFinalisedLCIOTrack(marlinTrk, trkHits, &track, fit_backwards, covMatrix, _bField, _maxChi2PerHit); + } catch (...) { + + // delete Track; + // delete marlinTrk; + error() << "MarlinTrk::createFinalisedLCIOTrack " << endmsg; + throw ; + + } + std::cout << "fucd------------------4" << std::endl; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + if ( status != IMarlinTrack::success && _runMarlinTrkDiagnostics ) { + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->skip_current_track(); + } +#endif + */ + + std::vector<std::pair<edm4hep::TrackerHit* , double> > hits_in_fit ; + std::vector<std::pair<edm4hep::TrackerHit* , double> > outliers ; + std::vector<edm4hep::TrackerHit*> all_hits; + all_hits.reserve(300); + + marlinTrk->getHitsInFit(hits_in_fit); + + for ( unsigned ihit = 0; ihit < hits_in_fit.size(); ++ihit) { + all_hits.push_back(hits_in_fit[ihit].first); + } + + UTIL::BitField64 cellID_encoder( lcio::ILDCellID0::encoder_string ) ; + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, true, cellID_encoder); + + marlinTrk->getOutliers(outliers); + + for ( unsigned ihit = 0; ihit < outliers.size(); ++ihit) { + all_hits.push_back(outliers[ihit].first); + } + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, false, cellID_encoder); + + delete marlinTrk; + + int nhits_in_vxd = track.getSubDetectorHitNumbers(0); + int nhits_in_ftd = track.getSubDetectorHitNumbers(1); + int nhits_in_sit = track.getSubDetectorHitNumbers(2); + + //debug() << " Hit numbers for Track "<< track->id() << ": " + debug() << " Hit numbers for Track "<< iTrk <<": " + << " vxd hits = " << nhits_in_vxd + << " ftd hits = " << nhits_in_ftd + << " sit hits = " << nhits_in_sit + << endmsg; + + //if (nhits_in_vxd > 0) Track->setTypeBit( lcio::ILDDetID::VXD ) ; + //if (nhits_in_ftd > 0) Track->setTypeBit( lcio::ILDDetID::FTD ) ; + //if (nhits_in_sit > 0) Track->setTypeBit( lcio::ILDDetID::SIT ) ; + + + + if( status != IMarlinTrack::success ) { + + //delete track; + debug() << "SiliconTrackingAlg::FinalRefit: Track fit failed with error code " << status << " track dropped. Number of hits = "<< trkHits.size() << endmsg; + continue ; + } + + if( track.getNdf() < 0) { + //delete track; + debug() << "SiliconTrackingAlg::FinalRefit: Track fit returns " << track.getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + //delete track; + continue ; + } + + //trk_col->addElement(Track); + //fucd + //trk_col->push_back(track); + for(int i=0;i<track.trackStates_size();i++){ + // 1 = lcio::EVENT::TrackState::AtIP + edm4hep::TrackState trkStateIP = track.getTrackStates(i); + if(trkStateIP.location !=1) continue; + /* + if (trkStateIP == 0) { + debug() << "SiliconTrackingAlg::FinalRefit: Track fit returns " << track->getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + throw EVENT::Exception( std::string("SiliconTrackingAlg::FinalRefit: trkStateIP pointer == NULL ") ) ; + } + */ + // note trackAR which is of type TrackExtended, only takes fits set for ref point = 0,0,0 + trackAR->setOmega(trkStateIP.omega); + trackAR->setTanLambda(trkStateIP.tanLambda); + trackAR->setPhi(trkStateIP.phi); + trackAR->setD0(trkStateIP.D0); + trackAR->setZ0(trkStateIP.Z0); + + float cov[15]; + + for (int i = 0 ; i<15 ; ++i) { + cov[i] = trkStateIP.covMatrix.operator[](i); + } + + trackAR->setCovMatrix(cov); + trackAR->setChi2(track.getChi2()); + trackAR->setNDF(track.getNdf()); + + nSiSegments++; + + HelixClass helix_final; + + helix_final.Initialize_Canonical(trkStateIP.phi,trkStateIP.D0,trkStateIP.Z0,trkStateIP.omega,trkStateIP.tanLambda,_bField); + + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkP = sqrt(trkPx*trkPx+trkPy*trkPy+trkPz*trkPz); + eTot += trkP; + pxTot += trkPx; + pyTot += trkPy; + pzTot += trkPz; + } + } + } + + debug() << "SiliconTrackingAlg -> run " << _nRun + << " event " << _nEvt << endmsg; + debug() << "Number of Si tracks = " << nSiSegments << endmsg; + debug() << "Total 4-momentum of Si Tracks : E = " << std::setprecision(7) << eTot + << " Px = " << pxTot + << " Py = " << pyTot + << " Pz = " << pzTot << endmsg; + + +} + + +StatusCode SiliconTrackingAlg::setupGearGeom(){ + auto _gear = service<IGearSvc>("GearSvc"); + if ( !_gear ) { + error() << "Failed to find GearSvc ..." << endmsg; + return StatusCode::FAILURE; + } + gear::GearMgr* gearMgr = _gear->getGearMgr(); + _bField = gearMgr->getBField().at( gear::Vector3D( 0.,0.,0.) ).z() ; + debug() << "Field " << _bField << endmsg; + //-- VXD Parameters-- + _nLayersVTX = 0 ; + const gear::VXDParameters* pVXDDetMain = 0; + const gear::VXDLayerLayout* pVXDLayerLayout = 0; + + try{ + + debug() << " filling VXD parameters from gear::SITParameters " << endmsg ; + + pVXDDetMain = &gearMgr->getVXDParameters(); + pVXDLayerLayout = &(pVXDDetMain->getVXDLayerLayout()); + _nLayersVTX = pVXDLayerLayout->getNLayers(); + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::VXDParameters Not Present in GEAR FILE" << endmsg ; + + } + + + + //-- SIT Parameters-- + _nLayersSIT = 0 ; + const gear::ZPlanarParameters* pSITDetMain = 0; + const gear::ZPlanarLayerLayout* pSITLayerLayout = 0; + + try{ + + debug() << " filling SIT parameters from gear::SITParameters " << endmsg ; + + pSITDetMain = &gearMgr->getSITParameters(); + pSITLayerLayout = &(pSITDetMain->getZPlanarLayerLayout()); + _nLayersSIT = pSITLayerLayout->getNLayers(); + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SITParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nLayersSIT == 0 ){ + // try the old LOI style key value pairs as defined in the SSit03 Mokka drive + try{ + + info() << " SiliconTrackingAlg - Simple Cylinder Based SIT using parameters defined by SSit03 Mokka driver " << endmsg ; + + // SIT + + const gear::GearParameters& pSIT = gearMgr->getGearParameters("SIT"); + + const std::vector<double>& SIT_r = pSIT.getDoubleVals("SITLayerRadius" ) ; + const std::vector<double>& SIT_hl = pSIT.getDoubleVals("SITSupportLayerHalfLength" ) ; + + _nLayersSIT = SIT_r.size() ; + + if (_nLayersSIT != SIT_r.size() || _nLayersSIT != SIT_hl.size()) { + + error() << "ILDSITCylinderKalDetector miss-match between DoubleVec and nlayers exit(1) called from file " << __FILE__ << " line " << __LINE__ << endmsg ; + exit(1); + + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SIT Parameters from as defined in SSit03 Not Present in GEAR FILE" << endmsg ; + + } + + } + + + + //-- FTD Parameters-- + _petalBasedFTDWithOverlaps = false; + _nlayersFTD = 0; + + try{ + + debug() << " filling FTD parameters from gear::FTDParameters " << endmsg ; + + const gear::FTDParameters& pFTD = gearMgr->getFTDParameters(); + const gear::FTDLayerLayout& ftdlayers = pFTD.getFTDLayerLayout() ; + + _nlayersFTD = ftdlayers.getNLayers() ; + + for (unsigned int disk=0; disk < _nlayersFTD; ++disk) { + + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 0, 1) ); // front petal even numbered + + if ( ftdlayers.getNPetals(disk) > 0) { + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 1, 1) ); // front petal odd numbered + _petalBasedFTDWithOverlaps = true; + } + + } + + // SJA: Here we increase the size of _nlayersFTD as we are treating the + _nlayersFTD =_zLayerFTD.size() ; + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTDParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nlayersFTD == 0 ){ + + // FTD + try{ + + info() << " SiliconTrackingAlg - Simple Disc Based FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + const gear::GearParameters& pFTD = gearMgr->getGearParameters("FTD"); + + const std::vector<double>* pFTD_z = NULL; + + info() << " For FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + pFTD_z = &pFTD.getDoubleVals("FTDZCoordinate" ) ; + + _nlayersFTD = pFTD_z->size(); + + for (unsigned int i = 0; i<_nlayersFTD; ++i) { + _zLayerFTD.push_back((*pFTD_z)[i]); + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTD Parameters as defined in SFtd05 Not Present in GEAR FILE" << endmsg ; + + } + } + return StatusCode::SUCCESS; +} + +void SiliconTrackingAlg::TracksWithNHitsContainer::clear() +{ + for (std::vector< TrackExtendedVec >::iterator trackVecIter = _tracksNHits.begin(); + trackVecIter < _tracksNHits.end(); trackVecIter++) + { + for (TrackExtendedVec::iterator trackIter = trackVecIter->begin(); + trackIter < trackVecIter->end(); trackIter++) + { + delete *trackIter; + } + + trackVecIter->clear(); + } +} + diff --git a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp~ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp~ new file mode 100644 index 0000000000000000000000000000000000000000..5ed4f5593ae61e3124b1869bcad980f362e0ae0b --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp~ @@ -0,0 +1,3088 @@ +#include "SiliconTrackingAlg.h" +#include "GearSvc/IGearSvc.h" +#include "EventSeeder/IEventSeeder.h" +#include "TrackSystemSvc/ITrackSystemSvc.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/TrackerHit.h" +//#include "edm4hep/TrackerHitPlane.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackState.h" + +//#include "DataHelper/ClusterExtended.h" +//#include "DataHelper/TrackExtended.h" +//#include "DataHelper/TrackerHitExtended.h" +//#include "DataHelper/HelixClass.h" + +#include <iostream> +#include <algorithm> +#include <cmath> +#include <climits> + +#include <gear/GEAR.h> +#include <gear/GearMgr.h> +#include <gear/GearParameters.h> +#include <gear/VXDLayerLayout.h> +#include <gear/VXDParameters.h> +#include "gear/FTDLayerLayout.h" +#include "gear/FTDParameters.h" + +#include <gear/BField.h> + +#include <UTIL/BitField64.h> +#include <UTIL/BitSet32.h> +#include <UTIL/ILDConf.h> + +#include "TrackSystemSvc/MarlinTrkUtils.h" +#include "TrackSystemSvc/HelixTrack.h" +#include "TrackSystemSvc/HelixFit.h" +#include "TrackSystemSvc/IMarlinTrack.h" + +//#include "TrackSystemSvc/MarlinTrkDiagnostics.h" +//#ifdef MARLINTRK_DIAGNOSTICS_ON +//#include "TrackSystemSvc/DiagnosticsController.h" +//#endif + +//#include "MarlinCED.h" + +//#include "marlin/AIDAProcessor.h" + +//---- ROOT ----- +#include "TH1F.h" +#include "TH2F.h" + +using namespace edm4hep ; +//using namespace marlin ; +using namespace MarlinTrk ; + +using std::min; +using std::max; +using std::abs; + +const int SiliconTrackingAlg::_output_track_col_quality_GOOD = 1; +const int SiliconTrackingAlg::_output_track_col_quality_FAIR = 2; +const int SiliconTrackingAlg::_output_track_col_quality_POOR = 3; + +const double SiliconTrackingAlg::TWOPI = 2*M_PI; + +DECLARE_COMPONENT( SiliconTrackingAlg ) + +SiliconTrackingAlg::SiliconTrackingAlg(const std::string& name, ISvcLocator* svcLoc) +: GaudiAlgorithm(name, svcLoc) { + + //_description = "Pattern recognition in silicon trackers"; + + _fastfitter = new MarlinTrk::HelixFit(); + + _encoder = new UTIL::BitField64(lcio::ILDCellID0::encoder_string); + + _petalBasedFTDWithOverlaps = false; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Input Collections + // ^^^^^^^^^^^^^^^^^ + declareProperty("HeaderCol", _headerColHdl); + declareProperty("MCParticleCollection", _inMCColHdl, "Handle of the Input MCParticle collection"); + declareProperty("VTXHitCollection", _inVTXColHdl, "Handle of the Input VTX TrackerHits collection"); + declareProperty("FTDPixelHitCollection", _inFTDPixelColHdl, "Handle of the Input FTD TrackerHits collection"); + declareProperty("FTDSpacePointCollection", _inFTDSpacePointColHdl, "Handle of the Input FTD SpacePoints collection"); + declareProperty("SITHitCollection", _inSITColHdl, "Handle of the Input SIT TrackerHits collection"); + + // Output Collections + // ^^^^^^^^^^^^^^^^^^ + declareProperty("SiTrackCollection", _outColHdl, "Handle of the SiTrack output collection"); + //declareProperty("TrkHitRelCollection", _outRelColHdl, "Handle of TrackerHit Track relation collection"); + // Steering parameters + // ^^^^^^^^^^^^^^^^^^^ + + _output_track_col_quality = _output_track_col_quality_GOOD; + +} + + + +StatusCode SiliconTrackingAlg::initialize() { + + _nRun = -1 ; + _nEvt = 0 ; + //printParameters() ; + + // set up the geometery needed by KalTest + //FIXME: for now do KalTest only - make this a steering parameter to use other fitters + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return StatusCode::FAILURE; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return StatusCode::FAILURE; + } + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + std::cout << "fucd ==============" << _trksystem << std::endl; +#ifdef MARLINTRK_DIAGNOSTICS_ON + + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->init(_MarlinTrkDiagnosticsName,_MarlinTrkDiagnosticsName, _runMarlinTrkDiagnostics); + +#endif + + if(setupGearGeom()==StatusCode::FAILURE) return StatusCode::FAILURE; + + if (_useSIT == 0) + _nLayers = _nLayersVTX; + else + _nLayers = _nLayersVTX + _nLayersSIT; + + // initialise the container to have separate vectors for up to _nHitsChi2 hits. + _tracksWithNHitsContainer.resize(_nHitsChi2); + + _dPhi = TWOPI/_nDivisionsInPhi; + _dTheta = 2.0/_nDivisionsInTheta; + _dPhiFTD = TWOPI/_nPhiFTD; + // I leave this for the moment, but 0.3 is c/1e9. + // For the cut it does not make too much of a difference + double cutOnR = _cutOnPt/(0.3*_bField); + cutOnR = 1000.*cutOnR; + _cutOnOmega = 1/cutOnR; + + _output_track_col_quality = 0; + + return GaudiAlgorithm::initialize(); +} + +StatusCode SiliconTrackingAlg::execute(){ + + //_current_event = evt; + //_allHits.reserve(1000); + + _output_track_col_quality = _output_track_col_quality_GOOD; + + // zero triplet counters + _ntriplets = _ntriplets_good = _ntriplets_2MCP = _ntriplets_3MCP = _ntriplets_1MCP_Bad = _ntriplets_bad = 0; + + // Clearing the working containers from the previous event + // FIXME: partly done at the end of the event, in CleanUp. Make it consistent. + //_tracksWithNHitsContainer.clear(); + //_trackImplVec.clear(); + + //_colTrackerHits.clear(); + //_colNamesTrackerHits.clear(); + //auto header = _headerColHdl.get()->at(0); + //int evtNo = header.getEventNumber(); + //int runNo = header.getRunNumber(); + //debug() << "Processing Run[" << runNo << "]::Event[" << evtNo << "]" << endmsg; + + _trackImplVec.reserve(100); + _allHits.reserve(1000); + + int successVTX = InitialiseVTX(); + int successFTD = 0; + //int successFTD = InitialiseFTD(); + if (successVTX == 1) { + + debug() << " phi theta layer nh o : m : i :: o*m*i " << endmsg; + + for (int iPhi=0; iPhi<_nDivisionsInPhi; ++iPhi) { + for (int iTheta=0; iTheta<_nDivisionsInTheta;++iTheta) { + ProcessOneSector(iPhi,iTheta); // Process one VXD sector + } + } + + debug() << "End of Processing VXD and SIT sectors" << endmsg; + + } + + if (successFTD == 1) { + debug() << " phi side layer nh o : m : i :: o*m*i " << endmsg; + TrackingInFTD(); // Perform tracking in the FTD + debug() << "End of Processing FTD sectors" << endmsg; + } + + //if(0){ + if (successVTX == 1 || successFTD == 1) { + //if (successVTX == 1 ) { + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + Sorting( _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ) ); + + } + debug() << "End of Sorting " << endmsg; + + for (int nHits = _nHitsChi2; nHits >= 3 ;// the three is hard coded, sorry. + // It's the minimal number to form a track + nHits--) { + + TrackExtendedVec &tracksWithNHits = _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ); + for (TrackExtendedVec::iterator trackIter = tracksWithNHits.begin(); + trackIter < tracksWithNHits.end(); trackIter++) { + CreateTrack( *trackIter ); + } + debug() << "End of creating "<< nHits << " hits tracks " << endmsg; + } + + if (_attachFast == 0) { + if(successVTX) AttachRemainingVTXHitsSlow(); + if(successFTD) AttachRemainingFTDHitsSlow(); + } + else { + if(successVTX) AttachRemainingVTXHitsFast(); + if(successFTD) AttachRemainingFTDHitsFast(); + } + + debug() << "End of picking up remaining hits " << endmsg; + + //edm4hep::TrackCollection* trkCol = nullptr; + //edm4hep::LCRelationCollection* relCol = nullptr; + auto trkCol = _outColHdl.createAndPut(); + //auto relCol = _outRelColHdl.createAndPut(); + //std::cout << "fucd------------------" << std::endl; + /* + LCCollectionVec * trkCol = new LCCollectionVec(LCIO::TRACK); + // if we want to point back to the hits we need to set the flag + LCFlagImpl trkFlag(0) ; + trkFlag.setBit( LCIO::TRBIT_HITS ) ; + trkCol->setFlag( trkFlag.getFlag() ) ; + + LCCollectionVec * relCol = NULL; + */ + //FinalRefit(trkCol, relCol); + FinalRefit(trkCol); + //std::cout << "fucd------------------" << std::endl; + // set the quality of the output collection + switch (_output_track_col_quality) { + + case _output_track_col_quality_FAIR: + //trkCol->parameters().setValue( "QualityCode" , "Fair" ) ; + break; + + case _output_track_col_quality_POOR: + //trkCol->parameters().setValue( "QualityCode" , "Poor" ) ; + break; + + default: + //trkCol->parameters().setValue( "QualityCode" , "Good" ) ; + break; + } + /* + if (_UseEventDisplay) { + this->drawEvent(); + } + */ + } + + // fill event based histogram + /* + if (_createDiagnosticsHistograms) { + + // triplet histos + _histos->fill1D(DiagnosticsHistograms::hntriplets, _ntriplets); + _histos->fill1D(DiagnosticsHistograms::hntriplets_good, _ntriplets_good); + _histos->fill1D(DiagnosticsHistograms::hntriplets_2MCP, _ntriplets_2MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_3MCP, _ntriplets_3MCP); + _histos->fill1D(DiagnosticsHistograms::hntriplets_1MCP_Bad, _ntriplets_1MCP_Bad); + _histos->fill1D(DiagnosticsHistograms::hntriplets_bad, _ntriplets_bad); + + } + */ + /* + const edm4hep::MCParticleCollection* mcCol = nullptr; + try{ + mcCol =_inMCColHdl.get(); + } + catch(...){ + } + if(mcCol){ + int id = 0; + for(auto mcP : *mcCol){ + float pos[3]; + float mom[3]; + pos[0] = mcP.vertex()[0]; + pos[1] = mcP.vertex()[1]; + pos[2] = mcP.vertex()[2]; + mom[0] = mcP.momentum()[0]; + mom[1] = mcP.momentum()[1]; + mom[2] = mcP.momentum()[2]; + float charge = mcP.getCharge(); + HelixClass helix; + helix.Initialize_VP(pos,mom,charge,_bField); + float d0 = helix.getD0(); + float z0 = helix.getZ0(); + float omega = helix.getOmega(); + float phi0 = helix.getPhi0(); + float tanLambda = helix.getTanLambda(); + std::cout <<"MCParticle: " << evtNo << " " << id << " " << sqrt(mom[0]*mom[0]+mom[1]*mom[1]) << " " << acos(mom[2]/sqrt(mom[0]*mom[0]+mom[1]*mom[1]+mom[2]*mom[2])) + << " " << atan2(mom[1],mom[0]) + << " " << d0 << " " << phi0 << " " << omega << " " << z0 << " " << tanLambda << " " << mcP.vertex() << std::endl; + id++; + } + } + + const edm4hep::TrackCollection* trkCol = nullptr; + try{ + trkCol = _outColHdl.get(); + } + catch(...){ + } + if(trkCol){ + int id = 0; + for(auto track : *trkCol){ + int nstate = track->trackStates_size(); + for(int i=0;i<nstate;i++){ + edm4hep::TrackState trkState = track->getTrackStates(i); + if(trkState.location != 1) continue; + HelixClass helix_final; + helix_final.Initialize_Canonical(trkState.phi,trkState.D0,trkState.Z0,trkState.omega,trkState.tanLambda,_bField); + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkPt = sqrt(trkPx*trkPx+trkPy*trkPy); + std::cout << "Track parameter: " << evtNo << " " << id << " " << trkPt << " " << acos(trkPz/sqrt(trkPt*trkPt+trkPz*trkPz)) << " " << atan2(trkPy,trkPx) + << " " << trkState.D0 << " " << trkState.phi << " " << trkState.omega << " " << trkState.Z0 << " " << trkState.tanLambda + << " " << sqrt(trkState.covMatrix[0]) << " " << sqrt(trkState.covMatrix[2]) << " " << sqrt(trkState.covMatrix[5]) + << " " << sqrt(trkState.covMatrix[9]) << " " << sqrt(trkState.covMatrix[14]) << " " << std::endl; + id++; + break; + } + } + } + */ + CleanUp(); + debug() << "Event is done " << endmsg; + _nEvt++; + return StatusCode::SUCCESS; +} + + +void SiliconTrackingAlg::CleanUp() { + + _tracksWithNHitsContainer.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + unsigned int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + + if( iCode >= _sectors.size()){ + error() << "iCode index out of range: iCode = " << iCode << " _sectors.size() = " << _sectors.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + unsigned int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + + if( iCode >= _sectorsFTD.size()){ + //error() << "iCode index out of range: iCode = " << iCode << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + continue; + } + + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + delete hit; + } + } + } + } + _trackImplVec.clear(); + _allHits.clear(); +} + +int SiliconTrackingAlg::InitialiseFTD() { + + int success = 1; + + _nTotalFTDHits = 0; + _sectorsFTD.clear(); + _sectorsFTD.resize(2*_nlayersFTD*_nPhiFTD); + + // Reading in FTD Pixel Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDPixelCol = nullptr; + try { + hitFTDPixelCol = _inFTDPixelColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDPixelColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDPixelCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDPixelHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDPixelHitCollection; + // _colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDPixelCol->size(); + + debug() << "Number of FTD Pixel Hits = " << nelem << endmsg; + _nTotalFTDHits = nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDPixelCol){ + // edm4hep::TrackerHit* hit = hitFTDPixelCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended( hit ); + + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors V is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // SJA:FIXME Here dU and dV are almost certainly dX and dY ... should test ... + //double point_res_rphi = sqrt( hit->getdU()*hit->getdU() + hit->getdV()*hit->getdV() ); + double point_res_rphi = sqrt( hit.getCovMatrix()[2]*hit.getCovMatrix()[2] + hit.getCovMatrix()[5]*hit.getCovMatrix()[5] ); + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTrackingAlg => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD Pixel Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + } + } + // Reading out FTD SpacePoint Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitFTDSpacePointCol = nullptr; + try { + hitFTDSpacePointCol = _inFTDSpacePointColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inFTDSpacePointColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + + if(hitFTDSpacePointCol){ + //LCCollection * hitCollection = evt->getCollection(_FTDSpacePointCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _FTDSpacePointCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitFTDSpacePointCol->size(); + + debug() << "Number of FTD SpacePoints = " << nelem << endmsg; + _nTotalFTDHits += nelem; + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto hit : *hitFTDSpacePointCol){ + //edm4hep::TrackerHit* hit = hitFTDSpacePointCol->at(ielem); + + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + double point_res_rphi = 2 * sqrt( hit.getCovMatrix()[0] + hit.getCovMatrix()[2] ); + + hitExt->setResolutionRPhi( point_res_rphi ); + + // SJA:FIXME why is this needed? + hitExt->setResolutionZ(0.1); + + // type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + } + + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + unsigned int layer = static_cast<unsigned int>(getLayerID(&hit)); + unsigned int petalIndex = static_cast<unsigned int>(getModuleID(&hit)); + + if ( _petalBasedFTDWithOverlaps == true ) { + + // as we are dealing with staggered petals we will use 2*nlayers in each directions +/- z + // the layers will follow the even odd numbering of the petals + if ( petalIndex % 2 == 0 ) { + layer = 2*layer; + } + else { + layer = 2*layer + 1; + } + + } + + if (layer >= _nlayersFTD) { + error() << "SiliconTrackingAlg => fatal error in FTD : layer is outside allowed range : " << layer << " number of layers = " << _nlayersFTD << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhiFTD); + + int side = getSideID(&hit); + int iSemiSphere = 0; + + if (side > 0) + iSemiSphere = 1; + + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPhi; + _sectorsFTD[iCode].push_back( hitExt ); + + debug() << " FTD SpacePoint Hit added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iSemiSphere " << iSemiSphere << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + for (unsigned i=0; i<_sectorsFTD.size(); ++i) { + int nhits = _sectorsFTD[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in FTD Sector " << i << " = " << _sectorsFTD[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectorsFTD[i].size(); ++ihit) { + delete _sectorsFTD[i][ihit]; + } + _sectorsFTD[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in FTD Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + + } + + } + debug() << "FTD initialized" << endmsg; + return success; +} + +int SiliconTrackingAlg::InitialiseVTX() { + //std::cout << "fucd================" << std::endl; + _nTotalVTXHits = 0; + _nTotalSITHits = 0; + _sectors.clear(); + _sectors.resize(_nLayers*_nDivisionsInPhi*_nDivisionsInTheta); + //std::cout << "fucd================" << std::endl; + int success = 1; + // Reading out VTX Hits Collection + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + const edm4hep::TrackerHitCollection* hitVTXCol = nullptr; + try { + hitVTXCol = _inVTXColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inVTXColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitVTXCol){ + //LCCollection * hitCollection = evt->getCollection(_VTXHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _VTXHitCollection; + //_colTrackerHits.push_back(hitCollection); + //std::cout << "fucd================1" << std::endl; + int nelem = hitVTXCol->size(); + //std::cout << "fucd================2" << std::endl; + debug() << "Number of VTX hits = " << nelem << endmsg; + _nTotalVTXHits = nelem; + + for (int ielem=0; ielem<nelem; ++ielem) { + //for(auto hit : *hitVTXCol){ + edm4hep::TrackerHit hit = hitVTXCol->at(ielem); + //_allHits.push_back(hit); + //gear::Vector3D U(1.0,hit->getU()[1],hit->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,hit->getV()[1],hit->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,hit.getCovMatrix()[1],hit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,hit.getCovMatrix()[4],hit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + //debug() << "covMatrix : " << hit->getCovMatrix()[0] << " " << hit->getCovMatrix()[1] << endmsg; + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: VXD Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + //std::cout << "fucd: " << &hit << " " << &_allHits.back() << std::endl; + //TrackerHitExtended * hitExt = new TrackerHitExtended( &_allHits.back() ); + TrackerHitExtended * hitExt = new TrackerHitExtended(hit); + std::cout << "Saved TrackerHit pointer in TrackerHitExtended " << ielem << ": " << hitExt->getTrackerHit() << std::endl; + //std::cout << (&_allHits.back())->getPosition()[0] << " " << hit.getCovMatrix()[2] << " " << hit.getCovMatrix()[5] << std::endl; + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(hit.getCovMatrix()[2]); + hitExt->setResolutionZ(hit.getCovMatrix()[5]); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = hit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + // get the layer number + int layer = getLayerID(&hit); + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTrackingAlg => fatal error in VTX : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " VXD Hit " << hit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + + if (_useSIT > 0 ) { + const edm4hep::TrackerHitCollection* hitSITCol = nullptr; + try { + hitSITCol = _inSITColHdl.get(); + } + catch ( GaudiException &e ) { + debug() << "Collection " << _inSITColHdl.fullKey() << " is unavailable in event " << _nEvt << endmsg; + success = 0; + } + if(hitSITCol){ + //LCCollection *hitCollection = evt->getCollection(_SITHitCollection.c_str()); + + //_colNamesTrackerHits[hitCollection] = _SITHitCollection; + //_colTrackerHits.push_back(hitCollection); + + int nelem = hitSITCol->size(); + + debug() << "Number of SIT hits = " << nelem << endmsg; + _nTotalSITHits = nelem; + + //TrackerHit* trkhit = 0; + //TrackerHitPlane* trkhit_P = 0; + //TrackerHitZCylinder* trkhit_C = 0; + + double drphi(NAN); + double dz(NAN); + + //for (int ielem=0; ielem<nelem; ++ielem) { + for(auto trkhit : *hitSITCol){ + // hit could be of the following type + // 1) TrackerHit, either ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT or just standard TrackerHit + // 2) TrackerHitPlane, either 1D or 2D + // 3) TrackerHitZCylinder, if coming from a simple cylinder design as in the LOI + + // Establish which of these it is in the following order of likelyhood + // i) ILDTrkHitTypeBit::ONE_DIMENSIONAL (TrackerHitPlane) Should Never Happen: SpacePoints Must be Used Instead + // ii) ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT (TrackerHit) + // iii) TrackerHitPlane (Two dimentional) + // iv) TrackerHitZCylinder + // v) Must be standard TrackerHit + + //const edm4hep::TrackerHit* trkhit = hitSITCol->at(ielem); + + int layer = getLayerID(&trkhit); + + // VXD and SIT are treated as one system so SIT layers start from _nLayersVTX + layer = layer + _nLayersVTX; + + if (layer < 0 || layer >= _nLayers) { + error() << "SiliconTrackingAlg => fatal error in SIT : layer is outside allowed range : " << layer << endmsg; + exit(1); + } + + // first check that we have not been given 1D hits by mistake, as they won't work here + if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL ] ) { + + error() << "SiliconTrackingAlg: SIT Hit cannot be of type UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL COMPOSITE SPACEPOINTS must be use instead. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + + } + // most likely case: COMPOSITE_SPACEPOINT hits formed from stereo strip hits + else if ( UTIL::BitSet32( trkhit.getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ) { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // or a PIXEL based SIT, using 2D TrackerHitPlane like the VXD above + // by fucd + //else if ( ( trkhit_P = dynamic_cast<TrackerHitPlane*>( hitCollection->getElementAt( ielem ) ) ) ) { + else if( UTIL::BitSet32( trkhit.getType() )[ 31 ]){ + // first we need to check if the measurement vectors are aligned with the global coordinates + //gear::Vector3D U(1.0,trkhit_P->getU()[1],trkhit_P->getU()[0],gear::Vector3D::spherical); + //gear::Vector3D V(1.0,trkhit_P->getV()[1],trkhit_P->getV()[0],gear::Vector3D::spherical); + gear::Vector3D U(1.0,trkhit.getCovMatrix()[1],trkhit.getCovMatrix()[0],gear::Vector3D::spherical); + gear::Vector3D V(1.0,trkhit.getCovMatrix()[4],trkhit.getCovMatrix()[3],gear::Vector3D::spherical); + gear::Vector3D Z(0.0,0.0,1.0); + + const float eps = 1.0e-07; + // V must be the global z axis + if( fabs(1.0 - V.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: PIXEL SIT Hit measurment vectors V is not equal to the global Z axis. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + // U must be normal to the global z axis + if( fabs(U.dot(Z)) > eps ) { + error() << "SiliconTrackingAlg: PIXEL SIT Hit measurment vectors U is not in the global X-Y plane. \n\n exit(1) called from file " << __FILE__ << " and line " << __LINE__ << endmsg; + exit(1); + } + + //drphi = trkhit_P->getdU(); + //dz = trkhit_P->getdV(); + drphi = trkhit.getCovMatrix()[2]; + dz = trkhit.getCovMatrix()[5]; + } + + // or a simple cylindrical design, as used in the LOI + /* by fucd + else if ( ( trkhit_C = dynamic_cast<TrackerHitZCylinder*>( hitCollection->getElementAt( ielem ) ) ) ) { + + drphi = trkhit_C->getdRPhi(); + dz = trkhit_C->getdZ(); + + } + */ + // this would be very unlikely, but who knows ... just an ordinary TrackerHit, which is not a COMPOSITE_SPACEPOINT + else { + + // SJA:FIXME: fudge for now by a factor of two and ignore covariance + drphi = 2 * sqrt(trkhit.getCovMatrix()[0] + trkhit.getCovMatrix()[2]); + dz = sqrt(trkhit.getCovMatrix()[5]); + + } + // now that the hit type has been established carry on and create a + + TrackerHitExtended * hitExt = new TrackerHitExtended(trkhit); + + // SJA:FIXME: just use planar res for now + hitExt->setResolutionRPhi(drphi); + hitExt->setResolutionZ(dz); + + // set type is now only used in one place where it is set to 0 to reject hits from a fit, set to INT_MAX to try and catch any missuse + hitExt->setType(int(INT_MAX)); + // det is no longer used set to INT_MAX to try and catch any missuse + hitExt->setDet(int(INT_MAX)); + + double pos[3]; + double radius = 0; + + for (int i=0; i<3; ++i) { + pos[i] = trkhit.getPosition()[i]; + radius += pos[i]*pos[i]; + } + + radius = sqrt(radius); + + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + + if (Phi < 0.) Phi = Phi + TWOPI; + + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = layer + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + _sectors[iCode].push_back( hitExt ); + + debug() << " SIT Hit " << trkhit.id() << " added : @ " << pos[0] << " " << pos[1] << " " << pos[2] << " drphi " << hitExt->getResolutionRPhi() << " dz " << hitExt->getResolutionZ() << " iPhi = " << iPhi << " iTheta " << iTheta << " iCode = " << iCode << " layer = " << layer << endmsg; + + } + } + } + + + for (unsigned i=0; i<_sectors.size(); ++i) { + int nhits = _sectors[i].size(); + if( nhits != 0 ) debug() << " Number of Hits in VXD/SIT Sector " << i << " = " << _sectors[i].size() << endmsg; + if (nhits > _max_hits_per_sector) { + for (unsigned ihit=0; ihit<_sectors[i].size(); ++ihit) { + delete _sectors[i][ihit]; + } + _sectors[i].clear(); + if( nhits != 0 ) error() << " \n ### Number of Hits in VXD/SIT Sector " << i << " = " << nhits << " : Limit is set to " << _max_hits_per_sector << " : This sector will be dropped from track search, and QualityCode set to \"Poor\" " << endmsg; + + _output_track_col_quality = _output_track_col_quality_POOR; + } + } + debug() << "VXD initialized" << endmsg; + return success; +} + +StatusCode SiliconTrackingAlg::finalize(){ + + delete _fastfitter ; _fastfitter = 0; + delete _encoder ; _encoder = 0; + //delete _trksystem ; _trksystem = 0; + //delete _histos ; _histos = 0; + info() << "Processed " << _nEvt << " events " << endmsg; + return GaudiAlgorithm::finalize(); +} + + +void SiliconTrackingAlg::ProcessOneSector(int iPhi, int iTheta) { + + int counter = 0 ; + + int iPhi_Up = iPhi + 1; + int iPhi_Low = iPhi - 1; + int iTheta_Up = iTheta + 1; + int iTheta_Low = iTheta - 1; + if (iTheta_Low < 0) iTheta_Low = 0; + if (iTheta_Up >= _nDivisionsInTheta) iTheta_Up = _nDivisionsInTheta-1; + + int nComb = int( _Combinations.size() / 3 ); // number of triplet combinations + // std::cout << iPhi << " " << iTheta << " " << _nEvt << endmsg; + int iNC = 0; + + for (int iComb=0; iComb < nComb; ++iComb) { // loop over triplets + + int nLR[3]; + + for (int iS=0; iS<3; ++iS) { + nLR[iS] = _Combinations[iNC]; + iNC++; + } + + //std::cout << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " " << std::endl; + + // index of theta-phi bin of outer most layer + int iCode = nLR[0] + _nLayers*iPhi + _nLayers*_nDivisionsInPhi*iTheta; + + //std::cout << "size of vector = " << _sectors.size() << " iCode = " << iCode << std::endl; + + // get the all the hits in the outer most theta-phi bin + + TrackerHitExtendedVec& hitVecOuter = _sectors[iCode]; + + int nHitsOuter = int(hitVecOuter.size()); + if (nHitsOuter > 0) { + + //std::cout << " " << iPhi << " " << iTheta << " " << nLR[0] << " " << nLR[1] << " " << nLR[2] << " size of vector = " << hitVecOuter.size() << std::endl; + + for (int ipMiddle=iPhi_Low; ipMiddle<iPhi_Up+1;ipMiddle++) { // loop over phi in the Middle + + for (int itMiddle=iTheta_Low; itMiddle<iTheta_Up+1;itMiddle++) { // loop over theta in the Middle + + int iPhiMiddle = ipMiddle; + + // catch wrap-around + if (ipMiddle < 0) iPhiMiddle = _nDivisionsInPhi-1; + if (ipMiddle >= _nDivisionsInPhi) iPhiMiddle = ipMiddle - _nDivisionsInPhi; + + // index of current theta-phi bin of middle layer + iCode = nLR[1] + _nLayers*iPhiMiddle + _nLayers*_nDivisionsInPhi*itMiddle; + + // get the all the hits in the current middle theta-phi bin + TrackerHitExtendedVec& hitVecMiddle = _sectors[iCode]; + + int nHitsMiddle = int(hitVecMiddle.size()); + + // determine which inner theta-phi bins to look in + + int iPhiLowInner = iPhi_Low; + int iPhiUpInner = iPhi_Up; + int iThetaLowInner = iTheta_Low; + int iThetaUpInner = iTheta_Up; + + // test to see if this is the core bin of the current search + // if so, look into the neigboring bins in the inner layer + if (ipMiddle == iPhi && itMiddle==iTheta) { + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + else { + int difP = abs(ipMiddle-iPhi); // number of phi bins from core: can only be 1 or 0 due to hard coded 1 above + int difT = abs(itMiddle-iTheta);// number of theta bins from core: can only be 1 or 0 due to hard coded 1 above + int minP = min(ipMiddle,iPhi); // min phi: core bin or current phi bin middle + int minT = min(itMiddle,iTheta); // min theta: core bin or current theta bin middle + int maxP = max(ipMiddle,iPhi); // max phi: core bin or current phi bin middle + int maxT = max(itMiddle,iTheta); // max theta: core bin or current theta bin middle + + if (difP==1 && difT==1) { // if the diffence is a single bin in both phi and theta : only look in the bin adjacent to the core bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difP==0) { // must be +/-1 theta : only look in bins adjacent to the middle bin + iPhiLowInner = iPhi_Low; + iPhiUpInner = iPhi_Up; + iThetaLowInner = minT; + iThetaUpInner = maxT; + } + if (difT==0) { // must be +/-1 phi : only look in bins adjacent to the middle bin + iPhiLowInner = minP; + iPhiUpInner = maxP; + iThetaLowInner = iTheta_Low; + iThetaUpInner = iTheta_Up; + } + } + if (nHitsMiddle > 0) { // look into inner bins + + for (int ipInner=iPhiLowInner; ipInner<iPhiUpInner+1;ipInner++) { // loop over phi in the Inner + + for (int itInner=iThetaLowInner; itInner<iThetaUpInner+1;itInner++) { // loop over theta in the Inner + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + iCode = nLR[2] + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get hit for inner bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + if (nHitsInner > 0) { + + debug() << " " + << std::setw(3) << iPhi << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iTheta << " " << std::setw(3) << itMiddle << " " << std::setw(3) << itInner << " " + << std::setw(3) << nLR[0] << " " << std::setw(3) << nLR[1] << " " << std::setw(3) << nLR[2] << " " + << std::setw(3) << nHitsOuter << " : " << std::setw(3) << nHitsMiddle << " : " << std::setw(3) << nHitsInner << " :: " + << std::setw(3) << nHitsOuter*nHitsMiddle* nHitsInner << endmsg; + + // test all triplets + + for (int iOuter=0; iOuter<nHitsOuter; ++iOuter) { // loop over hits in the outer sector + TrackerHitExtended * outerHit = hitVecOuter[iOuter]; + for (int iMiddle=0;iMiddle<nHitsMiddle;iMiddle++) { // loop over hits in the middle sector + TrackerHitExtended * middleHit = hitVecMiddle[iMiddle]; + for (int iInner=0;iInner<nHitsInner;iInner++) { // loop over hits in the inner sector + TrackerHitExtended * innerHit = hitVecInner[iInner]; + HelixClass helix; + //std::cout <<"fucd++++++++++++++++++++++1" << std::endl; + // test fit to triplet + TrackExtended * trackAR = TestTriplet(outerHit,middleHit,innerHit,helix); + //std::cout <<"fucd++++++++++++++++++++++2" << std::endl; + if ( trackAR != NULL ) { + int nHits = BuildTrack(outerHit,middleHit,innerHit,helix,nLR[2], + iPhiLowInner,iPhiUpInner, + iThetaLowInner,iThetaUpInner,trackAR); + + _tracksWithNHitsContainer.getTracksWithNHitsVec(nHits).push_back(trackAR); + + counter ++ ; + } + //std::cout <<"fucd++++++++++++++++++++++3" << std::endl; + } // endloop over hits in the inner sector + } // endloop over hits in the middle sector + } // endloop over hits in the outer sector + } // endif nHitsInner > 0 + } // endloop over theta in the Inner + } // endloop over phi in the Inner + } // endif nHitsMiddle > 0 + } // endloop over theta in the Middle + } // endloop over phi in the Middle + } // endif nHitsOuter > 0 + } // endloop over triplets + + //debug() << " process one sectector theta,phi " << iTheta << ", " << iPhi << " number of loops : " << counter << endmsg ; +} + +TrackExtended * SiliconTrackingAlg::TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix) { + /* + Methods checks if the triplet of hits satisfies helix hypothesis + */ + //std::cout << "fucd================1" << std::endl; + // get the tracks already associated with the triplet + TrackExtendedVec& trackOuterVec = outerHit->getTrackExtendedVec(); + TrackExtendedVec& trackMiddleVec = middleHit->getTrackExtendedVec(); + TrackExtendedVec& trackInnerVec = innerHit->getTrackExtendedVec(); + + //std::cout << "fucd================2" << std::endl; + // check if all the hits are already assigned to a track + if ( (!trackOuterVec.empty()) && (!trackMiddleVec.empty()) && (!trackInnerVec.empty())) { + + TrackExtendedVec::const_iterator middleEndIter = trackMiddleVec.end(); + TrackExtendedVec::const_iterator outerEndIter = trackOuterVec.end(); + TrackExtendedVec::const_iterator innerEndIter = trackInnerVec.end(); + TrackExtendedVec::const_iterator outerBeginIter = trackOuterVec.begin(); + TrackExtendedVec::const_iterator innerBeginIter = trackInnerVec.begin(); + + // loop over the tracks from the middle hit + for (TrackExtendedVec::const_iterator middleIter = trackMiddleVec.begin(); + middleIter < middleEndIter; + ++middleIter) { + + // loop over the track from the outer hit + for (TrackExtendedVec::const_iterator outerIter = outerBeginIter; + outerIter < outerEndIter; + ++outerIter) { + + // if track from the outer and middle are not the same progress + if ( *outerIter != *middleIter ) continue; + + // loop over the tracks from the inner hit + for (TrackExtendedVec::const_iterator innerIter = innerBeginIter; + innerIter < innerEndIter; + ++innerIter) { + + // no need to check against middle, it is idendical to outer here + if ( *outerIter == *innerIter ) { + // an existing track already contains all three hits + // return a null pointer + debug() << " TestTriplet: track " << *outerIter << " already contains all three hits: Do not create new track from these hits " << endmsg ; + return 0; + } + + }// for inner + }// for outer + }// for middle + }// if all vectors are not empty + //std::cout << "fucd================3" << std::endl; + + // float dZ = FastTripletCheck(innerHit, middleHit, outerHit); + + // if (fabs(dZ) > _minDistCutAttach) + // return trackAR; + + + // increase triplet count + ++_ntriplets; + + // get the hit coordinates and errors + double xh[3]; + double yh[3]; + float zh[3]; + double wrh[3]; + float wzh[3]; + float rh[3]; + float ph[3]; + + float par[5]; + float epar[15]; + /*fucd + for(int i=0;i<_allHits.size();i++){ + std::cout << &_allHits.at(i) << std::endl; + } + */ + // first hit + xh[0] = outerHit->getTrackerHit()->getPosition()[0]; + yh[0] = outerHit->getTrackerHit()->getPosition()[1]; + zh[0] = float(outerHit->getTrackerHit()->getPosition()[2]); + wrh[0] = double(1.0/(outerHit->getResolutionRPhi()*outerHit->getResolutionRPhi())); + wzh[0] = 1.0/(outerHit->getResolutionZ()*outerHit->getResolutionZ()); + // second hit + xh[1] = middleHit->getTrackerHit()->getPosition()[0]; + yh[1] = middleHit->getTrackerHit()->getPosition()[1]; + zh[1] = float(middleHit->getTrackerHit()->getPosition()[2]); + wrh[1] = double(1.0/(middleHit->getResolutionRPhi()*middleHit->getResolutionRPhi())); + wzh[1] = 1.0/(middleHit->getResolutionZ()*middleHit->getResolutionZ()); + // third hit + xh[2] = innerHit->getTrackerHit()->getPosition()[0]; + yh[2] = innerHit->getTrackerHit()->getPosition()[1]; + zh[2] = float(innerHit->getTrackerHit()->getPosition()[2]); + wrh[2] = double(1.0/(innerHit->getResolutionRPhi()*innerHit->getResolutionRPhi())); + wzh[2] = 1.0/(innerHit->getResolutionZ()*innerHit->getResolutionZ()); + // calculate r and phi for all hits + for (int ih=0; ih<3; ih++) { + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = atan2(yh[ih],xh[ih]); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + + int NPT = 3; + int iopt = 2; + float chi2RPhi; + float chi2Z; + + debug() << " TestTriplet: Use fastHelixFit " << endmsg ; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + // get helix parameters + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + // chi2 is weighted here by a factor for both rphi and z + float Chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + int ndf = 2*NPT-5; + + + // check the truth information for the triplet + + // define these outside of the ifdef so that we don't need to keep repeating it. + //std::vector<TrackerHit*> hit_list; + //std::vector<MCParticle*> mcps_imo; + //std::vector<MCParticle*> mcp_s; + int triplet_code = 0; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + + int nmcps = 0; + int nbadHits = 0; + + int layer = 9 ; + int size = 3 ; + int marker = 1 ; + int ml = 0 ; + // float helix_max_r = 0; + float helix_max_z = 0; + int color = 0; + + // use the MCTruth4HitExt to get the MCPs + + hit_list.push_back(innerHit->getTrackerHit()); + hit_list.push_back(middleHit->getTrackerHit()); + hit_list.push_back(outerHit->getTrackerHit()); + + EVENT::MCParticle* mcp_i = 0; + EVENT::MCParticle* mcp_m = 0; + EVENT::MCParticle* mcp_o = 0; + + for (unsigned ihit = 0; ihit < hit_list.size(); ++ihit) { + + EVENT::TrackerHit* trkhit = hit_list[ihit]; + std::vector<MCParticle*> mcps; + + MarlinTrk::getMCParticlesForTrackerHit(trkhit, mcps); + + if (mcps.size() == 1) { + mcps_imo.push_back(mcps[0]); + ++nmcps; + } else { + mcps_imo.push_back(0); + ++nbadHits; + } + + } + + mcp_i = mcps_imo[0]; + mcp_m = mcps_imo[1]; + mcp_o = mcps_imo[2]; + + debug() + << "\n mcp_i = " << mcp_i + << "\n mcp_m = " << mcp_m + << "\n mcp_o = " << mcp_o + << endmsg; + + if( mcp_i ) { + mcp_s.push_back(mcp_i) ; + } + + if( mcp_m && mcp_m != mcp_i ) { + mcp_s.push_back(mcp_m); + } + + if( mcp_o && mcp_o != mcp_m && mcp_o != mcp_i ){ + mcp_s.push_back(mcp_o); + } + + nmcps = mcp_s.size(); + + if (_UseEventDisplay) { + // display this triplet and the MCPs from which it is formed + + MarlinCED::newEvent(this , _detector_model_for_drawing ) ; + + // CEDPickingHandler &pHandler=CEDPickingHandler::getInstance(); + // + // pHandler.update(_current_event); + + for (unsigned imcp = 0; imcp < mcp_s.size(); ++imcp) { + + MCParticle* mcp = mcp_s[imcp]; + + helix_max_z = fabsf(mcp->getEndpoint()[2]); + + + info() << "Draw MCParticle : " << *mcp <<endmsg; + + MarlinCED::add_layer_description("MCParticle_For_Fit", layer); + + MarlinCED::drawHelix( _bField , mcp->getCharge(), mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2], + mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2], layer , size , 0x7af774 , + 0.0, _helix_max_r , + helix_max_z, mcp->id() ) ; + + } + + const std::string colName = "Hits_For_Fit"; + + + size = 10 ; + layer = 11 ; + // ml = marker | ( layer << CED_LAYER_SHIFT ) ; + + //ced_describe_layer( colName.c_str() ,layer); + MarlinCED::add_layer_description(colName, layer); + + + color = 0xFFFFFF; + + for( std::vector<TrackerHit* >::const_iterator it = hit_list.begin(); it != hit_list.end() ; it++ ) { + + TrackerHit* trkhit = *it; + + ced_hit_ID(trkhit->getPosition()[0], + trkhit->getPosition()[1], + trkhit->getPosition()[2], + marker, layer, size , color, trkhit->id() ) ; + + } // hits + + } + + if (_createDiagnosticsHistograms) { + + // if no bad hits are present triplet_code = nmcps; + triplet_code = nmcps + nbadHits * 3 ; + + _histos->fill1D(DiagnosticsHistograms::htriplets, triplet_code); + + double pt = (2.99792458E-4*_bField) / omega ; // for r in mm, p in GeV and Bz in Tesla + + if (triplet_code == 1) { + ++_ntriplets_good; + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_good, pt, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_good, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_good, pt ); + } else { + + _histos->fill2D(DiagnosticsHistograms::htripletChi2vPt_bad, pt, Chi2); + _histos->fill1D(DiagnosticsHistograms::htriplets_chi2_bad, Chi2 ); + _histos->fill1D(DiagnosticsHistograms::htriplets_pt_bad, pt ); + + if(triplet_code == 2) { + ++_ntriplets_2MCP; + } else if (triplet_code == 3) { + ++_ntriplets_3MCP; + } else if (triplet_code == 4) { + ++_ntriplets_1MCP_Bad; + } else { + ++_ntriplets_bad; + } + } + + } + +#endif + */ + + // Check if track satisfies all conditions + + + // std::cout << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + // std::cout << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + // std::cout << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + // std::cout << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + + // if ( Chi2/float(ndf) > _chi2FitCut || fabs(d0) > _cutOnD0 || fabs(z0) > _cutOnZ0 || fabs(omega)>_cutOnOmega) + // return a null pointer + // return 0; + + bool failed = false; + + int quality_code = triplet_code * 10 ; + + if ( Chi2/float(ndf) > _chi2FitCut ) { + debug() << "Chi2/ndf = " << Chi2/float(ndf) << " , cut = " << _chi2FitCut << endmsg; + failed = true; + quality_code += 1; + } else if (fabs(d0) > _cutOnD0 ) { + debug() << "d0 = " << d0 << " , cut = " << _cutOnD0 << endmsg; + failed = true; + quality_code += 2; + } else if (fabs(z0) > _cutOnZ0 ) { + debug() << "z0 = " << z0 << " , cut = " << _cutOnZ0 << endmsg; + failed = true; + quality_code += 3; + } else if ( fabs(omega)>_cutOnOmega) { + debug() << "omega = " << omega << " , cut = " << _cutOnOmega << endmsg; + failed = true; + quality_code += 4; + } else { + debug() << "Success !!!!!!!" << endmsg; + } + /* + if (_createDiagnosticsHistograms) _histos->fill1D(DiagnosticsHistograms::htriplets, quality_code); + + if (_UseEventDisplay) { + drawEvent(); + } + */ + + if( failed ) { + // return a null pointer + return 0; + } + + + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + + TrackExtended * trackAR = new TrackExtended(); + trackAR->addTrackerHitExtended(outerHit); + trackAR->addTrackerHitExtended(middleHit); + trackAR->addTrackerHitExtended(innerHit); + outerHit->addTrackExtended(trackAR); + middleHit->addTrackExtended(trackAR); + innerHit->addTrackExtended(trackAR); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix(epar); + + + return trackAR; + +} + +int SiliconTrackingAlg::BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerLayer, + int iPhiLow, int iPhiUp, + int iThetaLow, int iThetaUp, + TrackExtended * trackAR) { + /** + Method for building up track in the VXD. Method starts from the found triplet and performs + sequential attachment of hits in other layers, which have hits within the search window. + Only searches inwards. + Given that we know we are now jumping over layers due to the doublet nature of the VXD, we + could optimise this to look for the hits in interleaving layers as well. + Currently a fast fit is being done for each additional hit, it could be more efficient to try and use kaltest? + + */ + + debug() << " BuildTrack starting " << endmsg; + + for (int layer = innerLayer-1; layer>=0; layer--) { // loop over remaining layers + float distMin = 1.0e+20; + TrackerHitExtended * assignedhit = NULL; + //std::cout << "fucd---------------------1" << std::endl; + // loop over phi in the Inner region + for (int ipInner=iPhiLow; ipInner<iPhiUp+1;ipInner++) { + + // loop over theta in the Inner region + for (int itInner=iThetaLow; itInner<iThetaUp+1;itInner++) { + + int iPhiInner = ipInner; + + // catch wrap-around + if (ipInner < 0) iPhiInner = _nDivisionsInPhi-1; + if (ipInner >= _nDivisionsInPhi) iPhiInner = ipInner - _nDivisionsInPhi; + + // get the index of the theta-phi bin to search + int iCode = layer + _nLayers*iPhiInner + _nLayers*_nDivisionsInPhi*itInner; + + // get the hits from this bin + TrackerHitExtendedVec& hitVecInner = _sectors[iCode]; + + int nHitsInner = int(hitVecInner.size()); + + // loop over hits in the Inner sector + for (int iInner=0;iInner<nHitsInner;iInner++) { + + TrackerHitExtended * currentHit = hitVecInner[iInner]; + + // get the position of the hit to test + float pos[3]; + float distance[3]; + + for (int i=0; i<3; ++i) { + pos[i] = float(currentHit->getTrackerHit()->getPosition()[i]); + } + + // get the distance of closest approach and distance s traversed to the POCA + float time = helix.getDistanceToPoint(pos,distance); + + // sanity check on s + if (time < 1.0e+10) { + + // check if this is the closest hit yet + if (distance[2] < distMin) { // distance[2] = sqrt( d0*d0 + z0*z0 ) + + // if yes store hit and distance + distMin = distance[2]; + assignedhit = currentHit; + } + } + } // endloop over hits in the Inner sector + } // endloop over theta in the Inner region + } // endloop over phi in the Inner region + //std::cout << "fucd---------------------2" << std::endl; + // check if closest hit fulfills the min distance cut + if (distMin < _minDistCutAttach) { + + // if yes try to include it in the fit + + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hvec.size()); + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hvec[ih]->getTrackerHit(); + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(hvec[ih]->getResolutionRPhi()*hvec[ih]->getResolutionRPhi())); + wzh[ih] = 1.0/(hvec[ih]->getResolutionZ()*hvec[ih]->getResolutionZ()); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + if (ph[ih] < 0.) + ph[ih] = TWOPI + ph[ih]; + } + edm4hep::TrackerHit * assignedTrkHit = assignedhit->getTrackerHit(); + xh[nHits] = assignedTrkHit->getPosition()[0]; + yh[nHits] = assignedTrkHit->getPosition()[1]; + zh[nHits] = float(assignedTrkHit->getPosition()[2]); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + if (ph[nHits] < 0.) + ph[nHits] = TWOPI + ph[nHits]; + wrh[nHits] = double(1.0/(assignedhit->getResolutionRPhi()*assignedhit->getResolutionRPhi())); + wzh[nHits] = 1.0/(assignedhit->getResolutionZ()*assignedhit->getResolutionZ()); + + int NPT = nHits + 1; + int iopt = 2; + float chi2RPhi; + float chi2Z; + +// std::cout << "######## number of hits to fit with _fastfitter = " << NPT << endmsg; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + bool validCombination = 0; + float Chi2 = FLT_MAX; + + if ((nHits+1) == 4) { + Chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if ((nHits+1) >= 5) { + Chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + int ndf = 2*NPT-5; + + // check if this is valid combination based on the chi2/ndf + validCombination = Chi2/float(ndf) < _chi2FitCut; + + if ( validCombination ) { + // assign hit to track and track to hit, update the track parameters + trackAR->addTrackerHitExtended(assignedhit); + assignedhit->addTrackExtended(trackAR); + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + trackAR->setD0(d0); + trackAR->setZ0(z0); + trackAR->setPhi(phi0); + trackAR->setTanLambda(tanlambda); + trackAR->setOmega(omega); + trackAR->setChi2( Chi2 ); + trackAR->setCovMatrix(epar); + trackAR->setNDF( ndf ); + } + + } + } // endloop over remaining layers + //std::cout << "fucd---------------------3" << std::endl; + TrackerHitExtendedVec& hvec = trackAR->getTrackerHitExtendedVec(); + int nTotalHits = int(hvec.size()); + +// std::cout << "######## number of hits to return = " << nTotalHits << endmsg; + + return nTotalHits; + +} + + +void SiliconTrackingAlg::Sorting(TrackExtendedVec & trackVec) { + /** + Sorting of Track Vector in ascending order of chi2/ndf + */ + + std::sort(trackVec.begin(), trackVec.end(), compare_TrackExtended() ); + + // also clean up? what does this do here? + for (size_t i=0, sizeOfVector=trackVec.size(); i<sizeOfVector; ++i) { + + TrackerHitExtendedVec& hitVec = trackVec[i]->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int ih=0;ih<nHits;ih++) { + hitVec[ih]->clearTrackVec(); + } + } + +} + +void SiliconTrackingAlg::CreateTrack(TrackExtended * trackAR ) { + + /** + Method which creates Track out of TrackExtended objects. Checks for possible + track splitting (separate track segments in VXD and FTD). + */ + + + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + for (int i=0; i<nHits; ++i) { + TrackExtendedVec& trackVec = hitVec[i]->getTrackExtendedVec(); + if (trackVec.size() != 0) + return ; + } + + // First check if the current track is piece of the split one + // look for matching track segment + + int found = 0; + + int nTrk = int(_trackImplVec.size()); + + for (int itrk=0; itrk<nTrk; ++itrk) { + TrackExtended * trackOld = _trackImplVec[itrk]; + TrackerHitExtendedVec& hitVecOld = trackOld->getTrackerHitExtendedVec(); + + float phiNew = trackAR->getPhi(); + float phiOld = trackOld->getPhi(); + float thetaNew = M_PI_2 - atan(trackAR->getTanLambda()); + float thetaOld = M_PI_2 - atan(trackOld->getTanLambda()); + + float angle = (cos(phiNew)*cos(phiOld)+sin(phiNew)*sin(phiOld))*sin(thetaNew)*sin(thetaOld)+cos(thetaNew)*cos(thetaOld); + angle = acos(angle); + + if (angle < _angleCutForMerging) { + int nHitsOld = int(hitVecOld.size()); + int nTotHits = nHits + nHitsOld; + double * xh = new double[nTotHits]; + double * yh = new double[nTotHits]; + float * zh = new float[nTotHits]; + double * wrh = new double[nTotHits]; + float * wzh = new float[nTotHits]; + float * rh = new float[nTotHits]; + float * ph = new float[nTotHits]; + float par[5]; + float epar[15]; + float refPoint[3] = {0.,0.,0.}; + for (int ih=0;ih<nHits;++ih) { + edm4hep::TrackerHit * trkHit = hitVec[ih]->getTrackerHit(); + float rR = hitVec[ih]->getResolutionRPhi(); + float rZ = hitVec[ih]->getResolutionZ(); + if (int(hitVec[ih]->getTrackExtendedVec().size()) != 0) + debug() << "WARNING : HIT POINTS TO TRACK " << endmsg; + xh[ih] = trkHit->getPosition()[0]; + yh[ih] = trkHit->getPosition()[1]; + zh[ih] = float(trkHit->getPosition()[2]); + wrh[ih] = double(1.0/(rR*rR)); + wzh[ih] = 1.0/(rZ*rZ); + rh[ih] = float(sqrt(xh[ih]*xh[ih]+yh[ih]*yh[ih])); + ph[ih] = float(atan2(yh[ih],xh[ih])); + } + for (int ih=0;ih<nHitsOld;++ih) { + edm4hep::TrackerHit * trkHit = hitVecOld[ih]->getTrackerHit(); + xh[ih+nHits] = trkHit->getPosition()[0]; + yh[ih+nHits] = trkHit->getPosition()[1]; + zh[ih+nHits] = float(trkHit->getPosition()[2]); + float rR = hitVecOld[ih]->getResolutionRPhi(); + float rZ = hitVecOld[ih]->getResolutionZ(); + wrh[ih+nHits] = double(1.0/(rR*rR)); + wzh[ih+nHits] = 1.0/(rZ*rZ); + rh[ih+nHits] = float(sqrt(xh[ih+nHits]*xh[ih+nHits]+yh[ih+nHits]*yh[ih+nHits])); + ph[ih+nHits] = float(atan2(yh[ih+nHits],xh[ih+nHits])); + + } + int NPT = nTotHits; + int iopt = 2; + float chi2RPhi; + float chi2Z; + int ndf = 2*NPT - 5; + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + + float eparmin[15]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + + float refPointMin[3]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + + float chi2Min = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Min = chi2Min/float(ndf); + + float chi2MinRPhi = chi2RPhi; + float chi2MinZ = chi2Z; + + int iBad = -1; + if (chi2Min < _chi2FitCut) { + found = 1; + } + else { // SJA:FIXME: UH What is going on here? setting weights to 0 and refitting? + float * wzhOld = new float[nTotHits]; + double * wrhOld = new double[nTotHits]; + for (int i=0;i<nTotHits;++i) { + wzhOld[i] = wzh[i]; + wrhOld[i] = wrh[i]; + } + for (int i=0; i<nTotHits; ++i) { + for (int j=0;j<nTotHits;++j) { + if (i == j) { + wrh[j] = 0.0; + wzh[j] = 0.0; + } + else { + wrh[j] = wrhOld[j]; + wzh[j] = wzhOld[j]; + } + } + + _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + float chi2Cur = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + chi2Cur = chi2Cur/float(ndf); + + if (chi2Cur < chi2Min) { + chi2Min = chi2Cur; + chi2MinRPhi = chi2RPhi; + chi2MinZ = chi2Z; + omega = par[0]; + tanlambda = par[1]; + phi0 = par[2]; + d0 = par[3]; + z0 = par[4]; + for (int iparam=0;iparam<15;++iparam) + eparmin[iparam] = epar[iparam]; + for (int ipp=0;ipp<3;++ipp) + refPointMin[ipp] = refPoint[ipp]; + iBad = i; + } + } + if (chi2Min < _chi2FitCut) { + found = 1; + } + delete[] wzhOld; + delete[] wrhOld; + } + + // Split track is found. + // Attach hits belonging to the current track segment to + // the track already created + if (found == 1) { + trackOld->ClearTrackerHitExtendedVec(); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * trkHit = hitVec[i]; + trkHit->clearTrackVec(); + if (i == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + for (int i=0;i<nHitsOld;++i) { + int icur = i+nHits; + TrackerHitExtended * trkHit = hitVecOld[i]; + trkHit->clearTrackVec(); + if (icur == iBad) { + } + else { + trackOld->addTrackerHitExtended(trkHit); + trkHit->addTrackExtended( trackOld ); + } + } + trackOld->setOmega(omega); + trackOld->setTanLambda(tanlambda); + trackOld->setPhi(phi0); + trackOld->setD0(d0); + trackOld->setZ0(z0); + + // std::cout << "Split track found " << d0 << " " << z0 << endmsg; + + // killeb: In the original SiliconTrackingAlg this was in the NOT simple helix branch. + // The rest of the code uses the simple helix branch, where ndf_D is never set. + // In fact it has never been initialised or used anywhere. I think this line should not be executed. + // ndf = ndf_D; + + trackOld->setChi2(chi2Min*float(ndf)); + trackOld->setNDF(ndf); + trackOld->setCovMatrix(eparmin); + // trackOld->setReferencePoint(refPointMin); + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + } + if (found == 1) + break; + } + + // Candidate is a unique track + // No other segments are found + if (found == 0 ) { + _trackImplVec.push_back(trackAR); + for (int i=0;i<nHits;++i) { + TrackerHitExtended * hit = hitVec[i]; + hit->addTrackExtended( trackAR ); + } + } + + +} + +void SiliconTrackingAlg::AttachRemainingVTXHitsFast() { + + std::vector<TrackerHitExtendedVec> nonAttachedHits; + nonAttachedHits.resize(_nDivisionsInPhi*_nDivisionsInTheta); + std::vector<TrackExtendedVec> trackVector; + trackVector.resize(_nDivisionsInPhi*_nDivisionsInTheta); + int nTracks = int(_trackImplVec.size()); + + for (int iTrk=0;iTrk<nTracks;++iTrk) { + TrackExtended * track = _trackImplVec[iTrk]; + double Phi = double(track->getPhi()); + if (Phi < 0) + Phi = Phi + TWOPI; + float tanlambda = track->getTanLambda(); + double cosTheta = double(tanlambda/sqrt(1+tanlambda*tanlambda)); + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + int iCode = iPhi + _nDivisionsInPhi*iTheta; + trackVector[iCode].push_back( track ); + } + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hitExt = hitVec[iH]; + TrackExtendedVec& trackVec = hitExt->getTrackExtendedVec(); + if (trackVec.size()==0) { + edm4hep::TrackerHit * hit = hitExt->getTrackerHit(); + double pos[3]; + double radius = 0; + for (int i=0; i<3; ++i) { + pos[i] = hit->getPosition()[i]; + radius += pos[i]*pos[i]; + } + radius = sqrt(radius); + double cosTheta = pos[2]/radius; + double Phi = atan2(pos[1],pos[0]); + if (Phi < 0.) Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhi); + int iTheta = int ((cosTheta + double(1.0))/_dTheta); + iCode = iPhi + _nDivisionsInPhi*iTheta; + nonAttachedHits[iCode].push_back( hitExt ); + } + } + } + } + } + + for (int iT=0; iT<_nDivisionsInTheta; ++iT) { + for (int iP=0; iP<_nDivisionsInPhi; ++iP) { + int iCode = iP + _nDivisionsInPhi*iT; + int nHits = int(nonAttachedHits[iCode].size()); + int iT1 = iT - 1; + int iT2 = iT + 1; + if (iT == 0) { + iT1 = iT; + iT2 = iT1 + 1; + } + if (iT == _nDivisionsInTheta - 1) { + iT2 = iT; + iT1 = iT2 - 1; + } + int iPHI[3]; + iPHI[0] = iP - 1; + iPHI[1] = iP; + iPHI[2] = iP + 1; + if (iP == 0) + iPHI[0] = _nDivisionsInPhi - 1; + if (iP == _nDivisionsInPhi - 1 ) + iPHI[2] = 0; + + for (int ihit = 0; ihit<nHits; ++ihit) { + + TrackerHitExtended * hit = nonAttachedHits[iCode][ihit]; + TrackExtended * trackToAttach = NULL; + float minDist = 1.0e+6; + + for (int iTheta = iT1; iTheta <iT2+1; ++iTheta) { + for (int indexP=0;indexP<3;++indexP) { + int iPhi = iPHI[indexP]; + int iCodeForTrack = iPhi + _nDivisionsInPhi*iTheta; + int nTrk = int(trackVector[iCodeForTrack].size()); + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = trackVector[iCodeForTrack][iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + break; + } + } + } + } + if (consider) { + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + HelixClass helix; + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int layer = getLayerID(hit->getTrackerHit()); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } + } + } +} + +void SiliconTrackingAlg::AttachRemainingVTXHitsSlow() { + + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int il=0;il<_nLayers;++il) { + for (int ip=0;ip<_nDivisionsInPhi;++ip) { + for (int it=0;it<_nDivisionsInTheta; ++it) { + int iCode = il + _nLayers*ip + _nLayers*_nDivisionsInPhi*it; + TrackerHitExtendedVec& hitVec = _sectors[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + // if (trackVec.size()==0) + // nonAttachedHits.push_back( hit ); + //-- allow hits that are only used in triplets to be re-attached + unsigned int maxTrackSize = 0; + for(unsigned int itrack = 0;itrack < trackVec.size();itrack++){ + TrackerHitExtendedVec hitVec_tmp= trackVec[itrack]->getTrackerHitExtendedVec(); + unsigned int isize = hitVec_tmp.size(); + if(isize>maxTrackSize)maxTrackSize = isize; + } + if (maxTrackSize<=3) { + debug() << " Add non attached hit to list: id = " << hit->getTrackerHit()->id() << endmsg; + nonAttachedHits.push_back( hit ); + } + + + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + debug() << " Try hit: id = " << hit->getTrackerHit()->id() << endmsg; + int layer = getLayerID( hit->getTrackerHit() ); + if (layer > _minimalLayerToAttach) { + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + if (_checkForDelta) { + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // Here we are trying to find if a hits are too close i.e. closer than _minDistToDelta + edm4hep::TrackerHit* trkhit1 = hit->getTrackerHit(); + edm4hep::TrackerHit* trkhit2 = hitVector[IHIT]->getTrackerHit(); + + if ( trkhit1->getCellID() == trkhit2->getCellID() ){ // i.e. they are in the same sensor + + float distance = 0.; + for (int iC=0;iC<3;++iC) { + float posFirst = float(hit->getTrackerHit()->getPosition()[iC]); + float posSecond = float(hitVector[IHIT]->getTrackerHit()->getPosition()[iC]); + float deltaPos = posFirst - posSecond; + distance += deltaPos*deltaPos; + } + distance = sqrt(distance); + if (distance<_minDistToDelta) { + consider = false; + debug() << " hit: id = " << hit->getTrackerHit()->id() << " condsidered delta together with hit " << trkhit2->id() << endmsg; + break; + } + } + } + } + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " : try attachement"<< endmsg; + AttachHitToTrack(trackToAttach,hit,iopt); + } else { + debug() << " Hit: id = " << hit->getTrackerHit()->id() << " rejected due to distance cut of " <<_minDistCutAttach<< " min distance = " << minDist << endmsg; + } + } + } +} + +void SiliconTrackingAlg::AttachRemainingFTDHitsSlow() { + TrackerHitExtendedVec nonAttachedHits; + nonAttachedHits.clear(); + + for (int iS=0;iS<2;++iS) { + for (unsigned int layer=0;layer<_nlayersFTD;++layer) { + for (int ip=0;ip<_nPhiFTD;++ip) { + int iCode = iS + 2*layer + 2*_nlayersFTD*ip; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + TrackExtendedVec& trackVec = hit->getTrackExtendedVec(); + if (trackVec.size()==0) + nonAttachedHits.push_back( hit ); + } + } + } + } + + int nNotAttached = int(nonAttachedHits.size()); + + int nTrk = int(_trackImplVec.size()); + for (int iHit=0; iHit<nNotAttached; ++iHit) { + TrackerHitExtended * hit = nonAttachedHits[iHit]; + float pos[3]; + for (int i=0; i<3; ++i) + pos[i] = hit->getTrackerHit()->getPosition()[i]; + float minDist = 1e+10; + TrackExtended * trackToAttach = NULL; + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + for (int IHIT=0;IHIT<NHITS;++IHIT) { + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + + consider = false; + break; + } + } + + + if (consider) { + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + if (tanlambda*float(getSideID(hit->getTrackerHit())) > 0) { + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < minDist) { + minDist = distance[2]; + trackToAttach = trackAR; + } + } + } + } + } + if (minDist < _minDistCutAttach && trackToAttach != NULL) { + int iopt = 2; + AttachHitToTrack(trackToAttach,hit,iopt); + } + } +} + + +void SiliconTrackingAlg::AttachRemainingFTDHitsFast() { + int nTrk = _trackImplVec.size(); + + for (int iTrk=0; iTrk<nTrk; ++iTrk) { + TrackExtended * trackAR = _trackImplVec[iTrk]; + HelixClass helix; + float phi0 = trackAR->getPhi(); + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + int iSemiSphere = 0; + if (tanlambda > 0) + iSemiSphere = 1; + float ref[3]; + for (int i=0;i<3;++i) + ref[i] = helix.getReferencePoint()[i]; + // Start loop over FTD layers + for (unsigned int layer=0;layer<_nlayersFTD;layer++) { + float ZL = _zLayerFTD[layer]; + if (iSemiSphere == 0) + ZL = - ZL; + float point[3]; + helix.getPointInZ(ZL,ref,point); + float Phi = atan2(point[1],point[0]); + if (Phi < 0) + Phi = Phi + TWOPI; + int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+10; + TrackerHitExtended * attachedHit = NULL; + for (int iP=iPhi-1;iP<=iPhi+1;++iP) { + int iPP = iP; + if (iP < 0) + iPP = iP + _nPhiFTD; + if (iP >= _nPhiFTD) + iPP = iP - _nPhiFTD; + int iCode = iSemiSphere + 2*layer + 2*_nlayersFTD*iPP; + int nHits = int(_sectorsFTD[iCode].size()); + for (int iHit=0;iHit<nHits;++iHit) { + TrackerHitExtended * hit = _sectorsFTD[iCode][iHit]; + bool consider = true; + TrackerHitExtendedVec& hitVector = trackAR->getTrackerHitExtendedVec(); + int NHITS = int(hitVector.size()); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + for (int IHIT=0;IHIT<NHITS;++IHIT) { + // if (hit->getTrackerHit()->getType() == hitVector[IHIT]->getTrackerHit()->getType()) { + if (hit->getTrackerHit()->getCellID() == hitVector[IHIT]->getTrackerHit()->getCellID()) { + consider = false; + break; + } + } + + + if (consider) { + float pos[3]; + for (int i=0;i<3;++i) { + pos[i] = hit->getTrackerHit()->getPosition()[i]; + } + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + } + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack(trackAR,attachedHit, iopt); + } + } + } +} + +void SiliconTrackingAlg::TrackingInFTD() { + + int nComb = int(_CombinationsFTD.size()) / 3; + + for (int iComb=0;iComb<nComb;++iComb) { + + int nLS[3]; + nLS[0] = _CombinationsFTD[3*iComb]; + nLS[1] = _CombinationsFTD[3*iComb+1]; + nLS[2] = _CombinationsFTD[3*iComb+2]; + + for (int iS=0;iS<2;++iS) { // loop over +z and -z + + // std::cout << "Combinations : " << iS << " " << nLS[0] << " " << nLS[1] << " " << nLS[2] << endmsg; + // int iC = iS + 2*nLS[0]; + // TrackerHitExtendedVec& hitVec = _sectorsFTD[iC]; + // int nO = int(hitVec.size()); + // iC = iS + 2*nLS[1]; + // hitVec = _sectorsFTD[iC]; + // int nM = int(hitVec.size()); + // iC = iS + 2*nLS[2]; + // hitVec = _sectorsFTD[iC]; + // int nI = int(hitVec.size()); + // std::cout << nO << " " << nM << " " << nI << endmsg; + + for (int ipOuter=0;ipOuter<_nPhiFTD;++ipOuter) { + + int ipMiddleLow = ipOuter - 1; + int ipMiddleUp = ipOuter + 1; + + unsigned int iCodeOuter = iS + 2*nLS[0] + 2*_nlayersFTD*ipOuter; + + if( iCodeOuter >= _sectorsFTD.size()){ + error() << "iCodeOuter index out of range: iCodeOuter = " << iCodeOuter << " _sectorsFTD.size() = " << _sectorsFTD.size() << " exit(1) called from file " << __FILE__ << " line " << __LINE__<< endmsg; + exit(1); + } + + TrackerHitExtendedVec& hitVecOuter = _sectorsFTD[iCodeOuter]; + + int nOuter = int(hitVecOuter.size()); + + for (int iOuter=0;iOuter<nOuter;++iOuter) { + + TrackerHitExtended * hitOuter = hitVecOuter[iOuter]; + + for (int ipMiddle=ipMiddleLow;ipMiddle<=ipMiddleUp;++ipMiddle) { + //for(int ipMiddle=0;ipMiddle<_nPhiFTD;++ipMiddle) { + int ipM = ipMiddle; + if (ipM < 0) + ipM = ipMiddle + _nPhiFTD; + if (ipM >= _nPhiFTD) + ipM = ipMiddle - _nPhiFTD; + int iCodeMiddle = iS + 2*nLS[1] + 2*_nlayersFTD*ipM; + + TrackerHitExtendedVec& hitVecMiddle = _sectorsFTD[iCodeMiddle]; + int ipInnerLow,ipInnerUp; + ipInnerLow = ipMiddle - 1; + ipInnerUp = ipMiddle + 1; + + int nMiddle = int(hitVecMiddle.size()); + + for (int iMiddle=0;iMiddle<nMiddle;++iMiddle) { + TrackerHitExtended * hitMiddle = hitVecMiddle[iMiddle]; + for (int ipInner=ipInnerLow;ipInner<=ipInnerUp;++ipInner) { + //for (int ipInner=0;ipInner<_nPhiFTD;++ipInner) { + int ipI = ipInner; + if (ipI < 0) + ipI = ipInner + _nPhiFTD; + if (ipI >= _nPhiFTD) + ipI = ipInner - _nPhiFTD; + int iCodeInner = iS + 2*nLS[2] + 2*_nlayersFTD*ipI; + TrackerHitExtendedVec& hitVecInner = _sectorsFTD[iCodeInner]; + + int nInner = int(hitVecInner.size()); + + for (int iInner=0;iInner<nInner;++iInner) { + + TrackerHitExtended * hitInner = hitVecInner[iInner]; + HelixClass helix; + // std::cout << endmsg; + // std::cout << "Outer Hit Type " << hitOuter->getTrackerHit()->getType() << " z = " << hitOuter->getTrackerHit()->getPosition()[2] + // << "\nMiddle Hit Type "<< hitMiddle->getTrackerHit()->getType() << " z = " << hitMiddle->getTrackerHit()->getPosition()[2] + // << "\nInner Hit Type "<< hitInner->getTrackerHit()->getType() << " z = " << hitInner->getTrackerHit()->getPosition()[2] << endmsg; + + debug() << " " + << std::setw(3) << ipOuter << " " << std::setw(3) << ipMiddle << " " << std::setw(3) << ipInner << " " + << std::setw(3) << iS << " " + << std::setw(3) << nLS[0] << " " << std::setw(3) << nLS[1] << " " << std::setw(3) << nLS[2] << " " + << std::setw(3) << nOuter << " : " << std::setw(3) << nMiddle << " : " << std::setw(3) << nInner << " :: " + << std::setw(3) << nOuter*nMiddle* nInner << endmsg; + + + TrackExtended * trackAR = TestTriplet(hitOuter,hitMiddle,hitInner,helix); + if (trackAR != NULL) { + // std::cout << "FTD triplet found" << endmsg; + int nHits = BuildTrackFTD(trackAR,nLS,iS); + + _tracksWithNHitsContainer.getTracksWithNHitsVec( nHits ).push_back( trackAR ); + } + } + } + } + } + } + } + } + } +} + + +int SiliconTrackingAlg::BuildTrackFTD(TrackExtended * trackAR, int * nLR, int iS) { + // std::cout << "BuildTrackFTD: Layers = " << nLR[0] << " " << nLR[1] << " " << nLR[2] << endmsg; + + // initialise a helix from the track + HelixClass helix; + const float d0 = trackAR->getD0(); + const float z0 = trackAR->getZ0(); + const float phi0 = trackAR->getPhi(); + const float tanlambda = trackAR->getTanLambda(); + const float omega = trackAR->getOmega(); + helix.Initialize_Canonical(phi0,d0,z0,omega,tanlambda,_bField); + float ref[3] = {helix.getReferencePoint()[0], + helix.getReferencePoint()[1], + helix.getReferencePoint()[2]}; + + for (int iL=0; iL < static_cast<int>(_nlayersFTD); ++iL) { + if (iL != nLR[0] && iL != nLR[1] && iL != nLR[2]) { + float point[3]; + float ZL = _zLayerFTD[iL]; + if (iS == 0) + ZL = - ZL; + helix.getPointInZ(ZL,ref,point); + // float Phi = atan2(point[1],point[0]); + // int iPhi = int(Phi/_dPhiFTD); + float distMin = 1e+6; + TrackerHitExtended * attachedHit = NULL; + for (int ip=0;ip<=_nPhiFTD;++ip) { + int iP = ip; + if (iP < 0) + iP = ip + _nPhiFTD; + if (iP >= _nPhiFTD) + iP = ip - _nPhiFTD; + int iCode = iS + 2*iL + 2*_nlayersFTD*iP; + TrackerHitExtendedVec& hitVec = _sectorsFTD[iCode]; + int nH = int(hitVec.size()); + for (int iH=0; iH<nH; ++iH) { + TrackerHitExtended * hit = hitVec[iH]; + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + float pos[3]; + for (int i=0;i<3;++i) + pos[i] = float(trkHit->getPosition()[i]); + float distance[3]; + float time = helix.getDistanceToPoint(pos,distance); + if (time < 1.0e+10) { + if (distance[2] < distMin) { + distMin = distance[2]; + attachedHit = hit; + } + } + } + } + // std::cout << "Layer = " << iL << " distMin = " << distMin << endmsg; + if (distMin < _minDistCutAttach && attachedHit != NULL) { + int iopt = 2; + AttachHitToTrack( trackAR, attachedHit, iopt); + } + } + } + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nH = int (hitVec.size()); + return nH; +} + +int SiliconTrackingAlg::AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt) { + + int attached = 0; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + int nHits = int(hitVec.size()); + + double * xh = new double[nHits+1]; + double * yh = new double[nHits+1]; + float * zh = new float[nHits+1]; + double * wrh = new double[nHits+1]; + float * wzh = new float[nHits+1]; + float * rh = new float[nHits+1]; + float * ph = new float[nHits+1]; + float par[5]; + float epar[15]; + + for (int i=0; i<nHits; ++i) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + xh[i] = double(trkHit->getPosition()[0]); + yh[i] = double(trkHit->getPosition()[1]); + zh[i] = float(trkHit->getPosition()[2]); + ph[i] = float(atan2(yh[i],xh[i])); + rh[i] = float(sqrt(xh[i]*xh[i]+yh[i]*yh[i])); + float rR = hitVec[i]->getResolutionRPhi(); + float rZ = hitVec[i]->getResolutionZ(); + wrh[i] = double(1.0/(rR*rR)); + wzh[i] = 1.0/(rZ*rZ); + } + + edm4hep::TrackerHit * trkHit = hit->getTrackerHit(); + xh[nHits] = double(trkHit->getPosition()[0]); + yh[nHits] = double(trkHit->getPosition()[1]); + zh[nHits] = float(trkHit->getPosition()[2]); + ph[nHits] = float(atan2(yh[nHits],xh[nHits])); + rh[nHits] = float(sqrt(xh[nHits]*xh[nHits]+yh[nHits]*yh[nHits])); + + float rR = hit->getResolutionRPhi(); + float rZ = hit->getResolutionZ(); + wrh[nHits] = double(1.0/(rR*rR)); + wzh[nHits] = 1.0/(rZ*rZ); + + + int NPT = nHits + 1; + + // SJA:FIXME the newtonian part is giving crazy results for FTD so just use iopt 2 for simply attaching hits + // using SIT and VXD doesn't seem to give any problems, so make it a function parameter and let the caller decide + // int iopt = 3; + + float chi2RPhi = 0 ; + float chi2Z = 0 ; + + + int error = _fastfitter->fastHelixFit(NPT, xh, yh, rh, ph, wrh, zh, wzh,iopt, par, epar, chi2RPhi, chi2Z); + par[3] = par[3]*par[0]/fabs(par[0]); + + + float omega = par[0]; + float tanlambda = par[1]; + float phi0 = par[2]; + float d0 = par[3]; + float z0 = par[4]; + float chi2 = FLT_MAX; + int ndf = INT_MAX; + + if (NPT == 3) { + chi2 = chi2RPhi*_chi2WRPhiTriplet+chi2Z*_chi2WZTriplet; + } + if (NPT == 4) { + chi2 = chi2RPhi*_chi2WRPhiQuartet+chi2Z*_chi2WZQuartet; + } + if (NPT > 4) { + chi2 = chi2RPhi*_chi2WRPhiSeptet+chi2Z*_chi2WZSeptet; + } + ndf = 2*NPT-5; + + + if ( error == 0 && chi2/float(ndf) < _chi2FitCut ) { + trackAR->addTrackerHitExtended(hit); + hit->addTrackExtended( trackAR ); + trackAR->setChi2( chi2 ); + trackAR->setOmega( omega ); + trackAR->setTanLambda( tanlambda ); + trackAR->setD0( d0 ); + trackAR->setZ0( z0 ); + trackAR->setPhi( phi0 ); + trackAR->setNDF( ndf ); + trackAR->setCovMatrix( epar ); + attached = 1; + debug() << "Attachement succeeded chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } else { + debug() << "Attachement failed chi2/float(ndf) = " << chi2/float(ndf) << " cut = " << _chi2FitCut << " chi2RPhi = " << chi2RPhi << " chi2Z = " << chi2Z << " error = " << error << endmsg; + } + + delete[] xh; + delete[] yh; + delete[] zh; + delete[] wrh; + delete[] wzh; + delete[] rh; + delete[] ph; + + return attached; + + +} + +void SiliconTrackingAlg::FinalRefit(edm4hep::TrackCollection* trk_col) { + + int nTracks = int(_trackImplVec.size()); + + int nSiSegments = 0; + float eTot = 0.; + float pxTot = 0.; + float pyTot = 0.; + float pzTot = 0.; + std::cout << "fucd============" << nTracks << std::endl; + for (int iTrk=0;iTrk<nTracks;++iTrk) { + + TrackExtended * trackAR = _trackImplVec[iTrk]; + TrackerHitExtendedVec& hitVec = trackAR->getTrackerHitExtendedVec(); + + int nHits = int(hitVec.size()); + std::cout << "fucd-------------" << iTrk << ": " << nHits << std::endl; + if( nHits >= _minimalHits) { + // int * lh = new int[nHits]; + std::vector<int> lh; + lh.resize(nHits); + + for (int i=0; i<nHits; ++i) { + lh[i]=0; + } + + float d0 = trackAR->getD0(); + float z0 = trackAR->getZ0(); + float omega = trackAR->getOmega(); + float tanlambda = trackAR->getTanLambda(); + float phi0 = trackAR->getPhi(); + + HelixClass * helix = new HelixClass(); + helix->Initialize_Canonical(phi0, d0, z0, omega, + tanlambda, _bField); + + + // get the point of closest approach to the reference point + // here it is implicitly assumed that the reference point is the origin + float Pos[3]; + Pos[0] = -d0*sin(phi0); + Pos[1] = d0*cos(phi0); + Pos[2] = z0; + + std::cout << "fucd------------------1" << std::endl; + // at this point is is possible to have hits from the same layer ... + // so a check is made to ensure that the hit with the smallest distance to the + // current helix hypothosis is used, the other hit has lh set to 0 + + // start loop over the hits to + for (int ihit=0;ihit<nHits;++ihit) { + + lh[ihit] = 1; // only hits which have lh=1 will be used for the fit + + // get the pointer to the lcio trackerhit for this hit + edm4hep::TrackerHit * trkHit = hitVec[ihit]->getTrackerHit(); + + int det = getDetectorID(trkHit); + + if (det == lcio::ILDDetID::VXD || det == lcio::ILDDetID::FTD || det == lcio::ILDDetID::SIT) { // only accept VXD, FTD or SIT + + + // int layer = getLayerID(trkHit); + // int moduleIndex = getModuleID(trkHit); + + // start a double loop over the hits which have already been checked + for (int lhit=0;lhit<ihit;++lhit) { + + // get the pointer to the lcio trackerhit for the previously checked hit + edm4hep::TrackerHit * trkHitS = hitVec[lhit]->getTrackerHit(); + + + // int layerS = getLayerID(trkHitS); + // int moduleIndexS = getModuleID(trkHitS); + + // SJA:FIXME: check to see if allowing no hits in the same sensor vs no hits in the same layer works + // if they are on the same layer and the previously checked hits has been declared good for fitting + // if ((trkHitS->getType() == trkHit->getType()) && (lh[lhit] == 1)) { + // check if the hits have the same layer and petal number + // hitVec[ihit]-> + // if ((layer == layerS) && (moduleIndex==moduleIndexS) && (lh[lhit] == 1)) { + if ( (trkHit->getCellID() == trkHitS->getCellID()) && (lh[lhit] == 1)) { + + // get the position of the hits + float xP[3]; + float xPS[3]; + for (int iC=0;iC<3;++iC) { + xP[iC] = float(trkHit->getPosition()[iC]); + xPS[iC] = float(trkHitS->getPosition()[iC]); + } + + // get the intersection of the helix with the either the cylinder or plane containing the hit + float Point[6]; + float PointS[6]; + + if (det == lcio::ILDDetID::FTD) { + + float time = helix->getPointInZ(xP[2],Pos,Point); + time = helix->getPointInZ(xPS[2],Pos,PointS); + + } else { + + float RAD = sqrt(xP[0]*xP[0]+xP[1]*xP[1]); + float RADS = sqrt(xPS[0]*xPS[0]+xPS[1]*xPS[1]); + float time = helix->getPointOnCircle(RAD,Pos,Point); + time = helix->getPointOnCircle(RADS,Pos,PointS); + + } + + float DIST = 0; + float DISTS = 0; + + // get the euclidean distance between the hit and the point of intersection + for (int iC=0;iC<3;++iC) { + DIST += (Point[iC]-xP[iC])*(Point[iC]-xP[iC]); + DISTS += (PointS[iC]-xPS[iC])*(PointS[iC]-xPS[iC]); + } + if (DIST < DISTS) { + lh[lhit] = 0; + } + else { + lh[ihit] = 0; + } + break; + } + } + } + } + + delete helix; + + std::vector<TrackerHit*> trkHits; + std::vector<TrackerHit*> trkHits_used_inFit; + + int nFit = 0; + for (int i=0; i<nHits; ++i) { + // check if the hit has been rejected as being on the same layer and further from the helix lh==0 + if (lh[i] == 1) { + edm4hep::TrackerHit * trkHit = hitVec[i]->getTrackerHit(); + nFit++; + if(trkHit) { + trkHits.push_back(trkHit); + } + else{ + throw EVENT::Exception( std::string("SiliconTrackingAlg::FinalRefit: TrackerHit pointer == NULL ") ) ; + } + } + else { // reject hit + // SJA:FIXME missuse of type find a better way to signal rejected hits + hitVec[i]->setType(int(0)); + } + } + + if( trkHits.size() < 3 ) { + debug() << "SiliconTrackingAlg::FinalRefit: Cannot fit less than 3 hits. Number of hits = " << trkHits.size() << endmsg; + continue ; + } + std::cout << "fucd------------------2" << std::endl; + //TrackImpl* Track = new TrackImpl ; + auto track = trk_col->create(); + //fucd + //edm4hep::Track track;// = new edm4hep::Track; + std::cout << "fucd------------------3" << std::endl; + // setup initial dummy covariance matrix + //std::vector<float> covMatrix; + //covMatrix.resize(15); + std::array<float,15> covMatrix; + + for (unsigned icov = 0; icov<covMatrix.size(); ++icov) { + covMatrix[icov] = 0; + } + + covMatrix[0] = ( _initialTrackError_d0 ); //sigma_d0^2 + covMatrix[2] = ( _initialTrackError_phi0 ); //sigma_phi0^2 + covMatrix[5] = ( _initialTrackError_omega ); //sigma_omega^2 + covMatrix[9] = ( _initialTrackError_z0 ); //sigma_z0^2 + covMatrix[14] = ( _initialTrackError_tanL ); //sigma_tanl^2 + + + std::vector< std::pair<float, edm4hep::TrackerHit*> > r2_values; + r2_values.reserve(trkHits.size()); + + for (std::vector<edm4hep::TrackerHit*>::iterator it=trkHits.begin(); it!=trkHits.end(); ++it) { + edm4hep::TrackerHit* h = *it; + float r2 = h->getPosition()[0]*h->getPosition()[0]+h->getPosition()[1]*h->getPosition()[1]; + r2_values.push_back(std::make_pair(r2, *it)); + } + + sort(r2_values.begin(),r2_values.end()); + //std::cout << "fucd------------------3" << std::endl; + trkHits.clear(); + trkHits.reserve(r2_values.size()); + + for (std::vector< std::pair<float, edm4hep::TrackerHit*> >::iterator it=r2_values.begin(); it!=r2_values.end(); ++it) { + trkHits.push_back(it->second); + } + //std::cout << "fucd------------------3 " << _trksystem << std::endl; + //for (unsigned ihit_indx=0 ; ihit_indx < trkHits.size(); ++ihit_indx) { + // std::cout << "fucd trk hit " << *trkHits[ihit_indx] << " " << trkHits[ihit_indx]->getCovMatrix()[0] + // << " " << BitSet32(trkHits[ihit_indx]->getType())[ ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] << endmsg; + //} + /* + auto _trackSystemSvc = service<ITrackSystemSvc>("TrackSystemSvc"); + if ( !_trackSystemSvc ) { + error() << "Failed to find TrackSystemSvc ..." << endmsg; + return; + } + _trksystem = _trackSystemSvc->getTrackSystem(); + + if( _trksystem == 0 ){ + error() << "Cannot initialize MarlinTrkSystem of Type: KalTest" <<endmsg; + return; + } + debug() << "_trksystem pointer " << _trksystem << endmsg; + + _trksystem->setOption( IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; + _trksystem->setOption( IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; + _trksystem->init() ; + */ + bool fit_backwards = IMarlinTrack::backward; + + MarlinTrk::IMarlinTrack* marlinTrk = nullptr; + try{ + marlinTrk = _trksystem->createTrack(); + } + catch(...){ + error() << "Cannot create MarlinTrack ! " << endmsg; + return; + } + + int status = 0; + std::cout << "fucd------------------3" << std::endl; + try { + status = MarlinTrk::createFinalisedLCIOTrack(marlinTrk, trkHits, &track, fit_backwards, covMatrix, _bField, _maxChi2PerHit); + } catch (...) { + + // delete Track; + // delete marlinTrk; + error() << "MarlinTrk::createFinalisedLCIOTrack " << endmsg; + throw ; + + } + std::cout << "fucd------------------4" << std::endl; + /* +#ifdef MARLINTRK_DIAGNOSTICS_ON + if ( status != IMarlinTrack::success && _runMarlinTrkDiagnostics ) { + void * dcv = _trksystem->getDiagnositicsPointer(); + DiagnosticsController* dc = static_cast<DiagnosticsController*>(dcv); + dc->skip_current_track(); + } +#endif + */ + + std::vector<std::pair<edm4hep::TrackerHit* , double> > hits_in_fit ; + std::vector<std::pair<edm4hep::TrackerHit* , double> > outliers ; + std::vector<edm4hep::TrackerHit*> all_hits; + all_hits.reserve(300); + + marlinTrk->getHitsInFit(hits_in_fit); + + for ( unsigned ihit = 0; ihit < hits_in_fit.size(); ++ihit) { + all_hits.push_back(hits_in_fit[ihit].first); + } + + UTIL::BitField64 cellID_encoder( lcio::ILDCellID0::encoder_string ) ; + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, true, cellID_encoder); + + marlinTrk->getOutliers(outliers); + + for ( unsigned ihit = 0; ihit < outliers.size(); ++ihit) { + all_hits.push_back(outliers[ihit].first); + } + + MarlinTrk::addHitNumbersToTrack(&track, all_hits, false, cellID_encoder); + + delete marlinTrk; + + int nhits_in_vxd = track.getSubDetectorHitNumbers(0); + int nhits_in_ftd = track.getSubDetectorHitNumbers(1); + int nhits_in_sit = track.getSubDetectorHitNumbers(2); + + //debug() << " Hit numbers for Track "<< track->id() << ": " + debug() << " Hit numbers for Track "<< iTrk <<": " + << " vxd hits = " << nhits_in_vxd + << " ftd hits = " << nhits_in_ftd + << " sit hits = " << nhits_in_sit + << endmsg; + + //if (nhits_in_vxd > 0) Track->setTypeBit( lcio::ILDDetID::VXD ) ; + //if (nhits_in_ftd > 0) Track->setTypeBit( lcio::ILDDetID::FTD ) ; + //if (nhits_in_sit > 0) Track->setTypeBit( lcio::ILDDetID::SIT ) ; + + + + if( status != IMarlinTrack::success ) { + + //delete track; + debug() << "SiliconTrackingAlg::FinalRefit: Track fit failed with error code " << status << " track dropped. Number of hits = "<< trkHits.size() << endmsg; + continue ; + } + + if( track.getNdf() < 0) { + //delete track; + debug() << "SiliconTrackingAlg::FinalRefit: Track fit returns " << track.getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + //delete track; + continue ; + } + + //trk_col->addElement(Track); + //fucd + //trk_col->push_back(track); + for(int i=0;i<track.trackStates_size();i++){ + // 1 = lcio::EVENT::TrackState::AtIP + edm4hep::TrackState trkStateIP = track.getTrackStates(i); + if(trkStateIP.location !=1) continue; + /* + if (trkStateIP == 0) { + debug() << "SiliconTrackingAlg::FinalRefit: Track fit returns " << track->getNdf() << " degress of freedom track dropped. Number of hits = "<< trkHits.size() << endmsg; + throw EVENT::Exception( std::string("SiliconTrackingAlg::FinalRefit: trkStateIP pointer == NULL ") ) ; + } + */ + // note trackAR which is of type TrackExtended, only takes fits set for ref point = 0,0,0 + trackAR->setOmega(trkStateIP.omega); + trackAR->setTanLambda(trkStateIP.tanLambda); + trackAR->setPhi(trkStateIP.phi); + trackAR->setD0(trkStateIP.D0); + trackAR->setZ0(trkStateIP.Z0); + + float cov[15]; + + for (int i = 0 ; i<15 ; ++i) { + cov[i] = trkStateIP.covMatrix.operator[](i); + } + + trackAR->setCovMatrix(cov); + trackAR->setChi2(track.getChi2()); + trackAR->setNDF(track.getNdf()); + + nSiSegments++; + + HelixClass helix_final; + + helix_final.Initialize_Canonical(trkStateIP.phi,trkStateIP.D0,trkStateIP.Z0,trkStateIP.omega,trkStateIP.tanLambda,_bField); + + float trkPx = helix_final.getMomentum()[0]; + float trkPy = helix_final.getMomentum()[1]; + float trkPz = helix_final.getMomentum()[2]; + float trkP = sqrt(trkPx*trkPx+trkPy*trkPy+trkPz*trkPz); + eTot += trkP; + pxTot += trkPx; + pyTot += trkPy; + pzTot += trkPz; + } + } + } + + debug() << "SiliconTrackingAlg -> run " << _nRun + << " event " << _nEvt << endmsg; + debug() << "Number of Si tracks = " << nSiSegments << endmsg; + debug() << "Total 4-momentum of Si Tracks : E = " << std::setprecision(7) << eTot + << " Px = " << pxTot + << " Py = " << pyTot + << " Pz = " << pzTot << endmsg; + + +} + + +StatusCode SiliconTrackingAlg::setupGearGeom(){ + auto _gear = service<IGearSvc>("GearSvc"); + if ( !_gear ) { + error() << "Failed to find GearSvc ..." << endmsg; + return StatusCode::FAILURE; + } + gear::GearMgr* gearMgr = _gear->getGearMgr(); + _bField = gearMgr->getBField().at( gear::Vector3D( 0.,0.,0.) ).z() ; + debug() << "Field " << _bField << endmsg; + //-- VXD Parameters-- + _nLayersVTX = 0 ; + const gear::VXDParameters* pVXDDetMain = 0; + const gear::VXDLayerLayout* pVXDLayerLayout = 0; + + try{ + + debug() << " filling VXD parameters from gear::SITParameters " << endmsg ; + + pVXDDetMain = &gearMgr->getVXDParameters(); + pVXDLayerLayout = &(pVXDDetMain->getVXDLayerLayout()); + _nLayersVTX = pVXDLayerLayout->getNLayers(); + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::VXDParameters Not Present in GEAR FILE" << endmsg ; + + } + + + + //-- SIT Parameters-- + _nLayersSIT = 0 ; + const gear::ZPlanarParameters* pSITDetMain = 0; + const gear::ZPlanarLayerLayout* pSITLayerLayout = 0; + + try{ + + debug() << " filling SIT parameters from gear::SITParameters " << endmsg ; + + pSITDetMain = &gearMgr->getSITParameters(); + pSITLayerLayout = &(pSITDetMain->getZPlanarLayerLayout()); + _nLayersSIT = pSITLayerLayout->getNLayers(); + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SITParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nLayersSIT == 0 ){ + // try the old LOI style key value pairs as defined in the SSit03 Mokka drive + try{ + + info() << " SiliconTrackingAlg - Simple Cylinder Based SIT using parameters defined by SSit03 Mokka driver " << endmsg ; + + // SIT + + const gear::GearParameters& pSIT = gearMgr->getGearParameters("SIT"); + + const std::vector<double>& SIT_r = pSIT.getDoubleVals("SITLayerRadius" ) ; + const std::vector<double>& SIT_hl = pSIT.getDoubleVals("SITSupportLayerHalfLength" ) ; + + _nLayersSIT = SIT_r.size() ; + + if (_nLayersSIT != SIT_r.size() || _nLayersSIT != SIT_hl.size()) { + + error() << "ILDSITCylinderKalDetector miss-match between DoubleVec and nlayers exit(1) called from file " << __FILE__ << " line " << __LINE__ << endmsg ; + exit(1); + + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::SIT Parameters from as defined in SSit03 Not Present in GEAR FILE" << endmsg ; + + } + + } + + + + //-- FTD Parameters-- + _petalBasedFTDWithOverlaps = false; + _nlayersFTD = 0; + + try{ + + debug() << " filling FTD parameters from gear::FTDParameters " << endmsg ; + + const gear::FTDParameters& pFTD = gearMgr->getFTDParameters(); + const gear::FTDLayerLayout& ftdlayers = pFTD.getFTDLayerLayout() ; + + _nlayersFTD = ftdlayers.getNLayers() ; + + for (unsigned int disk=0; disk < _nlayersFTD; ++disk) { + + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 0, 1) ); // front petal even numbered + + if ( ftdlayers.getNPetals(disk) > 0) { + _zLayerFTD.push_back( ftdlayers.getSensitiveZposition(disk, 1, 1) ); // front petal odd numbered + _petalBasedFTDWithOverlaps = true; + } + + } + + // SJA: Here we increase the size of _nlayersFTD as we are treating the + _nlayersFTD =_zLayerFTD.size() ; + + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTDParameters Not Present in GEAR FILE" << endmsg ; + + } + + if( _nlayersFTD == 0 ){ + + // FTD + try{ + + info() << " SiliconTrackingAlg - Simple Disc Based FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + const gear::GearParameters& pFTD = gearMgr->getGearParameters("FTD"); + + const std::vector<double>* pFTD_z = NULL; + + info() << " For FTD using parameters defined by SFtd05 Mokka driver " << endmsg ; + + pFTD_z = &pFTD.getDoubleVals("FTDZCoordinate" ) ; + + _nlayersFTD = pFTD_z->size(); + + for (unsigned int i = 0; i<_nlayersFTD; ++i) { + _zLayerFTD.push_back((*pFTD_z)[i]); + } + } + catch( gear::UnknownParameterException& e){ + + debug() << " ### gear::FTD Parameters as defined in SFtd05 Not Present in GEAR FILE" << endmsg ; + + } + } + return StatusCode::SUCCESS; +} + +void SiliconTrackingAlg::TracksWithNHitsContainer::clear() +{ + for (std::vector< TrackExtendedVec >::iterator trackVecIter = _tracksNHits.begin(); + trackVecIter < _tracksNHits.end(); trackVecIter++) + { + for (TrackExtendedVec::iterator trackIter = trackVecIter->begin(); + trackIter < trackVecIter->end(); trackIter++) + { + delete *trackIter; + } + + trackVecIter->clear(); + } +} + diff --git a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..e5cfca0cb76ded4a59ce14347794834427b5277f --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h @@ -0,0 +1,429 @@ +#ifndef SiliconTrackingAlg_h +#define SiliconTrackingAlg_h + +//#include "marlin/Processor.h" +//#include <marlin/Global.h> +#include "FWCore/DataHandle.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/TrackCollection.h" +//#include "edm4hep/LCRelationCollection.h" + +//#include "lcio.h" +#include <string> +#include <vector> +#include <cmath> +//#include <IMPL/TrackImpl.h> +#include "DataHelper/ClusterExtended.h" +#include "DataHelper/TrackExtended.h" +#include "DataHelper/TrackerHitExtended.h" +#include "DataHelper/HelixClass.h" + +#include "TrackSystemSvc/IMarlinTrack.h" + +#include <UTIL/BitField64.h> +#include <UTIL/ILDConf.h> + +//using namespace edm4hep ; + +namespace gear{ + class GearMgr ; +} + +namespace MarlinTrk { + class HelixFit; + class IMarlinTrkSystem ; +} + +namespace UTIL{ + class LCRelationNavigator ; +} + +class TrackExtended; +class TrackerHitExtended; +class HelixClass; + +/** === Silicon Tracking Processor === <br> + * Processor performing stand-alone pattern recognition + * in the vertex detector (VTX), forward tracking disks and SIT. <br> + * The procedure consists of three steps : <br> + * 1) Tracking in VTX and SIT ; <br> + * 2) Tracking in FTD ; <br> + * 3) Merging compatible track segments reconstructed in VTX and FTD <br> + * STEP 1 : TRACKING IN VTX and SIT <br> + * Algorithm starts with finding of hit triplets satisfying helix hypothesis <br> + * in three different layers. Two layers of SIT are effectively considered as outermost <br> + * layers of the vertex detector. To accelerate procedure, the 4-pi solid angle + * is divided in NDivisionsInTheta and NDivisionsInPhi sectors in cosQ and Phi, + * respectively. Triplets are looked for in 2x2 window of adjacent sectors. + * Once triplet is found, attempt is made to associate additional hits to + * track. Combinatin of hits is accepted for further analysis if the Chi2 + * of the fit is less than certain predefined threshold. All accepted + * combinations are sorted in ascending order of their Chi2. First track candidate + * in the sorted array is automatically accepted. The hits belonging to this track are + * marked as used, and track candidates sharing these hits are discarded. + * The procedure proceeds with increasing index of track candidate in the sorted + * array until all track candidate have been output or discarded. <br> + * STEP 2 : TRACKING IN FTD <br> + * In the next step tracking in FTD is performed. The strategy of tracking in the FTD + * is the same as used for tracking in the VTX+SIT. <br> + * STEP 3 : MERGING TRACK SEGMENTS FOUND IN FTD AND VTX+SIT <br> + * In the last step, track segments reconstructed in the FTD and VTX+SIT, belonging to the + * same track are identified and merged into one track. All possible + * pairings are tested for their compatibility. + * The number of pairings considered is Ntrk_VTX_SIT*Ntrk_FTD, where Ntrk_VTX_SIT is the number of + * track segments reconstructed in the first step in VTX+SIT (segments containing solely VTX and SIT hits) and + * Ntrk_FTD is the number of track segments reconstructed in the second step + * (segments containing solely FTD hits). + * Pair of segments is accepted for further examination if the angle between track segments and + * than certain specified threshold. + * Pairing satisfying this condition is subjected for + * addtitional test. The fit is performed on unified array of hits belonging to both segments. + * If the chi2 of the fit does not exceed predefined cut value two segments are unified into + * one track. + * <h4>Input collections and prerequisites</h4> + * Processor requires collection of digitized vertex, sit and ftd tracker hits. <br> + * If such a collections with the user specified names do not exist + * processor takes no action. <br> + * <h4>Output</h4> + * Processor produces an LCIO collection of the Tracks. Each track is characterised by + * five parameters : Omega (signed curvuture), Tan(lambda) where + * lambda is the dip angle, Phi (azimuthal angle @ point of closest approach), D0 (signed impact parameter), + * Z0 (displacement along z axis at the point of closest approach to IP). Covariance matrix for these parameters is also provided. + * Only lower left corner of the covariance matrix is stored. The sequence of the covariance matrix elements + * assigned to track is the following: <br> + * (Omega,Omega) <br> + * (Omega,TanLambda), (TanLambda,TanLambda) <br> + * (Omega,Phi), (TanLamda,Phi), (Phi,Phi) <br> + * (Omega,D0), (TanLambda,D0), (Phi,D0), (D0,D0) <br> + * (Omega,Z0), (TanLambda,Z0), (Phi,Z0), (D0,Z0), (Z0,Z0) <br> + * The number of hits in the different subdetectors associated + * with each track can be accessed via method Track::getSubdetectorHitNumbers(). + * This method returns vector of integers : <br> + * number of VTX hits in track is the first element in this vector + * (Track::getSubdetectorHitNumbers()[0]) <br> + * number of FTD hits in track is the second element in this vector + * (Track::getSubdetectorHitNumbers()[1]) <br> + * number of SIT hits in track is the third element in this vector + * (Track::getSubdetectorHitNumbers()[2]) <br> + * Output track collection has a name "SiTracks". <br> + * @param VTXHitCollectionName name of input VTX TrackerHit collection <br> + * (default parameter value : "VTXTrackerHits") <br> + * @param FTDHitCollectionName name of input FTD TrackerHit collection <br> + * (default parameter value : "FTDTrackerHits") <br> + * @param SITHitCollectionName name of input SIT TrackerHit collection <br> + * (default parameter value : "SITTrackerHits") <br> + * @param SiTrackCollectionName name of the output Silicon track collection <br> + * (default parameter value : "SiTracks") <br> + * @param LayerCombinations combinations of layers used to search for hit triplets in VTX+SIT <br> + * (default parameters : 6 4 3 6 4 2 6 3 2 5 4 3 5 4 2 5 3 2 4 3 2 4 3 1 4 2 1 3 2 1) <br> + * Note that in the VTX+SIT system the first and the second layers of SIT have indicies nLayerVTX and nLayerVTX+1. + * Combination given above means that triplets are looked first in layers 6 4 3, and then + * in 6 4 2; 5 4 3; 6 3 2 etc. NOTE THAT LAYER INDEXING STARTS FROM 0. + * LAYER 0 is the innermost layer <br> + * @param LayerCombinationsFTD combinations of layers used to search for hit triplets in FTD <br> + * (default parameters 6 5 4 5 4 3 5 4 2 5 4 1 5 3 2 5 3 1 5 2 1 4 3 2 4 3 1 + * 4 3 0 4 2 1 4 2 0 4 1 0 3 2 1 3 2 0 3 1 0 2 1 0). + * NOTE THAT TRACKS IN FTD ARE SEARCHED ONLY IN ONE HEMISPHERE. TRACK IS NOT + * ALLOWED TO HAVE HITS BOTH IN BACKWARD AND FORWARD PARTS OF FTD SIMULTANEOUSLY. + * @param NDivisionsInPhi Number of divisions in Phi for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInTheta Number of divisions in cosQ for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInPhiFTD Number of divisions in Phi for tracking in FTD <br> + * (default value is 3) <br> + * @param Chi2WRphiTriplet weight on chi2 in R-Phi plane for track with 3 hits <br> + * (default value is 1) <br> + * @param Chi2WZTriplet weight on chi2 in S-Z plane for track with 3 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiQuartet weight on chi2 in R-Phi plane to accept track with 4 hits <br> + * (default value is 1) <br> + * @param Chi2WZQuartet weight on chi2 in S-Z plane for track with 4 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiSeptet weight on chi2 in R-Phi plane for track with 5 and more hits <br> + * (default value is 1) <br> + * @param Chi2WZSeptet Cut on chi2 in S-Z plane for track with 5 and more hits <br> + * (default value is 0.5) <br> + * @param Chi2FitCut Cut on chi2/ndf to accept track candidate <br> + * (default value is 100.) <br> + * @param AngleCutForMerging cut on the angle between two track segments. + * If the angle is greater than this cut, segments are not allowed to be merged. <br> + * (default value is 0.1) <br> + * @param MinDistCutAttach cut on the distance (in mm) from hit to the helix. This parameter is used + * to decide whether hit can be attached to the track. If the distance is less than + * cut value. The track is refitted with a given hit being added to the list of hits already + * assigned for the track. Additional hit is assigned if chi2 of the new fit has good chi2. <br> + * (default value is 2 ) <br> + * @param MinLayerToAttach the minimal layer index to attach VTX hits to the found hit triplets <br> + * (default value is -1) <br> + * @param CutOnZ0 cut on Z0 parameter of track (in mm). If abs(Z0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnD0 cut on D0 parameter of track (in mm). If abs(D0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnPt cut on Pt (GeV/c). If Pt is less than this cut, track is discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 0.1) <br> + * @param MinimalHits minimal number of hits in track required <br> + * (default value is 3) <br> + * @param NHitsChi2 Maximal number of hits for which a track with n hits is aways better than one with n-1 hits. + * For tracks with equal or more than NHitsChi2 the track with the lower \f$\chi^2\f$ is better. + * (default value is 5) <br> + * @param FastAttachment if this flag is set to 1, less accurate but fast procedure to merge additional hits to tracks is used <br> + * if set to 0, a more accurate, but slower procedure is invoked <br> + * (default value is 0) <br> + * @param UseSIT When this flag is set to 1, SIT is included in pattern recognition. When this flag is set + * to 0, SIT is excluded from the procedure of pattern recognition <br> + * (default value is 1) <br> + * <br> + * @author A. Raspereza (MPI Munich)<br> + */ +class SiliconTrackingAlg : public GaudiAlgorithm { + public: + + SiliconTrackingAlg(const std::string& name, ISvcLocator* svcLoc); + + virtual StatusCode initialize() ; + + virtual StatusCode execute() ; + + virtual StatusCode finalize() ; + +protected: + + int _nRun ; + int _nEvt ; + //EVENT::LCEvent* _current_event; + int _nLayers; + unsigned int _nLayersVTX; + unsigned int _nLayersSIT; + int _ntriplets, _ntriplets_good, _ntriplets_2MCP, _ntriplets_3MCP, _ntriplets_1MCP_Bad, _ntriplets_bad; + + MarlinTrk::HelixFit* _fastfitter; + gear::GearMgr* _GEAR; + /** pointer to the IMarlinTrkSystem instance + */ + MarlinTrk::IMarlinTrkSystem* _trksystem ; + //bool _runMarlinTrkDiagnostics; + //std::string _MarlinTrkDiagnosticsName; + typedef std::vector<int> IntVec; + + Gaudi::Property<IntVec> _Combinations{this, "LayerCombinations", {8,6,5, 8,6,4, 8,6,3, 8,6,2, 8,5,3, 8,5,2, 8,4,3, 8,4,2, 6,5,3, 6,5,2, 6,4,3, 6,4,2, 6,3,1, 6,3,0, 6,2,1, 6,2,0, + 5,3,1, 5,3,0, 5,2,1, 5,2,0, 4,3,1, 4,3,0, 4,2,1, 4,2,0}}; + Gaudi::Property<IntVec> _CombinationsFTD{this, "LayerCombinationsFTD", {4,3,2, 4,3,1, 4,3,0, 4,2,1, 4,2,0, 4,1,0, 3,2,1, 3,2,0, 3,1,0, 2,1,0, + 9,8,7, 9,8,6, 9,8,5, 9,7,6, 9,7,5, 9,6,5, 8,7,6, 8,7,5, 8,6,5, 7,6,5}}; + Gaudi::Property<int> _nDivisionsInPhi{this, "NDivisionsInPhi", 80}; + Gaudi::Property<int> _nDivisionsInPhiFTD{this, "NDivisionsInPhiFTD", 30}; + Gaudi::Property<int> _nDivisionsInTheta{this, "NDivisionsInTheta", 80}; + Gaudi::Property<float> _chi2WRPhiTriplet{this, "Chi2WRphiTriplet", 1.}; + Gaudi::Property<float> _chi2WRPhiQuartet{this, "Chi2WRphiQuartet", 1.}; + Gaudi::Property<float> _chi2WRPhiSeptet{this, "Chi2WRphiSeptet", 1.}; + Gaudi::Property<float> _chi2WZTriplet{this, "Chi2WZTriplet", 0.5}; + Gaudi::Property<float> _chi2WZQuartet{this, "Chi2WZQuartet", 0.5}; + Gaudi::Property<float> _chi2WZSeptet{this, "Chi2WZSeptet", 0.5}; + Gaudi::Property<float> _chi2FitCut{this, "Chi2FitCut", 120.}; + Gaudi::Property<float> _angleCutForMerging{this, "AngleCutForMerging", 0.1}; + Gaudi::Property<float> _minDistCutAttach{this, "MinDistCutAttach", 2.5}; + Gaudi::Property<float> _minimalLayerToAttach{this, "MinLayerToAttach", -1}; + Gaudi::Property<float> _cutOnD0{this, "CutOnD0", 100.0}; + Gaudi::Property<float> _cutOnZ0{this, "CutOnZ0", 100.0}; + Gaudi::Property<float> _cutOnPt{this, "CutOnPt", 0.05}; + Gaudi::Property<int> _minimalHits{this, "MinimalHits",3}; + Gaudi::Property<int> _nHitsChi2{this, "NHitsChi2", 5}; + Gaudi::Property<int> _max_hits_per_sector{this, "MaxHitsPerSector", 100}; + Gaudi::Property<int> _attachFast{this, "FastAttachment", 0}; + Gaudi::Property<bool> _useSIT{this, "UseSIT", true}; + Gaudi::Property<float> _initialTrackError_d0{this, "InitialTrackErrorD0",1e6}; + Gaudi::Property<float> _initialTrackError_phi0{this, "InitialTrackErrorPhi0",1e2}; + Gaudi::Property<float> _initialTrackError_omega{this, "InitialTrackErrorOmega",1e-4}; + Gaudi::Property<float> _initialTrackError_z0{this, "InitialTrackErrorZ0",1e6}; + Gaudi::Property<float> _initialTrackError_tanL{this, "InitialTrackErrorTanL",1e2}; + Gaudi::Property<float> _maxChi2PerHit{this, "MaxChi2PerHit", 1e2}; + Gaudi::Property<int> _checkForDelta{this, "CheckForDelta", 1}; + Gaudi::Property<float> _minDistToDelta{this, "MinDistToDelta", 0.25}; + Gaudi::Property<bool> _MSOn{this, "MultipleScatteringOn", true}; + Gaudi::Property<bool> _ElossOn{this, "EnergyLossOn", true}; + Gaudi::Property<bool> _SmoothOn{this, "SmoothOn", true}; + Gaudi::Property<float> _helix_max_r{this, "HelixMaxR", 2000.}; + + //std::vector<int> _colours; + + /** helper function to get collection using try catch block */ + //LCCollection* GetCollection( LCEvent * evt, std::string colName ) ; + + /** helper function to get relations using try catch block */ + //LCRelationNavigator* GetRelations( LCEvent * evt, std::string RelName ) ; + + /** input MCParticle collection and threshold used for Drawing + */ + //Gaudi::Property<Float> _MCpThreshold{this, "MCpThreshold", 0.1}; + //std::string _colNameMCParticles; + + /// Compare tracks according to their chi2/ndf + struct compare_TrackExtended{ + // n.b.: a and b should be TrackExtended const *, but the getters are not const :-( + bool operator()(TrackExtended *a, TrackExtended *b) const { + if ( a == b ) return false; + return (a->getChi2()/a->getNDF() < b->getChi2()/b->getNDF() ); + } + }; + + + //std::string _VTXHitCollection; + //std::string _FTDPixelHitCollection; + //std::string _FTDSpacePointCollection; + //std::string _SITHitCollection; + //std::string _siTrkCollection; + + //std::vector< LCCollection* > _colTrackerHits; + //std::map< LCCollection*, std::string > _colNamesTrackerHits; + + // Input collections + DataHandle<edm4hep::EventHeaderCollection> _headerColHdl{"EventHeaderCol", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::MCParticleCollection> _inMCColHdl{"MCParticle", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inVTXColHdl{"VXDCollection", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inFTDPixelColHdl{"FTDPixelCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inVTXColHdl{"VXDTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDPixelColHdl{"FTDPixelTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDSpacePointColHdl{"FTDSpacePoints", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inSITColHdl{"SITTrackerHits", Gaudi::DataHandle::Reader, this}; + // Output collections + DataHandle<edm4hep::TrackCollection> _outColHdl{"SiTracks", Gaudi::DataHandle::Writer, this}; + //DataHandle<edm4hep::LCRelationCollection> _outRelColHdl{"TrackerHitRelations", Gaudi::DataHandle::Reader, this}; + + std::vector<TrackerHitExtendedVec> _sectors; + std::vector<TrackerHitExtendedVec> _sectorsFTD; + + /** + * A helper class to allow good code readability by accessing tracks with N hits. + * As the smalest valid track contains three hits, but the first index in a vector is 0, + * this class hides the index-3 calculation. As the vector access is inline there should be + * no performance penalty. + */ + class TracksWithNHitsContainer { + public: + /// Empty all the vectors and delete the tracks contained in it. + void clear(); + + /// Set the size to allow a maximum of maxHit hits. + inline void resize(size_t maxHits) { + _tracksNHits.resize(maxHits-2); + _maxIndex=(maxHits-3); + } + + // Sort all track vectors according to chi2/nDof + // void sort(); + + /// Returns the TrackExtendedVec for track with n hits. + /// In case n is larger than the maximal number the vector with the largest n ist returned. + /// \attention The smallest valid number is three! For + /// performance reasons there is no safety check! + inline TrackExtendedVec & getTracksWithNHitsVec( size_t nHits ) { + //return _tracksNHits[ std::min(nHits-3, _maxIndex) ]; + // for debugging: with boundary check + return _tracksNHits.at(std::min(nHits-3, _maxIndex)); + } + + protected: + std::vector< TrackExtendedVec > _tracksNHits; + size_t _maxIndex; /// local cache variable to avoid calculation overhead + }; + + TracksWithNHitsContainer _tracksWithNHitsContainer; + + int InitialiseVTX(); + int InitialiseFTD(); + void ProcessOneSector(int iSectorPhi, int iSectorTheta); + void CleanUp(); + TrackExtended * TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix); + + int BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerlayer, + int iPhiLow, int iPhiUp, + int iTheta, int iThetaUp, + TrackExtended * trackAR); + + void Sorting( TrackExtendedVec & trackVec); + void CreateTrack(TrackExtended * trackAR ); + void AttachRemainingVTXHitsSlow(); + void AttachRemainingFTDHitsSlow(); + void AttachRemainingVTXHitsFast(); + void AttachRemainingFTDHitsFast(); + void TrackingInFTD(); + int BuildTrackFTD(TrackExtended* trackAR, int* nLR, int iS); + int AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt); + + void FinalRefit(edm4hep::TrackCollection*);//, edm4hep::LCRelationCollection*); + + float _bField; + + // two pi is not a constant in cmath. Calculate it, once! + static const double TWOPI; + + double _dPhi; + double _dTheta; + double _dPhiFTD; + + float _resolutionRPhiVTX; + float _resolutionZVTX; + + float _resolutionRPhiFTD; + float _resolutionZFTD; + + float _resolutionRPhiSIT; + float _resolutionZSIT; + + float _phiCutForMerging; + float _tanlambdaCutForMerging; + //float _angleCutForMerging; + + float _distRPhi; + float _distZ; + + float _cutOnOmega; + + TrackExtendedVec _trackImplVec; + + int _nTotalVTXHits,_nTotalFTDHits,_nTotalSITHits; + + // int _createMap; + + UTIL::BitField64* _encoder; + int getDetectorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::subdet]; } + int getSideID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::side]; }; + int getLayerID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::layer]; }; + int getModuleID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::module]; }; + int getSensorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::sensor]; }; + + StatusCode setupGearGeom() ; + + std::vector<float> _zLayerFTD; + + unsigned int _nlayersFTD; + bool _petalBasedFTDWithOverlaps; + int _nPhiFTD; + + int _output_track_col_quality; + static const int _output_track_col_quality_GOOD; + static const int _output_track_col_quality_FAIR; + static const int _output_track_col_quality_POOR; + + std::vector<edm4hep::TrackerHit> _allHits; +} ; + +#endif + + + diff --git a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h~ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h~ new file mode 100644 index 0000000000000000000000000000000000000000..6418e101980a2436d1c4bd4d63c35c0558b62441 --- /dev/null +++ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.h~ @@ -0,0 +1,429 @@ +#ifndef SiliconTrackingAlg_h +#define SiliconTrackingAlg_h + +//#include "marlin/Processor.h" +//#include <marlin/Global.h> +#include "FWCore/DataHandle.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/TrackCollection.h" +//#include "edm4hep/LCRelationCollection.h" + +//#include "lcio.h" +#include <string> +#include <vector> +#include <cmath> +//#include <IMPL/TrackImpl.h> +#include "DataHelper/ClusterExtended.h" +#include "DataHelper/TrackExtended.h" +#include "DataHelper/TrackerHitExtended.h" +#include "DataHelper/HelixClass.h" + +#include "TrackSystemSvc/IMarlinTrack.h" + +#include <UTIL/BitField64.h> +#include <UTIL/ILDConf.h> + +//using namespace edm4hep ; + +namespace gear{ + class GearMgr ; +} + +namespace MarlinTrk { + class HelixFit; + class IMarlinTrkSystem ; +} + +namespace UTIL{ + class LCRelationNavigator ; +} + +class TrackExtended; +class TrackerHitExtended; +class HelixClass; + +/** === Silicon Tracking Processor === <br> + * Processor performing stand-alone pattern recognition + * in the vertex detector (VTX), forward tracking disks and SIT. <br> + * The procedure consists of three steps : <br> + * 1) Tracking in VTX and SIT ; <br> + * 2) Tracking in FTD ; <br> + * 3) Merging compatible track segments reconstructed in VTX and FTD <br> + * STEP 1 : TRACKING IN VTX and SIT <br> + * Algorithm starts with finding of hit triplets satisfying helix hypothesis <br> + * in three different layers. Two layers of SIT are effectively considered as outermost <br> + * layers of the vertex detector. To accelerate procedure, the 4-pi solid angle + * is divided in NDivisionsInTheta and NDivisionsInPhi sectors in cosQ and Phi, + * respectively. Triplets are looked for in 2x2 window of adjacent sectors. + * Once triplet is found, attempt is made to associate additional hits to + * track. Combinatin of hits is accepted for further analysis if the Chi2 + * of the fit is less than certain predefined threshold. All accepted + * combinations are sorted in ascending order of their Chi2. First track candidate + * in the sorted array is automatically accepted. The hits belonging to this track are + * marked as used, and track candidates sharing these hits are discarded. + * The procedure proceeds with increasing index of track candidate in the sorted + * array until all track candidate have been output or discarded. <br> + * STEP 2 : TRACKING IN FTD <br> + * In the next step tracking in FTD is performed. The strategy of tracking in the FTD + * is the same as used for tracking in the VTX+SIT. <br> + * STEP 3 : MERGING TRACK SEGMENTS FOUND IN FTD AND VTX+SIT <br> + * In the last step, track segments reconstructed in the FTD and VTX+SIT, belonging to the + * same track are identified and merged into one track. All possible + * pairings are tested for their compatibility. + * The number of pairings considered is Ntrk_VTX_SIT*Ntrk_FTD, where Ntrk_VTX_SIT is the number of + * track segments reconstructed in the first step in VTX+SIT (segments containing solely VTX and SIT hits) and + * Ntrk_FTD is the number of track segments reconstructed in the second step + * (segments containing solely FTD hits). + * Pair of segments is accepted for further examination if the angle between track segments and + * than certain specified threshold. + * Pairing satisfying this condition is subjected for + * addtitional test. The fit is performed on unified array of hits belonging to both segments. + * If the chi2 of the fit does not exceed predefined cut value two segments are unified into + * one track. + * <h4>Input collections and prerequisites</h4> + * Processor requires collection of digitized vertex, sit and ftd tracker hits. <br> + * If such a collections with the user specified names do not exist + * processor takes no action. <br> + * <h4>Output</h4> + * Processor produces an LCIO collection of the Tracks. Each track is characterised by + * five parameters : Omega (signed curvuture), Tan(lambda) where + * lambda is the dip angle, Phi (azimuthal angle @ point of closest approach), D0 (signed impact parameter), + * Z0 (displacement along z axis at the point of closest approach to IP). Covariance matrix for these parameters is also provided. + * Only lower left corner of the covariance matrix is stored. The sequence of the covariance matrix elements + * assigned to track is the following: <br> + * (Omega,Omega) <br> + * (Omega,TanLambda), (TanLambda,TanLambda) <br> + * (Omega,Phi), (TanLamda,Phi), (Phi,Phi) <br> + * (Omega,D0), (TanLambda,D0), (Phi,D0), (D0,D0) <br> + * (Omega,Z0), (TanLambda,Z0), (Phi,Z0), (D0,Z0), (Z0,Z0) <br> + * The number of hits in the different subdetectors associated + * with each track can be accessed via method Track::getSubdetectorHitNumbers(). + * This method returns vector of integers : <br> + * number of VTX hits in track is the first element in this vector + * (Track::getSubdetectorHitNumbers()[0]) <br> + * number of FTD hits in track is the second element in this vector + * (Track::getSubdetectorHitNumbers()[1]) <br> + * number of SIT hits in track is the third element in this vector + * (Track::getSubdetectorHitNumbers()[2]) <br> + * Output track collection has a name "SiTracks". <br> + * @param VTXHitCollectionName name of input VTX TrackerHit collection <br> + * (default parameter value : "VTXTrackerHits") <br> + * @param FTDHitCollectionName name of input FTD TrackerHit collection <br> + * (default parameter value : "FTDTrackerHits") <br> + * @param SITHitCollectionName name of input SIT TrackerHit collection <br> + * (default parameter value : "SITTrackerHits") <br> + * @param SiTrackCollectionName name of the output Silicon track collection <br> + * (default parameter value : "SiTracks") <br> + * @param LayerCombinations combinations of layers used to search for hit triplets in VTX+SIT <br> + * (default parameters : 6 4 3 6 4 2 6 3 2 5 4 3 5 4 2 5 3 2 4 3 2 4 3 1 4 2 1 3 2 1) <br> + * Note that in the VTX+SIT system the first and the second layers of SIT have indicies nLayerVTX and nLayerVTX+1. + * Combination given above means that triplets are looked first in layers 6 4 3, and then + * in 6 4 2; 5 4 3; 6 3 2 etc. NOTE THAT LAYER INDEXING STARTS FROM 0. + * LAYER 0 is the innermost layer <br> + * @param LayerCombinationsFTD combinations of layers used to search for hit triplets in FTD <br> + * (default parameters 6 5 4 5 4 3 5 4 2 5 4 1 5 3 2 5 3 1 5 2 1 4 3 2 4 3 1 + * 4 3 0 4 2 1 4 2 0 4 1 0 3 2 1 3 2 0 3 1 0 2 1 0). + * NOTE THAT TRACKS IN FTD ARE SEARCHED ONLY IN ONE HEMISPHERE. TRACK IS NOT + * ALLOWED TO HAVE HITS BOTH IN BACKWARD AND FORWARD PARTS OF FTD SIMULTANEOUSLY. + * @param NDivisionsInPhi Number of divisions in Phi for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInTheta Number of divisions in cosQ for tracking in VTX+SIT <br> + * (default value is 40) <br> + * @param NDivisionsInPhiFTD Number of divisions in Phi for tracking in FTD <br> + * (default value is 3) <br> + * @param Chi2WRphiTriplet weight on chi2 in R-Phi plane for track with 3 hits <br> + * (default value is 1) <br> + * @param Chi2WZTriplet weight on chi2 in S-Z plane for track with 3 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiQuartet weight on chi2 in R-Phi plane to accept track with 4 hits <br> + * (default value is 1) <br> + * @param Chi2WZQuartet weight on chi2 in S-Z plane for track with 4 hits <br> + * (default value is 0.5) <br> + * @param Chi2WRphiSeptet weight on chi2 in R-Phi plane for track with 5 and more hits <br> + * (default value is 1) <br> + * @param Chi2WZSeptet Cut on chi2 in S-Z plane for track with 5 and more hits <br> + * (default value is 0.5) <br> + * @param Chi2FitCut Cut on chi2/ndf to accept track candidate <br> + * (default value is 100.) <br> + * @param AngleCutForMerging cut on the angle between two track segments. + * If the angle is greater than this cut, segments are not allowed to be merged. <br> + * (default value is 0.1) <br> + * @param MinDistCutAttach cut on the distance (in mm) from hit to the helix. This parameter is used + * to decide whether hit can be attached to the track. If the distance is less than + * cut value. The track is refitted with a given hit being added to the list of hits already + * assigned for the track. Additional hit is assigned if chi2 of the new fit has good chi2. <br> + * (default value is 2 ) <br> + * @param MinLayerToAttach the minimal layer index to attach VTX hits to the found hit triplets <br> + * (default value is -1) <br> + * @param CutOnZ0 cut on Z0 parameter of track (in mm). If abs(Z0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnD0 cut on D0 parameter of track (in mm). If abs(D0) is greater than the cut value, track is + * discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 100) <br> + * @param CutOnPt cut on Pt (GeV/c). If Pt is less than this cut, track is discarded (used to suppress fake + * track rate in the presence of beam induced background hits) <br> + * (default value is 0.1) <br> + * @param MinimalHits minimal number of hits in track required <br> + * (default value is 3) <br> + * @param NHitsChi2 Maximal number of hits for which a track with n hits is aways better than one with n-1 hits. + * For tracks with equal or more than NHitsChi2 the track with the lower \f$\chi^2\f$ is better. + * (default value is 5) <br> + * @param FastAttachment if this flag is set to 1, less accurate but fast procedure to merge additional hits to tracks is used <br> + * if set to 0, a more accurate, but slower procedure is invoked <br> + * (default value is 0) <br> + * @param UseSIT When this flag is set to 1, SIT is included in pattern recognition. When this flag is set + * to 0, SIT is excluded from the procedure of pattern recognition <br> + * (default value is 1) <br> + * <br> + * @author A. Raspereza (MPI Munich)<br> + */ +class SiliconTrackingAlg : public GaudiAlgorithm { + public: + + SiliconTracking(const std::string& name, ISvcLocator* svcLoc); + + virtual StatusCode initialize() ; + + virtual StatusCode execute() ; + + virtual StatusCode finalize() ; + +protected: + + int _nRun ; + int _nEvt ; + //EVENT::LCEvent* _current_event; + int _nLayers; + unsigned int _nLayersVTX; + unsigned int _nLayersSIT; + int _ntriplets, _ntriplets_good, _ntriplets_2MCP, _ntriplets_3MCP, _ntriplets_1MCP_Bad, _ntriplets_bad; + + MarlinTrk::HelixFit* _fastfitter; + gear::GearMgr* _GEAR; + /** pointer to the IMarlinTrkSystem instance + */ + MarlinTrk::IMarlinTrkSystem* _trksystem ; + //bool _runMarlinTrkDiagnostics; + //std::string _MarlinTrkDiagnosticsName; + typedef std::vector<int> IntVec; + + Gaudi::Property<IntVec> _Combinations{this, "LayerCombinations", {8,6,5, 8,6,4, 8,6,3, 8,6,2, 8,5,3, 8,5,2, 8,4,3, 8,4,2, 6,5,3, 6,5,2, 6,4,3, 6,4,2, 6,3,1, 6,3,0, 6,2,1, 6,2,0, + 5,3,1, 5,3,0, 5,2,1, 5,2,0, 4,3,1, 4,3,0, 4,2,1, 4,2,0}}; + Gaudi::Property<IntVec> _CombinationsFTD{this, "LayerCombinationsFTD", {4,3,2, 4,3,1, 4,3,0, 4,2,1, 4,2,0, 4,1,0, 3,2,1, 3,2,0, 3,1,0, 2,1,0, + 9,8,7, 9,8,6, 9,8,5, 9,7,6, 9,7,5, 9,6,5, 8,7,6, 8,7,5, 8,6,5, 7,6,5}}; + Gaudi::Property<int> _nDivisionsInPhi{this, "NDivisionsInPhi", 80}; + Gaudi::Property<int> _nDivisionsInPhiFTD{this, "NDivisionsInPhiFTD", 30}; + Gaudi::Property<int> _nDivisionsInTheta{this, "NDivisionsInTheta", 80}; + Gaudi::Property<float> _chi2WRPhiTriplet{this, "Chi2WRphiTriplet", 1.}; + Gaudi::Property<float> _chi2WRPhiQuartet{this, "Chi2WRphiQuartet", 1.}; + Gaudi::Property<float> _chi2WRPhiSeptet{this, "Chi2WRphiSeptet", 1.}; + Gaudi::Property<float> _chi2WZTriplet{this, "Chi2WZTriplet", 0.5}; + Gaudi::Property<float> _chi2WZQuartet{this, "Chi2WZQuartet", 0.5}; + Gaudi::Property<float> _chi2WZSeptet{this, "Chi2WZSeptet", 0.5}; + Gaudi::Property<float> _chi2FitCut{this, "Chi2FitCut", 120.}; + Gaudi::Property<float> _angleCutForMerging{this, "AngleCutForMerging", 0.1}; + Gaudi::Property<float> _minDistCutAttach{this, "MinDistCutAttach", 2.5}; + Gaudi::Property<float> _minimalLayerToAttach{this, "MinLayerToAttach", -1}; + Gaudi::Property<float> _cutOnD0{this, "CutOnD0", 100.0}; + Gaudi::Property<float> _cutOnZ0{this, "CutOnZ0", 100.0}; + Gaudi::Property<float> _cutOnPt{this, "CutOnPt", 0.05}; + Gaudi::Property<int> _minimalHits{this, "MinimalHits",3}; + Gaudi::Property<int> _nHitsChi2{this, "NHitsChi2", 5}; + Gaudi::Property<int> _max_hits_per_sector{this, "MaxHitsPerSector", 100}; + Gaudi::Property<int> _attachFast{this, "FastAttachment", 0}; + Gaudi::Property<bool> _useSIT{this, "UseSIT", true}; + Gaudi::Property<float> _initialTrackError_d0{this, "InitialTrackErrorD0",1e6}; + Gaudi::Property<float> _initialTrackError_phi0{this, "InitialTrackErrorPhi0",1e2}; + Gaudi::Property<float> _initialTrackError_omega{this, "InitialTrackErrorOmega",1e-4}; + Gaudi::Property<float> _initialTrackError_z0{this, "InitialTrackErrorZ0",1e6}; + Gaudi::Property<float> _initialTrackError_tanL{this, "InitialTrackErrorTanL",1e2}; + Gaudi::Property<float> _maxChi2PerHit{this, "MaxChi2PerHit", 1e2}; + Gaudi::Property<int> _checkForDelta{this, "CheckForDelta", 1}; + Gaudi::Property<float> _minDistToDelta{this, "MinDistToDelta", 0.25}; + Gaudi::Property<bool> _MSOn{this, "MultipleScatteringOn", true}; + Gaudi::Property<bool> _ElossOn{this, "EnergyLossOn", true}; + Gaudi::Property<bool> _SmoothOn{this, "SmoothOn", true}; + Gaudi::Property<float> _helix_max_r{this, "HelixMaxR", 2000.}; + + //std::vector<int> _colours; + + /** helper function to get collection using try catch block */ + //LCCollection* GetCollection( LCEvent * evt, std::string colName ) ; + + /** helper function to get relations using try catch block */ + //LCRelationNavigator* GetRelations( LCEvent * evt, std::string RelName ) ; + + /** input MCParticle collection and threshold used for Drawing + */ + //Gaudi::Property<Float> _MCpThreshold{this, "MCpThreshold", 0.1}; + //std::string _colNameMCParticles; + + /// Compare tracks according to their chi2/ndf + struct compare_TrackExtended{ + // n.b.: a and b should be TrackExtended const *, but the getters are not const :-( + bool operator()(TrackExtended *a, TrackExtended *b) const { + if ( a == b ) return false; + return (a->getChi2()/a->getNDF() < b->getChi2()/b->getNDF() ); + } + }; + + + //std::string _VTXHitCollection; + //std::string _FTDPixelHitCollection; + //std::string _FTDSpacePointCollection; + //std::string _SITHitCollection; + //std::string _siTrkCollection; + + //std::vector< LCCollection* > _colTrackerHits; + //std::map< LCCollection*, std::string > _colNamesTrackerHits; + + // Input collections + DataHandle<edm4hep::EventHeaderCollection> _headerColHdl{"EventHeaderCol", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::MCParticleCollection> _inMCColHdl{"MCParticle", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inVTXColHdl{"VXDCollection", Gaudi::DataHandle::Reader, this}; + //DataHandle<edm4hep::TrackerHitPlaneCollection> _inFTDPixelColHdl{"FTDPixelCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inVTXColHdl{"VXDTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDPixelColHdl{"FTDPixelTrackerHits", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inFTDSpacePointColHdl{"FTDSpacePoints", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> _inSITColHdl{"SITTrackerHits", Gaudi::DataHandle::Reader, this}; + // Output collections + DataHandle<edm4hep::TrackCollection> _outColHdl{"SiTracks", Gaudi::DataHandle::Writer, this}; + //DataHandle<edm4hep::LCRelationCollection> _outRelColHdl{"TrackerHitRelations", Gaudi::DataHandle::Reader, this}; + + std::vector<TrackerHitExtendedVec> _sectors; + std::vector<TrackerHitExtendedVec> _sectorsFTD; + + /** + * A helper class to allow good code readability by accessing tracks with N hits. + * As the smalest valid track contains three hits, but the first index in a vector is 0, + * this class hides the index-3 calculation. As the vector access is inline there should be + * no performance penalty. + */ + class TracksWithNHitsContainer { + public: + /// Empty all the vectors and delete the tracks contained in it. + void clear(); + + /// Set the size to allow a maximum of maxHit hits. + inline void resize(size_t maxHits) { + _tracksNHits.resize(maxHits-2); + _maxIndex=(maxHits-3); + } + + // Sort all track vectors according to chi2/nDof + // void sort(); + + /// Returns the TrackExtendedVec for track with n hits. + /// In case n is larger than the maximal number the vector with the largest n ist returned. + /// \attention The smallest valid number is three! For + /// performance reasons there is no safety check! + inline TrackExtendedVec & getTracksWithNHitsVec( size_t nHits ) { + //return _tracksNHits[ std::min(nHits-3, _maxIndex) ]; + // for debugging: with boundary check + return _tracksNHits.at(std::min(nHits-3, _maxIndex)); + } + + protected: + std::vector< TrackExtendedVec > _tracksNHits; + size_t _maxIndex; /// local cache variable to avoid calculation overhead + }; + + TracksWithNHitsContainer _tracksWithNHitsContainer; + + int InitialiseVTX(); + int InitialiseFTD(); + void ProcessOneSector(int iSectorPhi, int iSectorTheta); + void CleanUp(); + TrackExtended * TestTriplet(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix); + + int BuildTrack(TrackerHitExtended * outerHit, + TrackerHitExtended * middleHit, + TrackerHitExtended * innerHit, + HelixClass & helix, + int innerlayer, + int iPhiLow, int iPhiUp, + int iTheta, int iThetaUp, + TrackExtended * trackAR); + + void Sorting( TrackExtendedVec & trackVec); + void CreateTrack(TrackExtended * trackAR ); + void AttachRemainingVTXHitsSlow(); + void AttachRemainingFTDHitsSlow(); + void AttachRemainingVTXHitsFast(); + void AttachRemainingFTDHitsFast(); + void TrackingInFTD(); + int BuildTrackFTD(TrackExtended* trackAR, int* nLR, int iS); + int AttachHitToTrack(TrackExtended * trackAR, TrackerHitExtended * hit, int iopt); + + void FinalRefit(edm4hep::TrackCollection*);//, edm4hep::LCRelationCollection*); + + float _bField; + + // two pi is not a constant in cmath. Calculate it, once! + static const double TWOPI; + + double _dPhi; + double _dTheta; + double _dPhiFTD; + + float _resolutionRPhiVTX; + float _resolutionZVTX; + + float _resolutionRPhiFTD; + float _resolutionZFTD; + + float _resolutionRPhiSIT; + float _resolutionZSIT; + + float _phiCutForMerging; + float _tanlambdaCutForMerging; + //float _angleCutForMerging; + + float _distRPhi; + float _distZ; + + float _cutOnOmega; + + TrackExtendedVec _trackImplVec; + + int _nTotalVTXHits,_nTotalFTDHits,_nTotalSITHits; + + // int _createMap; + + UTIL::BitField64* _encoder; + int getDetectorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::subdet]; } + int getSideID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::side]; }; + int getLayerID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::layer]; }; + int getModuleID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::module]; }; + int getSensorID(edm4hep::TrackerHit* hit) { _encoder->setValue(hit->getCellID()); return (*_encoder)[lcio::ILDCellID0::sensor]; }; + + StatusCode setupGearGeom() ; + + std::vector<float> _zLayerFTD; + + unsigned int _nlayersFTD; + bool _petalBasedFTDWithOverlaps; + int _nPhiFTD; + + int _output_track_col_quality; + static const int _output_track_col_quality_GOOD; + static const int _output_track_col_quality_FAIR; + static const int _output_track_col_quality_POOR; + + std::vector<edm4hep::TrackerHit> _allHits; +} ; + +#endif + + + diff --git a/Utilities/DataHelper/CMakeLists.txt~ b/Utilities/DataHelper/CMakeLists.txt~ deleted file mode 100644 index ccbc04fc3b35548799ec0b72116c0c43b7dc1ec1..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/CMakeLists.txt~ +++ /dev/null @@ -1,26 +0,0 @@ -gaudi_subdir(DataHelper v0r0) - -#find_package(CLHEP REQUIRED) -#find_package(GEAR REQUIRED) -#find_package(GSL REQUIRED ) -#find_package(LCIO REQUIRED ) -#find_package(podio REQUIRED ) -#find_package(K4FWCore REQUIRED) -find_package(EDM4HEP REQUIRED) - -gaudi_depends_on_subdirs() - -set(DataHelper_srcs src/*.cc) - -gaudi_install_headers(DataHelper) - -#gaudi_add_library(DataHelperLib ${DataHelperLib_srcs} -# PUBLIC_HEADERS DataHelper -# LINK_LIBRARIES EDM4HEP::edm4hep EDM4HEP::edm4hepDict -#) - -# Modules -gaudi_add_module(DataHelper ${DataHelper_srcs} - INCLUDE_DIRS K4FWCore GaudiKernel GaudiAlgLib CLHEP gear ${GSL_INCLUDE_DIRS} ${LCIO_INCLUDE_DIRS} - LINK_LIBRARIES K4FWCore GaudiKernel GaudiAlgLib CLHEP $ENV{GEAR}/lib/libgearsurf.so ${GSL_LIBRARIES} ${LCIO_LIBRARIES} EDM4HEP::edm4hep EDM4HEP::edm4hepDict -) diff --git a/Utilities/DataHelper/src/CaloHitExtended.cc~ b/Utilities/DataHelper/src/CaloHitExtended.cc~ deleted file mode 100644 index 3adab51d1e2e032a1e61294379faea57bfe631a7..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/CaloHitExtended.cc~ +++ /dev/null @@ -1,128 +0,0 @@ -#include "CaloHitExtended.h" -#include <math.h> - -CaloHitExtended::CaloHitExtended(const edm4hep::CalorimeterHit& calhit, int type) - :_calohit(calhit){ - _type = type; - _index = 0; - _calohitTo = NULL; - _calohitFrom = NULL; -} - -CaloHitExtended::~CaloHitExtended(){ -} - -CalorimeterHit* CaloHitExtended::getCalorimeterHit() { - return &_calohit; -} - -CaloHitExtended* CaloHitExtended::getCaloHitTo() { - return _calohitTo; -} - -CaloHitExtended* CaloHitExtended::getCaloHitFrom() { - return _calohitFrom; -} - -ClusterExtended* CaloHitExtended::getClusterExtended() { - return _clusterAR; -} - -int CaloHitExtended::getIndex() { - return _index; - -} - -int CaloHitExtended::getType() { - return _type; - -} -const float* CaloHitExtended::getDirVec() { - return _dirVec; -} - -float CaloHitExtended::getYresTo() { - return _yresTo; -} - -float CaloHitExtended::getYresFrom() { - return _yresFrom; -} - - - -float CaloHitExtended::getGenericDistance() { - return _genericDistance; -} - -//void CaloHitExtended::setCalorimeterHit(CalorimeterHit* calhit) { -// _calohit = calhit; -//} - -void CaloHitExtended::setCaloHitTo(CaloHitExtended* calhitto) { - _calohitTo = calhitto; -} - -void CaloHitExtended::setCaloHitFrom(CaloHitExtended* calhitfrom) { - _calohitFrom = calhitfrom; -} - -void CaloHitExtended::setClusterExtended(ClusterExtended* cluster) { - _clusterAR = cluster; -} - -void CaloHitExtended::setIndex(int index) { - _index = index; -} - -void CaloHitExtended::setType(int type) { - _type = type; -} - -void CaloHitExtended::setDirVec(float* dirVec) { - float modulus(0.); - for (int i(0); i < 3; ++i) { - modulus += dirVec[i]*dirVec[i]; - } - - modulus = sqrt(modulus); - - if (modulus <= 0.) { - _dirVec[0] = 0.; - _dirVec[1] = 0.; - _dirVec[2] = 1.; - } - else { - _dirVec[0] = dirVec[0] / modulus; - _dirVec[1] = dirVec[1] / modulus; - _dirVec[2] = dirVec[2] / modulus; - } -} - -void CaloHitExtended::setYresTo(float yresto) { - _yresTo = yresto; -} - -void CaloHitExtended::setYresFrom(float yresfrom) { - _yresFrom = yresfrom; -} - -void CaloHitExtended::setGenericDistance(float genericDistance) { - _genericDistance = genericDistance; -} - -void CaloHitExtended::setDistanceToCalo(float caloDistance) { - _caloDistance = caloDistance; -} - -float CaloHitExtended::getDistanceToCalo() { - return _caloDistance; -} - -void CaloHitExtended::setDistanceToNearestHit(float distanceToNearest) { - _distanceToNearestHit = distanceToNearest; -} - -float CaloHitExtended::getDistanceToNearestHit() { - return _distanceToNearestHit; -} diff --git a/Utilities/DataHelper/src/CaloHitExtended.h~ b/Utilities/DataHelper/src/CaloHitExtended.h~ deleted file mode 100644 index 65781a9da8ef764072422e57be4b458117aea6c3..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/CaloHitExtended.h~ +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef CaloHitExtended_H -#define CaloHitExtended_H 1 - -//#include "lcio.h" -//#include "EVENT/LCIO.h" -#include "edm4hep/CalorimeterHit.h" -#include "ClusterExtended.h" - -using namespace edm4hep ; - -class ClusterExtended; - -/** - * Class extending native LCIO class CalorimeterHit. <br> - * Class CaloHitExtended is used in TrackwiseClustering <br> - * and Wolf processors. <br> - * @author A. Raspereza (DESY)<br> - * @version $Id: CaloHitExtended.h,v 1.4 2006-02-22 14:53:27 owendt Exp $<br> - */ -class CaloHitExtended { - - public: - - CaloHitExtended(CalorimeterHit* calhit, int type); - - ~CaloHitExtended(); - - CalorimeterHit * getCalorimeterHit(); - CaloHitExtended * getCaloHitTo(); - CaloHitExtended * getCaloHitFrom(); - ClusterExtended * getClusterExtended(); - int getIndex(); - int getType(); - const float* getDirVec(); - float getYresTo(); - float getYresFrom(); - float getGenericDistance(); - - void setCalorimeterHit(CalorimeterHit* calhit); - void setCaloHitTo(CaloHitExtended* calhitto); - void setCaloHitFrom(CaloHitExtended* calohitfrom); - void setClusterExtended(ClusterExtended* cluster); - void setIndex(int index); - void setType(int type); - void setDirVec(float* dirVec); - void setYresTo(float yresto); - void setYresFrom(float yresfrom); - void setGenericDistance(float genericDistance); - void setDistanceToCalo(float distanceToCalo); - float getDistanceToCalo(); - void setDistanceToNearestHit(float distanceToNearest); - float getDistanceToNearestHit(); - - - private: - - CalorimeterHit * _calohit; - CaloHitExtended * _calohitTo; - CaloHitExtended * _calohitFrom; - ClusterExtended * _clusterAR; - int _index; - int _type; - float _dirVec[3]; - float _yresTo; - float _yresFrom; - float _genericDistance; - float _caloDistance; - float _distanceToNearestHit; - -}; - -#endif diff --git a/Utilities/DataHelper/src/ClusterExtended.cc~ b/Utilities/DataHelper/src/ClusterExtended.cc~ deleted file mode 100644 index a5f99aebdda6b0d18f4f85aeff8ed1a03bf92ac0..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/ClusterExtended.cc~ +++ /dev/null @@ -1,232 +0,0 @@ -#include "CaloHitExtended.h" -#include "TrackExtended.h" -#include "ClusterExtended.h" -#include <math.h> - -ClusterExtended::ClusterExtended() { - _hitVector.clear(); - _trackVector.clear(); - - _direction[0] = 0.; - _direction[1] = 0.; - _direction[2] = 0.; - - _startingPoint[0] = 0.; - _startingPoint[1] = 0.; - _startingPoint[2] = 0.; - -} - -ClusterExtended::ClusterExtended( Cluster * cluster ) { - _hitVector.clear(); - _trackVector.clear(); - - _direction[0] = 0.; - _direction[1] = 0.; - _direction[2] = 0.; - - _startingPoint[0] = 0.; - _startingPoint[1] = 0.; - _startingPoint[2] = 0.; - - _cluster = cluster; - -} - - - - -ClusterExtended::ClusterExtended(CaloHitExtended * calohit) { - - _hitVector.clear(); - _hitVector.push_back(calohit); - _trackVector.clear(); - - float rad(0); - - _startingPoint[0] = calohit->getCalorimeterHit()->getPosition().x; - _startingPoint[1] = calohit->getCalorimeterHit()->getPosition().y; - _startingPoint[2] = calohit->getCalorimeterHit()->getPosition().z; - - for (int i(0); i < 3; ++i) { - rad += _startingPoint[i]*_startingPoint[i]; - } - - rad = sqrt(rad); - - _direction[0] = _startingPoint[0]/rad; - _direction[1] = _startingPoint[1]/rad; - _direction[2] = _startingPoint[2]/rad; - -} - -ClusterExtended::ClusterExtended(TrackExtended * track) { - _hitVector.clear(); - _trackVector.clear(); - _trackVector.push_back(track); - for (int i(0); i < 3; ++i) { - _startingPoint[i] = track->getSeedPosition()[i]; - _direction[i] = track->getSeedDirection()[i]; - } -} - - -ClusterExtended::~ClusterExtended() { - _hitVector.clear(); - _trackVector.clear(); -} - -CaloHitExtendedVec& ClusterExtended::getCaloHitExtendedVec() { - return _hitVector; -} - -TrackExtendedVec& ClusterExtended::getTrackExtendedVec() { - return _trackVector; -} - -const float* ClusterExtended::getStartingPoint() { - return _startingPoint; -} - -const float* ClusterExtended::getDirection() { - return _direction; -} - -void ClusterExtended::setStartingPoint(float* sPoint) { - _startingPoint[0] = sPoint[0]; - _startingPoint[1] = sPoint[1]; - _startingPoint[2] = sPoint[2]; - -} - -void ClusterExtended::setDirection(float* direct) { - _direction[0] = direct[0]; - _direction[1] = direct[1]; - _direction[2] = direct[2]; -} - -void ClusterExtended::addCaloHitExtended(CaloHitExtended* calohit) { - _hitVector.push_back(calohit); -} - -void ClusterExtended::addTrackExtended(TrackExtended * track) { - _trackVector.push_back(track); -} - -void ClusterExtended::Clear() { - _hitVector.clear(); - _trackVector.clear(); - -} - -void ClusterExtended::setType( int type ) { - _type = type; -} - -int ClusterExtended::getType() { - return _type; -} - -void ClusterExtended::setCluster(Cluster * cluster) { - _cluster = cluster; -} - -Cluster * ClusterExtended::getCluster() { - return _cluster; -} - -void ClusterExtended::setAxis(float * axis) { - _axis[0] = axis[0]; - _axis[1] = axis[1]; - _axis[2] = axis[2]; -} -float * ClusterExtended::getAxis() { - return _axis; -} - -void ClusterExtended::setEccentricity( float eccentricity) { - _eccentricity = eccentricity; -} -float ClusterExtended::getEccentricity() { - return _eccentricity; -} - -void ClusterExtended::setHelix(HelixClass helix) { - _helix = helix; - int nHits = int(_hitVector.size()); - float timeMax = -1.0e+20; - float timeMin = 1.0e+20; - for (int ihit=0;ihit<nHits;++ihit) { - float pos[3]; - for (int i=0;i<3;++i) - pos[i]=_hitVector[ihit]->getCalorimeterHit()->getPosition()[i]; - - float distance[3]; - float time = _helix.getDistanceToPoint(pos,distance); - if (time > timeMax) { - timeMax = time; - _upEdge[0] = pos[0]; - _upEdge[1] = pos[1]; - _upEdge[2] = pos[2]; - } - if (time < timeMin) { - timeMin = time; - _lowEdge[0] = pos[0]; - _lowEdge[1] = pos[1]; - _lowEdge[2] = pos[2]; - } - - } - -} -HelixClass & ClusterExtended::getHelix() { - return _helix; -} - -void ClusterExtended::setHelixChi2R(float helixChi2) { - _helixChi2R = helixChi2; -} -float ClusterExtended::getHelixChi2R() { - return _helixChi2R; -} - -void ClusterExtended::setHelixChi2Z(float helixChi2) { - _helixChi2Z = helixChi2; -} -float ClusterExtended::getHelixChi2Z() { - return _helixChi2Z; -} - - - -void ClusterExtended::setPosition(float * position) { - _position[0] = position[0]; - _position[1] = position[1]; - _position[2] = position[2]; - -} - -float * ClusterExtended::getPosition() { - return _position; -} - -void ClusterExtended::setUpEdge(float * upEdge) { - _upEdge[0] = upEdge[0]; - _upEdge[1] = upEdge[1]; - _upEdge[2] = upEdge[2]; -} - -void ClusterExtended::setLowEdge(float * lowEdge) { - _lowEdge[0] = lowEdge[0]; - _lowEdge[1] = lowEdge[1]; - _lowEdge[2] = lowEdge[2]; -} - -float * ClusterExtended::getUpEdge() { - return _upEdge; -} - -float * ClusterExtended::getLowEdge() { - return _lowEdge; -} - diff --git a/Utilities/DataHelper/src/ClusterExtended.h~ b/Utilities/DataHelper/src/ClusterExtended.h~ deleted file mode 100644 index 4a1802408875a859b16673659ca4f71545590eb4..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/ClusterExtended.h~ +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef ClusterExtended_H -#define ClusterExtended_H 1 - -#include "CaloHitExtended.h" -#include "TrackExtended.h" -#include "plcio/Cluster.h" -#include "HelixClass.h" - -using namespace plcio; - -//class TrackExtended; -//typedef std::vector<TrackExtended*> TrackExtendedVec; - -//class CaloHitExtended; -//typedef std::vector<CaloHitExtended*> CaloHitExtendedVec; - -//class ClusterExtended; -//typedef std::vector<ClusterExtended*> ClusterExtendedVec; - -/** - * Class extending native LCIO class Cluster. <br> - * Class ClusterExtended is used in TrackwiseClustering <br> - * and Wolf processors. <br> - * @author A. Raspereza (DESY)<br> - * @version $Id: ClusterExtended.h,v 1.4 2006-02-22 14:41:41 owendt Exp $<br> - */ - -class ClusterExtended { - - public: - - ClusterExtended(); - ClusterExtended( Cluster * cluster ); - ClusterExtended(CaloHitExtended * calohit); - ClusterExtended(TrackExtended * track); - - ~ClusterExtended(); - - CaloHitExtendedVec & getCaloHitExtendedVec(); - TrackExtendedVec & getTrackExtendedVec(); - const float* getStartingPoint(); - const float* getDirection(); - void setStartingPoint(float* sPoint); - void setDirection(float* direct); - void addCaloHitExtended(CaloHitExtended * calohit); - void addTrackExtended(TrackExtended * track); - void setType( int type ); - int getType(); - - void Clear(); - - void setCluster(Cluster * cluster); - Cluster * getCluster(); - - void setAxis(float * axis); - float * getAxis(); - - void setEccentricity( float eccentricity); - float getEccentricity(); - - void setHelix(HelixClass helix); - HelixClass & getHelix(); - - void setHelixChi2R(float helixChi2); - float getHelixChi2R(); - - void setHelixChi2Z(float helixChi2); - float getHelixChi2Z(); - - void setPosition(float * position); - float * getPosition(); - - void setLowEdge(float * lowEdge); - float * getLowEdge(); - void setUpEdge(float * upEdge); - float * getUpEdge(); - - - private: - - TrackExtendedVec _trackVector; - CaloHitExtendedVec _hitVector; - float _startingPoint[3]; - float _direction[3]; - - int _type; - Cluster * _cluster; - - float _axis[3]; - float _position[3]; - float _eccentricity; - - HelixClass _helix; - float _helixChi2R; - float _helixChi2Z; - - float _lowEdge[3]; - float _upEdge[3]; - - -}; - -typedef std::vector<ClusterExtended*> ClusterExtendedVec; - -#endif diff --git a/Utilities/DataHelper/src/GroupTracks.cc~ b/Utilities/DataHelper/src/GroupTracks.cc~ deleted file mode 100644 index fdbda40da169b1481030cb6f9f0ef5a5baaeb9ba..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/GroupTracks.cc~ +++ /dev/null @@ -1,40 +0,0 @@ -#include "TrackExtended.h" -#include "GroupTracks.h" - -GroupTracks::GroupTracks() { - _trackARVec.clear(); - _edges[0] = 0.0; - _edges[1] = 0.0; -} - -GroupTracks::GroupTracks( TrackExtended * track ) { - _trackARVec.clear(); - _trackARVec.push_back( track ); - _edges[0] = 0.0; - _edges[1] = 0.0; -} - -GroupTracks::~GroupTracks() {} - -void GroupTracks::addTrackExtended( TrackExtended * track ) { - _trackARVec.push_back( track ); -} - -void GroupTracks::ClearTrackExtendedVec() { - _trackARVec.clear(); -} - -TrackExtendedVec & GroupTracks::getTrackExtendedVec() { - return _trackARVec; -} - -void GroupTracks::setEdges(float * edges) { - - _edges[0] = edges[0]; - _edges[1] = edges[1]; - -} - -float * GroupTracks::getEdges() { - return _edges; -} diff --git a/Utilities/DataHelper/src/GroupTracks.h~ b/Utilities/DataHelper/src/GroupTracks.h~ deleted file mode 100644 index 681117bb199bb70ed0bd13b37ce8518f1dd6e643..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/GroupTracks.h~ +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef GROUPTRACKS_H -#define GROUPTRACKS_H 1 - -#include "TrackExtended.h" -#include "ClusterExtended.h" -#include <vector> - -//fg : forwar declaration needed because of circular include .... -class TrackExtended; -typedef std::vector<TrackExtended*> TrackExtendedVec; -//fg : forward .... - -/** - * Class GroupTracks is needed to group track segments <br> - * with close helix parameters. Needed for Tracking. <br> - * * @author A. Raspereza (DESY)<br> - * @version $Id: GroupTracks.h,v 1.4 2007-09-05 09:39:49 rasp Exp $<br> - */ -class GroupTracks; - -typedef std::vector<GroupTracks*> GroupTracksVec; - -class GroupTracks { - - public: - GroupTracks(); - GroupTracks(TrackExtended * track ); - ~GroupTracks(); - - void addTrackExtended( TrackExtended * track ); - void ClearTrackExtendedVec(); - TrackExtendedVec & getTrackExtendedVec(); - void setEdges(float * edges); - float * getEdges(); - - private: - - TrackExtendedVec _trackARVec; - - float _edges[2]; - -}; - -#endif diff --git a/Utilities/DataHelper/src/HelixClass.cc~ b/Utilities/DataHelper/src/HelixClass.cc~ deleted file mode 100644 index d16ac9559ad83d565812f5acfbcd6531aa0b0511..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/HelixClass.cc~ +++ /dev/null @@ -1,768 +0,0 @@ -#include "HelixClass.h" -#include <math.h> -#include <stdlib.h> -#include <iostream> -//#include "ced_cli.h" - -HelixClass::HelixClass() { - _const_2pi = 2.0*M_PI; - _const_pi2 = 0.5*M_PI; - _FCT = 2.99792458E-4; -} - -HelixClass::~HelixClass() {} - -void HelixClass::Initialize_VP(float * pos, float * mom, float q, float B) { - _referencePoint[0] = pos[0]; - _referencePoint[1] = pos[1]; - _referencePoint[2] = pos[2]; - _momentum[0] = mom[0]; - _momentum[1] = mom[1]; - _momentum[2] = mom[2]; - _charge = q; - _bField = B; - _pxy = sqrt(mom[0]*mom[0]+mom[1]*mom[1]); - _radius = _pxy / (_FCT*B); - _omega = q/_radius; - _tanLambda = mom[2]/_pxy; - _phiMomRefPoint = atan2(mom[1],mom[0]); - _xCentre = pos[0] + _radius*cos(_phiMomRefPoint-_const_pi2*q); - _yCentre = pos[1] + _radius*sin(_phiMomRefPoint-_const_pi2*q); - _phiRefPoint = atan2(pos[1]-_yCentre,pos[0]-_xCentre); - _phiAtPCA = atan2(-_yCentre,-_xCentre); - _phi0 = -_const_pi2*q + _phiAtPCA; - while (_phi0<0) _phi0+=_const_2pi; - while (_phi0>=_const_2pi) _phi0-=_const_2pi; - _xAtPCA = _xCentre + _radius*cos(_phiAtPCA); - _yAtPCA = _yCentre + _radius*sin(_phiAtPCA); - // _d0 = -_xAtPCA*sin(_phi0) + _yAtPCA*cos(_phi0); - double pxy = double(_pxy); - double radius = pxy/double(_FCT*B); - double xCentre = double(pos[0]) + radius*double(cos(_phiMomRefPoint-_const_pi2*q)); - double yCentre = double(pos[1]) + radius*double(sin(_phiMomRefPoint-_const_pi2*q)); - - double d0; - - if (q>0) { - d0 = double(q)*radius - double(sqrt(xCentre*xCentre+yCentre*yCentre)); - } - else { - d0 = double(q)*radius + double(sqrt(xCentre*xCentre+yCentre*yCentre)); - } - - _d0 = float(d0); - -// if (fabs(_d0)>0.001 ) { -// std::cout << "New helix : " << std::endl; -// std::cout << " Position : " << pos[0] -// << " " << pos[1] -// << " " << pos[2] << std::endl; -// std::cout << " Radius = " << _radius << std::endl; -// std::cout << " RC = " << sqrt(_xCentre*_xCentre+_yCentre*_yCentre) << std::endl; -// std::cout << " D0 = " << _d0 << std::endl; -// } - - _pxAtPCA = _pxy*cos(_phi0); - _pyAtPCA = _pxy*sin(_phi0); - float deltaPhi = _phiRefPoint - _phiAtPCA; - float xCircles = -pos[2]*q/(_radius*_tanLambda) - deltaPhi; - xCircles = xCircles/_const_2pi; - int nCircles; - int n1,n2; - - if (xCircles >= 0.) { - n1 = int(xCircles); - n2 = n1 + 1; - } - else { - n1 = int(xCircles) - 1; - n2 = n1 + 1; - } - - if (fabs(n1-xCircles) < fabs(n2-xCircles)) { - nCircles = n1; - } - else { - nCircles = n2; - } - _z0 = pos[2] + _radius*_tanLambda*q*(deltaPhi + _const_2pi*nCircles); - -} - -void HelixClass::Initialize_Canonical(float phi0, float d0, float z0, - float omega, float tanLambda, float B) { - _omega = omega; - _d0 = d0; - _phi0 = phi0; - _z0 = z0; - _tanLambda = tanLambda; - _charge = omega/fabs(omega); - _radius = 1./fabs(omega); - _xAtPCA = -_d0*sin(_phi0); - _yAtPCA = _d0*cos(_phi0); - _referencePoint[0] = _xAtPCA; - _referencePoint[1] = _yAtPCA; - _referencePoint[2] = _z0; - _pxy = _FCT*B*_radius; - _momentum[0] = _pxy*cos(_phi0); - _momentum[1] = _pxy*sin(_phi0); - _momentum[2] = _tanLambda * _pxy; - _pxAtPCA = _momentum[0]; - _pyAtPCA = _momentum[1]; - _phiMomRefPoint = atan2(_momentum[1],_momentum[0]); - _xCentre = _referencePoint[0] + - _radius*cos(_phi0-_const_pi2*_charge); - _yCentre = _referencePoint[1] + - _radius*sin(_phi0-_const_pi2*_charge); - _phiAtPCA = atan2(-_yCentre,-_xCentre); - _phiRefPoint = _phiAtPCA ; - _bField = B; -} - - -void HelixClass::Initialize_BZ(float xCentre, float yCentre, float radius, - float bZ, float phi0, float B, float signPz, - float zBegin) { - - _radius = radius; - _pxy = _FCT*B*_radius; - _charge = -(bZ*signPz)/fabs(bZ*signPz); - _momentum[2] = -_charge*_pxy/(bZ*_radius); - _xCentre = xCentre; - _yCentre = yCentre; - _omega = _charge/radius; - _phiAtPCA = atan2(-_yCentre,-_xCentre); - _phi0 = -_const_pi2*_charge + _phiAtPCA; - while (_phi0<0) _phi0+=_const_2pi; - while (_phi0>=_const_2pi) _phi0-=_const_2pi; - _xAtPCA = _xCentre + _radius*cos(_phiAtPCA); - _yAtPCA = _yCentre + _radius*sin(_phiAtPCA); - _d0 = -_xAtPCA*sin(_phi0) + _yAtPCA*cos(_phi0); - _pxAtPCA = _pxy*cos(_phi0); - _pyAtPCA = _pxy*sin(_phi0); - _referencePoint[2] = zBegin; - _referencePoint[0] = xCentre + radius*cos(bZ*zBegin+phi0); - _referencePoint[1] = yCentre + radius*sin(bZ*zBegin+phi0); - _phiRefPoint = atan2(_referencePoint[1]-_yCentre,_referencePoint[0]-_xCentre); - _phiMomRefPoint = -_const_pi2*_charge + _phiRefPoint; - _tanLambda = _momentum[2]/_pxy; - _momentum[0] = _pxy*cos(_phiMomRefPoint); - _momentum[1] = _pxy*sin(_phiMomRefPoint); - - float deltaPhi = _phiRefPoint - _phiAtPCA; - float xCircles = bZ*_referencePoint[2] - deltaPhi; - xCircles = xCircles/_const_2pi; - int nCircles; - int n1,n2; - - if (xCircles >= 0.) { - n1 = int(xCircles); - n2 = n1 + 1; - } - else { - n1 = int(xCircles) - 1; - n2 = n1 + 1; - } - - if (fabs(n1-xCircles) < fabs(n2-xCircles)) { - nCircles = n1; - } - else { - nCircles = n2; - } - _z0 = _referencePoint[2] - (deltaPhi + _const_2pi*nCircles)/bZ; - _bField = B; - -} - -const float * HelixClass::getMomentum() { - return _momentum; -} -const float * HelixClass::getReferencePoint() { - return _referencePoint; -} -float HelixClass::getPhi0() { - if (_phi0<0.0) - _phi0 += 2*M_PI; - return _phi0; -} -float HelixClass::getD0() { - return _d0; -} -float HelixClass::getZ0() { - return _z0; -} -float HelixClass::getOmega() { - return _omega; -} -float HelixClass::getTanLambda() { - return _tanLambda; -} -float HelixClass::getPXY() { - return _pxy; -} -float HelixClass::getXC() { - return _xCentre; -} - -float HelixClass::getYC() { - return _yCentre; -} - -float HelixClass::getRadius() { - return _radius; -} - -float HelixClass::getBz() { - return _bZ; -} - -float HelixClass::getPhiZ() { - return _phiZ; -} - -float HelixClass::getCharge() { - return _charge; -} - -float HelixClass::getPointInXY(float x0, float y0, float ax, float ay, - float * ref , float * point) { - - float time; - - float AA = sqrt(ax*ax+ay*ay); - - - if (AA <= 0) { - time = -1.0e+20; - return time; - } - - - float BB = ax*(x0-_xCentre) + ay*(y0-_yCentre); - BB = BB / AA; - - float CC = (x0-_xCentre)*(x0-_xCentre) - + (y0-_yCentre)*(y0-_yCentre) - _radius*_radius; - - CC = CC / AA; - - float DET = BB*BB - CC; - float tt1 = 0.; - float tt2 = 0.; - float xx1,xx2,yy1,yy2; - - - if (DET < 0 ) { - time = 1.0e+10; - point[0]=0.0; - point[1]=0.0; - point[2]=0.0; - return time; - } - - - tt1 = - BB + sqrt(DET); - tt2 = - BB - sqrt(DET); - - xx1 = x0 + tt1*ax; - yy1 = y0 + tt1*ay; - xx2 = x0 + tt2*ax; - yy2 = y0 + tt2*ay; - - float phi1 = atan2(yy1-_yCentre,xx1-_xCentre); - float phi2 = atan2(yy2-_yCentre,xx2-_xCentre); - float phi0 = atan2(ref[1]-_yCentre,ref[0]-_xCentre); - - float dphi1 = phi1 - phi0; - float dphi2 = phi2 - phi0; - - if (dphi1 < 0 && _charge < 0) { - dphi1 = dphi1 + _const_2pi; - } - else if (dphi1 > 0 && _charge > 0) { - dphi1 = dphi1 - _const_2pi; - } - - if (dphi2 < 0 && _charge < 0) { - dphi2 = dphi2 + _const_2pi; - } - else if (dphi2 > 0 && _charge > 0) { - dphi2 = dphi2 - _const_2pi; - } - - // Times - tt1 = -_charge*dphi1*_radius/_pxy; - tt2 = -_charge*dphi2*_radius/_pxy; - - if (tt1 < 0. ) - std::cout << "WARNING " << tt1 << std::endl; - if (tt2 < 0. ) - std::cout << "WARNING " << tt2 << std::endl; - - - if (tt1 < tt2) { - point[0] = xx1; - point[1] = yy1; - time = tt1; - } - else { - point[0] = xx2; - point[1] = yy2; - time = tt2; - } - - point[2] = ref[2]+time*_momentum[2]; - - - - return time; - -} - - -float HelixClass::getPointOnCircle(float Radius, float * ref, float * point) { - - float distCenterToIP = sqrt(_xCentre*_xCentre + _yCentre*_yCentre); - - point[0] = 0.0; - point[1] = 0.0; - point[2] = 0.0; - - if ((distCenterToIP+_radius)<Radius) { - float xx = -1.0e+20; - return xx; - } - - if ((_radius+Radius)<distCenterToIP) { - float xx = -1.0e+20; - return xx; - } - - float phiCentre = atan2(_yCentre,_xCentre); - float phiStar = Radius*Radius + distCenterToIP*distCenterToIP - - _radius*_radius; - - phiStar = 0.5*phiStar/fmax(1.0e-20,Radius*distCenterToIP); - - if (phiStar > 1.0) - phiStar = 0.9999999; - - if (phiStar < -1.0) - phiStar = -0.9999999; - - phiStar = acos(phiStar); - - float tt1,tt2,time; - - float xx1 = Radius*cos(phiCentre+phiStar); - float yy1 = Radius*sin(phiCentre+phiStar); - - float xx2 = Radius*cos(phiCentre-phiStar); - float yy2 = Radius*sin(phiCentre-phiStar); - - - float phi1 = atan2(yy1-_yCentre,xx1-_xCentre); - float phi2 = atan2(yy2-_yCentre,xx2-_xCentre); - float phi0 = atan2(ref[1]-_yCentre,ref[0]-_xCentre); - - float dphi1 = phi1 - phi0; - float dphi2 = phi2 - phi0; - - if (dphi1 < 0 && _charge < 0) { - dphi1 = dphi1 + _const_2pi; - } - else if (dphi1 > 0 && _charge > 0) { - dphi1 = dphi1 - _const_2pi; - } - - if (dphi2 < 0 && _charge < 0) { - dphi2 = dphi2 + _const_2pi; - } - else if (dphi2 > 0 && _charge > 0) { - dphi2 = dphi2 - _const_2pi; - } - - // Times - tt1 = -_charge*dphi1*_radius/_pxy; - tt2 = -_charge*dphi2*_radius/_pxy; - - if (tt1 < 0. ) - std::cout << "WARNING " << tt1 << std::endl; - if (tt2 < 0. ) - std::cout << "WARNING " << tt2 << std::endl; - - - float time2; - if (tt1 < tt2) { - point[0] = xx1; - point[1] = yy1; - point[3] = xx2; - point[4] = yy2; - time = tt1; - time2 = tt2; - } - else { - point[0] = xx2; - point[1] = yy2; - point[3] = xx1; - point[4] = yy1; - time = tt2; - time2 = tt1; - } - - point[2] = ref[2]+time*_momentum[2]; - point[5] = ref[2]+time2*_momentum[2]; - - - return time; - -} - - -float HelixClass::getPointInZ(float zLine, float * ref, float * point) { - - float time = zLine - ref[2]; - - if (_momentum[2] == 0.) { - time = -1.0e+20; - point[0] = 0.; - point[1] = 0.; - point[2] = 0.; - return time; - } - - time = time/_momentum[2]; - - float phi0 = atan2(ref[1] - _yCentre , ref[0] - _xCentre); - float phi = phi0 - _charge*_pxy*time/_radius; - float xx = _xCentre + _radius*cos(phi); - float yy = _yCentre + _radius*sin(phi); - - point[0] = xx; - point[1] = yy; - point[2] = zLine; - - return time; - - -} - -float HelixClass::getDistanceToPoint(float * xPoint, float * Distance) { - - float zOnHelix; - float phi = atan2(xPoint[1]-_yCentre,xPoint[0]-_xCentre); - float phi0 = atan2(_referencePoint[1]-_yCentre,_referencePoint[0]-_xCentre); - //calculate distance to XYprojected centre of Helix, comparing this with distance to radius around centre gives DistXY - float DistXY = (_xCentre-xPoint[0])*(_xCentre-xPoint[0]) + (_yCentre-xPoint[1])*(_yCentre-xPoint[1]); - DistXY = sqrt(DistXY); - DistXY = fabs(DistXY - _radius); - - int nCircles = 0; - - if (fabs(_tanLambda*_radius)>1.0e-20) { - float xCircles = phi0 - phi -_charge*(xPoint[2]-_referencePoint[2])/(_tanLambda*_radius); - xCircles = xCircles/_const_2pi; - int n1,n2; - - if (xCircles >= 0.) { - n1 = int(xCircles); - n2 = n1 + 1; - } - else { - n1 = int(xCircles) - 1; - n2 = n1 + 1; - } - - if (fabs(n1-xCircles) < fabs(n2-xCircles)) { - nCircles = n1; - } - else { - nCircles = n2; - } - - } - - float DPhi = _const_2pi*((float)nCircles) + phi - phi0; - - zOnHelix = _referencePoint[2] - _charge*_radius*_tanLambda*DPhi; - - float DistZ = fabs(zOnHelix - xPoint[2]); - float Time; - - if (fabs(_momentum[2]) > 1.0e-20) { - Time = (zOnHelix - _referencePoint[2])/_momentum[2]; - } - else { - Time = _charge*_radius*DPhi/_pxy; - } - - Distance[0] = DistXY; - Distance[1] = DistZ; - Distance[2] = sqrt(DistXY*DistXY+DistZ*DistZ); - - return Time; - - -} - -//When we are not interested in the exact distance, we can check if we are -//already far enough away in XY, before we start calculating in Z as the -//distance will only increase -float HelixClass::getDistanceToPoint(const std::vector<float>& xPoint, float distCut) { - //calculate distance to XYprojected centre of Helix, comparing this with distance to radius around centre gives DistXY - float tempx = xPoint[0]-_xCentre; - float tempy = xPoint[1]-_yCentre; - float tempsq = sqrt(tempx*tempx + tempy*tempy); - float tempdf = tempsq - _radius; - float DistXY = fabs( tempdf ); - //If this is bigger than distCut, we dont have to know how much bigger this is - if( DistXY > distCut) { - return DistXY; - } - - int nCircles = 0; - float phi = atan2(tempy,tempx); - float phi0 = atan2(_referencePoint[1]-_yCentre,_referencePoint[0]-_xCentre); - float phidiff = phi0-phi; - float tempz = xPoint[2] - _referencePoint[2];//Yes referencePoint - float tanradius = _tanLambda*_radius; - if (fabs(tanradius)>1.0e-20) { - float xCircles = (phidiff -_charge*tempz/tanradius)/_const_2pi; - int n1,n2; - if (xCircles >= 0.) { - n1 = int(xCircles); - n2 = n1 + 1; - } - else { - n1 = int(xCircles) - 1; - n2 = n1 + 1; - } - if (fabs(n1-xCircles) < fabs(n2-xCircles)) { - nCircles = n1; - } - else { - nCircles = n2; - } - } - float DistZ = - tempz - _charge*tanradius*(_const_2pi*((float)nCircles) - phidiff); - return sqrt(DistXY*DistXY+DistZ*DistZ); -}//getDistanceToPoint(vector,float) - -float HelixClass::getDistanceToPoint(const float* xPoint, float distCut) { - std::vector<float> xPosition(xPoint, xPoint + 3 );//We are expecting three coordinates, must be +3, last element is excluded! - return getDistanceToPoint(xPosition, distCut); -}//getDistanceToPoint(float*,float) - - - -void HelixClass::setHelixEdges(float * xStart, float * xEnd) { - for (int i=0; i<3; ++i) { - _xStart[i] = xStart[i]; - _xEnd[i] = xEnd[i]; - } - -} - -float HelixClass::getDistanceToHelix(HelixClass * helix, float * pos, float * mom) { - - float x01 = getXC(); - float y01 = getYC(); - - float x02 = helix->getXC(); - float y02 = helix->getYC(); - - float rad1 = getRadius(); - float rad2 = helix->getRadius(); - - float distance = sqrt((x01-x02)*(x01-x02)+(y01-y02)*(y01-y02)); - - bool singlePoint = true; - - float phi1 = 0; - float phi2 = 0; - - if (rad1+rad2<distance) { - phi1 = atan2(y02-y01,x02-x01); - phi2 = atan2(y01-y02,x01-x02); - } - else if (distance+rad2<rad1) { - phi1 = atan2(y02-y01,x02-x01); - phi2 = phi1; - } - else if (distance+rad1<rad2) { - phi1 = atan2(y01-y02,x01-x02); - phi2 = phi1; - } - else { - singlePoint = false; - float cosAlpha = 0.5*(distance*distance+rad2*rad2-rad1*rad1)/(distance*rad2); - float alpha = acos(cosAlpha); - float phi0 = atan2(y01-y02,x01-x02); - phi1 = phi0 + alpha; - phi2 = phi0 - alpha; - } - - - float ref1[3]; - float ref2[3]; - for (int i=0;i<3;++i) { - ref1[i]=_referencePoint[i]; - ref2[i]=helix->getReferencePoint()[i]; - } - - float pos1[3]; - float pos2[3]; - float mom1[3]; - float mom2[3]; - - - if (singlePoint ) { - - float xSect1 = x01 + rad1*cos(phi1); - float ySect1 = y01 + rad1*sin(phi1); - float xSect2 = x02 + rad2*cos(phi2); - float ySect2 = y02 + rad2*sin(phi2); - float R1 = sqrt(xSect1*xSect1+ySect1*ySect1); - float R2 = sqrt(xSect2*xSect2+ySect2*ySect2); - - getPointOnCircle(R1,ref1,pos1); - helix->getPointOnCircle(R2,ref2,pos2); - - } - else { - - float xSect1 = x02 + rad2*cos(phi1); - float ySect1 = y02 + rad2*sin(phi1); - float xSect2 = x02 + rad2*cos(phi2); - float ySect2 = y02 + rad2*sin(phi2); - -// std::cout << "(xSect1,ySect1)=(" << xSect1 << "," << ySect1 << ")" << std::endl; -// std::cout << "(xSect2,ySect2)=(" << xSect2 << "," << ySect2 << ")" << std::endl; - - float temp21[3]; - float temp22[3]; - - float phiI2 = atan2(ref2[1]-y02,ref2[0]-x02); - float phiF21 = atan2(ySect1-y02,xSect1-x02); - float phiF22 = atan2(ySect2-y02,xSect2-x02); - float deltaPhi21 = phiF21 - phiI2; - float deltaPhi22 = phiF22 - phiI2; - float charge2 = helix->getCharge(); - float pxy2 = helix->getPXY(); - float pz2 = helix->getMomentum()[2]; - if (deltaPhi21 < 0 && charge2 < 0) { - deltaPhi21 += _const_2pi; - } - else if (deltaPhi21 > 0 && charge2 > 0) { - deltaPhi21 -= _const_2pi; - } - - if (deltaPhi22 < 0 && charge2 < 0) { - deltaPhi22 += _const_2pi; - } - else if (deltaPhi22 > 0 && charge2 > 0) { - deltaPhi22 -= _const_2pi; - } - - float time21 = -charge2*deltaPhi21*rad2/pxy2; - float time22 = -charge2*deltaPhi22*rad2/pxy2; - - float Z21 = ref2[2] + time21*pz2; - float Z22 = ref2[2] + time22*pz2; - - temp21[0] = xSect1; temp21[1] = ySect1; temp21[2] = Z21; - temp22[0] = xSect2; temp22[1] = ySect2; temp22[2] = Z22; - - -// std::cout << "temp21 = " << temp21[0] << " " << temp21[1] << " " << temp21[2] << std::endl; -// std::cout << "temp22 = " << temp22[0] << " " << temp22[1] << " " << temp22[2] << std::endl; - - - float temp11[3]; - float temp12[3]; - - float phiI1 = atan2(ref1[1]-y01,ref1[0]-x01); - float phiF11 = atan2(ySect1-y01,xSect1-x01); - float phiF12 = atan2(ySect2-y01,xSect2-x01); - float deltaPhi11 = phiF11 - phiI1; - float deltaPhi12 = phiF12 - phiI1; - float charge1 = _charge; - float pxy1 = _pxy; - float pz1 = _momentum[2]; - if (deltaPhi11 < 0 && charge1 < 0) { - deltaPhi11 += _const_2pi; - } - else if (deltaPhi11 > 0 && charge1 > 0) { - deltaPhi11 -= _const_2pi; - } - - if (deltaPhi12 < 0 && charge1 < 0) { - deltaPhi12 += _const_2pi; - } - else if (deltaPhi12 > 0 && charge1 > 0) { - deltaPhi12 -= _const_2pi; - } - - float time11 = -charge1*deltaPhi11*rad1/pxy1; - float time12 = -charge1*deltaPhi12*rad1/pxy1; - - float Z11 = ref1[2] + time11*pz1; - float Z12 = ref1[2] + time12*pz1; - - temp11[0] = xSect1; temp11[1] = ySect1; temp11[2] = Z11; - temp12[0] = xSect2; temp12[1] = ySect2; temp12[2] = Z12; - -// std::cout << "temp11 = " << temp11[0] << " " << temp11[1] << " " << temp11[2] << std::endl; -// std::cout << "temp12 = " << temp12[0] << " " << temp12[1] << " " << temp12[2] << std::endl; - - float Dist1 = 0; - float Dist2 = 0; - - for (int j=0;j<3;++j) { - Dist1 += (temp11[j]-temp21[j])*(temp11[j]-temp21[j]); - Dist2 += (temp12[j]-temp22[j])*(temp12[j]-temp22[j]); - } - - if (Dist1<Dist2) { - for (int l=0;l<3;++l) { - pos1[l] = temp11[l]; - pos2[l] = temp21[l]; - } - } - else { - for (int l=0;l<3;++l) { - pos1[l] = temp12[l]; - pos2[l] = temp22[l]; - } - } - - } - - getExtrapolatedMomentum(pos1,mom1); - helix->getExtrapolatedMomentum(pos2,mom2); - - float helixDistance = 0; - - for (int i=0;i<3;++i) { - helixDistance += (pos1[i] - pos2[i])*(pos1[i] - pos2[i]); - pos[i] = 0.5*(pos1[i]+pos2[i]); - mom[i] = mom1[i]+mom2[i]; - } - helixDistance = sqrt(helixDistance); - - return helixDistance; - -} - -void HelixClass::getExtrapolatedMomentum(float * pos, float * momentum) { - - float phi = atan2(pos[1]-_yCentre,pos[0]-_xCentre); - if (phi <0.) phi += _const_2pi; - phi = phi - _phiAtPCA + _phi0; - momentum[0] = _pxy*cos(phi); - momentum[1] = _pxy*sin(phi); - momentum[2] = _momentum[2]; - - -} diff --git a/Utilities/DataHelper/src/LineClass.cc~ b/Utilities/DataHelper/src/LineClass.cc~ deleted file mode 100644 index e23db1fa3f46982b8fff4a5ecb27a0264896f97d..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/LineClass.cc~ +++ /dev/null @@ -1,73 +0,0 @@ -#include "LineClass.h" -#include <math.h> - -/* - * Constructor - */ - -LineClass::LineClass(float x0, - float y0, - float z0, - float ax, - float ay, - float az) { - _x0[0] = x0; - _x0[1] = y0; - _x0[2] = z0; - _ax[0] = ax; - _ax[1] = ay; - _ax[2] = az; -} - -LineClass::LineClass(float *x0, - float *ax) { - - for (int i=0; i<3; ++i) { - _x0[i] = x0[i]; - _ax[i] = ax[i]; - } -} - -float * LineClass::getReferencePoint() { - return _x0; -} - -float * LineClass::getDirectionalVector() { - return _ax; -} - -void LineClass::setReferencePoint(float *x0) { - for (int i=0; i<3; ++i) - _x0[i] = x0[i]; -} - -void LineClass::setDirectionalVector(float *ax) { - for (int i=0; i<3; ++i) - _ax[i] = ax[i]; - -} - -float LineClass::getDistanceToPoint(float * xpoint, float * pos) { - - float dif[3]; - float prod = 0; - float den = 0; - for (int i=0; i<3; ++i) { - dif[i] = xpoint[i] - _x0[i]; - prod += _ax[i]*dif[i]; - den += _ax[i]*_ax[i]; - } - float time = prod/fmax(1e-10,den); - - float dist = 0.0; - for (int i=0; i<3; ++i) { - pos[i] = _x0[i] + _ax[i]*time; - dist += (xpoint[i]-pos[i])*(xpoint[i]-pos[i]); - } - dist = sqrt(dist); - - return dist; - - - -} diff --git a/Utilities/DataHelper/src/TrackExtended.cc~ b/Utilities/DataHelper/src/TrackExtended.cc~ deleted file mode 100644 index 773937055c850be0249ad5b0d732f8e88462b251..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/TrackExtended.cc~ +++ /dev/null @@ -1,229 +0,0 @@ -#include "ClusterExtended.h" -#include "TrackerHitExtended.h" -#include "TrackExtended.h" -#include <math.h> - -TrackExtended::TrackExtended( ) { - _track = NULL; - _superCluster = NULL; - _trackerHitVector.clear(); - _clusterVec.clear(); - _group = NULL; -} - -TrackExtended::TrackExtended( Track * track) { - _track = track; - _superCluster = NULL; - _trackerHitVector.clear(); - _clusterVec.clear(); - _group = NULL; - -} - -TrackExtended::TrackExtended( TrackerHitExtended * trackerhit) { - _trackerHitVector.clear(); - _trackerHitVector.push_back(trackerhit); - _track = NULL; - _superCluster = NULL; - _clusterVec.clear(); - _group = NULL; -} - - -TrackExtended::~TrackExtended() {} - -Track * TrackExtended::getTrack() { - return _track; -} - -const float * TrackExtended::getSeedPosition() { - return _seedPosition; -} - -const float * TrackExtended::getSeedDirection() { - return _seedDirection; -} - -ClusterExtendedVec & TrackExtended::getClusterVec() { - return _clusterVec; -} - -ClusterExtended * TrackExtended::getSuperCluster() { - return _superCluster; -} - -TrackerHitExtendedVec & TrackExtended::getTrackerHitExtendedVec() { - return _trackerHitVector; -} - -void TrackExtended::addCluster(ClusterExtended * cluster) { - _clusterVec.push_back(cluster); -} - -void TrackExtended::setSuperCluster(ClusterExtended * superCluster) { - _superCluster = superCluster; -} - -void TrackExtended::setSeedDirection( float * seedDirection ) { - _seedDirection[0] = seedDirection[0]; - _seedDirection[1] = seedDirection[1]; - _seedDirection[2] = seedDirection[2]; -} - -void TrackExtended::setSeedPosition( float * seedPosition) { - _seedPosition[0] = seedPosition[0]; - _seedPosition[1] = seedPosition[1]; - _seedPosition[2] = seedPosition[2]; -} - -void TrackExtended::addTrackerHitExtended( TrackerHitExtended * trackerhit) { - _trackerHitVector.push_back(trackerhit); - -} - -void TrackExtended::ClearTrackerHitExtendedVec() { - _trackerHitVector.clear(); -} - -void TrackExtended::setX0( float x0 ) { - _x0 = x0; -} - -void TrackExtended::setD0( float d0 ) { - _d0 = d0; -} - -void TrackExtended::setZ0( float z0 ) { - _z0 = z0; -} - -void TrackExtended::setY0( float y0 ) { - _y0 = y0; -} - -void TrackExtended::setR0( float r0 ) { - _r0 = r0; -} - -void TrackExtended::setBz( float bz ) { - _bz = bz; -} - -void TrackExtended::setPhi0( float phi0 ) { - _phi0 = phi0; -} - -void TrackExtended::setPhi( float phi ) { - _phi = phi; -} - -void TrackExtended::setOmega( float omega ) { - _omega = omega; -} - -void TrackExtended::setTanLambda( float tanLambda ) { - _tanLambda = tanLambda; -} -void TrackExtended::setNDF( int ndf) { - _ndf = ndf; -} - - -float TrackExtended::getX0() { - return _x0; -} - -float TrackExtended::getY0() { - return _y0; -} - -float TrackExtended::getR0() { - return _r0; -} - -float TrackExtended::getBz() { - return _bz; -} - -float TrackExtended::getD0() { - return _d0; -} - -float TrackExtended::getZ0() { - return _z0; -} - -float TrackExtended::getPhi0() { - return _phi0; -} - -float TrackExtended::getPhi() { - return _phi; -} - -float TrackExtended::getOmega() { - return _omega; -} - -float TrackExtended::getTanLambda() { - return _tanLambda; -} - -int TrackExtended::getNDF() { - return _ndf; -} - -void TrackExtended::setStart(float * xStart) { - _xStart[0] = xStart[0]; - _xStart[1] = xStart[1]; - _xStart[2] = xStart[2]; -} - -void TrackExtended::setEnd(float * xEnd) { - _xEnd[0] = xEnd[0]; - _xEnd[1] = xEnd[1]; - _xEnd[2] = xEnd[2]; -} - -float * TrackExtended::getStart() { - return _xStart; -} - -float * TrackExtended::getEnd() { - return _xEnd; -} - -void TrackExtended::setGroupTracks( GroupTracks * group ) { - _group = group; -} - -GroupTracks * TrackExtended::getGroupTracks() { - return _group; -} - -float TrackExtended::getChi2() { - return _chi2; -} - -void TrackExtended::setChi2(float chi2) { - _chi2 = chi2; -} - -void TrackExtended::setCovMatrix(float * cov) { - for (int i=0; i<15; ++i) - _cov[i] = cov[i]; -} - -float * TrackExtended::getCovMatrix() { - return _cov; -} - -// void TrackExtended::setType(int type) { -// _type = type - -// } - -// int TrackExtended::getType() { -// return _type; - -// } diff --git a/Utilities/DataHelper/src/TrackExtended.h~ b/Utilities/DataHelper/src/TrackExtended.h~ deleted file mode 100644 index e6cbd4a03eb21bb267221a97dd853d49ef86c1c9..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/TrackExtended.h~ +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef TRACKAR_H -#define TRACKAR_H 1 - -//#include "lcio.h" -//#include "EVENT/LCIO.h" -#include "plcio/Track.h" -#include <vector> -//#include "ClusterExtended.h" -//#include "TrackerHitExtended.h" -#include "GroupTracks.h" - -using namespace plcio; - -class ClusterExtended; -//class GroupTracks; -class TrackerHitExtended; -typedef std::vector<TrackerHitExtended*> TrackerHitExtendedVec; -typedef std::vector<ClusterExtended*> ClusterExtendedVec; - -/** - * Class extending native LCIO class Track. <br> - * Class TrackExtended is used in TrackwiseClustering <br> - * and Wolf processors. <br> - * @author A. Raspereza (DESY)<br> - * @version $Id: TrackExtended.h,v 1.8 2007-09-05 09:39:49 rasp Exp $<br> - */ - -class TrackExtended { - - public: - - - TrackExtended( ); - TrackExtended( TrackerHitExtended * trackerhit ); - TrackExtended( plcio::Track * track ); - ~TrackExtended(); - - plcio::Track * getTrack(); - const float * getSeedDirection(); - const float * getSeedPosition(); - ClusterExtendedVec & getClusterVec(); - ClusterExtended * getSuperCluster(); - TrackerHitExtendedVec & getTrackerHitExtendedVec(); - void addCluster(ClusterExtended * cluster); - void setSuperCluster(ClusterExtended * superCluster); - void setSeedDirection( float * seedDirection ); - void setSeedPosition( float * seedPosition); - void addTrackerHitExtended( TrackerHitExtended * trackerhit); - void ClearTrackerHitExtendedVec(); - - void setX0(float x0); - void setY0(float y0); - void setR0(float r0); - void setD0(float d0); - void setZ0(float z0); - void setBz(float bz); - void setPhi0(float phi0); - void setPhi(float phi); - void setOmega(float omega); - void setTanLambda(float tanLambda); - - - void setStart(float * xStart); - void setEnd(float * xEnd); - - - float getX0(); - float getY0(); - float getD0(); - float getZ0(); - float getOmega(); - float getTanLambda(); - float getPhi(); - float getR0(); - float getBz(); - float getPhi0(); - - float * getStart(); - float * getEnd(); - - void setGroupTracks( GroupTracks * group ); - GroupTracks * getGroupTracks(); - - float getChi2(); - void setChi2(float chi2); - - int getNDF(); - void setNDF(int ndf); - - float * getCovMatrix(); - void setCovMatrix( float * cov); - - private: - - ClusterExtended *_superCluster; - ClusterExtendedVec _clusterVec; - GroupTracks * _group; - Track * _track; - float _seedDirection[3]; - float _seedPosition[3]; - TrackerHitExtendedVec _trackerHitVector; - - float _x0; - float _y0; - float _r0; - float _bz; - float _phi0; - - float _xStart[3]; - float _xEnd[3]; - - float _d0; // d0 in canonical parameterisation - float _z0; // z0 in canonical parameterisation - float _omega; // omega in canonical parameterisation - float _tanLambda; // tanlambda in canonical parameterisation - float _phi; // phi in canonical parameterisation - - float _chi2; // chi2 of the fit - - float _cov[15]; // covariance matrix - - int _ndf; // NDF - - int _type; // Track type; - -}; - -typedef std::vector<TrackExtended*> TrackExtendedVec; - -#endif diff --git a/Utilities/DataHelper/src/TrackerHitExtended.cc~ b/Utilities/DataHelper/src/TrackerHitExtended.cc~ deleted file mode 100644 index 551b1923c5ca4df818c95cbad6abe394195145a9..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/TrackerHitExtended.cc~ +++ /dev/null @@ -1,133 +0,0 @@ -#include "TrackExtended.h" -#include "TrackerHitExtended.h" - -TrackerHitExtended::TrackerHitExtended(const edm4hep::TrackerHit& trackerhit): - _trackerHit(trackerhit){ - _trackAR = NULL; - _trackVecAR.clear(); - _usedInFit = false; -} - -TrackerHitExtended::~TrackerHitExtended() { - -} - -void TrackerHitExtended::setTrackExtended(TrackExtended * trackAR) { - _trackAR = trackAR; - _trackVecAR.clear(); - _trackVecAR.push_back(trackAR); - -} - -void TrackerHitExtended::addTrackExtended(TrackExtended * trackAR) { - _trackVecAR.push_back(trackAR); -} - -TrackExtendedVec & TrackerHitExtended::getTrackExtendedVec() { - return _trackVecAR; -} - - -void TrackerHitExtended::setTrackerHitTo(TrackerHitExtended * hitTo) { - _hitTo = hitTo; -} - -void TrackerHitExtended::setTrackerHitFrom(TrackerHitExtended * hitFrom) { - _hitFrom = hitFrom; - -} - -void TrackerHitExtended::setGenericDistance(float genericDistance) { - _genericDistance = genericDistance; -} - -//void TrackerHitExtended::setTrackerHit(edm4hep::TrackerHit * hit) { -// _trackerHit = hit; -//} - -void TrackerHitExtended::setYresTo(float yresTo) { - _yresTo = yresTo; -} - -void TrackerHitExtended::setYresFrom(float yresFrom) { - _yresFrom = yresFrom; -} - -void TrackerHitExtended::setDirVec(float * dirVec) { - _dirVec[0] = dirVec[0]; - _dirVec[1] = dirVec[1]; - _dirVec[2] = dirVec[2]; -} - -void TrackerHitExtended::setType(int ityp) { - _type = ityp; -} - -void TrackerHitExtended::setDet(int idet) { - _idet = idet; -} - -edm4hep::TrackerHit * TrackerHitExtended::getTrackerHit() { - return &_trackerHit; -} - -TrackExtended * TrackerHitExtended::getTrackExtended() { - return _trackAR; -} - -TrackerHitExtended * TrackerHitExtended::getTrackerHitFrom() { - return _hitFrom; -} -TrackerHitExtended * TrackerHitExtended::getTrackerHitTo() { - return _hitTo; -} -float TrackerHitExtended::getGenericDistance() { - return _genericDistance; -} -float TrackerHitExtended::getYresTo() { - return _yresTo; -} -float TrackerHitExtended::getYresFrom() { - return _yresFrom; -} - -float * TrackerHitExtended::getDirVec() { - return _dirVec; -} - -void TrackerHitExtended::clearTrackVec() { - _trackVecAR.clear(); -} - -float TrackerHitExtended::getResolutionRPhi() { - return _rphiReso; -} - -float TrackerHitExtended::getResolutionZ() { - return _zReso; -} - -void TrackerHitExtended::setResolutionRPhi(float rphiReso) { - _rphiReso = rphiReso; -} - -void TrackerHitExtended::setResolutionZ(float zReso) { - _zReso = zReso; -} - -int TrackerHitExtended::getType() { - return _type; -} - -int TrackerHitExtended::getDet() { - return _idet; -} - -void TrackerHitExtended::setUsedInFit(bool usedInFit) { - _usedInFit = usedInFit; -} - -bool TrackerHitExtended::getUsedInFit() { - return _usedInFit; -} - diff --git a/Utilities/DataHelper/src/TrackerHitExtended.h~ b/Utilities/DataHelper/src/TrackerHitExtended.h~ deleted file mode 100644 index e2a85261afe5b9e119755766ea9bdb915e914f5e..0000000000000000000000000000000000000000 --- a/Utilities/DataHelper/src/TrackerHitExtended.h~ +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef TRACKERHITAR_H -#define TRACKERHITAR_H 1 - -//#include "lcio.h" -//#include "EVENT/LCIO.h" -#include "edm4hep/TrackerHit.h" -//#include "TrackExtended.h" -#include <vector> - - -//using namespace edm4hep; - -class TrackExtended; -typedef std::vector<TrackExtended*> TrackExtendedVec; - -/** - * Class extending native LCIO class TrackerHit. <br> - * Class TrackerHitExtended is used in TrackwiseClustering <br> - * and Wolf processors. <br> - * @author A. Raspereza (DESY)<br> - * @version $Id: TrackerHitExtended.h,v 1.7 2007-09-05 09:39:49 rasp Exp $<br> - */ -class TrackerHitExtended { - - public: - - TrackerHitExtended(const edm4hep::TrackerHit& trackerhit); - ~TrackerHitExtended(); - void setTrackExtended(TrackExtended * trackAR); - void addTrackExtended(TrackExtended * trackAR); - void setTrackerHitTo(TrackerHitExtended * hitTo); - void setTrackerHitFrom(TrackerHitExtended * hitFrom); - void setGenericDistance(float genericDistance); - void setTrackerHit(edm4hep::TrackerHit hit); - void setYresTo(float yresTo); - void setYresFrom(float yresFrom); - void setDirVec(float * dirVec); - void clearTrackVec(); - void setResolutionRPhi(float rphiReso); - void setResolutionZ(float zReso); - void setType(int type); - void setDet(int idet); - void setUsedInFit(bool usedInFit); - - edm4hep::TrackerHit* getTrackerHit(); - TrackExtended * getTrackExtended(); - TrackExtendedVec & getTrackExtendedVec(); - TrackerHitExtended * getTrackerHitFrom(); - TrackerHitExtended * getTrackerHitTo(); - float getGenericDistance(); - float getYresTo(); - float getYresFrom(); - float * getDirVec(); - float getResolutionRPhi(); - float getResolutionZ(); - int getType(); - int getDet(); - bool getUsedInFit(); - - private: - - edm4hep::TrackerHit _trackerHit; - TrackExtended * _trackAR; - TrackerHitExtended * _hitTo; - TrackerHitExtended * _hitFrom; - TrackExtendedVec _trackVecAR; - - float _rphiReso; - float _zReso; - float _yresTo; - float _yresFrom; - float _genericDistance; - float _dirVec[3]; - - int _type; - int _idet; - - bool _usedInFit; - -}; - -typedef std::vector<TrackerHitExtended*> TrackerHitExtendedVec; - -#endif