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

#include <MDTSensitiveDetectorCosmics.h>

Inheritance diagram for MDTSensitiveDetectorCosmics:
Collaboration diagram for MDTSensitiveDetectorCosmics:

Public Member Functions

 MDTSensitiveDetectorCosmics (const std::string &name, const std::string &hitCollectionName, const unsigned int nTubesMax)
 construction/destruction More...
 
 ~MDTSensitiveDetectorCosmics ()=default
 
void Initialize (G4HCofThisEvent *HCE) override final
 member functions More...
 
G4bool ProcessHits (G4Step *aStep, G4TouchableHistory *ROhist) override final
 

Private Member Functions

 FRIEND_TEST (MDTSensitiveDetectorCosmicstest, Initialize)
 
 FRIEND_TEST (MDTSensitiveDetectorCosmicstest, ProcessHits)
 
 FRIEND_TEST (MDTSensitiveDetectorCosmicstest, GetIdentifier)
 
int GetIdentifier (const G4TouchableHistory *touchHist)
 

Private Attributes

Amg::Vector3D m_mom
 
double m_momMag
 
Amg::Vector3D m_vertex
 
Amg::Vector3D m_currVertex
 
Amg::Vector3D m_globH
 
SG::WriteHandle< MDTSimHitCollectionm_MDTHitColl
 member data More...
 
const MdtHitIdHelperm_muonHelper
 
double m_driftRadius
 
double m_globalTime
 
Amg::Vector3D m_localPosition
 
double m_DEFAULT_TUBE_RADIUS
 radius assigned to radius if radius is invalid More...
 

Detailed Description

Author
danie.nosp@m.la.r.nosp@m.ebuzz.nosp@m.i@pv.nosp@m..infn.nosp@m..it
nveld.nosp@m.ik@n.nosp@m.ikhef.nosp@m..nl

Class methods and properties

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

Once a G4Step is perfomed by the particle in the sensitive volume (both when the particle leaves the tube or stops in it), Pre and PostStepPositions are tranformed into local coordinates (chamber reference system, with Z along the tube direction and XY tranversal plane) and used to calculate the local direction of the track.

Two cases are given: 1) the particle over-passed the wire: here the drift radius (the impact parameter) is computed as the local direction distance from the wire;
2) the step doesn't allow the particle to over-pass the wire: here the shortest distance to the wire, which is one of the two end-points, is calculated for each step which occurs inside the sensitive volumes and only the closer one is kept; this case includes also the hard scattering case inside the sensitive volume.

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

The modified version (Daniela Rebuzzi, 16/12/2005) calculates the tof for the cosmics, using as t0 the time to the closest approach of the track to (0,0,0). This implementation works also for slow particles, since the discrimination physics event/cosmics is done relying on the G4Track vertex (not on the tof).

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

1) stationName, stationEta, 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 and stationEta are calculated starting from the volume copy number, assigned by MuonGeoModel.

2) multilayer: when a volume is found in the hierarchy, whose name contains the substring "component", the multilayer is set to 1 or to 2, according to the component number (multilayer=1 if the component is 1, 5 or 8; multilayer=2 if the component is 3, 7, 8, 10, 11 or 14).

3) tubeLayer and tube: when a volume is found in the hierarchy, whose name contains the substring "Drift", tubeLayer and tube are calculated starting from the Drift volume copy number.

notes:

1) this implementation of the MDT Sensitive Detectors can handle different situations: hard scattering of the muon on the sensitive volume (its direction changes), soft secondary particles completely included in the sensitive volume, muon hits masked by secondaries, like delta rays.

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

3) more than none MDT hit can occur in the same tube. The hit selection is done at the level of the digitization procedure.

4) the MDTHit object contains: the SimID, the drift radius and the globalTime.

Definition at line 89 of file MDTSensitiveDetectorCosmics.h.

Constructor & Destructor Documentation

◆ MDTSensitiveDetectorCosmics()

MDTSensitiveDetectorCosmics::MDTSensitiveDetectorCosmics ( const std::string &  name,
const std::string &  hitCollectionName,
const unsigned int  nTubesMax 
)

construction/destruction

Definition at line 26 of file MDTSensitiveDetectorCosmics.cxx.

27  : G4VSensitiveDetector( name )
28  , m_momMag(0.)
29  , m_MDTHitColl( hitCollectionName )
30  , m_driftRadius(0.)
31  , m_globalTime(0.)
33 {
35 }

◆ ~MDTSensitiveDetectorCosmics()

MDTSensitiveDetectorCosmics::~MDTSensitiveDetectorCosmics ( )
default

