35 #include "TGeoManager.h"
36 #include "TGeoVolume.h"
37 #include "TGeoPhysicalNode.h"
38 #include "TGeoMatrix.h"
41 #include "StETofUtil/StETofGeometry.h"
42 #include "StMessMgr.h"
44 #include "StETofHit.h"
45 #include "StMuDSTMaker/COMMON/StMuETofHit.h"
46 #include "StPicoEvent/StPicoETofHit.h"
48 #include "tables/St_etofAlign_Table.h"
50 #include "StarMagField.h"
61 StETofNode::StETofNode(
const TGeoPhysicalNode& gpNode )
62 : mSafetyMarginX( 0. ),
67 mGeoMatrix =
static_cast< TGeoHMatrix*
> ( gpNode.GetMatrix() );
68 mBox =
static_cast< TGeoBBox*
> ( gpNode.GetShape() );
73 StETofNode::StETofNode(
const TGeoPhysicalNode& gpNode,
const float& dx,
const float& dy,
const StThreeVectorD alignment = { 0, 0, 0 } )
74 : mSafetyMarginX( 0. ),
78 mGeoMatrix =
static_cast< TGeoHMatrix*
> ( gpNode.GetMatrix() );
80 mBox =
static_cast< TGeoBBox*
> ( gpNode.GetShape() );
83 float dz = mBox->GetDZ();
84 mBox->SetBoxDimensions( dx, dy, dz );
88 double xl[3] = { -alignment.x(), -alignment.y(), -alignment.z() };
91 local2Master( xl, xm );
94 mGeoMatrix->SetDx(xm[ 0 ]);
95 mGeoMatrix->SetDy(xm[ 1 ]);
96 mGeoMatrix->SetDz(xm[ 2 ]);
99 LOG_DEBUG <<
"StETofNode::Created physical node at: "<< xm[ 0 ]<<
","<< xm[ 1 ]<<
"," << xm[ 2 ]<<
" with alignments: "<< alignment.x()<<
","<< alignment.y()<<
"," << alignment.z()<< endm;
101 mNormal = calcXYPlaneNormal();
103 mEtaMin = calcEta( -1. );
104 mEtaMax = calcEta( 1. );
106 mPhiMin = calcPhi( -1, -1. );
107 mPhiMax = calcPhi( -1, 1. );
109 if( mDebug ) print();
113 StETofNode::convertPos(
StETofNode* from,
const double* pos_from,
StETofNode* to,
double* pos_to )
116 from->local2Master( pos_from, pos_to );
120 from->local2Master( pos_from, xg );
121 to->master2Local( xg, pos_to );
127 StETofNode::local2Master(
const double* local,
double* master )
130 mGeoMatrix->LocalToMaster( local, master );
135 StETofNode::master2Local(
const double* master,
double* local )
138 mGeoMatrix->MasterToLocal( master, local );
143 StETofNode::calcCenterPos()
146 double xl[3] = { 0, 0, 0 };
149 local2Master( xl, xm );
156 StETofNode::calcXYPlaneNormal()
161 double xl[ 3 ] = { 0, 0, 1 };
165 local2Master( xl, xm );
177 StETofNode::calcEta(
const double& rel_local_x )
180 double xl[3] = { 0, 0, 0 };
183 if( fabs( rel_local_x ) <= 1. && rel_local_x != 0. ) {
184 double dx = mBox->GetDX();
185 xl[ 0 ] = dx * rel_local_x;
188 local2Master( xl, xm );
189 return StThreeVectorD( xm[ 0 ], xm[ 1 ], xm[ 2 ] ).pseudoRapidity();
194 StETofNode::calcPhi(
const double& rel_local_x,
const double& rel_local_y )
198 double xl[3] = { 0, 0, 0 };
201 if( fabs( rel_local_x ) <= 1. && rel_local_x != 0. ) {
202 double dx = mBox->GetDX();
203 xl[ 0 ] = dx * rel_local_x;
205 if( fabs( rel_local_y ) <= 1. && rel_local_y != 0. ) {
206 double dy = mBox->GetDY();
207 xl[ 1 ] = dy * rel_local_y;
210 local2Master( xl, xm );
216 StETofNode::buildMembers()
219 mCenter = calcCenterPos();
220 mNormal = calcXYPlaneNormal();
222 mEtaMin = calcEta( -1. );
223 mEtaMax = calcEta( 1. );
225 mPhiMin = calcPhi( -1, -1. );
226 mPhiMax = calcPhi( -1, 1. );
228 if( mDebug ) print();
233 StETofNode::setSafetyMargins(
const double* margins )
241 if( margins[ 0 ] < 0 || margins[ 1 ] < 0 ) {
242 LOG_DEBUG <<
"StETofNode::setSafetyMargins() -- WARNING: input values are negative" << endm;
244 mSafetyMarginX = margins[ 0 ];
245 mSafetyMarginY = margins[ 1 ];
250 StETofNode::isLocalPointIn(
const double* local )
255 if ( fabs( local[ 0 ] ) > mBox->GetDX() + mSafetyMarginX )
return false;
256 if ( fabs( local[ 1 ] ) > mBox->GetDY() + mSafetyMarginY )
return false;
257 if ( fabs( local[ 2 ] ) > mBox->GetDZ() )
return false;
267 double xm[ 3 ] = { global.x(), global.y(), global.z() };
270 master2Local( xm, xl );
272 return isLocalPointIn( xl );
276 StETofNode::isGlobalPointIn(
const TVector3& global )
279 double xm[ 3 ] = { global.x(), global.y(), global.z() };
282 master2Local( xm, xl );
284 return isLocalPointIn( xl );
292 float maxPathLength = 1000;
294 bool isInside =
false;
298 pathLength = helix.
pathLength( mCenter, mNormal );
300 if( pathLength > 0 && pathLength < maxPathLength ) {
301 cross = helix.at( pathLength );
302 theta = mNormal.angle( -helix.cat( pathLength ) );
306 isInside = isGlobalPointIn( cross );
313 StETofNode::helixCross(
const StPicoHelix& helix,
double& pathLength, TVector3& cross,
double& theta )
317 float maxPathLength = 1000;
319 bool isInside =
false;
323 TVector3 center( mCenter.x(), mCenter.y(), mCenter.z() );
324 TVector3 normal( mNormal.x(), mNormal.y(), mNormal.z() );
325 pathLength = helix.
pathLength( center, normal );
327 if( pathLength > 0 && pathLength < maxPathLength ) {
328 cross = helix.at( pathLength );
329 theta = normal.Angle( -helix.cat( pathLength ) );
333 isInside = isGlobalPointIn( cross );
340 StETofNode::print(
const Option_t* opt )
const
342 double* trans = mGeoMatrix->GetTranslation();
343 double* rotMat = mGeoMatrix->GetRotationMatrix();
345 LOG_INFO <<
" -------- "
346 <<
"\nBox dimension: " << mBox->GetDX() <<
" : " << mBox->GetDY() <<
" : " << mBox->GetDZ()
347 <<
"\ncenter pos: " << mCenter.x() <<
" : " << mCenter.y() <<
" : " << mCenter.z()
348 <<
"\ncenter phi: " << mCenter.phi() <<
", eta: " << mCenter.pseudoRapidity()
349 <<
"\nphi range: " << mPhiMin <<
" : " << mPhiMax
350 <<
"\teta range: " << mEtaMin <<
" : " << mEtaMax
351 <<
"\nXYplane normal: " << mNormal.x() <<
" : " << mNormal.y() <<
" : " << mNormal.z()
352 <<
"\ntrans [0-2] = " << trans[ 0 ] <<
" " << trans[ 1 ] <<
" " << trans[ 2 ]
353 <<
"\nrotMat[0-2] = " << rotMat[ 0 ] <<
" " << rotMat[ 1 ] <<
" " << rotMat[ 2 ]
354 <<
"\nrotMat[3-5] = " << rotMat[ 3 ] <<
" " << rotMat[ 4 ] <<
" " << rotMat[ 5 ]
355 <<
"\nrotMat[6-8] = " << rotMat[ 6 ] <<
" " << rotMat[ 7 ] <<
" " << rotMat[ 8 ]
356 <<
"\n ------------------------------------------------ " << endm;
370 StETofGeomModule::StETofGeomModule(
const TGeoPhysicalNode& gpNode,
const int moduleId )
372 mModuleIndex( moduleId ),
375 mSector = calcSector( moduleId );
376 mPlane = calcPlane( moduleId );
378 mETofCounter.reserve( eTofConst::nCounters );
380 if( mDebug ) print();
384 StETofGeomModule::addCounter(
const TGeoPhysicalNode& gpNode,
const float& dx,
const float& dy,
const int moduleId,
const int counterId,
const double* safetyMargins = initializer_list<double>({0, 0}).begin(),
const StThreeVectorD alignment = {0,0,0} )
388 counter->setSafetyMargins( safetyMargins );
390 mETofCounter.push_back( counter );
395 StETofGeomModule::counter(
const unsigned int i )
const
397 if( mETofCounter.size() <= i || i < 0 ) {
398 LOG_ERROR <<
"Counter not defined" << endm;
402 return mETofCounter[ i ];
406 StETofGeomModule::clearCounters()
408 for(
size_t i=0; i<mETofCounter.size(); i++ ) {
409 LOG_DEBUG <<
"deleting counter (" << i <<
")" << endm;
410 delete mETofCounter[ i ];
412 mETofCounter.clear();
417 StETofGeomModule::calcSector(
const int moduleId )
421 return ( moduleId / eTofConst::nPlanes ) + eTofConst::sectorStart;
426 StETofGeomModule::calcPlane(
const int moduleId )
430 return ( moduleId % eTofConst::nPlanes ) + eTofConst::zPlaneStart;
435 StETofGeomModule::print(
const Option_t* opt )
const
437 LOG_INFO <<
"StETofGeomModule, module# = " << mModuleIndex <<
" sector = " << mSector <<
" plane = " << mPlane << endm;
438 StETofNode::print( opt );
452 StETofGeomCounter::StETofGeomCounter(
const TGeoPhysicalNode& gpNode,
const int moduleId,
const int counterId )
454 mModuleIndex( moduleId ),
455 mCounterIndex( counterId ),
458 mSector = calcSector( moduleId );
459 mPlane = calcPlane( moduleId );
463 if( mDebug ) print();
467 StETofGeomCounter::StETofGeomCounter(
const TGeoPhysicalNode& gpNode,
const float& dx,
const float& dy,
const int moduleId,
const int counterId,
const StThreeVectorD alignment = { 0, 0, 0 } )
469 mModuleIndex( moduleId ),
470 mCounterIndex( counterId ),
473 mSector = calcSector( moduleId );
474 mPlane = calcPlane( moduleId );
478 if( mDebug ) print();
482 StETofGeomCounter::calcSector(
const int moduleId )
486 return ( moduleId / eTofConst::nPlanes ) + eTofConst::sectorStart;
491 StETofGeomCounter::calcPlane(
const int moduleId )
495 return ( moduleId % eTofConst::nPlanes ) + eTofConst::zPlaneStart;
500 StETofGeomCounter::createGeomStrips()
503 float counterDx = this->box()->GetDX();
504 float stripPitch = 2 * counterDx / eTofConst::nStrips;
506 for(
int i=0; i<=eTofConst::nStrips; i++) {
507 mStripX[ i ] = stripPitch * i - counterDx;
513 StETofGeomCounter::findStrip(
const double* local )
519 double xl[ 3 ] = { local[ 0 ], 0. ,0. };
521 if( isLocalPointIn( xl ) ) {
522 for(
int i=0; i<eTofConst::nStrips; i++ ) {
523 if( mStripX[ i ] <= xl[ 0 ] && xl[ 0 ] <= mStripX[ i+1 ] ) {
528 if( xl[ 0 ] < mStripX[ 0 ] ) iStrip = 0;
529 if( xl[ 0 ] > mStripX[ eTofConst::nStrips ] ) iStrip = 33;
537 StETofGeomCounter::print(
const Option_t* opt )
const
539 LOG_INFO <<
"StETofGeomCounter, module# = " << mModuleIndex <<
" sector = " << mSector <<
" plane = " << mPlane <<
" counter = " << mCounterIndex + 1 << endm;
540 StETofNode::print( opt );
554 StETofGeometry::StETofGeometry(
const char* name,
const char* title )
555 : TNamed( name, title ),
559 mStarBField( nullptr ),
560 mFileNameAlignParam(
"")
566 StETofGeometry::~StETofGeometry()
573 StETofGeometry::init( TGeoManager* geoManager,
const double* safetyMargins,
const bool useHelixSwimmer )
576 LOG_ERROR <<
" *** StETofGeometry::Init - cannot find TGeoManager *** " << endm;
580 LOG_DEBUG <<
" +++ geoManager : " << geoManager << endm;
584 if ( !mFileNameAlignParam.empty() ) {
585 readAlignmentParameters();
587 readAlignmentDatabase();
590 if( mAlignmentParameters.size() != eTofConst::nCounters * eTofConst::nModules ){
591 LOG_ERROR <<
"StETofGeometry::Init(...) - Wrong size of counter alignment vector. Either incomplete alignment file or non-existant database table." << endm;
595 int iCounterAlignment = 0;
597 for(
int sector = eTofConst::sectorStart; sector <= eTofConst::sectorStop; sector++ ) {
599 for(
int plane = eTofConst::zPlaneStart; plane <= eTofConst::zPlaneStop; plane++ ) {
600 std::string geoPath(
formTGeoPath( geoManager, plane, sector ) );
602 if( geoPath.empty() ) {
603 LOG_INFO <<
"StETofGeometry::Init(...) - cannot find path to ETOF module "
604 "(id " << plane << sector <<
"). Skipping..." << endm;
609 const TGeoPhysicalNode* gpNode = geoManager->MakePhysicalNode( geoPath.c_str() );
611 int moduleId = calcModuleIndex( sector, plane );
613 mETofModule[ mNValidModules-1 ] =
new StETofGeomModule( *gpNode, moduleId );
618 for(
int counter = eTofConst::counterStart; counter <= eTofConst::counterStop; counter++ ) {
619 std::string geoPath(
formTGeoPath( geoManager, plane, sector, counter ) );
621 if( geoPath.empty() ) {
622 LOG_DEBUG <<
"StETofGeometry::Init(...) - cannot find path to ETOF counter "
623 "(id " << plane << sector <<
", " << counter <<
"). Skipping..." << endm;
627 const TGeoPhysicalNode* gpNode = geoManager->MakePhysicalNode( geoPath.c_str() );
631 std::string geoPathActiveVolume(
formTGeoPath( geoManager, plane, sector, counter, gap ) );
633 if( geoPathActiveVolume.empty() ) {
634 LOG_DEBUG <<
"StETofGeometry::Init(...) - cannot find path to ETOF counter gas gap (for active area evaluation)"
635 "(id " << plane << sector <<
", " << counter <<
"). Skipping..." << endm;
639 const TGeoPhysicalNode* gpNodeActiveVolume = geoManager->MakePhysicalNode( geoPathActiveVolume.c_str() );
641 const TGeoBBox* activeVolume =
static_cast< TGeoBBox*
> ( gpNodeActiveVolume->GetShape() );
643 float dx = activeVolume->GetDX();
644 float dy = activeVolume->GetDY();
646 LOG_DEBUG << activeVolume->GetDX() <<
" " << activeVolume->GetDY() <<
" " << activeVolume->GetDZ() << endm;
648 int counterId = counter - eTofConst::counterStart;
649 mETofModule[ mNValidModules-1 ]->addCounter( *gpNode, dx, dy, moduleId, counterId, safetyMargins, mAlignmentParameters.at(iCounterAlignment) );
656 LOG_INFO <<
"amount of valid modules: " << mNValidModules << endm;
660 if( useHelixSwimmer ) {
662 if( !StarMagField::Instance() ) {
663 LOG_INFO <<
" no StMagField available ... " << endm;
666 mStarBField = StarMagField::Instance();
667 LOG_INFO <<
" ... initializing magnetic field from StarMagField: fScale = " << mStarBField->GetFactor() << endm;
679 StETofGeometry::reset()
681 for(
size_t i=0; i<mNValidModules; i++ ) {
682 LOG_DEBUG <<
"for ETofModule (" << i <<
")" << endm;
683 mETofModule[ i ]->clearCounters();
685 LOG_DEBUG <<
"deleting ETofModule (" << i <<
")" << endm;
686 delete mETofModule[ i ];
687 mETofModule[ i ] = 0;
689 LOG_INFO <<
"StETofGeometry cleared up ...." << endm;
692 mAlignmentParameters.clear();
695 mStarBField =
nullptr;
707 std::ostringstream geoPath;
709 geoPath <<
"/HALL_1/CAVE_1/MagRefSys_1/ETOF_" << plane << sector;
711 bool found = geoManager->CheckPath( geoPath.str().c_str() );
717 geoPath <<
"/HALL_1/CAVE_1/ETOF_" << plane << sector;
722 geoPath <<
"/EGAS_1/ECOU_" << counter;
725 found = geoManager->CheckPath( geoPath.str().c_str() );
727 return found ? geoPath.str() :
"";
734 std::ostringstream geoPath;
736 geoPath <<
"/HALL_1/CAVE_1/MagRefSys_1/ETOF_" << plane << sector;
738 bool found = geoManager->CheckPath( geoPath.str().c_str() );
744 geoPath <<
"/HALL_1/CAVE_1/ETOF_" << plane << sector;
749 geoPath <<
"/EGAS_1/ECOU_" << counter;
752 geoPath <<
"/EGAP_" << gap;
755 found = geoManager->CheckPath( geoPath.str().c_str() );
757 return found ? geoPath.str() :
"";
762 StETofGeometry::calcModuleIndex(
const int& sector,
const int& plane )
765 return (plane - eTofConst::zPlaneStart ) + eTofConst::nPlanes * ( sector - eTofConst::sectorStart );
770 StETofGeometry::calcVolumeIndex(
const int& sector,
const int& plane,
const int& counter,
const int& strip )
773 int idMultiplier[ 3 ] = { 10000, 1000, 100 };
774 int id = sector * idMultiplier[ 0 ] + plane * idMultiplier[ 1 ] + counter * idMultiplier[ 2 ] + strip;
780 StETofGeometry::decodeVolumeIndex(
const int& volumeId,
int& sector,
int& plane,
int& counter,
int& strip )
783 int idMultiplier[ 3 ] = { 10000, 1000, 100 };
785 sector = volumeId / idMultiplier[ 0 ];
786 plane = ( volumeId % idMultiplier[ 0 ] ) / idMultiplier[ 1 ];
787 counter = ( volumeId % idMultiplier[ 1 ] ) / idMultiplier[ 2 ];
788 strip = volumeId % idMultiplier[ 2 ];
793 StETofGeometry::findETofNode(
const int moduleId,
const int counterId )
798 for(
unsigned int i=0; i<mNValidModules; i++ ) {
799 if( mETofModule[ i ]->moduleIndex() == moduleId ) {
805 if( iModule == -1 ) {
806 LOG_ERROR <<
"ETOF volume for moduleId " << moduleId <<
" and counter " << counterId <<
" is not loaded ..." << endm;
810 int nValidCounters = mETofModule[ iModule ]->numberOfCounters();
812 for(
int j=0; j<nValidCounters; j++ ) {
813 if( mETofModule[ iModule ]->counter( j )->counterIndex() == counterId ) {
819 if( iCounter == -1 ) {
820 LOG_ERROR <<
"ETOF volume for moduleId " << moduleId <<
" and counter " << counterId <<
" is not loaded ..." << endm;
824 return mETofModule[ iModule ]->counter( iCounter );
828 StETofGeometry::pointMaster2local(
const int moduleId,
const int counterId,
const double* master,
double* local )
834 if( !findETofNode( moduleId, counterId ) ) {
835 LOG_ERROR <<
"ETOF volume of a hit is not loaded in the geometry" << endm;
839 findETofNode( moduleId, counterId )->master2Local( master, local );
844 StETofGeometry::hitLocal2Master(
const int moduleId,
const int counterId,
const double* local,
double* master )
850 if( !findETofNode( moduleId, counterId ) ) {
851 LOG_ERROR <<
"ETOF volume of a hit is not loaded in the geometry" << endm;
855 findETofNode( moduleId, counterId )->local2Master( local, master );
864 double xg[ 3 ] = { 0., 0., 0. };
866 int moduleId = calcModuleIndex( hit->
sector(), hit->
zPlane() );
867 int counterId = hit->
counter() - 1;
869 if( !findETofNode( moduleId, counterId ) ) {
870 LOG_ERROR <<
"ETOF volume of a hit is not loaded in the geometry" << endm;
874 findETofNode( moduleId, counterId )->local2Master( xl, xg );
880 StETofGeometry::hitLocal2Master(
StMuETofHit* hit )
882 return hitLocal2Master( (
StETofHit* ) hit );
892 double xg[ 3 ] = { 0., 0., 0. };
894 int moduleId = calcModuleIndex( hit->
sector(), hit->
zPlane() );
895 int counterId = hit->
counter() - 1;
897 if( !findETofNode( moduleId, counterId ) ) {
898 LOG_ERROR <<
"ETOF volume of a hit is not loaded in the geometry" << endm;
899 return TVector3( 0., 0., 0. );
902 findETofNode( moduleId, counterId )->local2Master( xl, xg );
904 return TVector3( xg[ 0 ], xg[ 1 ], xg[ 2 ] );
909 StETofGeometry::helixCrossPlane(
const StHelixD& helix,
const double& z )
912 LOG_INFO <<
"zplane:" << z << endm;
922 logPoint(
"( outer- ) helix origin" , helix.
origin() );
925 if( s<0. || s>4000. )
return StThreeVectorD( -999., -999., 999. );
928 if( point.perp() > 300. )
return StThreeVectorD( -999., -999., 999. );
931 LOG_INFO <<
"pathLength @ ETOF plane = " << s << endm;
932 logPoint(
"intersection", point );
939 StETofGeometry::helixCrossETofPlane(
const StHelixD& helix )
941 return helixCrossPlane( helix, eTofConst::zplanes[ 1 ] );
948 helixSwimmer = helix;
953 double zTpcEdge = -220.;
954 if( z > zTpcEdge )
return;
958 if( s<0. || s>4000. ) {
967 double bField = getFieldZ( posTpcEdge ) * kilogauss;
969 int charge = helix.charge( bField );
972 const int nSteps = 10;
973 double stepWidth = ( z - zTpcEdge ) / nSteps;
978 for(
int i=0; i<nSteps; i++ ) {
979 double zInStep = zTpcEdge + stepWidth * ( i+1 );
981 bField = getFieldZ( posInStep ) * kilogauss;
984 s = helixInStep.pathLength(
StThreeVectorD( 0., 0., zInStep ), n );
985 if( s<0. || s>4000. ) {
989 posInStep = helixInStep.at( s );
992 momInStep = helixInStep.momentumAt( s, bField );
997 logPoint(
"ideal", helix.at( pathlength ) );
998 logPoint(
"swimmer", helixInStep.at( s ) );
1000 LOG_INFO <<
" pt: " << momInStep.perp() <<
" helix curvature: " << helixInStep.curvature() <<
" radius: " << 1./ helixInStep.curvature() << endm;
1001 LOG_INFO <<
"stepWidth: " << stepWidth <<
" bField: " << bField <<
" pathLength: " << s <<
" mom phi:" << momInStep.phi() << endm;
1017 StThreeVectorD point = helixCrossPlane( helix, eTofConst::zplanes[ 1 ] );
1019 if( fabs( point.x() + 999 ) < 1e-5 ) {
1020 std::vector< int > r;
1024 LOG_DEBUG <<
"track phi @ ETOF= " << point.phi() << endm;
1026 return sectorAtPhi( point.phi() );
1030 StETofGeometry::sectorAtPhi(
const double& angle )
1032 float phi = angle + ( M_PI / 24 );
1035 if ( phi < 0. ) phi += 2. * M_PI;
1038 double slice = M_PI / 12.;
1044 vector< int > sectorId = { 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 19, 20 };
1046 double iSlice = phi / slice;
1049 int intSlice = ( int ) iSlice;
1051 int indexA = ( intSlice / 2 ) % sectorId.size();
1054 if( intSlice % 2 == 0 ) {
1055 sectorA = sectorId[ indexA ];
1058 int indexB = ( indexA + 1 ) % sectorId.size();
1060 sectorA = sectorId[ indexA ];
1061 sectorB = sectorId[ indexB ];
1063 if ( isDebugOn() ) {
1064 LOG_INFO <<
"phi = " << phi <<
", iSlice = " << iSlice <<
", SectorA: " << sectorA <<
", SectorB: " << sectorB << endm;
1067 vector< int > r = { sectorA };
1069 r.push_back( sectorB );
1085 if( sectorsCrossed.size() == 0 )
return;
1087 if( sectorsCrossed.size() == 1 ) LOG_DEBUG <<
"sector crossed: " << sectorsCrossed[ 0 ] << endm;
1088 if( sectorsCrossed.size() == 2 ) LOG_DEBUG <<
"sectors crossed: " << sectorsCrossed[ 0 ] <<
", " << sectorsCrossed[ 1 ] << endm;
1091 for(
unsigned int i=0; i<mNValidModules; i++ ) {
1092 if( !mETofModule[ i ] )
continue;
1095 int iSector = mETofModule[ i ]->sector();
1096 auto found = std::find( std::begin( sectorsCrossed ), std::end( sectorsCrossed ), iSector );
1098 if( found == std::end( sectorsCrossed ) )
continue;
1100 LOG_DEBUG << iSector <<
" " << mETofModule[ i ]->plane() << endm;
1102 double module_pathLen;
1103 double module_theta;
1106 bool helixCrossedModule = mETofModule[ i ]->helixCross( helix, module_pathLen, module_cross, module_theta );
1108 module_theta *= 180. / M_PI;
1111 if( mDebug && helixCrossedModule ) {
1112 LOG_INFO <<
" -----------" <<
"\nmoduleId:"<< mETofModule[ i ]->moduleIndex() <<
" helix_crossed: " << helixCrossedModule
1113 <<
" sector: " << mETofModule[ i ]->sector() <<
" plane: " << mETofModule[ i ]->plane() << endm;
1114 LOG_INFO <<
"pathLength: " << module_pathLen <<
" absolute impact angle: " << module_theta <<
" degree" << endm;
1115 logPoint(
"crossing point" , module_cross );
1116 LOG_INFO <<
"cross.eta: " << module_cross.pseudoRapidity() << endm;
1121 if( !helixCrossedModule )
continue;
1125 double swimmerPathLen;
1129 helixSwimmer( helix, swimmerHelix, mETofModule[ i ]->centerPos().z() + 5., swimmerPathLen );
1133 int nValidCounters = mETofModule[ i ]->numberOfCounters();
1134 for(
int j=0; j<nValidCounters; j++ ) {
1139 bool helixCrossedCounter =
false;
1143 helixCrossedCounter = mETofModule[ i ]->counter( j )->helixCross( swimmerHelix, pathLen, cross, theta );
1144 pathLen += swimmerPathLen;
1145 if( mDebug ) LOG_DEBUG <<
" using swimmer helix" << endm;
1149 helixCrossedCounter = mETofModule[ i ]->counter( j )->helixCross( helix, pathLen, cross, theta );
1150 if( mDebug ) LOG_DEBUG <<
" using ideal helix" << endm;
1153 if( helixCrossedCounter ) {
1154 theta *= 180. / M_PI;
1159 global[ 0 ] = cross.x();
1160 global[ 1 ] = cross.y();
1161 global[ 2 ] = cross.z();
1163 mETofModule[ i ]->counter( j )->master2Local( global, local );
1164 int strip = mETofModule[ i ]->counter( j )->findStrip( local );
1166 int sector = mETofModule[ i ]->sector();
1167 int plane = mETofModule[ i ]->plane();
1168 int counter = mETofModule[ i ]->counter( j )->counterIndex() + 1;
1170 int volumeIndex = calcVolumeIndex( sector, plane, counter, strip );
1172 idVec.push_back( volumeIndex );
1173 crossVec.push_back( cross );
1174 localVec.push_back(
StThreeVectorD( local[ 0 ], local[ 1 ], local[ 2 ] ) );
1175 thetaVec.push_back( theta );
1176 pathLenVec.push_back( pathLen );
1179 LOG_INFO <<
" -----------" <<
"\ncounterId: " << mETofModule[ i ]->counter( j )->counterIndex() << endm;
1180 LOG_INFO <<
"pathLength: " << pathLen <<
" impact angle: " << theta <<
" degree" << endm;
1181 logPoint(
"crossing point" , cross );
1182 LOG_INFO <<
"cross.eta: " << cross.pseudoRapidity() <<
"\n" << endm;
1183 LOG_INFO <<
"localX: " << local[ 0 ] <<
" localY: " << local[ 1 ] <<
" localZ: " << local[ 2 ] << endm;
1184 LOG_INFO <<
"Strip: " << strip <<
" * * * " << endm;
1194 StETofGeometry::logPoint(
const char* text,
const StThreeVectorD& point )
1196 LOG_INFO << text <<
" at (" << point.x() <<
", " << point.y() <<
", " << point.z() <<
")" << endm;
1201 StETofGeometry::module(
const unsigned int i )
1203 if( isInitDone() && i < mNValidModules ) {
1204 return mETofModule[ i ];
1206 else return nullptr;
1212 StETofGeometry::helixCrossETofPlane(
const StPicoHelix& helix )
1214 return helixCrossPlane( helix, eTofConst::zplanes[ 1 ] );
1220 StETofGeometry::helixCrossPlane(
const StPicoHelix& helix,
const double& z )
1222 TVector3 r( 0, 0, z );
1225 TVector3 n( 0, 0, 1 );
1228 logPoint(
"( outer- ) helix origin" , helix.
origin() );
1231 TVector3 point = helix.at( s );
1234 LOG_INFO <<
"pathLength @ z = " << s << endm;
1235 logPoint(
"intersection", point );
1246 helixSwimmer = helix;
1249 TVector3 n( 0., 0., 1. );
1251 double zTpcEdge = -220.;
1252 if( z > zTpcEdge )
return;
1255 double s = helix.
pathLength( TVector3( 0., 0., zTpcEdge ), n );
1256 if( s<0. || s>4000. ) {
1262 TVector3 posTpcEdge = helix.at( s );
1265 double bField = getFieldZ( posTpcEdge ) * kilogauss;
1266 TVector3 momTpcEdge = helix.
momentumAt( s, bField );
1267 int charge = helix.
charge( bField );
1270 const int nSteps = 10;
1271 double stepWidth = ( z - zTpcEdge ) / nSteps;
1273 TVector3 posInStep = posTpcEdge;
1274 TVector3 momInStep = momTpcEdge;
1276 for(
int i=0; i<nSteps; i++ ) {
1277 double zInStep = zTpcEdge + stepWidth * ( i+1 );
1279 bField = getFieldZ( posInStep ) * kilogauss;
1282 s = helixInStep.pathLength( TVector3( 0., 0., zInStep ), n );
1283 if( s<0. || s>4000. ) {
1287 posInStep = helixInStep.at( s );
1290 momInStep = helixInStep.momentumAt( s, bField );
1295 logPoint(
"ideal", helix.at( pathlength ) );
1296 logPoint(
"swimmer", helixInStep.at( s ) );
1298 LOG_INFO <<
" pt: " << momInStep.Perp() <<
" helix curvature: " << helixInStep.curvature() <<
" radius: " << 1./ helixInStep.curvature() << endm;
1299 LOG_INFO <<
"stepWidth: " << stepWidth <<
" bField: " << bField <<
" pathLength: " << s <<
" mom phi:" << momInStep.Phi() << endm;
1315 TVector3 point = helixCrossETofPlane( helix );
1317 LOG_DEBUG <<
"track phi @ ETOF= " << point.Phi() << endm;
1319 return sectorAtPhi( point.Phi() );
1333 if( sectorsCrossed.size() == 1 ) LOG_DEBUG <<
"sector crossed: " << sectorsCrossed[ 0 ] << endm;
1334 if( sectorsCrossed.size() == 2 ) LOG_DEBUG <<
"sectors crossed: " << sectorsCrossed[ 0 ] <<
", " << sectorsCrossed[ 1 ] << endm;
1337 for(
unsigned int i=0; i<mNValidModules; i++ ) {
1338 if( !mETofModule[ i ] )
continue;
1341 int iSector = mETofModule[ i ]->sector();
1342 auto found = std::find( std::begin( sectorsCrossed ), std::end( sectorsCrossed ), iSector );
1344 if( found == std::end( sectorsCrossed ) )
continue;
1346 LOG_DEBUG << iSector <<
" " << mETofModule[i]->plane() << endm;
1348 double module_pathLen;
1349 double module_theta;
1350 TVector3 module_cross;
1352 bool helixCrossedModule = mETofModule[ i ]->helixCross( helix, module_pathLen, module_cross, module_theta );
1354 module_theta = fabs( module_theta * 180. / M_PI );
1357 if( mDebug && helixCrossedModule ) {
1358 LOG_INFO <<
" -----------" <<
"\nmoduleId:"<< mETofModule[ i ]->moduleIndex() <<
" helix_crossed: " << helixCrossedModule
1359 <<
" sector: " << mETofModule[ i ]->sector() <<
" plane: " << mETofModule[ i ]->plane() << endm;
1360 LOG_INFO <<
"pathLength: " << module_pathLen <<
" absolute impact angle: " << module_theta <<
" degree" << endm;
1361 logPoint(
"crossing point" , module_cross );
1362 LOG_INFO <<
"cross.eta: " << module_cross.PseudoRapidity() << endm;
1367 if( !helixCrossedModule )
continue;
1372 double swimmerPathLen;
1376 helixSwimmer( helix, swimmerHelix, mETofModule[ i ]->centerPos().z() + 5., swimmerPathLen );
1380 int nValidCounters = mETofModule[ i ]->numberOfCounters();
1381 for(
int j=0; j<nValidCounters; j++ ) {
1386 bool helixCrossedCounter =
false;
1390 helixCrossedCounter = mETofModule[ i ]->counter( j )->helixCross( swimmerHelix, pathLen, cross, theta );
1391 pathLen += swimmerPathLen;
1392 if( mDebug ) LOG_DEBUG <<
" using swimmer helix" << endm;
1396 helixCrossedCounter = mETofModule[ i ]->counter( j )->helixCross( helix, pathLen, cross, theta );
1397 if( mDebug ) LOG_DEBUG <<
" using ideal helix" << endm;
1400 theta = fabs( theta * 180. / M_PI );
1402 if( helixCrossedCounter ) {
1406 global[ 0 ] = cross.x();
1407 global[ 1 ] = cross.y();
1408 global[ 2 ] = cross.z();
1410 mETofModule[ i ]->counter( j )->master2Local( global, local );
1411 int strip = mETofModule[ i ]->counter( j )->findStrip( local );
1413 int sector = mETofModule[ i ]->sector();
1414 int plane = mETofModule[ i ]->plane();
1415 int counter = mETofModule[ i ]->counter( j )->counterIndex() + 1;
1417 int volumeIndex = calcVolumeIndex( sector, plane, counter, strip );
1419 idVec.push_back( volumeIndex );
1420 crossVec.push_back( cross );
1421 localVec.push_back( TVector3( local[ 0 ], local[ 1 ], local[ 2 ] ) );
1422 thetaVec.push_back( theta );
1425 LOG_INFO <<
" -----------" <<
"\ncounterId: " << mETofModule[ i ]->counter( j )->counterIndex() << endm;
1426 LOG_INFO <<
"pathLength: " << pathLen <<
" absolute impact angle: " << theta <<
" degree" << endm;
1427 logPoint(
"crossing point" , cross );
1428 LOG_INFO <<
"cross.eta: " << cross.PseudoRapidity() <<
"\n" << endm;
1429 LOG_INFO <<
"localX: " << local[ 0 ] <<
" localY: " << local[ 1 ] <<
" localZ: " << local[ 2 ] << endm;
1430 LOG_INFO <<
"Strip: " << strip <<
" * * * " << endm;
1440 StETofGeometry::logPoint(
const char* text,
const TVector3& point )
1442 LOG_INFO << text <<
" at (" << point.x() <<
", " << point.y() <<
", " << point.z() <<
")" << endm;
1447 if( !mStarBField ) {
1451 double B[ 3 ] = { 0, 0, 0 };
1452 double X[ 3 ] = { pos.x(), pos.y(), pos.z() };
1453 mStarBField->BField( X, B );
1459 StETofGeometry::getField(
const TVector3& pos ) {
1460 if( !mStarBField ) {
1461 return TVector3( -999., -999., -999. );
1464 double B[ 3 ] = { 0, 0, 0 };
1465 double X[ 3 ] = { pos.X(), pos.Y(), pos.Z() };
1466 mStarBField->BField( X, B );
1468 return TVector3( B[ 0 ], B[ 1 ], B[ 2 ] );
1479 StETofGeometry::getFieldZ(
const TVector3& pos ) {
1480 TVector3 bField = getField( pos );
1485 StETofGeometry::getFieldZ(
const double& x,
const double& y,
const double& z ) {
1486 if( !mStarBField ) {
1490 double B[ 3 ] = { 0, 0, 0 };
1491 double X[ 3 ] = { x, y, z };
1493 mStarBField->BField( X, B );
1499 StETofGeometry::readAlignmentParameters(){
1500 LOG_INFO <<
"etofAlignParam: filename provided --> use parameter file: " << mFileNameAlignParam << endm;
1505 paramFile.open( mFileNameAlignParam );
1507 if( !paramFile.is_open() ) {
1508 LOG_INFO <<
"unable to get the alignments parameters from file --> file does not exist" << endm;
1516 while( paramFile >> tempX >> tempY >> tempZ ) {
1517 counterAlignmentParameter =
StThreeVectorD( tempX, tempY, tempZ );
1518 mAlignmentParameters.push_back( counterAlignmentParameter );
1523 if( mAlignmentParameters.size() != 108 ) {
1524 LOG_WARN <<
"parameter file for alignments has not the right amount of entries: " << mAlignmentParameters.size() <<
" instead of 108 !!!!" << endm;
1530 StETofGeometry::readAlignmentDatabase(){
1531 LOG_INFO <<
"No etof alignment file provided --> use database: " << endm;
1535 TDataSet* dbDataSet = StMaker::GetChain()->GetDataBase(
"Geometry/etof/etofAlign");
1537 LOG_ERROR <<
"unable to get the dataset from the database" << endm;
1541 St_etofAlign* etofAlign =
static_cast< St_etofAlign *
> ( dbDataSet->
Find(
"etofAlign" ) );
1543 LOG_ERROR <<
"unable to get the align params from the database" << endm;
1547 etofAlign_st* table = etofAlign->GetTable();
1553 for(
int iCounter = 0; iCounter < eTofConst::nCounters * eTofConst::nModules; iCounter++){
1554 tempX = table->detectorAlignX[iCounter];
1555 tempY = table->detectorAlignY[iCounter];
1556 tempZ = table->detectorAlignZ[iCounter];
1558 mAlignmentParameters.push_back( counterAlignmentParameter );
TVector3 momentumAt(Double_t, Double_t) const
Return momemtum at S.
Float_t localX() const
Return local X coordinate (cm) across strips w.r.t. center of eTOF counter volume.
void helixCrossCounter(const StPhysicalHelixD &helix, std::vector< int > &idVec, std::vector< StThreeVectorD > &crossVec, std::vector< StThreeVectorD > &localVec, std::vector< double > &thetaVec, std::vector< double > &pathLenVec)
std::string formTGeoPath(const TGeoManager *geoManager, int plane, int sector, int counter=-1)
Int_t sector() const
Return eTOF sector number (equal to TPC sector numbering)
std::vector< int > helixCrossSector(const StHelixD &helix)
pair< Double_t, Double_t > pathLength(Double_t r) const
path length at given r (cylindrical r)
const TVector3 & origin() const
Return origin of the helix = starting point.
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
unsigned int counter() const
Counter.
const StThreeVector< double > & origin() const
-sign(q*B);
Helis parametrization for the particle.
Int_t charge(Double_t) const
Return charge of a particle.
unsigned int zPlane() const
ZPlane.
double localX() const
X-position.
Stores eTOF hit information.
double localY() const
Y-position.
Helix parametrization that uses ROOT TVector3.
unsigned int sector() const
Sector.
Float_t localY() const
Return local Y coordinate (cm) along strips w.r.t. center of eTOF counter volume. ...
virtual TDataSet * Find(const char *path) const