00001 #include "SensitiveDetector.hh" 00002 #include "DetectorConstruction.hh" 00003 #include "RunAction.hh" 00004 00005 #include "G4Step.hh" 00006 #include "Randomize.hh" 00007 #include "G4RunManager.hh" 00008 00009 #include "G4HCofThisEvent.hh" 00010 00011 #include "G4HCtable.hh" 00012 #include "G4SDManager.hh" 00013 00014 #include "G4Proton.hh" 00015 00016 00017 SensitiveDetector::SensitiveDetector(G4String SDname) 00018 : G4VSensitiveDetector(SDname) 00019 { 00020 // -- obtain detector construction and run action pointers through the run manager 00021 m_detector = (DetectorConstruction*)(G4RunManager::GetRunManager()->GetUserDetectorConstruction()); 00022 m_runAction = (RunAction*)(G4RunManager::GetRunManager()->GetUserRunAction()); 00023 00024 // -->> jour4b2: 00025 // ---------------------------------------------------------------------------------- 00026 // -- 'collectionName' is a protected data member of base class G4VSensitiveDetector. 00027 // -- Here we declare the name of the collection we will be using. 00028 // ---------------------------------------------------------------------------------- 00029 collectionName.insert("AstronautCollection"); 00030 00031 // -- Note that we may add as many collection names we would wish: ie 00032 // -- a sensitive detector can have many collections. 00033 } 00034 00035 SensitiveDetector::~SensitiveDetector() 00036 {} 00037 00038 G4bool SensitiveDetector::ProcessHits(G4Step *step, G4TouchableHistory *) 00039 { 00040 // -- step is garanteed to be is astronaut's volume : no need to check for volume 00041 00042 G4TouchableHandle touchable = step->GetPreStepPoint()->GetTouchableHandle(); 00043 // energy deposit in this step 00044 G4double edep = step->GetTotalEnergyDeposit(); 00045 00046 if (edep <= 0.) return false; 00047 00048 // get step points in world coordinate system 00049 G4ThreeVector point1 = step->GetPreStepPoint()->GetPosition(); 00050 G4ThreeVector point2 = step->GetPostStepPoint()->GetPosition(); 00051 00052 // randomize point of energy deposition 00053 G4ThreeVector pointE = point1 + G4UniformRand()*(point2 - point1); 00054 // transform it in local coordinate system 00055 G4ThreeVector localPointE 00056 = touchable->GetHistory()->GetTopTransform().TransformPoint(pointE); 00057 00058 // extract z and offset 00059 G4double zLocal = 0.5*(m_detector->GetAstronautHeight()) - localPointE.z(); 00060 00061 00062 // ------------- 00063 // -->> jour4b2: 00064 // ------------- 00065 00066 // sum edep in RunAction (in SD vector): 00067 // -->> we remove this call from here : m_runAction->SumDepthDoseSD(zLocal,edep); 00068 00069 // -- obtain the slice number corresponding to the zLocal 00070 // -- coordinate. This will be used to to label the hit: 00071 G4int k = m_runAction->GetSliceNumber(zLocal); // <<-- new method of run action, added for this exercise 00072 // ------------------------------------------------ 00073 // -- Get or create, if necessary, hit for slice k: 00074 // ------------------------------------------------ 00075 if (k > -1) { // << -- "-1" corresponds to an error code, should not happen ;-) 00076 AstroHit* hit(0); 00077 if (m_hitIndex[k] == -1) // <<-- means hit for slice k was not created, so created 00078 { 00079 // -- Create a new hit, for slice k: 00080 hit = new AstroHit(k); 00081 // -- Flag the creation of this new hit, for slice k. 00082 // -- For this, we replace the "-1" at position k in the 00083 // -- index table, the index of this hit in the hit collection: 00084 m_hitIndex[k] = m_hitCollection->insert(hit) - 1; // size of collection is returned by insert(..), so index of new hit is size - 1 00085 } 00086 else // <<-- hit was already created, just get its pointer 00087 { 00088 hit = (*m_hitCollection)[m_hitIndex[k]]; 00089 } 00090 // ----------------------------------------------------- 00091 // -- finally we accumulate this step energy in the hit: 00092 // ----------------------------------------------------- 00093 hit->addE(edep); 00094 // -- get G4Track pointer: 00095 G4Track* track = step->GetTrack(); 00096 // -- check this track is a proton: 00097 if (track->GetDefinition() == G4Proton::ProtonDefinition()) 00098 { 00099 hit->accumulateProton(track->GetKineticEnergy()); 00100 } 00101 } 00102 00103 00104 return true; 00105 00106 } 00107 00108 void SensitiveDetector::Initialize(G4HCofThisEvent* HCE) 00109 { 00110 // -- G4cout << "Initialize method of SD `" << GetName() << "' called." << G4endl; 00111 00112 // ------------------------------ 00113 // -- Creation of the collection 00114 // ------------------------------ 00115 // -- collectionName[0] is "AstronautCollection", as declared in constructor 00116 m_hitCollection = new AstroHitCollection(GetName(), collectionName[0]); 00117 00118 // ---------------------------------------------------------------------------- 00119 // -- and attachment of this collection to the "Hits Collection of this Event": 00120 // ---------------------------------------------------------------------------- 00121 // -- To insert the collection, we need to get an index for it. This index 00122 // -- is unique to the collection. It is provided by the GetCollectionID(...) 00123 // -- method (which calls what is needed in the kernel to get this index). 00124 static G4int HCID = -1; 00125 if (HCID<0) HCID = GetCollectionID(0); // <<-- this is to get an ID for collectionName[0] 00126 HCE->AddHitsCollection(HCID, m_hitCollection); 00127 00128 // -- Question : what are these lines made for ? 00129 m_hitIndex.clear(); 00130 m_hitIndex.resize(m_runAction->GetNumberOfSlices(), -1); 00131 00132 } 00133 00134 void SensitiveDetector::EndOfEvent(G4HCofThisEvent*) 00135 { 00136 //-- G4cout << "EndOfEvent method of SD `" << GetName() << "' called." << G4endl; 00137 00138 // -- we could have attached the collection to the G4HCofThisEvent in this 00139 // -- method as well (instead of Initialize). 00140 }