Member Function Documentation

◆ FRIEND_TEST() [1/3]

MDTSensitiveDetectorCosmics::FRIEND_TEST ( MDTSensitiveDetectorCosmicstest  ,
GetIdentifier   
)
private

◆ FRIEND_TEST() [2/3]

MDTSensitiveDetectorCosmics::FRIEND_TEST ( MDTSensitiveDetectorCosmicstest  ,
Initialize   
)
private

◆ FRIEND_TEST() [3/3]

MDTSensitiveDetectorCosmics::FRIEND_TEST ( MDTSensitiveDetectorCosmicstest  ,
ProcessHits   
)
private

◆ GetIdentifier()

int MDTSensitiveDetectorCosmics::GetIdentifier ( const G4TouchableHistory *  touchHist)
private

Definition at line 176 of file MDTSensitiveDetectorCosmics.cxx.

177 {
178  // attributes of the MDT identifier construction
179  std::string stationName;
180  int stationEta=0;
181  int stationPhi=0;
182  int multilayer=0;
183  int tubeLayer=0;
184  int tube=0;
185 
186  bool isAssembly = false;
187  // scan geometry tree to identify the tube
188  for (int i = touchHist->GetHistoryDepth(); i>=0; i--) {
189 
190  std::string::size_type npos;
191  std::string::size_type loc1;
192  std::string::size_type loc2;
193  std::string volName = touchHist->GetVolume(i)->GetName();
194 
195  // check if this station is an assembly
196  if ((npos = volName.find("av_")) != std::string::npos &&
197  (npos = volName.find("impr_")) != std::string::npos) isAssembly = true;
198 
199  // station: name, eta and phi (-> chamber!)
200  if ((npos = volName.find("station")) != std::string::npos && (!isAssembly)) {
201 
202  volName.resize(npos-2);
203  int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
204  volCopyNo=volCopyNo%1000;
205  stationName = volName;
206  stationEta = volCopyNo/100;
207  stationPhi = abs(volCopyNo%100);
208 
209  }
210  else if ((npos = volName.find("component")) != std::string::npos && (!isAssembly)) { // multilayer
211 
212  int gmID = 0;
213  if ((loc1 = volName.find('[')) != std::string::npos) {
214  if ((loc2 = volName.find(']', loc1+1)) != std::string::npos) {
215  std::istringstream istrvar(volName.substr(loc1+1,loc2-loc1-1));
216  istrvar>>gmID;
217  }
218  }
219  multilayer = gmID;
220 
221  } else if ((npos = volName.find("MDT")) != std::string::npos && isAssembly) {
222 
223  // vol name for Assembly components are
224  // av_WWW_impr_XXX_Muon::BMSxMDTxx_pv_ZZZ_NAME
225  // where WWW is ass. istance nr.
226  // XXX is comp. imprint nr.
227  // BMSxMDTxx is the name of the comp. log.Vol.
228  // x station sub-type; xx technology subtype
229  // ZZZ is the comp. number of order
230  // NAME is the comp. tag (geoIdentifierTag)
231  // for MDTs NAME is ml[1] or ml[2]
232  // copy numbers for Ass.components are =
233  // CopyNoBase(= geoIdentifierTag of the assembly) + geoIdentifierTag of the component
234  // geoIdentifierTag of the component = Job
235  // geoIdentifierTag of the assembly = (sideC*10000 +
236  // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
237  // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
238  //
239  if ((loc1 = volName.find("Muon::")) != std::string::npos) {
240  stationName = volName.substr(loc1+6,3);
241  }
242 
243  int copyNr = touchHist->GetVolume(i)->GetCopyNo();
244  int copyNrBase = int(copyNr/100000);
245  int sideC = int(copyNrBase/10000);
246  int zi = int((copyNrBase%1000)/100);
247  int fi = int(copyNrBase%100);
248  if (sideC == 1) zi = -zi;
249  stationEta = zi;
250  stationPhi = fi;
251 
252  int gmID = 0;
253  if ((loc1 = volName.find('[')) != std::string::npos) {
254  if ((loc2 = volName.find(']', loc1+1)) != std::string::npos) {
255  std::istringstream istrvar(volName.substr(loc1+1,loc2-loc1-1));
256  istrvar>>gmID;
257  }
258  }
259  multilayer = gmID;
260  } else if ((npos = volName.find("Drift")) != std::string::npos) { // layer and tube
261  tubeLayer = touchHist->GetVolume(i)->GetCopyNo()/maxNTubesPerLayer;
262  tube = touchHist->GetVolume(i)->GetCopyNo()%maxNTubesPerLayer;
263  }
264  }
265  //construct the hit identifier
266  return m_muonHelper->BuildMdtHitId(stationName, stationPhi, stationEta, multilayer,tubeLayer, tube);
267 }

