00001
00002
00003
00004
00005
00006 #include "BDSExecOptions.hh"
00007 #include "BDSDebug.hh"
00008 #include "BDSGlobalConstants.hh"
00009
00010 #include "BDSEnergyCounterSD.hh"
00011 #include "BDSEnergyCounterHit.hh"
00012 #include "BDSLogicalVolumeInfo.hh"
00013 #include "G4AffineTransform.hh"
00014 #include "G4Event.hh"
00015 #include "G4EventManager.hh"
00016 #include "G4ios.hh"
00017 #include "G4LogicalVolume.hh"
00018 #include "G4ParticleDefinition.hh"
00019 #include "G4RotationMatrix.hh"
00020 #include "G4SDManager.hh"
00021 #include "G4Step.hh"
00022 #include "G4ThreeVector.hh"
00023 #include "G4TouchableHistory.hh"
00024 #include "G4Track.hh"
00025 #include "G4VPhysicalVolume.hh"
00026 #include "G4VTouchable.hh"
00027
00028 #include <map>
00029
00030 #define NMAXCOPY 5
00031
00032 BDSEnergyCounterSD::BDSEnergyCounterSD(G4String name)
00033 :G4VSensitiveDetector(name),
00034 energyCounterCollection(NULL),
00035 primaryCounterCollection(NULL),
00036 HCIDe(-1),
00037 HCIDp(-1),
00038 enrg(0.0),
00039 X(0.0),
00040 Y(0.0),
00041 Z(0.0),
00042 S(0.0),
00043 x(0.0),
00044 y(0.0),
00045 z(0.0)
00046 {
00047 verbose = BDSExecOptions::Instance()->GetVerbose();
00048 itsName = name;
00049 collectionName.insert("energy_counter");
00050 collectionName.insert("primary_counter");
00051 }
00052
00053 BDSEnergyCounterSD::~BDSEnergyCounterSD()
00054 {;}
00055
00056 void BDSEnergyCounterSD::Initialize(G4HCofThisEvent* HCE)
00057 {
00058 energyCounterCollection = new BDSEnergyCounterHitsCollection(SensitiveDetectorName,collectionName[0]);
00059 if (HCIDe < 0)
00060 {HCIDe = G4SDManager::GetSDMpointer()->GetCollectionID(energyCounterCollection);}
00061 HCE->AddHitsCollection(HCIDe,energyCounterCollection);
00062
00063 primaryCounterCollection = new BDSEnergyCounterHitsCollection
00064 (SensitiveDetectorName,collectionName[1]);
00065 if (HCIDp < 0)
00066 {HCIDp = G4SDManager::GetSDMpointer()->GetCollectionID(primaryCounterCollection);}
00067 HCE->AddHitsCollection(HCIDp,primaryCounterCollection);
00068 }
00069
00070 G4bool BDSEnergyCounterSD::ProcessHits(G4Step*aStep, G4TouchableHistory* readOutTH)
00071 {
00072 if(BDSGlobalConstants::Instance()->GetStopTracks())
00073 enrg = (aStep->GetTrack()->GetTotalEnergy() - aStep->GetTotalEnergyDeposit());
00074
00075
00076
00077 else
00078 enrg = aStep->GetTotalEnergyDeposit();
00079 #ifdef BDSDEBUG
00080 G4cout << "BDSEnergyCounterSD> enrg = " << enrg << G4endl;
00081 #endif
00082
00083 if (enrg==0.) return false;
00084
00085
00086 G4int nCopy;
00087 if (readOutTH)
00088 {nCopy = readOutTH->GetCopyNumber();}
00089 else
00090 {nCopy = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetCopyNo();}
00091 #ifdef BDSDEBUG
00092 if(nCopy>0){
00093 G4cout << "BDSEnergyCounterSD::ProcessHits> nCopy = " << nCopy << G4endl;
00094 }
00095 #endif
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 if (!readOutTH)
00117 {
00118 G4cout << __METHOD_NAME__ << "hit in a sensitive volume without readout geometry" << G4endl;
00119 G4cerr << __METHOD_NAME__ << "hit not recorded!" << G4endl;
00120 return true;
00121 }
00122
00123
00124
00125 G4AffineTransform tf = readOutTH->GetHistory()->GetTopTransform();
00126
00127
00128 G4ThreeVector posbefore = aStep->GetPreStepPoint()->GetPosition();
00129 G4ThreeVector posafter = aStep->GetPostStepPoint()->GetPosition();
00130
00131
00132
00133 G4ThreeVector posbeforelocal = tf.TransformPoint(posbefore);
00134 G4ThreeVector posafterlocal = tf.TransformPoint(posafter);
00135
00136
00137
00138 Y = 0.5 * (posbefore.x() + posafter.x());
00139 Y = 0.5 * (posbefore.y() + posafter.y());
00140 Z = 0.5 * (posbefore.z() + posafter.z());
00141 S = GetSPositionOfStep(aStep);
00142
00143 x = 0.5 * (posbeforelocal.x() + posafterlocal.x());
00144 y = 0.5 * (posbeforelocal.y() + posafterlocal.y());
00145 z = 0.5 * (posbeforelocal.z() + posafterlocal.z());
00146
00147 G4int event_number = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
00148
00149 if(verbose && BDSGlobalConstants::Instance()->GetStopTracks())
00150 {
00151 G4cout << "BDSEnergyCounterSD: Current Volume: "
00152 << aStep->GetPreStepPoint()->GetPhysicalVolume()->GetName()
00153 << "\tEvent: " << event_number
00154 << "\tEnergy: " << enrg/CLHEP::GeV
00155 << "GeV\tPosition: " << S/CLHEP::m <<" m"<< G4endl;
00156 }
00157
00158 G4double weight = aStep->GetTrack()->GetWeight();
00159 if (weight == 0){
00160 G4cerr << "Error: BDSEnergyCounterSD: weight = 0" << G4endl;
00161 exit(1);
00162 }
00163 G4int ptype = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
00164 G4String volName = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetName();
00165 G4String regionName = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()->GetName();
00166
00167 G4bool precisionRegion = false;
00168 if (regionName.contains((G4String)"precisionRegion")) {
00169 precisionRegion=true;
00170 }
00171
00172
00173 G4int turnstaken = BDSGlobalConstants::Instance()->GetTurnsTaken();
00174
00175
00176
00177 BDSEnergyCounterHit* ECHit = new BDSEnergyCounterHit(nCopy,
00178 enrg,
00179 X,
00180 Y,
00181 Z,
00182 S,
00183 x,
00184 y,
00185 z,
00186 volName,
00187 ptype,
00188 weight,
00189 precisionRegion,
00190 turnstaken,
00191 event_number
00192 );
00193
00194 energyCounterCollection->insert(ECHit);
00195
00196
00197 if (aStep->GetTrack()->GetParentID() == 0) {
00198
00199
00200 BDSEnergyCounterHit* PCHit = new BDSEnergyCounterHit(*ECHit);
00201
00202
00203 G4double primaryEnergy = BDSGlobalConstants::Instance()->GetBeamKineticEnergy();
00204 PCHit->SetEnergy(primaryEnergy);
00205 primaryCounterCollection->insert(PCHit);
00206 }
00207
00208 if(BDSGlobalConstants::Instance()->GetStopTracks())
00209 aStep->GetTrack()->SetTrackStatus(fStopAndKill);
00210
00211 return true;
00212 }
00213
00214 G4bool BDSEnergyCounterSD::ProcessHits(G4GFlashSpot *aSpot,G4TouchableHistory*)
00215 {
00216 enrg = aSpot->GetEnergySpot()->GetEnergy();
00217 #ifdef BDSDEBUG
00218 G4cout << "BDSEnergyCounterSD>gflash enrg = " << enrg << G4endl;
00219 #endif
00220 if (enrg==0.) return false;
00221 G4VPhysicalVolume* pCurrentVolume = aSpot->GetTouchableHandle()->GetVolume();
00222 G4String volName = pCurrentVolume->GetName();
00223 G4int nCopy = pCurrentVolume->GetCopyNo();
00224 #ifdef BDSDEBUG
00225 if(nCopy>0){
00226 G4cout << "BDSEnergyCounterSD::ProcessHits>gFlash nCopy = " << nCopy << G4endl;
00227 }
00228 #endif
00229 if(nCopy > NMAXCOPY-1)
00230 {
00231 G4cerr << " BDSEnergyCounterSD: nCopy too large: nCopy = " << nCopy
00232 << " NMAXCOPY = " << NMAXCOPY
00233 << " Volume = "<< volName;
00234 G4Exception("Killing program in BDSEnergyCounterSD::ProcessHits", "-1", FatalException, "");
00235 }
00236
00237
00238 G4AffineTransform tf = (aSpot->GetTouchableHandle()->GetHistory()->GetTopTransform());
00239 G4ThreeVector pos = aSpot->GetPosition();
00240
00241
00242 G4ThreeVector poslocal = tf.TransformPoint(pos);
00243
00244
00245 Y = pos.x();
00246 Y = pos.y();
00247 Z = pos.z();
00248 S = GetSPositionOfSpot(aSpot);
00249
00250 x = poslocal.x();
00251 y = poslocal.y();
00252 z = poslocal.z();
00253
00254 G4int event_number = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
00255
00256 if(verbose && BDSGlobalConstants::Instance()->GetStopTracks())
00257 {
00258 G4cout << " BDSEnergyCounterSD: Current Volume: " << volName
00259 << " Event: " << event_number
00260 << " Energy: " << enrg/CLHEP::GeV << " GeV"
00261 << " Position: " << S/CLHEP::m << " m"
00262 << G4endl;
00263 }
00264
00265 G4double weight = aSpot->GetOriginatorTrack()->GetPrimaryTrack()->GetWeight();
00266 if (weight == 0){
00267 G4cerr << "Error: BDSEnergyCounterSD: weight = 0" << G4endl;
00268 exit(1);
00269 }
00270 int ptype = aSpot->GetOriginatorTrack()->GetPrimaryTrack()->GetDefinition()->GetPDGEncoding();
00271
00272 G4int turnstaken = BDSGlobalConstants::Instance()->GetTurnsTaken();
00273
00274
00275 BDSEnergyCounterHit* ECHit = new BDSEnergyCounterHit(nCopy,
00276 enrg,
00277 X,
00278 Y,
00279 Z,
00280 S,
00281 x,
00282 y,
00283 z,
00284 volName,
00285 ptype,
00286 weight,
00287 0,
00288 turnstaken,
00289 event_number
00290 );
00291
00292 energyCounterCollection->insert(ECHit);
00293
00294
00295 if (aSpot->GetOriginatorTrack()->GetPrimaryTrack()->GetParentID() == 0) {
00296
00297
00298 BDSEnergyCounterHit* PCHit = new BDSEnergyCounterHit(*ECHit);
00299 G4double primaryEnergy = BDSGlobalConstants::Instance()->GetBeamKineticEnergy();
00300 PCHit->SetEnergy(primaryEnergy);
00301 primaryCounterCollection->insert(PCHit);
00302 }
00303
00304 return true;
00305 }
00306
00307 G4double BDSEnergyCounterSD::GetSPositionOfStep(G4Step* aStep)
00308 {
00309 G4double thespos;
00310
00311
00312 G4LogicalVolume* thevolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
00313
00314 typedef std::map<G4LogicalVolume*,BDSLogicalVolumeInfo*>::iterator it_type;
00315 it_type search = BDSGlobalConstants::Instance()->LogicalVolumeInfo()->find(thevolume);
00316
00317 if (search == BDSGlobalConstants::Instance()->LogicalVolumeInfo()->end()){
00318
00319
00320 thespos = -1.0*CLHEP::m;
00321 }
00322 else {
00323 thespos = BDSGlobalConstants::Instance()->GetLogicalVolumeInfo(thevolume)->GetSPos();
00324 G4ThreeVector prestepposition = aStep->GetPreStepPoint()->GetPosition();
00325 G4AffineTransform tf = (aStep->GetPreStepPoint()->GetTouchableHandle()->GetHistory()->GetTopTransform());
00326 G4ThreeVector prestepposlocal = tf.TransformPoint(prestepposition);
00327 thespos += prestepposlocal.z();
00328 }
00329 return thespos;
00330 }
00331
00332 G4double BDSEnergyCounterSD::GetSPositionOfSpot(G4GFlashSpot* aSpot)
00333 {
00334 G4double thespos;
00335
00336
00337 G4LogicalVolume* thevolume = aSpot->GetTouchableHandle()->GetVolume()->GetLogicalVolume();
00338
00339
00340 typedef std::map<G4LogicalVolume*,BDSLogicalVolumeInfo*>::iterator it_type;
00341 it_type search = BDSGlobalConstants::Instance()->LogicalVolumeInfo()->find(thevolume);
00342
00343 if (search == BDSGlobalConstants::Instance()->LogicalVolumeInfo()->end()){
00344
00345
00346 thespos = -1.0*CLHEP::m;
00347 }
00348 else {
00349 thespos = BDSGlobalConstants::Instance()->GetLogicalVolumeInfo(thevolume)->GetSPos();
00350 G4ThreeVector pos = aSpot->GetPosition();
00351 G4AffineTransform tf = (aSpot->GetTouchableHandle()->GetHistory()->GetTopTransform());
00352 G4ThreeVector localposition = tf.TransformPoint(pos);
00353 thespos += localposition.z();
00354 }
00355 return thespos;
00356 }