ATLAS Offline Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
TGCSensitiveDetector Class Reference

#include <TGCSensitiveDetector.h>

Inheritance diagram for TGCSensitiveDetector:
Collaboration diagram for TGCSensitiveDetector:

Public Member Functions

 TGCSensitiveDetector (const std::string &name, const std::string &hitCollectionName)
 construction/destruction More...
 
 ~TGCSensitiveDetector ()
 
void Initialize (G4HCofThisEvent *HCE) override final
 member functions More...
 
G4bool ProcessHits (G4Step *aStep, G4TouchableHistory *ROHist) override final
 

Private Member Functions

 FRIEND_TEST (TGCSensitiveDetectortest, Initialize)
 
 FRIEND_TEST (TGCSensitiveDetectortest, ProcessHits)
 

Private Attributes

SG::WriteHandle< TGCSimHitCollectionm_myTGCHitColl
 member data More...
 
const TgcHitIdHelperm_muonHelper
 

Detailed Description

Author
haseg.nosp@m.awa@.nosp@m.azusa.nosp@m..shi.nosp@m.nshu-.nosp@m.u.ac.nosp@m..jp

Class methods and properties

The method TGCSensitiveDetector::ProcessHits is executed by the G4 kernel each time a charged particle (or a geantino) crosses one of the TGC Gas volumes.

Navigating with the touchableHistory method GetHistoryDepth() through the hierarchy of the volumes crossed by the particles, the TGCSensitiveDetector determinates the correct set of geometry parameters to be folded in the Simulation Identifier associated to each hit. The TGC SimIDs are 32-bit unsigned integers, built using the MuonSimEvent/TgcHitIdHelper class which inherits from the MuonHitIdHelper base class.

We describe in the following, how each field of the identifier is retrieved.

1) stationName and stationPhi: when a volume is found in the hierarchy, whose name contains the substring "station", the stationName is extracted from the volume's name; stationPhi is calculated starting from the volume copy number assigned by MuonGeoModel. Separate cases when the station are "F" or "E" type.

2) stationEta: when a volume is found in the hierarchy, whose name contains the substring "tgccomponent", stationEta is calculated starting from the volume copy number assigned by MuonGeoModel. Possibility to calculate the stationPhi at this level, from the copy number assigned by MuonGeoModel (if the copyNo > 1000).

3) gasGap: when a volume is found in the hierarchy, whose name contains the substring "Gas Volume Layer" or "TGCGas", the gasGap is calculated from the volume copy number, according to the positive or negative Z value, in the Atlas global reference system.

@section Some notes:

1) since the volume copy numbers strongly depend on the database layout, the volume name (whether it contains the string "Q02", for instance) is used to retrieve geometry information. In the year 2018 and even some years before there are not any more other database layouts / volumes than MUONQ02 and therefore some logic was removed

2) for each hit, the time of flight (the G4 globalTime), is recorded and associated to the hit.

3) the TGCHit object contains: the SimID, the globalTime, the hit position in the local reference system, the track director cosine in the local reference system and the track identifier.

Definition at line 71 of file TGCSensitiveDetector.h.

Constructor & Destructor Documentation

◆ TGCSensitiveDetector()

TGCSensitiveDetector::TGCSensitiveDetector ( const std::string &  name,
const std::string &  hitCollectionName 
)

construction/destruction

Definition at line 16 of file TGCSensitiveDetector.cxx.

17  : G4VSensitiveDetector( name )
18  , m_myTGCHitColl( hitCollectionName )
19 {
21 }

◆ ~TGCSensitiveDetector()

TGCSensitiveDetector::~TGCSensitiveDetector ( )
inline

Definition at line 78 of file TGCSensitiveDetector.h.

78 {}

Member Function Documentation

◆ FRIEND_TEST() [1/2]

TGCSensitiveDetector::FRIEND_TEST ( TGCSensitiveDetectortest  ,
Initialize   
)
private

◆ FRIEND_TEST() [2/2]

TGCSensitiveDetector::FRIEND_TEST ( TGCSensitiveDetectortest  ,
ProcessHits   
)
private

◆ Initialize()

void TGCSensitiveDetector::Initialize ( G4HCofThisEvent *  HCE)
finaloverride

member functions

Definition at line 24 of file TGCSensitiveDetector.cxx.

25 {
26  if (!m_myTGCHitColl.isValid()) m_myTGCHitColl = std::make_unique<TGCSimHitCollection>();
27 }

◆ ProcessHits()

G4bool TGCSensitiveDetector::ProcessHits ( G4Step *  aStep,
G4TouchableHistory *  ROHist 
)
finaloverride

Definition at line 29 of file TGCSensitiveDetector.cxx.