◆ Initialize()

void MDTSensitiveDetectorCosmics::Initialize ( G4HCofThisEvent *  HCE)
finaloverride

member functions

Definition at line 38 of file MDTSensitiveDetectorCosmics.cxx.

39 {
40  if (!m_MDTHitColl.isValid()) m_MDTHitColl = std::make_unique<MDTSimHitCollection>();
42  // START OF COSMICS SPECIFIC CODE
43  m_mom = Amg::Vector3D(0.,0.,0.);
44  m_globH = Amg::Vector3D(0.,0.,0.);
45  // END OF COSMICS SPECIFIC CODE
46 }

◆ ProcessHits()

G4bool MDTSensitiveDetectorCosmics::ProcessHits ( G4Step *  aStep,
G4TouchableHistory *  ROhist 
)
finaloverride

Definition at line 48 of file MDTSensitiveDetectorCosmics.cxx.

48  {
49 
50  G4Track* currentTrack = aStep->GetTrack();
51 
52  // MDTs sensitive to charged particle only
53  if (currentTrack->GetDefinition()->GetPDGCharge() == 0.0) {
54  if (currentTrack->GetDefinition()!=G4Geantino::GeantinoDefinition()) return true;
55  else if (currentTrack->GetDefinition()==G4ChargedGeantino::ChargedGeantinoDefinition()) return true;
56  }
57 
58  G4VPhysicalVolume* physVolPostStep = aStep->GetPostStepPoint()->GetPhysicalVolume();
59  if (nullptr == physVolPostStep) return true;
60 
61  // hit information to be recorded
62  double globalTime;
63  double driftRadius;
64  Amg::Vector3D localPosition;
65  localPosition.setZero();
66 
67  // get top transformation
68  const G4AffineTransform trans = currentTrack->GetTouchable()->GetHistory()->GetTopTransform();
69 
70  // START OF COSMICS SPECIFIC CODE
71  // global coordinates
72  G4ThreeVector globVrtx = aStep->GetPreStepPoint()->GetPosition();
73 
74  // distance of the hit from (0,0,0) vertex - calculated from the PreStepPoint (approximation)
75  double dist = globVrtx.mag();
76  double lightspeed = 299.792458; /* in vacuo speed of light [mm/ns] */
77  double tOrigin = dist / lightspeed;
78 
79  G4int trackid = aStep->GetTrack()->GetTrackID();
80  m_currVertex = Amg::Hep3VectorToEigen( aStep->GetTrack()->GetVertexPosition() );
81 
82  // for cosmics: only primary muon tracks - track momentum when first entering the spectrometer (one muon per event)
83  if ((m_currVertex != m_vertex) && (trackid == 1)) {
84  // after calculationg the momentum magnidude, normalize it
85  m_mom = Amg::Hep3VectorToEigen( currentTrack->GetMomentum() );
86  m_momMag = m_mom.mag();
87  m_mom.normalize();
88  // the direction of the primary mu is used to calculate the t0, the position ot the t0, m_globH, is ONE for a track
89  Amg::Vector3D globVrtxFix = Amg::Hep3VectorToEigen( globVrtx );
90  double AlphaGlobal = -1*(globVrtxFix[0]*m_mom[0] + globVrtxFix[1]*m_mom[1] + globVrtxFix[2]*m_mom[2])/(m_mom[0]*m_mom[0] + m_mom[1]*m_mom[1] + m_mom[2]*m_mom[2]);
91  m_globH = globVrtxFix + AlphaGlobal*m_mom;
92 // G4cout << "COSMICS MAIN TRACK IN THE MDT!" << G4endl;
93  }
94  double globalDist = sqrt((m_globH[0] - globVrtx[0])*(m_globH[0] - globVrtx[0]) +
95  (m_globH[1] - globVrtx[1])*(m_globH[1] - globVrtx[1]) +
96  (m_globH[2] - globVrtx[2])*(m_globH[2] - globVrtx[2]));
97  double tof = globalDist / lightspeed;
98  // END OF COSMICS SPECIFIC CODE
99 
100  // transform pre and post step positions to local positions
101 
102  Amg::Vector3D localVertex1( Amg::Hep3VectorToEigen( trans.TransformPoint(aStep->GetPreStepPoint()->GetPosition()) ) );
103  Amg::Vector3D localVertex2( Amg::Hep3VectorToEigen( trans.TransformPoint(aStep->GetPostStepPoint()->GetPosition()) ) );
104 
105  // calculate local direction from begin- and end-point of the step
106  Amg::Vector3D localDirection( (localVertex2 - localVertex1) ); // normalized
107  localDirection.z() = 0.; // look in xy-plane
108 
109  // See if particle passed wire by projecting begin- and end-point on the step direction
110  if( (localVertex2.dot(localDirection)) * (localVertex1.dot(localDirection)) < 0 ) { // particle passed wire
111 
112  // compute drift radius ( = impact parameter)
113  double Xpos = localVertex1[0];
114  double Ypos = localVertex1[1];
115  double Xdir = localDirection[0];
116  double Ydir = localDirection[1];
117 
118  double Alpha = -1*(Xpos*Xdir + Ypos*Ydir)/(Xdir*Xdir + Ydir*Ydir); // localPosition*localDirection
119 
120  localPosition = localVertex1 + Alpha*(localVertex2-localVertex1);
121  driftRadius = localPosition.perp();
122  globalTime = aStep->GetPreStepPoint()->GetGlobalTime(); // take pre step time
123 
124  }else{ // particle didn't pass wire, one of the end-points is the shortest distance to the wire
125 
126  // calculate which of the two end-points is closer to the wire
127  double dist1 = localVertex1.perp();
128  double dist2 = localVertex2.perp();
129  if( dist1 < dist2 ){ // first is closer
130  driftRadius = dist1;
131  localPosition = localVertex1;
132  globalTime = aStep->GetPreStepPoint()->GetGlobalTime();
133  }else{ // second is closer
134  driftRadius = dist2;
135  localPosition = localVertex2;
136  globalTime = aStep->GetPostStepPoint()->GetGlobalTime();
137  }
138  }
139  m_vertex = Amg::Hep3VectorToEigen( aStep->GetTrack()->GetVertexPosition() );
140 
141  if( driftRadius < m_driftRadius ){ // check if current step came closer to the wire than the previous ones
143  // if the track m_vertex is far from (0,0,0), takes the tof, otherwise take the "usual" g4 globalTime
144  ((((m_vertex.mag()) < 100) || ((fabs(globalTime - tOrigin)) < 0.1) ) ? (m_globalTime = globalTime) : (m_globalTime = tof));
145  // if m_globalTime != globalTime and m_globalTime != tof in the output, this is due to multiple hits
146  // before founding the good one (small approximation)
147  m_localPosition = localPosition;
148  }
149 
150  // check if particle left tube or stopped in tube
151  G4String namePreStepMat = aStep->GetPreStepPoint()->GetMaterial()->GetName();
152  G4String namePostStepMat = aStep->GetPostStepPoint()->GetMaterial()->GetName();
153  G4String nameSD = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetSensitiveDetector()->GetName();
154 
155  // see if we were in the sensitive volume and left it, or the particle was killed
156  if( ((nameSD) && (namePreStepMat != namePostStepMat)) || (currentTrack->GetTrackStatus() == fStopAndKill)){
157 
158  // get identifier
159  const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
160  int MDTid = GetIdentifier(touchHist);
161 
162  TrackHelper trHelp(aStep->GetTrack());
163 
164  // construct new mdt hit
165  m_MDTHitColl->Emplace(MDTid, m_globalTime, m_driftRadius, m_localPosition, trHelp.GenerateParticleLink(),
166  aStep->GetStepLength(),
167  aStep->GetTotalEnergyDeposit(),
168  currentTrack->GetDefinition()->GetPDGEncoding(),
169  aStep->GetPreStepPoint()->GetKineticEnergy());
170 
171  m_driftRadius = m_DEFAULT_TUBE_RADIUS; // reset start value of driftRadius
172  }
173  return true;
174 }

