78 #include "StMtdGeometry.h"
80 #include "StMessMgr.h"
81 #include "TGeoManager.h"
82 #include "TGeoVolume.h"
86 #include "StThreeVectorD.hh"
87 #include "StPhysicalHelixD.hh"
88 #include "PhysicalConstants.h"
89 #include "SystemOfUnits.h"
90 #include "StDetectorDbMaker/St_MagFactorC.h"
91 #include "tables/St_mtdGeant2BacklegIDMap_Table.h"
94 const Double_t StMtdGeometry::mMtdMinR = 392.802;
95 const Double_t StMtdGeometry::mMtdMaxR = 418.865;
96 const Double_t StMtdGeometry::mMagInR = 303.290;
97 const Double_t StMtdGeometry::mMagOutR = 364.290;
98 const Double_t StMtdGeometry::mEmcInR = 223.505;
99 const Double_t StMtdGeometry::mEmcOutR = 248.742;
102 const char* StMtdGeometry::modulePref =
"MTRA";
116 StMtdGeoNode::StMtdGeoNode(TGeoVolume *vol, TGeoHMatrix *mat,
StThreeVectorD point, Int_t nExtraCells)
120 fMatrix =
new TGeoHMatrix();
121 fMatrix->CopyFrom(mat);
122 fVolume = vol->CloneVolume();
124 fNExtraCells = nExtraCells;
126 fNormal = YZPlaneNormal();
129 StMtdGeoNode::~StMtdGeoNode()
140 void StMtdGeoNode::UpdateMatrix()
151 fTransMRS = fMatrix->GetTranslation();
152 fRotMRS = fMatrix->GetRotationMatrix();
155 LOG_WARN<<
"No TGeoHMatrix!"<<endm;
160 void StMtdGeoNode::LocalToMaster(
const Double_t* local, Double_t* master)
175 master[0] = fTransMRS[0] + fRotMRS[0]*x + fRotMRS[1]*y + fRotMRS[2]*z;
176 master[1] = fTransMRS[1] + fRotMRS[3]*x + fRotMRS[4]*y + fRotMRS[5]*z;
177 master[2] = fTransMRS[2] + fRotMRS[6]*x + fRotMRS[7]*y + fRotMRS[8]*z;
179 LOG_WARN <<
" No TGeoHMatrix::LocalToMaster is wrong, so do nothing" << endm;
182 fMatrix->LocalToMaster(local, master);
197 void StMtdGeoNode::MasterToLocal(
const Double_t* master, Double_t* local)
206 x = master[0] - fTransMRS[0];
207 y = master[1] - fTransMRS[1];
208 z = master[2] - fTransMRS[2];
210 local[0] = fRotMRS[0]*x + fRotMRS[3]*y + fRotMRS[6]*z;
211 local[1] = fRotMRS[1]*x + fRotMRS[4]*y + fRotMRS[7]*z;
212 local[2] = fRotMRS[2]*x + fRotMRS[5]*y + fRotMRS[8]*z;
215 LOG_WARN<<
" No TGeoHMatrix::MasterToLocal is wrong, so do nothing" << endm;
218 fMatrix->MasterToLocal(master,local);
222 x = master[0] - fTransMRS[0];
223 y = master[1] - fTransMRS[1];
224 z = master[2] - fTransMRS[2];
227 test[0] = fRotMRS[0]*x + fRotMRS[3]*y + fRotMRS[6]*z;
228 test[1] = fRotMRS[1]*x + fRotMRS[4]*y + fRotMRS[7]*z;
229 test[2] = fRotMRS[2]*x + fRotMRS[5]*y + fRotMRS[8]*z;
243 Double_t ux[3], nx[3];
245 ux[0] = 1; ux[1] = 0; ux[2] = 0;
246 LocalToMaster(ux,nx);
248 nx[0] -= fTransMRS[0];
249 nx[1] -= fTransMRS[1];
250 nx[2] -= fTransMRS[2];
255 Bool_t StMtdGeoNode::HelixCross(
const StPhysicalHelixD helix,
const Double_t pathToMagOutR,
const Double_t tofToMagOutR, Double_t &pathL, Double_t &
tof,
StThreeVectorD &cross){
257 Float_t MaxPathLength = 1000.;
264 if(TMath::IsNaN(oh.x())||TMath::IsNaN(oh.y())||TMath::IsNaN(oh.z())||TMath::Abs(oh.perp())>450.||TMath::Abs(oh.z())>300.)
return ret;
266 double betaGam = helix.momentum(gMtdGeometry->GetFieldZ(oh)).mag()/muonMass;
267 double velocity = sqrt(betaGam*betaGam/(1+betaGam*betaGam))*c_light*1e-9;
268 tof = pathL/velocity;
269 LOG_DEBUG<<
"StMtdGeoNode::HelixCross() pathL = "<<pathL<<
" point ("<<fPoint.x()<<
","<<fPoint.y()<<
","<<fPoint.z()<<
") normal("<<fNormal.x()<<
","<<fNormal.y()<<
","<<fNormal.z()<<
") radius = "<<fPoint.perp()<<endm;
270 if(pathL>0 && pathL<MaxPathLength){
271 cross = helix.at(pathL);
272 ret = IsGlobalPointIn(cross);
273 LOG_DEBUG<<
"track cross point "<<cross.x()<<
","<<cross.y()<<
","<<cross.z()<<endm;
274 pathL += pathToMagOutR;
282 Double_t xl[3], xg[3];
286 MasterToLocal(xg, xl);
287 Bool_t ret = IsLocalPointIn(xl[0], xl[1], xl[2]);
292 Bool_t StMtdGeoNode::IsLocalPointIn(
const Double_t x,
const Double_t y,
const Double_t z){
293 TGeoBBox *brik = (TGeoBBox*)fVolume->GetShape();
294 Double_t dx = brik->GetDX();
295 Float_t nExtraCells = fNExtraCells>1.66?fNExtraCells-1.66:0;
296 Double_t dy = brik->GetDY()+nExtraCells*(gMtdCellWidth+gMtdCellGap);
297 Double_t dz = brik->GetDZ();
298 Bool_t ret = -dx<x && x<dx && -dy<y && y<dy && -dz<z && z<dz;
319 StMtdGeoBackleg::StMtdGeoBackleg (Int_t iMTTG, Int_t iBL, TGeoVolume *vol, TGeoHMatrix *mat,
StThreeVectorD point, Int_t nExtraCells)
320 :
StMtdGeoNode(vol, mat, point, nExtraCells), mMTTGIndex(iMTTG), mBacklegIndex(iBL)
325 StMtdGeoBackleg::~StMtdGeoBackleg()
341 StMtdGeoModule::StMtdGeoModule (Int_t iMTRA, Int_t iMod, TGeoVolume *vol, TGeoHMatrix *mat,
StThreeVectorD point, Int_t nExtraCells)
342 :
StMtdGeoNode(vol, mat, point, nExtraCells), mMTRAIndex(iMTRA), mModuleIndex(iMod)
347 StMtdGeoModule::~StMtdGeoModule()
353 Int_t StMtdGeoModule::FindCellId(
const Double_t *local){
355 if ( IsLocalPointIn(local[0],local[1],local[2]) ) {
356 cellId = TMath::FloorNint((local[1]+(gMtdCellWidth+gMtdCellGap)*gMtdNCells/2.)/(gMtdCellWidth+gMtdCellGap));
362 Float_t StMtdGeoModule::GetCellPhiCenter(Int_t iCell){
363 Float_t phi = fPoint.phi();
364 Float_t r = fPoint.perp();
365 Float_t stripPhiCen = 0.;
366 if(mModuleIndex>0&&mModuleIndex<4){
367 stripPhiCen = phi-(gMtdNCells/2.-0.5-iCell)*(gMtdCellWidth+gMtdCellGap)/r;
369 stripPhiCen = phi+(gMtdNCells/2.-0.5-iCell)*(gMtdCellWidth+gMtdCellGap)/r;
371 if(stripPhiCen>2.*TMath::Pi()) stripPhiCen -= 2.*TMath::Pi();
372 if(stripPhiCen<0.) stripPhiCen += 2.*TMath::Pi();
377 Float_t StMtdGeoModule::GetCellZCenter(Int_t iCell){
382 Float_t StMtdGeoModule::GetCellLocalYCenter(Int_t iCell, Int_t iBL, Int_t idTruth){
385 Float_t cell_width = gMtdCellWidth+gMtdCellGap;
386 Float_t y_center = (mModuleIndex<4? 1 : -1) * (iCell-gMtdNCells/2+0.5) * cell_width;
392 if(iBL==8) y_center -= 3 * cell_width;
393 if(iBL==24) y_center += 2 * cell_width;
400 Float_t StMtdGeoModule::GetCellLocalYCenter(Int_t iCell){
403 Float_t cell_width = gMtdCellWidth+gMtdCellGap;
404 Float_t y_center = (mModuleIndex<4? 1 : -1) * (iCell-gMtdNCells/2+0.5) * cell_width;
437 mGeoManager = manager;
439 fMagEloss =
new TF1(
"f2",
"[0]*exp(-pow([1]/x,[2]))",0.,100);
440 fMagEloss->SetParameters(1.38147e+00,6.08655e-02,5.03337e-01);
442 for(
int i=0;i<gMtdNBacklegs;i++) {
443 mMtdGeoBackleg[i] = 0;
444 for(
int j=0;j<gMtdNModules;j++) {
445 mMtdGeoModule[i][j] = 0;
450 LOG_INFO <<
"Warning !! There is already StMtdGeometry at pointer="
451 << (
void*)gMtdGeometry <<
", so it is deleted"
458 StMtdGeometry::~StMtdGeometry()
461 LOG_INFO <<
"StMtdGeometry at pointer =" << (
void*)gMtdGeometry
462 <<
" will be deleted" << endm;
467 void StMtdGeometry::Init(
StMaker *maker){
469 if(maker->Debug()) DebugOn();
471 Int_t mYear = maker->GetDateTime().GetYear();
473 LOG_INFO<<
"Input data from year "<<mYear<<endm;
479 LOG_INFO<<
" Initializing locked mag.field for simulation! "<<endm;
482 assert(StarMagField::Instance());
483 mStarBField = StarMagField::Instance();
484 LOG_INFO<<
" Initializing mag.field from StarMagField! fScale = "<<mStarBField->GetFactor()<<endm;
490 LOG_WARN<<
"No geant2backlegID table for 2012 and before"<<endm;
494 LOG_INFO <<
"Retrieving geant2backlegID table from database ..." << endm;
496 TDataSet *dataset = maker->GetDataBase(
"Geometry/mtd/mtdGeant2BacklegIDMap");
497 St_mtdGeant2BacklegIDMap *mtdGeant2BacklegIDMap =
static_cast<St_mtdGeant2BacklegIDMap*
>(dataset->
Find(
"mtdGeant2BacklegIDMap"));
498 if ( !mtdGeant2BacklegIDMap )
500 LOG_ERROR <<
"No mtdGeant2BacklegIDMap found in database" << endm;
504 mtdGeant2BacklegIDMap_st *mGeant2BLTable =
static_cast<mtdGeant2BacklegIDMap_st*
>(mtdGeant2BacklegIDMap->GetTable());
507 for ( Int_t i = 0; i < 30; i++ )
509 mMTTG2BL[i] = (Int_t)mGeant2BLTable->geant2backlegID[i];
510 if(mMTTG2BL[i]>30 || mMTTG2BL[i]<0) LOG_ERROR<<
" Wrong map! check database! "<<endm;
515 LOG_ERROR <<
"No geant2backlegIDMap table found in database" << endm;
519 for(
int i=0;i<30;++i)
523 if(i<11||i>19) mMTRA2Mod[i][j] = j+1;
526 if(j==3||j==4) mMTRA2Mod[i][j] = 0;
527 else mMTRA2Mod[i][j] = j+2;
533 if(mGeoManager->CheckPath(
"/HALL_1/CAVE_1/MUTD_1/MTMT_1")){
534 LOG_INFO<<
"found y2012 geometry"<<endm;
537 else if(mGeoManager->CheckPath(
"/HALL_1/CAVE_1/MagRefSys_1/MUTD_1")){
538 LOG_INFO<<
"found y2015 geometry"<<endm;
543 TGeoVolume *mMtdGeom = mGeoManager->FindVolumeFast(
"MUTD");
544 const char *elementName = mMtdGeom->GetName();
546 if(IsDebugOn()) LOG_INFO <<
" found detector:"<<elementName<<endm;
547 TGeoIterator next(mMtdGeom);
548 if(mGeoYear==2015) next.SetTopName(
"/HALL_1/CAVE_1/MagRefSys_1/MUTD_1");
549 else next.SetTopName(
"/HALL_1/CAVE_1/MUTD_1");
551 TGeoVolume *blVol = 0;
552 TGeoVolume *modVol = 0;
555 Double_t minR = 999.;
557 while ( (node=(TGeoNode*)next()) )
559 TString name = node->GetName();
562 if(!mGeoManager->CheckPath(path.Data())){
563 LOG_WARN<<
"Path "<<path.Data()<<
" is not found"<<endm;
566 mGeoManager->cd(path.Data());
567 TGeoVolume *detVol = mGeoManager->GetCurrentVolume();
568 Bool_t found = ( IsMTTG(detVol) || IsMTRA(detVol) );
570 detVol->SetVisibility(kTRUE);
574 detVol->SetVisibility(kFALSE);
577 if(IsDebugOn()) LOG_INFO<<
"currentpath = "<<mGeoManager->GetPath()<<
" node name="<<mGeoManager->GetCurrentNode()->GetName()<<endm;
581 blVol = (TGeoVolume *)detVol;
582 Int_t iMTTG = node->GetNumber();
583 if(IsDebugOn()) LOG_INFO<<
"Node name = "<<node->GetName()<<
" iMTTG="<<iMTTG<<endm;
594 if(iMTTG==1) iBL = 27;
595 else if(iMTTG==2) iBL = 28;
598 LOG_ERROR<<
"Wrong BL id, this is not Y2012 geometry!"<<endm;
605 LOG_ERROR<<
"Wrong BL id, this is not Y2012 geometry!"<<endm;
612 iBL = mMTTG2BL[iMTTG-1];
615 Double_t local[3] = {0,0,0};
616 mGeoManager->LocalToMaster(local,op);
618 TGeoHMatrix *mat = mGeoManager->GetCurrentMatrix();
622 Double_t *trans = mat->GetTranslation();
623 Double_t *rot = mat->GetRotationMatrix();
624 trans[0] = -1*trans[0];
627 mat->SetTranslation(trans);
628 mat->SetRotation(rot);
629 point.setX(-1*op[0]);
632 if(IsDebugOn()) LOG_INFO<<
"iMTTG="<<iMTTG<<
" iBL="<<iBL<<endm;
639 modVol = (TGeoVolume *)detVol;
640 Int_t iMTRA = node->GetNumber();
642 Int_t iMod = mMTRA2Mod[ibackleg-1][iMTRA-1];
643 if(mGeoYear==2012&&ibackleg==26){
647 Double_t local[3] = {0,0,0};
648 mGeoManager->LocalToMaster(local,op);
650 double R = sqrt(op[0]*op[0]+op[1]*op[1]);
654 TGeoHMatrix *mat = mGeoManager->GetCurrentMatrix();
658 Double_t *trans = mat->GetTranslation();
659 Double_t *rot = mat->GetRotationMatrix();
660 trans[0] = -1*trans[0];
663 mat->SetTranslation(trans);
664 mat->SetRotation(rot);
665 point.setX(-1*op[0]);
669 if(IsDebugOn()) LOG_INFO<<
"iMTRA="<<iMTRA<<
" iMod="<<iMod<<endm;
676 for(
int i=0;i<gMtdNBacklegs;i++){
677 for(
int j=0;j<gMtdNModules;j++){
678 if(mMtdGeoModule[i][j])
679 LOG_INFO<<
"valid (backleg,module) = "<<i+1<<
","<<j+1<<endm;
692 Double_t pathL2Vtx = 0.;
693 ProjToVertex(helix,vertex,pathL2Vtx,tof,dcaPos);
696 LOG_INFO<<
"------------ start of projection to magOutR ------------"<<endm;
697 LOG_INFO<<
" to vertex("<< vertex.x()<<
","<<vertex.y()<<
","<<vertex.z()<<
") dca = "<<dcaPos.mag()<<endm;
703 if(sInnerEmc.first<=0 && sInnerEmc.second<=0)
return kFALSE;
704 double rInnerEmc = (sInnerEmc.first < 0 || sInnerEmc.second < 0)
705 ? max(sInnerEmc.first, sInnerEmc.second) : min(sInnerEmc.first, sInnerEmc.second);
708 if(TMath::IsNaN(innerEmcPos.x())||TMath::IsNaN(innerEmcPos.y())||TMath::IsNaN(innerEmcPos.z())||TMath::Abs(innerEmcPos.perp())>450.||TMath::Abs(innerEmcPos.z())>300.)
return kFALSE;
709 Double_t bField = GetFieldZ(innerEmcPos);
710 Int_t charge = helix.charge(bField);
711 if(IsDebugOn()) LOG_INFO<<
" charge = "<<charge<<
" bField = "<<bField<<endm;
712 StThreeVectorD innerEmcMom = helix.momentumAt(rInnerEmc,bField*tesla);
715 double betaGam = innerEmcMom.mag()/muonMass;
716 double vInner = sqrt(betaGam*betaGam/(1+betaGam*betaGam))*c_light*1e-9;
717 double tof2InnerEmc = -9999.;
718 tof2InnerEmc = (pathL2Vtx+rInnerEmc)/vInner;
721 LOG_INFO<<
" to Emcinner: pos x,y,z:"<<innerEmcPos.x()<<
","<<innerEmcPos.y()<<
","<<innerEmcPos.z()<<endm;
722 LOG_INFO<<
" to Emcinner: mom p,pt,eta,phi:"<<innerEmcMom.mag()<<
","<<innerEmcMom.perp()<<
","<<innerEmcMom.pseudoRapidity()<<
","<<innerEmcMom.phi()<<endm;
723 LOG_INFO<<
" to Emcinner: tof:"<<tof2InnerEmc<<endm;
727 const int nEmcStep = 4;
728 double rEmcStep = (mEmcOutR-mEmcInR)/nEmcStep;
729 double pathLEmcLayer[nEmcStep];
730 double tofEmcLayer[nEmcStep];
731 double vEmc = -9999.;
732 double betaGamEmc= -9999.;
735 Double_t elossEmc = 0.;
737 if(
mCosmicFlag&&EmcLayerPos.phi()>0&&EmcLayerPos.phi()<TMath::Pi()) elossEmc = -1.*gMtdMuonELossInEmc/nEmcStep;
738 else elossEmc = gMtdMuonELossInEmc/nEmcStep;
740 for(
int i=0; i<nEmcStep; i++){
741 double EmcLayerRadius = mEmcInR+rEmcStep*(i+1);
743 if(TMath::IsNaN(EmcLayerPos.x())||TMath::IsNaN(EmcLayerPos.y())||TMath::IsNaN(EmcLayerPos.z())||TMath::Abs(EmcLayerPos.perp())>450.||TMath::Abs(EmcLayerPos.z())>300.)
return kFALSE;
744 bField = GetFieldZ(EmcLayerPos);
747 pairD sEmcLayer = helixInEmc.pathLength(EmcLayerRadius);
748 if(sEmcLayer.first<=0 && sEmcLayer.second<=0)
return kFALSE;
750 double rEmcLayer = (sEmcLayer.first < 0 || sEmcLayer.second < 0)
751 ? max(sEmcLayer.first, sEmcLayer.second) : min(sEmcLayer.first, sEmcLayer.second);
753 betaGamEmc = EmcLayerMom.mag()/muonMass;
754 vEmc = sqrt(betaGamEmc*betaGamEmc/(1.+betaGamEmc*betaGamEmc))*c_light*1e-9;
755 pathLEmcLayer[i] = rEmcLayer;
756 tofEmcLayer[i] = rEmcLayer/vEmc;
758 EmcLayerPos = helixInEmc.at(rEmcLayer);
759 EmcLayerMom = helixInEmc.momentumAt(rEmcLayer,bField*tesla);
761 EmcLayerMom = (EmcLayerMom.mag()-elossEmc)/EmcLayerMom.mag()*EmcLayerMom;
765 double tof2OuterEmc = 0.;
766 for(
int i=0;i<nEmcStep;i++) tof2OuterEmc += tofEmcLayer[i];
767 LOG_INFO<<
" to Emcouter: pos x,y,z:"<<EmcLayerPos.x()<<
","<<EmcLayerPos.y()<<
","<<EmcLayerPos.z()<<endm;
768 LOG_INFO<<
" to Emcouter: mom p,pt,eta,phi:"<<EmcLayerMom.mag()<<
","<<EmcLayerMom.perp()<<
","<<EmcLayerMom.pseudoRapidity()<<
","<<EmcLayerMom.phi()<<endm;
769 LOG_INFO<<
" to Emcouter: tof:"<<tof2OuterEmc<<endm;
773 if(TMath::IsNaN(EmcLayerPos.x())||TMath::IsNaN(EmcLayerPos.y())||TMath::IsNaN(EmcLayerPos.z())||TMath::Abs(EmcLayerPos.perp())>450.||TMath::Abs(EmcLayerPos.z())>300.)
return kFALSE;
774 bField = GetFieldZ(EmcLayerPos);
775 const int nCoilStep = 5;
776 double rCoilStep = (mMagInR-mEmcOutR)/nCoilStep;
777 double pathLCoilLayer[nCoilStep];
778 double tofCoilLayer[nCoilStep];
780 double betaGamCoil=-9999.;
783 Double_t elossCoil = 0.;
785 if(
mCosmicFlag&&CoilLayerPos.phi()>0&&CoilLayerPos.phi()<TMath::Pi()) elossCoil = -1.*gMtdMuonELossInCoil/nCoilStep;
786 else elossCoil = gMtdMuonELossInCoil/nCoilStep;
788 for(
int i=0; i<nCoilStep; i++){
789 double CoilLayerRadius = mEmcOutR+rCoilStep*(i+1);
791 if(TMath::IsNaN(CoilLayerPos.x())||TMath::IsNaN(CoilLayerPos.y())||TMath::IsNaN(CoilLayerPos.z())||TMath::Abs(CoilLayerPos.perp())>450.||TMath::Abs(CoilLayerPos.z())>300.)
return kFALSE;
792 bField = GetFieldZ(CoilLayerPos);
793 StPhysicalHelixD helixInCoil(CoilLayerMom,CoilLayerPos,bField*tesla,charge);
795 pairD sCoilLayer = helixInCoil.pathLength(CoilLayerRadius);
796 if(sCoilLayer.first<=0 && sCoilLayer.second<=0)
return kFALSE;
798 double rCoilLayer = (sCoilLayer.first < 0 || sCoilLayer.second < 0)
799 ? max(sCoilLayer.first, sCoilLayer.second) : min(sCoilLayer.first, sCoilLayer.second);
801 betaGamCoil = CoilLayerMom.mag()/muonMass;
802 vCoil = sqrt(betaGamCoil*betaGamCoil/(1.+betaGamCoil*betaGamCoil))*c_light*1e-9;
803 pathLCoilLayer[i] = rCoilLayer;
804 tofCoilLayer[i] = rCoilLayer/vCoil;
806 CoilLayerPos = helixInCoil.at(rCoilLayer);
807 CoilLayerMom = helixInCoil.momentumAt(rCoilLayer,bField*tesla);
809 LOG_INFO<<
" to Coil Layer "<<i<<
" bField = "<<bField<<endm;
810 LOG_INFO<<
" to Coil Layer"<< i <<
" : pos x,y,z:"<<CoilLayerPos.x()<<
","<<CoilLayerPos.y()<<
","<<CoilLayerPos.z()<<endm;
811 LOG_INFO<<
" to Coil Layer"<< i <<
" : mom p,pt,eta,phi:"<<CoilLayerMom.mag()<<
","<<CoilLayerMom.perp()<<
","<<CoilLayerMom.pseudoRapidity()<<
","<<CoilLayerMom.phi()<<endm;
814 CoilLayerMom = (CoilLayerMom.mag()-elossCoil)/CoilLayerMom.mag()*CoilLayerMom;
818 double tof2OuterCoil = 0.;
819 for(
int i=0;i<nCoilStep;i++) tof2OuterCoil += tofCoilLayer[i];
820 LOG_INFO<<
" to Coilouter: pos x,y,z:"<<CoilLayerPos.x()<<
","<<CoilLayerPos.y()<<
","<<CoilLayerPos.z()<<endm;
821 LOG_INFO<<
" to Coilouter: mom p,pt,eta,phi:"<<CoilLayerMom.mag()<<
","<<CoilLayerMom.perp()<<
","<<CoilLayerMom.pseudoRapidity()<<
","<<CoilLayerMom.phi()<<endm;
822 LOG_INFO<<
" to Coilouter: tof:"<<tof2OuterCoil<<endm;
826 const Int_t nMagStep = 10;
827 double pathLMagLayer[nMagStep];
828 double tofMagLayer[nMagStep];
831 double rStep = (mMagOutR-mMagInR)/nMagStep;
834 Double_t elossMag = 0.;
835 double mMagELoss = 0.;
837 mMagELoss = fMagEloss->Eval(innerEmcMom.mag())-gMtdMuonELossInEmc-gMtdMuonELossInCoil;
838 if(
mCosmicFlag&&MagLayerPos.phi()>0&&MagLayerPos.phi()<TMath::Pi()) elossMag = -1.*mMagELoss/nMagStep;
839 else elossMag = mMagELoss/nMagStep;
842 LOG_INFO<<
" mMagELoss = "<<mMagELoss<<
" p = "<<innerEmcMom.mag()<<endm;
844 for(
int i=0; i<nMagStep; i++){
846 double MagLayerRadius = mMagInR+rStep*(i+1);
847 if(TMath::IsNaN(MagLayerPos.x())||TMath::IsNaN(MagLayerPos.y())||TMath::IsNaN(MagLayerPos.z())||TMath::Abs(MagLayerPos.perp())>450.||TMath::Abs(MagLayerPos.z())>300.)
return kFALSE;
848 bField = GetFieldZ(MagLayerPos);
852 LOG_INFO<<
" to Magnet layer "<<i<<
" bField = "<<bField<<endm;
853 LOG_INFO<<
" to Magnet Layer "<< i <<
" : pos x,y,z:"<<MagLayerPos.x()<<
","<<MagLayerPos.y()<<
","<<MagLayerPos.z()<<endm;
854 LOG_INFO<<
" to Magnet Layer "<< i <<
" : mom p,pt,eta,phi:"<<MagLayerMom.mag()<<
","<<MagLayerMom.perp()<<
","<<MagLayerMom.pseudoRapidity()<<
","<<MagLayerMom.phi()<<endm;
856 pairD sMagLayer = helixInMag.pathLength(MagLayerRadius);
857 if(sMagLayer.first<=0 && sMagLayer.second<=0)
return kFALSE;
859 double rMagLayer = (sMagLayer.first < 0 || sMagLayer.second < 0)
860 ? max(sMagLayer.first, sMagLayer.second) : min(sMagLayer.first, sMagLayer.second);
862 betaGamMag = MagLayerMom.mag()/muonMass;
863 vMag = sqrt(betaGamMag*betaGamMag/(1+betaGamMag*betaGamMag))*c_light*1e-9;
864 pathLMagLayer[i] = rMagLayer;
865 tofMagLayer[i] = rMagLayer/vMag;
867 MagLayerPos = helixInMag.at(rMagLayer);
868 MagLayerMom = helixInMag.momentumAt(rMagLayer,bField*tesla);
870 double momMag = MagLayerMom.mag();
871 if(momMag<elossMag)
return kFALSE;
872 MagLayerMom = (momMag-elossMag)/momMag*MagLayerMom;
876 double tof2OuterMag = 0.;
877 for(
int i=0;i<nMagStep;i++) tof2OuterMag += tofMagLayer[i];
878 LOG_INFO<<
" to OuterMag: pos x,y,z:"<<MagLayerPos.x()<<
","<<MagLayerPos.y()<<
","<<MagLayerPos.z()<<endm;
879 LOG_INFO<<
" to OuterMag: mom p,pt,eta,phi:"<<MagLayerMom.mag()<<
","<<MagLayerMom.perp()<<
","<<MagLayerMom.pseudoRapidity()<<
","<<MagLayerMom.phi()<<endm;
880 LOG_INFO<<
" to OuterMag: tof:"<<tof2OuterMag<<endm;
883 double tof2MagOuter = -9999.;
884 tof2MagOuter = tof2InnerEmc;
885 for(
int i=0;i<nEmcStep;i++) tof2MagOuter += tofEmcLayer[i];
886 for(
int i=0;i<nCoilStep;i++) tof2MagOuter += tofCoilLayer[i];
887 for(
int i=0;i<nMagStep;i++) tof2MagOuter += tofMagLayer[i];
889 double pathL2MagOuter = -9999.;
890 if(IsDebugOn()) LOG_INFO<<
" path to vertex("<< vertex.x()<<
","<<vertex.y()<<
","<<vertex.z()<<
") = "<<pathL2Vtx<<endm;
891 pathL2MagOuter = pathL2Vtx+rInnerEmc;
892 if(IsDebugOn()) LOG_INFO<<
" path to inner Emc = "<<pathL2MagOuter<<endm;
893 for(
int i=0;i<nEmcStep;i++) pathL2MagOuter += pathLEmcLayer[i];
894 if(IsDebugOn()) LOG_INFO<<
" path to outer Emc = "<<pathL2MagOuter<<endm;
895 for(
int i=0;i<nCoilStep;i++) pathL2MagOuter += pathLCoilLayer[i];
896 if(IsDebugOn()) LOG_INFO<<
" path to outer Coil = "<<pathL2MagOuter<<endm;
897 for(
int i=0;i<nMagStep;i++) pathL2MagOuter += pathLMagLayer[i];
898 if(IsDebugOn()) LOG_INFO<<
" path to outer mag = "<<pathL2MagOuter<<endm;
900 pathL = pathL2MagOuter;
903 if(TMath::IsNaN(MagLayerPos.x())||TMath::IsNaN(MagLayerPos.y())||TMath::IsNaN(MagLayerPos.z())||TMath::Abs(MagLayerPos.perp())>450.||TMath::Abs(MagLayerPos.z())>300.)
return kFALSE;
904 bField = GetFieldZ(MagLayerPos);
908 LOG_INFO<<
"bField of magnet outside is "<<bField<<
" from magMap = "<<GetFieldZ(MagLayerPos)<<
" mom = "<<MagLayerMom.x()<<
","<<MagLayerMom.y()<<
","<<MagLayerMom.z()<<
" mag = "<<MagLayerMom.mag()<<endm;
909 LOG_INFO<<
"------------ end of projection to magOutR ------------"<<endm;
921 if(TMath::IsNaN(oh.x())||TMath::IsNaN(oh.y())||TMath::IsNaN(oh.z())||TMath::Abs(oh.perp())>450.||TMath::Abs(oh.z())>300.)
return;
922 Double_t betaGam = helix.momentum(GetFieldZ(oh)).mag()/muonMass;
923 Double_t v = sqrt(betaGam*betaGam/(1+betaGam*betaGam))*c_light*1e-9;
931 Bool_t StMtdGeometry::ProjToBLModVect(
const StPhysicalHelixD helix, IntVec &blVect, IntVec &modVect){
936 Double_t R_mtd[2] = {mMtdMinR,mMtdMaxR};
937 Double_t iBL[2] = {0,0};
938 Double_t iMod[2] = {0,0};
939 for(
int i=0;i<2;i++) {
940 Double_t s = helix.
pathLength(R_mtd[i]).first;
941 if(s<0.) s = helix.
pathLength(R_mtd[i]).second;
943 Double_t phi = point.phi();
944 Double_t z = point.z();
946 iBL[i] = FindBLId(phi);
947 iMod[i] = FindModId(z);
950 for (Int_t i = 0; i < 2; i++) {
951 for(Int_t j=0;j<3;j++){
952 Int_t idx = iBL[i]-1+j;
953 if(idx>gMtdNBacklegs) idx -= gMtdNBacklegs;
954 if(idx<1) idx += gMtdNBacklegs;
955 if(idx>0&&idx<=gMtdNBacklegs) blVect.push_back(idx);
958 RemoveDuplicate(blVect);
959 for (Int_t i = 0; i < 2; i++) {
960 for(Int_t j=0;j<3;j++){
961 Int_t idx = iMod[i]-1+j;
962 if(idx>0&&idx<=gMtdNModules) modVect.push_back(idx);
965 RemoveDuplicate(modVect);
969 void StMtdGeometry::RemoveDuplicate(IntVec &vec){
971 sort(vec.begin(),vec.end());
973 for(IntVec::iterator tmpIter = vec.begin();tmpIter<vec.end();++tmpIter){
974 if(tmpIter==vec.begin()){
987 Int_t StMtdGeometry::FindBLId(Double_t phi){
990 if(phi<0) phi += 2.*(TMath::Pi());
991 double backLegPhiWidth = 8.*(TMath::Pi())/180.;
992 double backLegPhiGap = 4.*(TMath::Pi())/180.;
993 double dphi = backLegPhiWidth+backLegPhiGap;
994 iBL = (int)(phi/dphi);
998 if(IsDebugOn()) LOG_WARN<<
"Invalid BL id:"<<iBL<<
" input phi = "<<phi<<endm;
1005 Int_t StMtdGeometry::FindModId(Double_t z){
1009 iMod = (int)((z+2.5*gMtdCellLength)/gMtdCellLength+1);
1012 if(IsDebugOn()) LOG_WARN<<
"Invalid Module id:"<<iMod<<
" input z = "<<z<<endm;
1019 Bool_t StMtdGeometry::HelixCrossCellIds(
const StPhysicalHelixD helix, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec, DoubleVec &tofVec){
1021 return HelixCrossCellIds(helix,vertex,idVec,pathVec,crossVec,tofVec);
1024 Bool_t StMtdGeometry::HelixCrossCellIds(
const StPhysicalHelixD helix,
const StThreeVectorD vertex, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec, DoubleVec &tofVec){
1031 Double_t pathLToMagOutR;
1032 Double_t tofToMagOutR;
1034 if(!ProjToMagOutR(helix,vertex,outHelix,pathLToMagOutR,tofToMagOutR,posAtMagOutR))
return kFALSE;
1039 if(!ProjToBLModVect(outHelix,projBLVec,projModVec))
return kFALSE;
1048 for (UInt_t i = 0; i < projBLVec.size(); i++) {
1049 Int_t iBL = projBLVec[i];
1050 if(!mMtdGeoBackleg[iBL-1])
continue;
1051 for (UInt_t j = 0; j < projModVec.size(); j++) {
1052 Int_t iMod = projModVec[j];
1053 if(!mMtdGeoModule[iBL-1][iMod-1])
continue;
1054 Double_t pathToMtd = 0.;
1055 Double_t tofToMtd = 0.;
1058 LOG_INFO<<
" checking track cross BL = "<<iBL<<
" Module = "<<iMod<<
" or not ... "<<endm;
1060 if(mMtdGeoModule[iBL-1][iMod-1]->HelixCross(outHelix,pathLToMagOutR,tofToMagOutR,pathToMtd,tofToMtd,crossToMtd)){
1061 Double_t global[3] = {crossToMtd.x(),crossToMtd.y(),crossToMtd.z()};
1062 Double_t local[3] = {0,0,0};
1063 mMtdGeoModule[iBL-1][iMod-1]->MasterToLocal(global,local);
1064 Int_t iCel = mMtdGeoModule[iBL-1][iMod-1]->FindCellId(local);
1065 if(iCel<-50)
continue;
1066 if(iMod>3) iCel = 11-iCel;
1067 cellId = CalcCellId(iBL , iMod, iCel);
1069 LOG_INFO<<
" track cross BL = "<<iBL<<
" Module = "<<iMod<<
" iCel = "<<iCel<<endm;
1070 LOG_INFO<<
" cellId = "<<cellId<<
" pathToMtd = "<<pathToMtd<<
" tofToMtd = "<<tofToMtd<<endm;
1073 idVec.push_back(cellId);
1074 pathVec.push_back(pathToMtd);
1075 crossVec.push_back(crossToMtd);
1076 tofVec.push_back(tofToMtd);
1084 Int_t StMtdGeometry::CalcCellId(Int_t iBL, Int_t iMod, Int_t iCel){
1085 Int_t cellId = -999;
1086 if(iBL<1|| iBL>gMtdNBacklegs)
return cellId;
1087 if(iMod<1|| iMod>gMtdNModules)
return cellId;
1088 if(iCel<-mNExtraCells || iCel>11+
mNExtraCells)
return cellId;
1089 cellId = iBL*1000+iMod*100+(iCel+50);
1097 Int_t iBL =
id/1000;
1098 Int_t iMod = (
id%1000)/100;
1099 Int_t iCell =
id%100-50;
1101 if(iBL<1 || iBL>gMtdNBacklegs)
return kFALSE;
1102 if(iMod<1 || iMod>gMtdNModules)
return kFALSE;
1103 if(iCell<-mNExtraCells || iCell>11+
mNExtraCells)
return kFALSE;
1107 void StMtdGeometry::DecodeCellId(Int_t
id, Int_t &iBL, Int_t &iMod, Int_t &iCell){
1110 iMod = (
id%1000)/100;
1116 return GetField(pos.x(),pos.y(),pos.z());
1120 Double_t B[3] = {0,0,0};
1121 Double_t X[3] = {x,y,z};
1122 mStarBField->BField(X,B);
1123 for(
int i=0;i<3;++i) B[i] /= 10.;
1132 Double_t StMtdGeometry::GetFieldZ(Double_t x, Double_t y, Double_t z)
const{
1137 StMtdGeoModule *StMtdGeometry::GetGeoModule(Int_t iBL, Int_t iMod)
const{
1138 if(iBL>0&&iBL<=gMtdNBacklegs&&iMod>0&&iMod<=gMtdNModules){
1139 return mMtdGeoModule[iBL-1][iMod-1];
1145 Bool_t StMtdGeometry::IsMTTG(
const TGeoVolume * vol)
const {
1146 Bool_t found =
false;
1147 for(
int i=0;i<4;i++){
1156 void StMtdGeometry::SetLockBField(Bool_t val){
Bool_t mCosmicFlag
Control message printing of this class.
Int_t mNExtraCells
Control mag field to FF.
Bool_t mELossFlag
Cosmic event flag.
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Bool_t IsIdValid(Int_t id)
return BL*1000+Module*100+(Cell+50). BL: 1-30, Module: 1-5, Cell: 0-11.
const StThreeVector< double > & origin() const
-sign(q*B);
Int_t mNValidBLs
Control matching range in the module.
StMtdGeometry(const char *name="mtdGeo", const char *title="Simplified Mtd Geometry", TGeoManager *manager=0)
EMC system outer radius.
static const char * backlegPref[4]
EMC system outer radius.
Bool_t mLockBField
Control energy loss flag.
virtual TDataSet * Find(const char *path) const