29  {
30 
31  G4Track* track = aStep->GetTrack();
32 
33  if (track->GetDefinition()->GetPDGCharge() == 0.0) {
34  if (track->GetDefinition()!=G4Geantino::GeantinoDefinition()) return true;
35  else if (track->GetDefinition()==G4ChargedGeantino::ChargedGeantinoDefinition()) return true;
36  }
37  const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
38  G4ThreeVector position = aStep->GetPreStepPoint()->GetPosition();
39  const G4AffineTransform trans = track->GetTouchable()->GetHistory()->GetTopTransform();
40 
41  // fields for the TGC identifier construction
42  std::string stationName;
43  int stationEta(0);
44  int stationPhi(0);
45  int gasGap = 0;
46 
47  // TGC hit information
48  double globalTime = aStep->GetPreStepPoint()->GetGlobalTime();
49  Amg::Vector3D localPosition = Amg::Hep3VectorToEigen( trans.TransformPoint(position) );
50  G4ThreeVector direcos = aStep->GetPreStepPoint()->GetMomentumDirection();
51  Amg::Vector3D localDireCos = Amg::Hep3VectorToEigen( trans.TransformAxis(direcos) );
52 
53  // scan geometry tree to identify hit channel
54  int zside(0);
55  bool isAssembly = false;
56  for (int i=touchHist->GetHistoryDepth();i>=0;i--) {
57 
58  std::string::size_type npos;
59  std::string::size_type nposStat;
60  std::string volName = touchHist->GetVolume(i)->GetName();
61 
62  // check if this station is an assembly
63  if ((npos = volName.find("av_")) != std::string::npos &&
64  (npos = volName.find("impr_")) != std::string::npos) isAssembly = true;
65 
66  // stationName and stationPhi
67  if ((npos = volName.find("station")) != std::string::npos && (!isAssembly)) {
68 
69  stationName = volName.substr(0,npos-2);
70  int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
71  if (volCopyNo > 0) {
72  zside = 1;
73  } else {
74  zside = -1;
75  }
76  if (stationName.at(2) == 'F') {
77 
78  stationPhi = (abs(volCopyNo%100)-1)*3;
79  if (abs(volCopyNo/100) > 3) {
80  stationPhi += abs(volCopyNo/100)-3;
81  } else {
82  stationPhi += abs(volCopyNo/100);
83  }
84 
85  stationPhi -= 1;
86  if (stationPhi <= 0) {
87  stationPhi = 24 - stationPhi;
88  }
89 
90  } else if (stationName.at(2) == 'E') {
91  if (stationName.at(1) == '4') {
92 
93  stationPhi = (abs(volCopyNo%100)-1)*3+abs(volCopyNo/100);
94 
95  if (abs(volCopyNo%100) < 4) {
96  stationPhi = stationPhi - 1;
97  if (stationPhi <= 0) {
98  stationPhi = 21 - stationPhi;
99  }
100  } else if(abs(volCopyNo%100) < 7) {
101  stationPhi = stationPhi - 1 - 1;
102  } else {
103  stationPhi = stationPhi - 2 - 1;
104  }
105 
106  } else {
107 
108  stationPhi = (abs(volCopyNo%100)-1)*6+abs(volCopyNo/100);
109 
110  stationPhi -= 2;
111  if (stationPhi <= 0) {
112  stationPhi = 48 - stationPhi;
113  }
114  }
115  }
116  } else if ((nposStat = volName.find("impr_")) != std::string::npos &&
117  (npos = volName.find("TGC")) != std::string::npos && isAssembly ) {
118  // vol name for Assembly components are
119  // av_WWW_impr_XXX_Muon::BMSxMDTxx_pv_ZZZ_NAME
120  // where WWW is ass. istance nr.
121  // XXX is comp. imprint nr.
122  // BMSxMDTxx is the name of the comp. log.Vol.
123  // x station sub-type; xx technology subtype
124  // ZZZ is No of order of this daugther
125  // NAME is the comp. tag (geoIdentifierTag)
126  // for TGCs it is stPhiJob[aaa] with
127  // aaa = 1000*stationPhi+Job;
128  // copy numbers for Ass.components are =
129  // CopyNoBase(= geoIdentifierTag of the assembly) + geoIdentifierTag of the component
130  // geoIdentifierTag of the component = Job
131  // geoIdentifierTag of the assembly = (sideC*10000 +
132  // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
133  // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
134  // mirsign = 1 if zi<0 and !mirrored; otherwise 0
135  std::string::size_type loc1,loc2;
136  if ((loc1 = volName.find("Muon::")) != std::string::npos) {
137  stationName = volName.substr(loc1+6,3); //type only
138  }
139 
140  int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
141  int copyNrBase = int(volCopyNo/100000);
142  int sideC = int(copyNrBase/10000);
143  int zi = int((copyNrBase%1000)/100);
144  if (sideC == 1) zi = -zi;
145  if (sideC) {
146  zside = -1;
147  } else {
148  zside = 1;
149  }
150  if (stationName.at(2) == 'F') {
151 
152  stationPhi = (abs(copyNrBase%100)-1)*3;
153  if (abs(copyNrBase/100) > 3) {
154  stationPhi += abs(copyNrBase/100)-3;
155  } else {
156  stationPhi += abs(copyNrBase/100);
157  }
158 
159  stationPhi -= 1;
160  if (stationPhi <= 0) {
161  stationPhi = 24 - stationPhi;
162  }
163 
164  } else if (stationName.at(2) == 'E') {
165  if (stationName.at(1) == '4') {
166 
167  stationPhi = (abs(copyNrBase%100)-1)*3+abs(copyNrBase/100);
168 
169  if (abs(copyNrBase%100) < 4) {
170  stationPhi = stationPhi - 1;
171  if (stationPhi <= 0) {
172  stationPhi = 21 - stationPhi;
173  }
174  } else if(abs(copyNrBase%100) < 7) {
175  stationPhi = stationPhi - 1 - 1;
176  } else {
177  stationPhi = stationPhi - 2 - 1;
178  }
179  } else {
180 
181  stationPhi = (abs(copyNrBase%100)-1)*6+abs(copyNrBase/100);
182 
183  stationPhi -= 2;
184  if (stationPhi <= 0) {
185  stationPhi = 48 - stationPhi;
186  }
187  }
188  }
189 
190  // now get the geoIdentifierTag of the rpc components
191  int gmID = 0;
192  if ((loc1 = volName.find('[')) != std::string::npos) {
193  if ((loc2 = volName.find(']', loc1+1)) != std::string::npos) {
194  std::istringstream istrvar(volName.substr(loc1+1,loc2-loc1-1));
195  istrvar>>gmID;
196  }
197  }
198  // stationEta, stationPhi
199  stationEta = zside*int(gmID%100);
200  if (gmID > 999) stationPhi = gmID/1000;
201 
202  // stationEta
203  } else if ((npos = volName.find("tgccomponent")) != std::string::npos && (!isAssembly)) {
204  int volCopyNo = abs(touchHist->GetVolume(i)->GetCopyNo());
205  stationEta = zside*volCopyNo%100;
206  if (volCopyNo > 1000) { // stationPhi overridden by the number assigned by MuonGeoModel
207  stationPhi = volCopyNo/1000;
208  }
209  // gasGap
210  } else if ((npos = volName.find("Gas Volume Layer")) != std::string::npos) {
211  int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
212  int iStation = atoi(stationName.substr(1,1).c_str());
213  if (zside < 0) {
214  if (iStation == 1)
215  gasGap = 3-(volCopyNo-3)/4;
216  else
217  gasGap = 2-(volCopyNo-3)/4;
218  } else {
219 // if (iStation == 1)
220  gasGap = (volCopyNo-3)/4+1;
221 // else
222 // gasGap = (volCopyNo-3)/4+1;
223  }
224  } else if ((npos = volName.find("TGCGas")) != std::string::npos) {
225 
226  int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
227 
228  if (volCopyNo != 0)
229  gasGap = volCopyNo;
230  }
231 
232  }
233 
234  //construct the hit identifier
236  stationPhi,
237  stationEta,
238  gasGap);
239  //m_muonHelper->Print(TGCid);
240 
241  // construct new tgc hit
242  TrackHelper trHelp(aStep->GetTrack());
243  m_myTGCHitColl->Emplace(TGCid,
244  globalTime,
245  localPosition,
246  localDireCos,
247  trHelp.GenerateParticleLink(),
248  aStep->GetTotalEnergyDeposit(),
249  aStep->GetStepLength(),
250  track->GetDefinition()->GetPDGEncoding(),
251  aStep->GetPreStepPoint()->GetKineticEnergy());
252  return true;
253 }