Member Data Documentation

◆ m_currVertex

Amg::Vector3D MDTSensitiveDetectorCosmics::m_currVertex
private

Definition at line 108 of file MDTSensitiveDetectorCosmics.h.

◆ m_DEFAULT_TUBE_RADIUS

double MDTSensitiveDetectorCosmics::m_DEFAULT_TUBE_RADIUS
private

radius assigned to radius if radius is invalid

Definition at line 120 of file MDTSensitiveDetectorCosmics.h.

◆ m_driftRadius

double MDTSensitiveDetectorCosmics::m_driftRadius
private

Definition at line 115 of file MDTSensitiveDetectorCosmics.h.

◆ m_globalTime

double MDTSensitiveDetectorCosmics::m_globalTime
private

Definition at line 116 of file MDTSensitiveDetectorCosmics.h.

◆ m_globH

Amg::Vector3D MDTSensitiveDetectorCosmics::m_globH
private

Definition at line 109 of file MDTSensitiveDetectorCosmics.h.

◆ m_localPosition

Amg::Vector3D MDTSensitiveDetectorCosmics::m_localPosition
private

Definition at line 117 of file MDTSensitiveDetectorCosmics.h.

◆ m_MDTHitColl

SG::WriteHandle<MDTSimHitCollection> MDTSensitiveDetectorCosmics::m_MDTHitColl
private

