11 #include <gsl/gsl_randist.h>
12 #include "marlin/VerbosityLevels.h"
13 #include "marlin/ProcessorEventSeeder.h"
16 #include "SimpleHelix.h"
18 #include "LCCylinder.h"
19 #include <IMPL/LCFlagImpl.h>
20 #include <IMPL/LCRelationImpl.h>
24 #include "constants.h"
28 #include <marlin/Global.h>
29 #include <gear/GEAR.h>
30 #include <gear/TPCParameters.h>
31 #include <gear/PadRowLayout2D.h>
32 #include <gear/BField.h>
34 #include "UTIL/LCTrackerConf.h"
35 #include <UTIL/ILDConf.h>
37 using namespace lcio ;
38 using namespace marlin ;
39 using namespace constants ;
42 #ifdef MARLIN_USE_AIDA
43 using namespace AIDA ;
62 _description =
"Produces TPC TrackerHit collection from SimTrackerHit collection, smeared in RPhi and Z. A search is made for adjacent hits on a pad row, if they are closer in z and r-phi than the steering parameters _doubleHitResRPhi (default value 2.0 mm) and _doubleHitResZ (default value 5.0 mm) they are considered to overlap. Clusters of hits smaller than _maxMerge (default value 3) are merged into a single tracker hit, with the position given as the average poision of the hits in phi and in z. Clusters which have _maxMerge hits or more are determined to be identifiable as multiple hits, and are not added to the tracker hit collection. This of course means that good hits caught up in a cluster of background hits will be lossed." ;
66 registerInputCollection( LCIO::SIMTRACKERHIT,
67 "TPCPadRowHitCollectionName" ,
68 "Name of the default pad-row based SimTrackerHit collection" ,
70 std::string(
"TPCCollection") ) ;
72 registerInputCollection( LCIO::SIMTRACKERHIT,
73 "TPCSpacePointCollectionName" ,
74 "Name of the additional space point collection which provides additional guide hits between pad row centers." ,
76 std::string(
"TPCSpacePointCollection") ) ;
78 registerInputCollection( LCIO::SIMTRACKERHIT,
79 "TPCLowPtCollectionName" ,
80 "Name of the LowPt SimTrackerHit collection Produced by Mokka TPC Driver TPC0X" ,
82 std::string(
"TPCLowPtCollection") ) ;
84 registerOutputCollection( LCIO::TRACKERHIT,
86 "Name of the Output TrackerHit collection" ,
88 std::string(
"TPCTrackerHits") ) ;
90 registerOutputCollection(LCIO::LCRELATION,
91 "SimTrkHitRelCollection",
92 "Name of TrackerHit SimTrackHit relation collection",
94 std::string(
"TPCTrackerHitRelations"));
96 registerProcessorParameter(
"UseRawHitsToStoreSimhitPointer",
97 "Store the pointer to the SimTrackerHits in RawHits (deprecated) ",
101 registerProcessorParameter(
"PointResolutionPadPhi" ,
102 "Pad Phi Resolution constant in TPC" ,
106 registerProcessorParameter(
"RejectCellID0" ,
107 "whether or not to use hits without proper cell ID (pad row)" ,
111 registerProcessorParameter(
"PointResolutionRPhi" ,
112 "R-Phi Resolution constant in TPC" ,
116 registerProcessorParameter(
"DiffusionCoeffRPhi" ,
117 "R-Phi Diffusion Coefficent in TPC" ,
121 registerProcessorParameter(
"N_eff" ,
122 "Number of Effective electrons per pad in TPC" ,
126 registerProcessorParameter(
"PointResolutionZ" ,
127 "TPC Z Resolution Coefficent independent of diffusion" ,
131 registerProcessorParameter(
"DiffusionCoeffZ" ,
132 "Z Diffusion Coefficent in TPC" ,
136 registerProcessorParameter(
"HitSortingBinningZ" ,
137 "Defines spatial slice in Z" ,
141 registerProcessorParameter(
"HitSortingBinningRPhi" ,
142 "Defines spatial slice in RP" ,
147 registerProcessorParameter(
"DoubleHitResolutionZ" ,
148 "Defines the minimum distance for two seperable hits in Z" ,
152 registerProcessorParameter(
"DoubleHitResolutionRPhi" ,
153 "Defines the minimum distance for two seperable hits in RPhi" ,
157 registerProcessorParameter(
"MaxClusterSizeForMerge" ,
158 "Defines the maximum number of adjacent hits which can be merged" ,
162 registerProcessorParameter(
"DontEncodeSide" ,
163 "Do not encode the side in the cellID of the TrackerHit",
184 _AF = AIDA_createAnalysisFactory();
189 _TRF = _AF->createTreeFactory();
213 _TREE = _TRF->create(
"TPCDigi.root",
227 _HF = _AF->createHistogramFactory(*_TREE);
229 _TREE->mkdir(
"Histograms");
251 _phiDiffHisto = _HF->createHistogram1D(
"Histograms/phi_diff",
252 "Calculated Phi - Track Phi",
255 _thetaDiffHisto = _HF->createHistogram1D(
"Histograms/theta_diff",
256 "Calculated Theta - Track Theta",
259 _phiRelHisto = _HF->createHistogram1D(
"Histograms/padPhi",
260 "Phi Relative to the Pad",
263 _thetaRelHisto = _HF->createHistogram1D(
"Histograms/padtheta",
264 "Theta Relative to the pad",
267 _rPhiDiffHisto = _HF->createHistogram1D(
"Histograms/rPhiDiff",
268 "rPhi_rec - rPhi_sim",
271 _zDiffHisto = _HF->createHistogram1D(
"Histograms/zDiff",
275 _zPullHisto = _HF->createHistogram1D(
"Histograms/zPull",
276 "(z_rec - z_sim) / Sigma_z",
279 _phiDistHisto = _HF->createHistogram1D(
"Histograms/phiDist",
283 _rPhiPullHisto = _HF->createHistogram1D(
"Histograms/rPhiPull",
284 "(rPhi_rec - rPhi_sim) / Sigma_rPhi",
287 _zSigmaVsZHisto = _HF->createHistogram2D(
"Histograms/zSigmaVsZ",
292 _zSigmaHisto = _HF->createHistogram1D(
"Histograms/zSigma",
296 _rPhiSigmaHisto = _HF->createHistogram1D(
"Histograms/rPhiSigma",
300 _radiusCheckHisto = _HF->createHistogram1D(
"Histograms/radiusCheck",
301 "R_hit - TPC Rmin - ((RowIndex + 0.5 )* padheight)",
304 _ResidualsRPhiHisto = _HF->createHistogram1D(
"Histograms/ResidualsRPhi",
305 "MC Track Phi - Hit Phi",
308 _NSimTPCHitsHisto = _HF->createHistogram1D(
"Histograms/SimTPCHits",
309 "Number of SimTPC Hits",
310 100, 0.0, 1000000.0);
312 _NBackgroundSimTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NBackgroundSimTPCHits",
313 "Number of Background SimTPC Hits",
314 100, 0.0, 1000000.0);
316 _NPhysicsSimTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NPhysicsSimTPCHits",
317 "Number of PhysicsSimTPC Hits",
320 _NPhysicsAbove02GeVSimTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NPhysicsAbove02GeVTPCHits",
321 "Number of PhysicsSimTPC Hits above 0.2GeV pt",
324 _NPhysicsAbove1GeVSimTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NPhysicsAbove1GeVPtTPCHits",
325 "Number of PhysicsSimTPC Hits above 1.0 GeV pt",
328 _NRecTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NRecTPCHits",
329 "Number of Rec TPC Hits",
332 _NLostPhysicsTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NLostPhysicsTPCHits",
333 "Number of PhysicsSimTPC Hits Lost",
336 _NLostPhysicsAbove02GeVPtTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NLostPhysicsAbove02GeVPtTPCHits",
337 "Number of PhysicsSimTPC Hits Lost above 0.2 GeV pt",
340 _NLostPhysicsAbove1GeVPtTPCHitsHisto = _HF->createHistogram1D(
"Histograms/NLostPhysicsAbove1GeVPtTPCHits",
341 "Number of PhysicsSimTPC Hits Lost above 1.0 GeV pt",
344 _NRevomedHitsHisto = _HF->createHistogram1D(
"Histograms/NRevomedHits",
345 "Number of Removed TPC hits",
346 100, 0.0, 1000000.0);
349 _NKeptPhysicsTPCHitsHistoPercent = _HF->createHistogram1D(
"Histograms/NKeptPhysicsTPCHitsPercent",
350 "Number of PhysicsSimTPC Hits Kept",
353 _NKeptPhysicsAbove02GeVPtTPCHitsHistoPercent = _HF->createHistogram1D(
"Histograms/NKeptPhysicsAbove02GeVPtTPCHitsPercent",
354 "Number of PhysicsSimTPC Hits Kept above 0.2 GeV pt",
357 _NKeptPhysicsAbove1GeVPtTPCHitsHistoPercent = _HF->createHistogram1D(
"Histograms/NKeptPhysicsAbove1GeVPtTPCHitsPercent",
358 "Number of PhysicsSimTPC Hits Kept above 1.0 GeV pt",
367 _random = gsl_rng_alloc(gsl_rng_ranlxs2);
368 Global::EVENTSEEDER->registerProcessor(
this);
384 gsl_rng_set(
_random, Global::EVENTSEEDER->getSeed(
this) ) ;
385 streamlog_out( DEBUG ) <<
"seed set to " << Global::EVENTSEEDER->getSeed(
this) <<
" for event number "<< evt->getEventNumber() << std::endl;
387 int numberOfVoxelsCreated(0);
401 static bool firstEvent =
true;
405 streamlog_out(DEBUG8) <<
" ========= processing event "
406 << std::setw(9) << evt->getEventNumber() <<
" run "
407 << std::setw(9) << evt->getRunNumber()
408 <<
" ========= " << endl;
411 if(firstEvent==
true) {
414 streamlog_out( DEBUG4 ) <<
"The relations to SimTrackerHits are now stored in relation collection " <<
_outRelColName <<
"\n SimTrackerHits are no longer stored in RawTrackerHits. Enable this deprecated feature by setting UseRawHitsToStoreSimhitPointer to true in steering file." << std::endl;
419 streamlog_out( DEBUG4 ) <<
"SimTrackerHits will be stored in RawTrackerHits. This is a deprecated please use the relations stored in " <<
_outRelColName << std::endl;
428 const gear::TPCParameters& gearTPC = Global::GEAR->getTPCParameters() ;
429 const gear::PadRowLayout2D& padLayout = gearTPC.getPadLayout() ;
431 const gear::Vector2D padCoord = padLayout.getPadCenter(1) ;
434 _padWidth = padLayout.getPadWidth(0)*padCoord[0];
443 LCFlagImpl lcFlag(0) ;
444 lcFlag.setBit( LCIO::LCREL_WEIGHTED ) ;
445 _relCol->setFlag( lcFlag.getFlag() ) ;
450 LCCollection* STHcol = 0 ;
454 catch(DataNotAvailableException &
e){
460 int n_sim_hits = STHcol->getNumberOfElements() ;
462 LCFlagImpl colFlag( STHcol->getFlag() ) ;
466 streamlog_out(DEBUG4) <<
"number of Pad-Row based SimHits = " << n_sim_hits << std::endl;
483 for(
int i=0; i< n_sim_hits; i++){
488 _SimTHit =
dynamic_cast<SimTrackerHit*
>( STHcol->getElementAt( i ) ) ;
492 double padTheta (0.0);
495 streamlog_out(DEBUG3) <<
"processing hit " << i << std::endl;
496 streamlog_out(DEBUG3) <<
" address = " <<
_SimTHit
497 <<
" x = " <<
_SimTHit->getPosition()[0]
498 <<
" y = " <<
_SimTHit->getPosition()[1]
499 <<
" z = " <<
_SimTHit->getPosition()[2]
505 double padheight = padLayout.getPadHeight(padLayout.getNearestPad(thisPoint.perp(),thisPoint.phi()));
507 const double bField = Global::GEAR->getBField().at(
gear::Vector3D( 0., 0., 0.) ).z() ;
509 const double FCT = 2.99792458E-4;
517 const double *momentumMC =
_mcp->getMomentum();
518 ptSqrdMC = momentumMC[0]*momentumMC[0]+momentumMC[1]*momentumMC[1] ;
520 streamlog_out(DEBUG3) <<
" mcp address = " <<
_mcp
521 <<
" px = " << momentumMC[0]
522 <<
" py = " << momentumMC[1]
523 <<
" pz = " << momentumMC[2]
540 if(colFlag.bitSet(LCIO::THBIT_MOMENTUM)) {
542 const float * mcpMomentum =
_SimTHit->getMomentum() ;
544 CLHEP::Hep3Vector mom(mcpMomentum[0],mcpMomentum[1],mcpMomentum[2]);
551 padPhi = fabs(thisPoint.deltaPhi(mom));
552 padTheta = mom.theta();
561 if (!
_mcp || (sqrt(ptSqrdMC) / (FCT*bField)) < ( padheight / (0.1 *
twopi))) {
567 padTheta =
twopi/4.0 ;
573 if (i < (n_sim_hits-1) ) {
574 _nextSimTHit =
dynamic_cast<SimTrackerHit*
>( STHcol->getElementAt( i+1 ) ) ;
582 if (i < (n_sim_hits-2) ) {
583 _nPlus2SimHit =
dynamic_cast<SimTrackerHit*
>( STHcol->getElementAt( i+2 ));
596 streamlog_out(DEBUG3) <<
"address of _previousSimTHit = " <<
_previousSimTHit
602 streamlog_out(DEBUG4) <<
"address of _nextSimTHit = " <<
_nextSimTHit
609 padPhi =
getPadPhi( &thisPoint, &precedingPoint, &thisPoint, &followingPoint);
610 padTheta =
getPadTheta(&precedingPoint, &thisPoint, &followingPoint);
619 padPhi =
getPadPhi( &thisPoint, &thisPoint, &followingPoint, &nPlus2Point);
620 padTheta =
getPadTheta(&thisPoint, &followingPoint, &nPlus2Point);
629 padPhi =
getPadPhi( &thisPoint, &nMinus2Point, &precedingPoint, &thisPoint);
630 padTheta =
getPadTheta(&nMinus2Point, &precedingPoint, &thisPoint);
634 padTheta =
twopi/4.0 ;
640 if(colFlag.bitSet(LCIO::THBIT_MOMENTUM)) {
642 const float * mcpMomentum =
_SimTHit->getMomentum() ;
644 CLHEP::Hep3Vector mom(mcpMomentum[0],mcpMomentum[1],mcpMomentum[2]);
646 double trackPhi = mom.phi();
648 if(trackPhi<0.0) trackPhi=trackPhi+
twopi;
649 if(trackPhi>twopi) trackPhi=trackPhi-
twopi;
650 if(trackPhi>twopi/2.0) trackPhi = trackPhi - twopi/2.0 ;
652 double localPhi = thisPoint.phi() - padPhi;
654 _phiRelHisto->fill(padPhi);
655 _phiDiffHisto->fill((fabs(localPhi - trackPhi))/trackPhi);
656 _thetaRelHisto->fill(padTheta);
657 _thetaDiffHisto->fill( (sin(padTheta) - sin(mom.theta()))/sin(mom.theta()) );
659 streamlog_out(DEBUG3) <<
"track Phi = " << trackPhi * (360.0 /
twopi) << endl;
660 streamlog_out(DEBUG3) <<
"localPhi = " << localPhi * (360.0 /
twopi) << endl;
661 streamlog_out(DEBUG3) <<
"pad Phi = " << padPhi * (360.0 /
twopi) << endl;
662 streamlog_out(DEBUG3) <<
"pad Phi from track mom = " << ( thisPoint.phi() - trackPhi ) * (360.0 / twopi) << endl;
663 streamlog_out(DEBUG3) <<
"padTheta = " << padTheta * (360.0 /
twopi) << endl;
664 streamlog_out(DEBUG3) <<
"padTheta from track mom = " << mom.theta() * (360.0 /
twopi) << endl;
672 int layerNumber =
_SimTHit->getCellID0();
693 double driftLength = gearTPC.getMaxDriftLength() - (fabs(thisPoint.z()));
695 if (driftLength <0) {
696 streamlog_out(DEBUG3) <<
" TPCDigiProcessor : Warning! driftLength < 0 " << driftLength <<
" --> Check out your GEAR file!!!!" << std::endl;
697 streamlog_out(DEBUG3) <<
"Setting driftLength to 0.1" << std::endl;
698 streamlog_out(DEBUG3) <<
"gearTPC.getMaxDriftLength() = " << gearTPC.getMaxDriftLength() << std::endl;
702 padheight = padLayout.getPadHeight(padLayout.getNearestPad(thisPoint.perp(),thisPoint.phi()));
706 double bReso = ( (
_diffRPhi *
_diffRPhi) /
_nEff ) * sin(padTheta) * ( 6.0 / (padheight) ) * ( (4.0 * 4.0) / (bField * bField) ) ;
708 double tpcRPhiRes = sqrt( aReso + bReso * (driftLength / 10.0) );
714 int padIndex = padLayout.getNearestPad(thisPoint.perp(),thisPoint.phi());
717 double TPCPadPlaneRMin = planeExt[0] ;
718 double TPCPadPlaneRMax = planeExt[1] ;
720 int iRowHit = padLayout.getRowNumber(padIndex);
721 int iPhiHit = padLayout.getPadNumber(padIndex);
722 int NBinsZ = (int) ((2.0 * gearTPC.getMaxDriftLength()) /
_binningZ);
723 int iZHit = (int) ( (
float) NBinsZ * ( gearTPC.getMaxDriftLength() + thisPoint.z() ) / ( 2.0 * gearTPC.getMaxDriftLength() ) ) ;
726 if(iZHit>NBinsZ) iZHit=NBinsZ;
729 thisPoint.setPerp(padLayout.getPadCenter(padIndex)[0]);
731 if( (thisPoint.perp() < TPCPadPlaneRMin) || (thisPoint.perp() > TPCPadPlaneRMax) ) {
732 streamlog_out(DEBUG3) <<
"Hit R not in TPC " << endl;
733 streamlog_out(DEBUG3) <<
"R = " << thisPoint.perp() << endl;
734 streamlog_out(DEBUG3) <<
"the tpc InnerRadius = " << TPCPadPlaneRMin << endl;
735 streamlog_out(DEBUG3) <<
"the tpc OuterRadius = " << TPCPadPlaneRMax << endl;
736 streamlog_out(DEBUG3) <<
"Hit Dropped " << endl;
740 if( (fabs(thisPoint.z()) > gearTPC.getMaxDriftLength()) ) {
741 streamlog_out(DEBUG3) <<
"Hit Z not in TPC " << endl;
742 streamlog_out(DEBUG3) <<
"Z = " << thisPoint.z() << endl;
743 streamlog_out(DEBUG3) <<
"the tpc Max Z = " << gearTPC.getMaxDriftLength() << endl;
744 streamlog_out(DEBUG3) <<
"Hit Dropped " << endl;
752 Voxel_tpc * atpcVoxel =
new Voxel_tpc(iRowHit,iPhiHit,iZHit, thisPoint, edep, tpcRPhiRes, tpcZRes);
755 ++numberOfVoxelsCreated;
770 LCCollection* STHcolLowPt = 0 ;
774 catch(DataNotAvailableException &e){
777 if(STHcolLowPt!=NULL){
779 int n_sim_hitsLowPt = STHcolLowPt->getNumberOfElements() ;
784 _padWidth = padLayout.getPadWidth(0)*padCoord[0];
786 streamlog_out(DEBUG4) <<
"number of LowPt hits:" << n_sim_hitsLowPt << std::endl;
789 for(
int i=0; i< n_sim_hitsLowPt; i++){
791 _SimTHit =
dynamic_cast<SimTrackerHit*
>( STHcolLowPt->getElementAt( i ) ) ;
796 double TPCPadPlaneRMin = planeExt[0] ;
797 double TPCPadPlaneRMax = planeExt[1] ;
799 int NBinsZ = (int) ((2.0 * gearTPC.getMaxDriftLength()) /
_binningZ);
801 if( (thisPoint.perp() < TPCPadPlaneRMin) || (thisPoint.perp() > TPCPadPlaneRMax) ) {
802 streamlog_out(DEBUG3) <<
"Hit R not in TPC " << endl;
803 streamlog_out(DEBUG3) <<
"R = " << thisPoint.perp() << endl;
804 streamlog_out(DEBUG3) <<
"the tpc InnerRadius = " << TPCPadPlaneRMin << endl;
805 streamlog_out(DEBUG3) <<
"the tpc OuterRadius = " << TPCPadPlaneRMax << endl;
806 streamlog_out(DEBUG3) <<
"Hit Dropped " << endl;
810 if( (fabs(thisPoint.z()) > gearTPC.getMaxDriftLength()) ) {
811 streamlog_out(DEBUG3) <<
"Hit Z not in TPC " << endl;
812 streamlog_out(DEBUG3) <<
"Z = " << thisPoint.z() << endl;
813 streamlog_out(DEBUG3) <<
"the tpc Max Z = " << gearTPC.getMaxDriftLength() << endl;
814 streamlog_out(DEBUG3) <<
"Hit Dropped " << endl;
818 int padIndex = padLayout.getNearestPad(thisPoint.perp(),thisPoint.phi());
821 int iRowHit = padLayout.getRowNumber(padIndex);
822 int iPhiHit = padLayout.getPadNumber(padIndex);
823 int iZHit = (int) ( (
float) NBinsZ *
824 ( gearTPC.getMaxDriftLength() + thisPoint.z() ) / ( 2.0 * gearTPC.getMaxDriftLength() ) ) ;
827 thisPoint.setPerp(padLayout.getPadCenter(padIndex)[0]);
837 Voxel_tpc * atpcVoxel =
new Voxel_tpc(iRowHit,iPhiHit,iZHit, thisPoint, edep, tpcRPhiRes, tpcZRes);
840 ++numberOfVoxelsCreated;
848 int number_of_adjacent_hits(0);
850 streamlog_out(DEBUG4) <<
"finished looping over simhits, number of voxels = " << numberOfVoxelsCreated << endl;
852 int numberOfhitsTreated(0);
854 vector <Voxel_tpc *> row_hits;
857 for (
unsigned int i = 0; i<
_tpcRowHits.size(); ++i){
860 std::sort(row_hits.begin(), row_hits.end(),
compare_phi );
863 for (
unsigned int j = 0; j<row_hits.size(); ++j){
865 ++numberOfhitsTreated;
867 for (
unsigned int k = j+1;
k<row_hits.size(); ++
k){
869 if(row_hits[
k]->getPhiIndex() > (row_hits[j]->getPhiIndex())+2){
874 else if( row_hits[
k]->getPhiIndex()==row_hits[j]->getPhiIndex()
876 ( (fabs(row_hits[
k]->getHep3Vector().deltaPhi(row_hits[j]->getHep3Vector()))) * row_hits[j]->getR()) <
_doubleHitResRPhi ) {
879 map <Voxel_tpc*,SimTrackerHit*> ::iterator it;
881 SimTrackerHit* Hit1 = NULL;
882 SimTrackerHit* Hit2 = NULL;
895 double pathlengthZ1(0.0);
896 double pathlengthZ2(0.0);
901 bool momentum_set =
true;
903 if( STHcol != NULL ){
904 LCFlagImpl colFlag( STHcol->getFlag() ) ;
905 momentum_set = momentum_set && colFlag.bitSet(LCIO::THBIT_MOMENTUM) ;
908 if( STHcolLowPt != NULL ){
909 LCFlagImpl colFlag( STHcolLowPt->getFlag() ) ;
910 momentum_set = momentum_set && colFlag.bitSet(LCIO::THBIT_MOMENTUM) ;
915 const float * Momentum1 = Hit1->getMomentum() ;
916 const float * Momentum2 = Hit2->getMomentum() ;
918 CLHEP::Hep3Vector mom1(Momentum1[0],Momentum1[1],Momentum1[2]);
919 CLHEP::Hep3Vector mom2(Momentum2[0],Momentum2[1],Momentum2[2]);
921 pathlengthZ1 = fabs( Hit1->getPathLength() * mom1.cosTheta() );
922 pathlengthZ2 = fabs( Hit2->getPathLength() * mom2.cosTheta() );
929 double dZ = fabs(row_hits[j]->getZ() - row_hits[k]->getZ());
931 double spacial_coverage = 0.5*(pathlengthZ1 + pathlengthZ2) +
_binningZ;
935 row_hits[j]->setAdjacent(row_hits[k]);
936 row_hits[
k]->setAdjacent(row_hits[j]);
937 ++number_of_adjacent_hits;
941 streamlog_out(DEBUG3) <<
"Hit1=" << Hit1 <<
"Hit2=" << Hit2 << endl;
950 for (
unsigned int j = 0; j<row_hits.size(); ++j){
964 vector <Voxel_tpc*>* hitsToMerge =
new vector <Voxel_tpc*>;
966 int clusterSize = seed_hit->
clusterFind(hitsToMerge);
979 for (
unsigned int i = 0; i<
_tpcRowHits.size(); ++i){
981 for (
unsigned int j = 0; j<row_hits.size(); ++j){
989 const double *mom=
_mcp->getMomentum() ;
990 double ptSQRD = mom[0]*mom[0]+mom[1]*mom[1] ;
998 streamlog_out(DEBUG4) <<
"the number of adjacent hits is " << number_of_adjacent_hits <<
" _doubleHitResZ " <<
_doubleHitResZ << endl;
999 streamlog_out(DEBUG4) <<
"number of rec_hits = " <<
_NRecTPCHits << endl ;
1000 streamlog_out(DEBUG4) <<
"finished row hits " << numberOfHits <<
" " << numberOfhitsTreated << endl;
1009 typeNames.push_back( LCIO::TPCHIT ) ;
1010 typeValues.push_back( 1 ) ;
1011 _trkhitVec->parameters().setValues(
"TrackerHitTypeNames" , typeNames ) ;
1012 _trkhitVec->parameters().setValues(
"TrackerHitTypeValues" , typeValues ) ;
1019 for (
unsigned int i = 0; i<
_tpcRowHits.size(); ++i){
1020 vector <Voxel_tpc *>* current_row = &
_tpcRowHits.at(i);
1021 for (
unsigned int j = 0; j<current_row->size(); ++j){
1022 delete current_row->at(j);
1044 streamlog_out(DEBUG4) <<
"_NSimTPCHits = " <<
_NSimTPCHits << endl;
1046 streamlog_out(DEBUG4) <<
"_NPhysicsSimTPCHits = " << _NPhysicsSimTPCHits << endl;
1047 streamlog_out(DEBUG4) <<
"_NPhysicsAbove02GeVSimTPCHits = " << _NPhysicsAbove02GeVSimTPCHits << endl;
1048 streamlog_out(DEBUG4) <<
"_NPhysicsAbove1GeVSimTPCHits = " << _NPhysicsAbove1GeVSimTPCHits << endl;
1049 streamlog_out(DEBUG4) <<
"_NRecTPCHits = " <<
_NRecTPCHits<< endl;
1053 streamlog_out(DEBUG4) <<
"_NRevomedHits = " <<
_NRevomedHits << endl;
1077 _TREE->cd(
"/Histograms");
1081 streamlog_out(MESSAGE) <<
"DIGICHECKPLOTS Finished" << endl;
1085 streamlog_out(MESSAGE) <<
"TPCDigiProcessor::end() " << name()
1086 <<
" processed " <<
_nEvt <<
" events in " <<
_nRun <<
" runs "
1093 const gear::TPCParameters& gearTPC = Global::GEAR->getTPCParameters() ;
1094 const gear::PadRowLayout2D& padLayout = gearTPC.getPadLayout() ;
1095 const gear::Vector2D padCoord = padLayout.getPadCenter(1) ;
1102 TrackerHitImpl* trkHit =
new TrackerHitImpl ;
1106 double tpcZRes = seed_hit->
getZRes();
1108 CLHEP::Hep3Vector point(seed_hit->
getX(),seed_hit->
getY(),seed_hit->
getZ());
1110 double unsmearedPhi = point.phi();
1112 double randrp = gsl_ran_gaussian(
_random,tpcRPhiRes);
1113 double randz = gsl_ran_gaussian(
_random,tpcZRes);
1115 point.setPhi( point.phi() + randrp/ point.perp() );
1116 point.setZ( point.z() + randz );
1119 if( fabs(point.z()) > gearTPC.getMaxDriftLength() ) point.setZ( (fabs(point.z()) / point.z() ) * gearTPC.getMaxDriftLength() );
1121 double pos[3] = {point.x(),point.y(),point.z()};
1122 trkHit->setPosition(pos);
1123 trkHit->setEDep(seed_hit->
getEDep());
1130 (*_cellid_encoder)[ lcio::LCTrackerCellID::subdet() ] = lcio::ILDDetID::TPC ;
1131 (*_cellid_encoder)[ lcio::LCTrackerCellID::layer() ] = seed_hit->
getRowIndex() ;
1132 (*_cellid_encoder)[ lcio::LCTrackerCellID::module() ] = 0 ;
1137 (*_cellid_encoder)[ lcio::LCTrackerCellID::side() ] = ( pos[2] < 0 ? -1 : 1 ) ;
1139 (*
_cellid_encoder)[ lcio::LCTrackerCellID::side() ] = lcio::ILDDetID::barrel ;
1145 if( std::isnan(unsmearedPhi) || std::isinf(unsmearedPhi) || std::isnan(tpcRPhiRes) || std::isinf(tpcRPhiRes) ) {
1146 std::stringstream errorMsg;
1147 errorMsg <<
"\nProcessor: TPCDigiProcessor \n"
1148 <<
"unsmearedPhi = "
1153 throw Exception(errorMsg.str());
1157 float covMat[TRKHITNCOVMATRIX]={float(sin(unsmearedPhi)*sin(unsmearedPhi)*tpcRPhiRes*tpcRPhiRes),
1158 float(-cos(unsmearedPhi)*sin(unsmearedPhi)*tpcRPhiRes*tpcRPhiRes),
1159 float(cos(unsmearedPhi)*cos(unsmearedPhi)*tpcRPhiRes*tpcRPhiRes),
1162 float(tpcZRes*tpcZRes) };
1164 trkHit->setCovMatrix(covMat);
1167 std::stringstream errorMsg;
1168 errorMsg <<
"\nProcessor: TPCDigiProcessor \n"
1169 <<
"SimTracker Pointer is NULL throwing exception\n"
1171 throw Exception(errorMsg.str());
1174 if(pos[0]*pos[0]+pos[1]*pos[1]>0.0){
1178 trkHit->rawHits().push_back(
_tpcHitMap[seed_hit] );
1181 LCRelationImpl* rel =
new LCRelationImpl;
1183 rel->setFrom (trkHit);
1185 rel->setWeight( 1.0 );
1194 SimTrackerHit* theSimHit =
_tpcHitMap[seed_hit];
1195 double rSimSqrd = theSimHit->getPosition()[0]*theSimHit->getPosition()[0] + theSimHit->getPosition()[1]*theSimHit->getPosition()[1];
1197 double phiSim = atan2(theSimHit->getPosition()[1],theSimHit->getPosition()[0]);
1199 double rPhiDiff = (point.phi() - phiSim)*sqrt(rSimSqrd);
1200 double rPhiPull = ((point.phi() - phiSim)*sqrt(rSimSqrd))/(sqrt((covMat[2])/(cos(point.phi())*cos(point.phi()))));
1202 double zDiff = point.getZ() - theSimHit->getPosition()[2];
1203 double zPull = zDiff/sqrt(covMat[5]);
1206 _rPhiDiffHisto->fill(rPhiDiff);
1207 _rPhiPullHisto->fill(rPhiPull);
1208 _phiDistHisto->fill(point.phi() - phiSim);
1209 _zDiffHisto->fill(zDiff);
1210 _zPullHisto->fill(zPull);
1212 _zSigmaVsZHisto->fill(seed_hit->
getZ(),sqrt(covMat[5]));
1213 _rPhiSigmaHisto->fill(sqrt((covMat[2])/(cos(point.phi())*cos(point.phi()))));
1214 _zSigmaHisto->fill(sqrt(covMat[5]));
1220 const gear::TPCParameters& gearTPC = Global::GEAR->getTPCParameters() ;
1221 const gear::PadRowLayout2D& padLayout = gearTPC.getPadLayout() ;
1222 const gear::Vector2D padCoord = padLayout.getPadCenter(1) ;
1224 TrackerHitImpl* trkHit =
new TrackerHitImpl ;
1232 unsigned number_of_hits_to_merge = hitsToMerge->size();
1235 for(
unsigned int ihitCluster = 0; ihitCluster < number_of_hits_to_merge; ++ihitCluster){
1237 sumZ += hitsToMerge->at(ihitCluster)->getZ();
1238 sumPhi += hitsToMerge->at(ihitCluster)->getPhi();
1239 sumEDep += hitsToMerge->at(ihitCluster)->getEDep();
1240 hitsToMerge->at(ihitCluster)->setIsMerged();
1241 lastR = hitsToMerge->at(ihitCluster)->getR();
1244 trkHit->rawHits().push_back(
_tpcHitMap[hitsToMerge->at(ihitCluster)] );
1247 LCRelationImpl* rel =
new LCRelationImpl;
1249 rel->setFrom (trkHit);
1250 rel->setTo (
_tpcHitMap[ hitsToMerge->at(ihitCluster) ]);
1251 rel->setWeight(
float(1.0/number_of_hits_to_merge) );
1256 double avgZ = sumZ/(hitsToMerge->size());
1257 double avgPhi = sumPhi/(hitsToMerge->size());
1260 sumEDep=sumEDep/(double)number_of_hits_to_merge;
1262 CLHEP::Hep3Vector* mergedPoint =
new CLHEP::Hep3Vector(1.0,1.0,1.0);
1263 mergedPoint->setPerp(lastR);
1264 mergedPoint->setPhi(avgPhi);
1265 mergedPoint->setZ(avgZ);
1276 CLHEP::Hep3Vector point( mergedPoint->getX(), mergedPoint->getY(), mergedPoint->getZ() ) ;
1280 double randrp = gsl_ran_gaussian(
_random,tpcRPhiRes);
1281 double randz = gsl_ran_gaussian(
_random,tpcZRes);
1283 point.setPhi( point.phi() + randrp/ point.perp() );
1284 point.setZ( point.z() + randz );
1287 if( fabs(point.z()) > gearTPC.getMaxDriftLength() ) point.setZ( (fabs(point.z()) / point.z() ) * gearTPC.getMaxDriftLength() );
1289 double pos[3] = {point.x(),point.y(),point.z()};
1292 trkHit->setPosition(pos);
1293 trkHit->setEDep(sumEDep);
1296 int padIndex = padLayout.getNearestPad(mergedPoint->perp(),mergedPoint->phi());
1297 int row = padLayout.getRowNumber(padIndex);
1299 (*_cellid_encoder)[ lcio::LCTrackerCellID::subdet() ] = lcio::ILDDetID::TPC ;
1300 (*_cellid_encoder)[ lcio::LCTrackerCellID::layer() ] = row ;
1301 (*_cellid_encoder)[ lcio::LCTrackerCellID::module() ] = 0 ;
1305 (*_cellid_encoder)[ lcio::LCTrackerCellID::side() ] = ( pos[2] < 0 ? -1 : 1 ) ;
1307 (*
_cellid_encoder)[ lcio::LCTrackerCellID::side() ] = lcio::ILDDetID::barrel ;
1312 double phi = mergedPoint->getPhi();
1315 if( std::isnan(phi) || std::isinf(phi) || std::isnan(tpcRPhiRes) || std::isinf(tpcRPhiRes) ) {
1316 std::stringstream errorMsg;
1317 errorMsg <<
"\nProcessor: TPCDigiProcessor \n"
1323 throw Exception(errorMsg.str());
1327 float covMat[TRKHITNCOVMATRIX]={float(sin(phi)*sin(phi)*tpcRPhiRes*tpcRPhiRes),
1328 float(-cos(phi)*sin(phi)*tpcRPhiRes*tpcRPhiRes),
1329 float(cos(phi)*cos(phi)*tpcRPhiRes*tpcRPhiRes),
1332 float(tpcZRes*tpcZRes)};
1334 trkHit->setCovMatrix(covMat);
1351 const double bField = Global::GEAR->getBField().at(
gear::Vector3D( 0., 0., 0.) ).z() ;
1352 const double FCT = 2.99792458E-4;
1353 double charge = mcp->getCharge();
1354 const double *mom = mcp->getMomentum();
1355 double pt = sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
1356 double radius = pt / (FCT*bField);
1357 double tanLambda = mom[2]/pt;
1358 double omega = charge / radius;
1366 LCVector3D refPoint(0.,0.,0);
1368 SimpleHelix* helix =
new SimpleHelix(D0,
1369 atan2(mom[1],mom[0]),
1377 LCVector3D startCylinder(0.,0.,-1000000.0);
1378 LCVector3D endCylinder(0.,0.,1000000.0);
1381 LCCylinder cylinder(startCylinder,endCylinder,thisPoint->perp(),endplane);
1383 bool pointExists =
false;
1385 double pathlength = helix->getIntersectionWithCylinder( cylinder, pointExists);
1387 LCErrorMatrix* errors =
new LCErrorMatrix();
1391 LCVector3D intersection = helix->getPosition(pathlength, errors);
1393 double intersectionPhi = atan2(intersection[1],intersection[0]);
1394 double residualRPhi = ((intersectionPhi-thisPoint->phi())) ;
1395 _ResidualsRPhiHisto->fill(residualRPhi);
1402 const gear::TPCParameters& gearTPC = Global::GEAR->getTPCParameters() ;
1403 const gear::PadRowLayout2D& padLayout = gearTPC.getPadLayout() ;
1405 int row = padLayout.getRowNumber(padLayout.getNearestPad(thisPoint->perp(),thisPoint->phi()));
1406 int pad = padLayout.getNearestPad(thisPoint->perp(),thisPoint->phi());
1408 double rHit_diff = thisPoint->perp()
1409 - padLayout.getPlaneExtent()[0]
1411 * padLayout.getPadHeight(pad)) ;
1413 _radiusCheckHisto->fill(rHit_diff);
1429 double TPCDigiProcessor::getPadPhi( CLHEP::Hep3Vector *thisPoint, CLHEP::Hep3Vector* firstPoint, CLHEP::Hep3Vector* middlePoint, CLHEP::Hep3Vector* lastPoint){
1431 CLHEP::Hep2Vector firstPointRPhi(firstPoint->x(),firstPoint->y());
1432 CLHEP::Hep2Vector middlePointRPhi(middlePoint->x(),middlePoint->y());
1433 CLHEP::Hep2Vector lastPointRPhi(lastPoint->x(),lastPoint->y());
1436 if( (fabs( firstPointRPhi.x() - middlePointRPhi.x() ) < 1.
e-05 && fabs( firstPointRPhi.y() - middlePointRPhi.y() ) < 1.
e-05)
1438 (fabs( middlePointRPhi.x() - lastPointRPhi.x() ) < 1.
e-05 && fabs( middlePointRPhi.y() - lastPointRPhi.y() ) < 1.
e-05)
1440 (fabs( firstPointRPhi.x() - lastPointRPhi.x() ) < 1.
e-05 && fabs( firstPointRPhi.y() - lastPointRPhi.y() ) < 1.
e-05)
1443 streamlog_out(WARNING) <<
" TPCDigiProcessor::getPadPhi "
1444 <<
"2 of the 3 SimTracker hits passed to Circle Fit are the same hit taking pad phi as PI/2\n"
1445 <<
" firstPoint->x() " << firstPoint->x()
1446 <<
" firstPoint->y() " << firstPoint->y()
1447 <<
" firstPoint->z() " << firstPoint->z()
1448 <<
" middlePoint->x() " << middlePoint->x()
1449 <<
" middlePoint->y() " << middlePoint->y()
1450 <<
" middlePoint->z() " << middlePoint->z()
1451 <<
" lastPoint->x() " << lastPoint->x()
1452 <<
" lastPoint->y() " << lastPoint->y()
1453 <<
" lastPoint.z() " << lastPoint->z()
1462 Circle theCircle(&firstPointRPhi, &middlePointRPhi, &lastPointRPhi);
1464 double localPhi = atan2((thisPoint->y() - theCircle.GetCenter()->y()) ,(thisPoint->x() - theCircle.GetCenter()->x())) + (
twopi/4.0) ;
1466 if(localPhi>
twopi) localPhi=localPhi -
twopi;
1467 if(localPhi<0.0) localPhi=localPhi +
twopi;
1468 if(localPhi>twopi/2.0) localPhi = localPhi - twopi/2.0 ;
1470 double pointPhi = thisPoint->phi();
1472 if(pointPhi>twopi) pointPhi=pointPhi -
twopi;
1473 if(pointPhi<0.0) pointPhi=pointPhi +
twopi;
1474 if(pointPhi>twopi/2.0) pointPhi = pointPhi - twopi/2.0 ;
1476 double padPhi = fabs(pointPhi - localPhi);
1479 if( std::isnan(padPhi) || std::isinf(padPhi) ) {
1480 std::stringstream errorMsg;
1481 errorMsg <<
"\nProcessor: TPCDigiProcessor \n"
1485 throw Exception(errorMsg.str());
1495 CLHEP::Hep2Vector firstPointRPhi(firstPoint->x(),firstPoint->y()) ;
1496 CLHEP::Hep2Vector middlePointRPhi(middlePoint->x(),middlePoint->y());
1497 CLHEP::Hep2Vector lastPointRPhi(lastPoint->x(),lastPoint->y());
1500 if( (fabs( firstPointRPhi.x() - middlePointRPhi.x() ) < 1.
e-05 && fabs( firstPointRPhi.y() - middlePointRPhi.y() ) < 1.
e-05)
1502 (fabs( middlePointRPhi.x() - lastPointRPhi.x() ) < 1.
e-05 && fabs( middlePointRPhi.y() - lastPointRPhi.y() ) < 1.
e-05)
1504 (fabs( firstPointRPhi.x() - lastPointRPhi.x() ) < 1.
e-05 && fabs( firstPointRPhi.y() - lastPointRPhi.y() ) < 1.
e-05)
1507 streamlog_out(WARNING) <<
" TPCDigiProcessor::getPadTheta "
1508 <<
"2 of the 3 SimTracker hits passed to Circle Fit are the same hit taking pad phi as PI/2\n"
1509 <<
" firstPoint->x() " << firstPoint->x()
1510 <<
" firstPoint->y() " << firstPoint->y()
1511 <<
" firstPoint->z() " << firstPoint->z()
1512 <<
" middlePoint->x() " << middlePoint->x()
1513 <<
" middlePoint->y() " << middlePoint->y()
1514 <<
" middlePoint->z() " << middlePoint->z()
1515 <<
" lastPoint->x() " << lastPoint->x()
1516 <<
" lastPoint->y() " << lastPoint->y()
1517 <<
" lastPoint.z() " << lastPoint->z()
1525 Circle theCircle(&firstPointRPhi, &middlePointRPhi, &lastPointRPhi);
1527 double deltaPhi = firstPoint->deltaPhi(*lastPoint);
1529 double pathlength = fabs(deltaPhi) * theCircle.GetRadius();
1531 double padTheta = atan ( pathlength / fabs(lastPoint->z() - firstPoint->z()) ) ;
1533 double pathlength1 = 2.0 * asin( ( sqrt (
1534 (middlePointRPhi.x() - firstPointRPhi.x()) * (middlePointRPhi.x()-firstPointRPhi.x())
1536 (middlePointRPhi.y()-firstPointRPhi.y()) * (middlePointRPhi.y()-firstPointRPhi.y())
1537 ) / 2.0 ) / theCircle.GetRadius() ) * theCircle.GetRadius() ;
1540 double pathlength2 = 2.0 * asin( ( sqrt (
1541 (lastPointRPhi.x()-middlePointRPhi.x()) * (lastPointRPhi.x()-middlePointRPhi.x())
1543 (lastPointRPhi.y()-middlePointRPhi.y()) * (lastPointRPhi.y()-middlePointRPhi.y())
1544 ) / 2.0 ) / theCircle.GetRadius() ) * theCircle.GetRadius() ;
1547 padTheta = atan ((fabs(pathlength1 + pathlength2)) / (fabs(lastPoint->z() - firstPoint->z())) ) ;
1550 if( std::isnan(padTheta) || std::isinf(padTheta) ) {
1551 std::stringstream errorMsg;
1552 errorMsg <<
"\nProcessor: TPCDigiProcessor \n"
1556 throw Exception(errorMsg.str());
int getNumberOfAdjacent()
SimTrackerHit * _nMinus2SimHit
std::vector< double * > DoubleVec
void writeMergedVoxelsToHit(std::vector< Voxel_tpc * > *hitList)
std::string _spacePointColName
virtual void init()
Called at the begin of the job before anything is read.
int _NLostPhysicsAbove1GeVPtTPCHits
CLHEP::Hep3Vector Vector3D
bool compare_z(Voxel_tpc *a, Voxel_tpc *b)
double getPadTheta(CLHEP::Hep3Vector *firstPointRPhi, CLHEP::Hep3Vector *middlePointRPhi, CLHEP::Hep3Vector *lastPointRPhi)
SimTrackerHit * _previousSimTHit
CellIDEncoder< TrackerHitImpl > * _cellid_encoder
EVENT::MCParticle * _nPlus2MCP
virtual void end()
Called after data processing for clean up.
double getPadPhi(CLHEP::Hep3Vector *thisPointRPhi, CLHEP::Hep3Vector *firstPointRPhi, CLHEP::Hep3Vector *middlePointRPhi, CLHEP::Hep3Vector *lastPointRPhi)
EVENT::MCParticle * _nextMCP
bool _use_raw_hits_to_store_simhit_pointer
int clusterFind(vector< Voxel_tpc * > *hitList)
LCCollectionVec * _trkhitVec
void plotHelixHitResidual(MCParticle *mcp, CLHEP::Hep3Vector *thisPointRPhi)
SimTrackerHit * _nPlus2SimHit
LCCollectionVec * _relCol
virtual void check(LCEvent *evt)
std::vector< std::vector< Voxel_tpc * > > _tpcRowHits
int _NLostPhysicsAbove02GeVPtTPCHits
MCParticle * getMCParticle(ReconstructedParticle *recPart, LCCollection *colMCTL)
bool compare_phi(Voxel_tpc *a, Voxel_tpc *b)
EVENT::MCParticle * _nMinus2MCP
std::vector< LCCollection * > LCCollectionVec
int _NBackgroundSimTPCHits
std::string _lowPtHitscolName
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
std::map< Voxel_tpc *, SimTrackerHit * > _tpcHitMap
SimTrackerHit * _nextSimTHit
int _NPhysicsAbove02GeVSimTPCHits
std::string _outRelColName
int _NPhysicsAbove1GeVSimTPCHits
void writeVoxelToHit(Voxel_tpc *aVoxel)
TPCDigiProcessor aTPCDigiProcessor
std::string _TPCTrackerHitsCol
Output collection name.
std::string _padRowHitColName
Input collection name.
EVENT::MCParticle * _previousMCP
std::vector< std::string > StringVec