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