member data

Definition at line 112 of file MDTSensitiveDetectorCosmics.h.

◆ m_mom

Amg::Vector3D MDTSensitiveDetectorCosmics::m_mom
private

Definition at line 105 of file MDTSensitiveDetectorCosmics.h.

◆ m_momMag

double MDTSensitiveDetectorCosmics::m_momMag
private

Definition at line 106 of file MDTSensitiveDetectorCosmics.h.

◆ m_muonHelper

const MdtHitIdHelper* MDTSensitiveDetectorCosmics::m_muonHelper
private

Definition at line 113 of file MDTSensitiveDetectorCosmics.h.

◆ m_vertex

Amg::Vector3D MDTSensitiveDetectorCosmics::m_vertex
private

Definition at line 107 of file MDTSensitiveDetectorCosmics.h.


The documentation for this class was generated from the following files:
MDTSensitiveDetectorCosmics::m_globH
Amg::Vector3D m_globH
Definition: MDTSensitiveDetectorCosmics.h:109
Muon::nsw::STGTPSegments::moduleIDBits::stationPhi
constexpr uint8_t stationPhi
station Phi 1 to 8
Definition: NSWSTGTPDecodeBitmaps.h:129
MDTSensitiveDetectorCosmics::m_muonHelper
const MdtHitIdHelper * m_muonHelper
Definition: MDTSensitiveDetectorCosmics.h:113
max
#define max(a, b)
Definition: cfImp.cxx:41
MDTSensitiveDetectorCosmics::m_momMag
double m_momMag
Definition: MDTSensitiveDetectorCosmics.h:106
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
ZDC::sideC
BySideTypeMod sideC(-1)
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
MDTSensitiveDetectorCosmics::m_driftRadius
double m_driftRadius
Definition: MDTSensitiveDetectorCosmics.h:115
Trk::loc2
@ loc2
generic first and second local coordinate
Definition: ParamDefs.h:41
MDTSensitiveDetectorCosmics::m_globalTime
double m_globalTime
Definition: MDTSensitiveDetectorCosmics.h:116
MdtHitIdHelper::GetHelper
static const MdtHitIdHelper * GetHelper(unsigned int nTubes=78)
Definition: MdtHitIdHelper.cxx:24
MDTSensitiveDetectorCosmics::m_DEFAULT_TUBE_RADIUS
double m_DEFAULT_TUBE_RADIUS
radius assigned to radius if radius is invalid
Definition: MDTSensitiveDetectorCosmics.h:120
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:92
Trk::driftRadius
@ driftRadius
trt, straws
Definition: ParamDefs.h:59
MDTSensitiveDetectorCosmics::m_vertex
Amg::Vector3D m_vertex
Definition: MDTSensitiveDetectorCosmics.h:107
MDTSensitiveDetectorCosmics::m_currVertex
Amg::Vector3D m_currVertex
Definition: MDTSensitiveDetectorCosmics.h:108
MDTSensitiveDetectorCosmics::m_MDTHitColl
SG::WriteHandle< MDTSimHitCollection > m_MDTHitColl
member data
Definition: MDTSensitiveDetectorCosmics.h:112
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MDTSensitiveDetectorCosmics::m_mom
Amg::Vector3D m_mom
Definition: MDTSensitiveDetectorCosmics.h:105
MDTSensitiveDetectorCosmics::GetIdentifier
int GetIdentifier(const G4TouchableHistory *touchHist)
Definition: MDTSensitiveDetectorCosmics.cxx:176
checkFileSG.fi
fi
Definition: checkFileSG.py:65
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:127
MDTSensitiveDetectorCosmics::m_localPosition
Amg::Vector3D m_localPosition
Definition: MDTSensitiveDetectorCosmics.h:117
Trk::loc1
@ loc1
Definition: ParamDefs.h:40
calibdata.tube
tube
Definition: calibdata.py:31
MdtHitIdHelper::BuildMdtHitId
int BuildMdtHitId(const std::string &, const int, const int, const int, const int, const int) const
Definition: MdtHitIdHelper.cxx:95