ATLAS Offline Software
Loading...
Searching...
No Matches
CSCSensitiveDetectorCosmics.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "G4Trd.hh"
7#include <string>
8#include <sstream>
11#include "MCTruth/TrackHelper.h"
12#include "G4Exception.hh"
13#include "G4Geantino.hh"
14#include "G4ChargedGeantino.hh"
15
17
18//comment the following line if you want hit information print out
19//#define CSCG4_DEBUG
20
21// construction/destruction
22CSCSensitiveDetectorCosmics::CSCSensitiveDetectorCosmics(const std::string& name, const std::string& hitCollectionName)
23 : G4VSensitiveDetector( name )
24 // START OF COSMICS-SPECIFIC CODE
25 , m_momMag(0.)
26 , m_globalTime(0.)
27 // END OF COSMICS-SPECIFIC CODE
28 , m_hitCollectionName( hitCollectionName )
29{
31}
32
33// Implemenation of memebr functions
35{
36 m_myCSCHitColl = nullptr;
37 if (auto* eventInfo = AtlasG4EventUserInfo::GetEventUserInfo()) {
38 m_myCSCHitColl = eventInfo->GetHitCollectionMap()->Find<CSCSimHitCollection>(m_hitCollectionName);
39 m_g4UserEventInfo = eventInfo;
40 }
41 // START OF COSMICS-SPECIFIC CODE
42 m_mom = Amg::Vector3D(0.,0.,0.);
43 m_globH = Amg::Vector3D(0.,0.,0.);
44 // END OF COSMICS-SPECIFIC CODE
45}
46
47G4bool CSCSensitiveDetectorCosmics::ProcessHits(G4Step* aStep,G4TouchableHistory* /*ROHist*/) {
48
49 if (!m_myCSCHitColl) {
50 G4Exception("CSCSensitiveDetectorCosmics::ProcessHits", "CSCCosmicHitCollectionMissing", FatalException,
51 "Hit collection not initialized; did SetupEvent run?");
52 return false;
53 }
54
55 G4Track* currentTrack = aStep->GetTrack();
56
58 auto trackDef = currentTrack->GetDefinition();
59 if (trackDef->GetPDGCharge() == 0.0) {
60 if (trackDef != G4Geantino::GeantinoDefinition()) return true;
61 else if (trackDef == G4ChargedGeantino::ChargedGeantinoDefinition()) return true;
62 }
63
64 const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
65 G4ThreeVector startPos=aStep->GetPreStepPoint()->GetPosition();
66 G4ThreeVector endPos=aStep->GetPostStepPoint()->GetPosition();
67 double kinEnergy = aStep->GetPreStepPoint()->GetKineticEnergy();
68
70
71 std::string stationName="";
72 int stationEta=0;
73 int stationPhi=0;
74 int multiLayer=0;
75 int wireLayer=0;
76
78
79 Amg::Vector3D HitStart = Amg::Vector3D(-1000,-1000,-1000);
80 Amg::Vector3D HitEnd = Amg::Vector3D(-1000,-1000,-1000);
81 double globalTime = -1;
82 double energyDeposit= -1;
83 G4int lundcode = -1;
85 //const int trackid(aStep->GetTrack()->GetTrackID());
86
87 // START OF COSMICS-SPECIFIC CODE
88 // global coordinates
89 Amg::Vector3D globVrtx = Amg::Hep3VectorToEigen( aStep->GetPreStepPoint()->GetPosition() );
90
91 // distance of the hit from (0,0,0) vertex - calculated from the PreStepPoint (approximation)
92 const double dist = globVrtx.mag();
93 const double lightspeed = 299.792458; /* in vacuo speed of light [mm/ns] */ //FIXME this should be taken from standard headers
94 const double tOrigin = dist / lightspeed;
95
96 m_currVertex = Amg::Hep3VectorToEigen( aStep->GetTrack()->GetVertexPosition() );
97
98 // for cosmics: only primary muon tracks - track momentum when first entering the spectrometer (one muon per event)
99 if ((m_currVertex != m_vertex) && (aStep->GetTrack()->GetTrackID() == 1)) {
100 // after calculationg the momentum magnidude, normalize it
101 m_mom = Amg::Hep3VectorToEigen( currentTrack->GetMomentum() );
102 m_momMag = m_mom.mag();
103 m_mom.normalize();
104 // the direction of the primary mu is used to calculate the t0, the position to the t0, m_globH, is ONE for a track
105 Amg::Vector3D globVrtxFix = globVrtx;
106 const 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]);
107 m_globH = globVrtxFix + AlphaGlobal*m_mom;
108 // G4cout << "COSMICS MAIN TRACK IN THES CSC!" << G4endl;
109 }
110 const double globalDist = sqrt((m_globH[0] - globVrtx[0])*(m_globH[0] - globVrtx[0]) +
111 (m_globH[1] - globVrtx[1])*(m_globH[1] - globVrtx[1]) +
112 (m_globH[2] - globVrtx[2])*(m_globH[2] - globVrtx[2]));
113 double tof = globalDist / lightspeed;
114 // END OF COSMICS SPECIFIC CODE
115
117
118 bool isAssembly = false;
119 for (int i = touchHist->GetHistoryDepth(); i>=0; --i) {
120 std::string::size_type npos;
121 std::string volName = touchHist->GetVolume(i)->GetName();
122
124 if ((npos = volName.find("av_")) != std::string::npos &&
125 (npos = volName.find("impr_")) != std::string::npos) isAssembly = true;
126
127 if ((npos = volName.find("station")) != std::string::npos && (!isAssembly)) {
128
130 volName.resize(npos-2);
131 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
132 stationName = volName;
133 //stationEta = volCopyNo/100;
134 // bug fix for 14.2.0 to cope with non-mirrored chambers as proposed by
135 // S.Spagnolo (ported from CSCSensitiveDetector.cxx for rel 20.3.3)
136 stationEta = (volCopyNo%1000)/100;
137 stationPhi = abs(volCopyNo%100);
138
139 } else if ((npos = volName.find("CSC")) != std::string::npos && isAssembly ) {
140 // vol name for Assembly components are
141 // av_WWW_impr_XXX_Muon::BMSxMDTxx_pv_ZZZ_NAME
142 // where WWW is ass. istance nr.
143 // XXX is comp. imprint nr.
144 // BMSxMDTxx is the name of the comp. log.Vol.
145 // x station sub-type; xx technology subtype
146 // ZZZ is No of order of this daugther
147 // NAME is the comp. tag (geoIdentifierTag)
148 // for CSCs it is cl[1] or cl[2]
149 // copy numbers for Ass.components are =
150 // CopyNoBase(= geoIdentifierTag of the assembly) + geoIdentifierTag of the component
151 // geoIdentifierTag of the component = Job
152 // geoIdentifierTag of the assembly = (sideC*10000 +
153 // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
154 // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
155
157 std::string::size_type loc1,loc2;
158 if ((loc1 = volName.find("Muon::")) != std::string::npos) {
159 stationName = volName.substr(loc1+6,3); //type only
160 }
161
163 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
164 int copyNrBase = int(volCopyNo/100000);
165 int sideC = int(copyNrBase/10000);
166 int zi = int((copyNrBase%1000)/100);
167 // int mirfl = int((copyNrBase%10000)/1000);
168 int fi = int(copyNrBase%100);
169 if (sideC == 1) zi = -zi;
170 stationEta = zi;
171 stationPhi = fi;
172
173 // now get the geoIdentifierTag of the rpc components
174 int gmID = 0;
175 if ((loc1 = volName.find('[')) != std::string::npos) {
176 if ((loc2 = volName.find(']', loc1+1)) != std::string::npos) {
177 std::istringstream istrvar(volName.substr(loc1+1,loc2-loc1-1));
178 istrvar>>gmID;
179 }
180 }
182 multiLayer = gmID;
183 } else if ((npos = volName.find("component")) != std::string::npos && (!isAssembly)) {
184
186 multiLayer = touchHist->GetVolume(i)->GetCopyNo();
187 if(multiLayer==3) multiLayer=2; //multilayer index
188 // G4cout << "CSC:::::: multiLayer "<<multiLayer << G4endl;
189 } else if ((npos = volName.find("CscArCO2")) != std::string::npos) {
190
192 wireLayer=touchHist->GetVolume(i)->GetCopyNo();
193 wireLayer+=1;
194 if(wireLayer==4) wireLayer=1;
195 else if(wireLayer==3) wireLayer=2;
196 else if(wireLayer==2) wireLayer=3;
197 else if(wireLayer==1) wireLayer=4;
198 // G4cout << "CSC:::::: wireLayer "<<wireLayer << G4endl;
199
201 G4String particle=aStep->GetTrack()->GetDefinition()->GetParticleName();
202 // http://www.slac.stanford.edu/BFROOT/www/Computing/Environment/NewUser/htmlbug/node51.html #GEANT code
203 if (particle=="gamma") lundcode=1; // FIXME was photon, but changed to gamma to match CSCSensitiveDetctor
204 else if (particle=="e+") lundcode=2;
205 else if (particle=="e-") lundcode=3;
206 else if (particle=="mu+") lundcode=5;
207 else if (particle=="mu-") lundcode=6;
208 else if (particle=="pi+") lundcode=8;
209 else if (particle=="pi-") lundcode=9;
210 else if (particle=="kaon+") lundcode=11;
211 else if (particle=="kaon-") lundcode=12;
212 else if (particle=="proton") lundcode=14;
213 else if (particle=="anti_proton") lundcode=15;
214 else if (particle=="sigma+") lundcode=19;
215 else if (particle=="sigma-") lundcode=21;
216 else if (particle=="anti_sigma-") lundcode=27;
217 else if (particle=="anti_sigma+") lundcode=29;
218 else if (particle=="deuteron") lundcode=45;
219 else if (particle=="geantino") lundcode=999;
220 else lundcode=0;
221
223 globalTime = aStep->GetPreStepPoint()->GetGlobalTime();
224
226 energyDeposit = aStep->GetTotalEnergyDeposit();
227
229 const G4AffineTransform transform = touchHist->GetHistory()->GetTopTransform();
230
232 HitStart = Amg::Hep3VectorToEigen( transform.TransformPoint(startPos) );
233
236 HitEnd = Amg::Hep3VectorToEigen( transform.TransformPoint(endPos) );
237
238 }
239 }
240
241 // START OF COSMICS SPECIFIC CODE
242 m_vertex = Amg::Hep3VectorToEigen( aStep->GetTrack()->GetVertexPosition() );
243 // if the track vertex is far from (0,0,0), takes the tof, otherwise take the "usual" g4 globalTime
244 (((m_vertex.mag() < 100) || ((fabs(globalTime - tOrigin)) < 0.1) ) ? (m_globalTime = globalTime)
245 : (m_globalTime = tof));
246 // if m_globalTime != globalTime and m_globalTime != tof in the output, this is due to multiple hits
247 // before founding the good one (small approximation)
248 // END OF COSMICS SPECIFIC CODE
249
250 TrackHelper trHelp(aStep->GetTrack());
251
253 HitID CSCid = m_muonHelper->BuildCscHitId(stationName, stationPhi,
254 stationEta, multiLayer, wireLayer);
255
257 m_myCSCHitColl->Emplace(CSCid, m_globalTime, energyDeposit,
258 HitStart, HitEnd, lundcode,
259 trHelp.GenerateParticleLink(m_g4UserEventInfo ? m_g4UserEventInfo->GetEventStore() : nullptr), kinEnergy);
260
261 // #ifndef CSCG4_DEBUG
262 //
263 // // printouts for cosmics
264 // G4cout << "------------------CSC------------------" << G4endl;
265 // G4cout << "Track "<<aStep->GetTrack()->GetTrackID() << G4endl;
266 // G4cout << "Track m_vertex "<<m_vertex[0]<<" " <<m_vertex[1]<<" " <<m_vertex[2] << G4endl;
267// G4cout << "Global position of the hit " << globVrtx[0] <<" " << globVrtx[1] <<" " << globVrtx[2] << G4endl;
268// G4cout << "Distance from (0,0,0) and time " << dist << " " <<tOrigin << G4endl;
269// G4cout << "Momentum "<<m_momMag << G4endl;
270// G4cout << "Momentum director cosines " <<m_mom[0]<<" " <<m_mom[1]<<" " <<m_mom[2] << G4endl;
271// G4cout << "Eta and phi "<<m_mom.eta()<<" " <<m_mom.phi() << G4endl;
272// G4cout << "Closest approach position and distance from (0,0,0) "
273// << m_globH[0] <<" "<<m_globH[1]<<" "<<m_globH[2]<<" "
274// << sqrt(m_globH[0]*m_globH[0] + m_globH[1]*m_globH[1] + m_globH[2]*m_globH[2]) << G4endl;
275// G4cout << "Distance from t0 and tof " << globalDist <<" " <<tof << G4endl;
276// G4cout << "g4 globalTime " << globalTime << G4endl;
277// G4cout << "Time " << m_globalTime << G4endl;
278//
279// G4cout << "TUB "<<m_muonHelper->GetStationName(CSCid)
280// << " "<<m_muonHelper->GetFieldValue("PhiSector")
281// << " "<<m_muonHelper->GetFieldValue("ZSector")
282// << " "<<m_muonHelper->GetFieldValue("ChamberLayer")
283// << " "<<m_muonHelper->GetFieldValue("WireLayer") << G4endl;
284//
285// G4cout << m_muonHelper->GetStationName(CSCid)<<" "<<newHit->print() << G4endl;
286//
287// #endif
288
289 return true;
290}
AtlasHitsVector< CSCSimHit > CSCSimHitCollection
int HitID
static AtlasG4EventUserInfo * GetEventUserInfo()
CSCSensitiveDetectorCosmics(const std::string &name, const std::string &hitCollectionName)
construction/destruction
void Initialize(G4HCofThisEvent *HCE) override final
member functions
G4bool ProcessHits(G4Step *aStep, G4TouchableHistory *ROhist) override final
static const CscHitIdHelper * GetHelper()
HepMcParticleLink GenerateParticleLink()
Generates a creates new HepMcParticleLink object on the stack based on GetUniqueID(),...
Definition TrackHelper.h:52
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
Eigen::Matrix< double, 3, 1 > Vector3D