Member Data Documentation

◆ m_muonHelper

const TgcHitIdHelper* TGCSensitiveDetector::m_muonHelper
private

Definition at line 87 of file TGCSensitiveDetector.h.

◆ m_myTGCHitColl

SG::WriteHandle<TGCSimHitCollection> TGCSensitiveDetector::m_myTGCHitColl
private

member data

Definition at line 86 of file TGCSensitiveDetector.h.


The documentation for this class was generated from the following files:
Muon::nsw::STGTPSegments::moduleIDBits::stationPhi
constexpr uint8_t stationPhi
station Phi 1 to 8
Definition: NSWSTGTPDecodeBitmaps.h:161
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
TGCSensitiveDetector::m_muonHelper
const TgcHitIdHelper * m_muonHelper
Definition: TGCSensitiveDetector.h:87
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
Trk::loc2
@ loc2
generic first and second local coordinate
Definition: ParamDefs.h:35
Amg::Hep3VectorToEigen
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
Definition: CLHEPtoEigenConverter.h:137
TrackHelper
Definition: TrackHelper.h:14
lumiFormat.i
int i
Definition: lumiFormat.py:85
TgcHitIdHelper::GetHelper
static const TgcHitIdHelper * GetHelper()
Definition: TgcHitIdHelper.cxx:23
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RPDUtils::sideC
unsigned constexpr int sideC
Definition: RPDUtils.h:15
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
TgcHitIdHelper::BuildTgcHitId
int BuildTgcHitId(const std::string &, const int, const int, const int) const
Definition: TgcHitIdHelper.cxx:77
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:159
HitID
int HitID
Definition: GenericMuonSimHit.h:13
Trk::loc1
@ loc1
Definition: ParamDefs.h:34
TGCSensitiveDetector::m_myTGCHitColl
SG::WriteHandle< TGCSimHitCollection > m_myTGCHitColl
member data
Definition: TGCSensitiveDetector.h:86