Code for download: session5_start.tar.gz
Exercise:
- Implement hit and sensitive detector classes for the Drift chamber (
EDChamberHit, EDChamberSD
) to account the following information when a charged track passed through the detector:- the chamber layer number
- the time when a particle hits chamber
- the hit local position (the position in the chamber volume frame)
- Implement hit and sensitive detector classes for the EM calorimeter (
EDEmCalorimeterHit, EDEmCalorimeterSD
) to account the following information:- the layer number
- the total energy deposit in the layer (= the accumulated deposit from all particles).
See example basic/B4/B4c.
- Add printing of the hit collections at the end of each event (in the
SD::EndOfEvent()
function). - Replace
EDEmCalorimeterSD
with a suitable Geant4 scorer.
See example basic/B4/B4d.- Do not remove already implemented
EDEmCalorimeter*
classes, but only comment out the SD setting inEDDetectorConstruction
class. - Add printing of hits accounted in the scorer in
EDEventAction::EndOfEventAction
. - Check that the results obtained with the scorer are identical with thoseobtained with the sensitive detector.
- Do not remove already implemented
Solution:
Solution step by step:
Accounting hits in drift chamber:
- Connect the EDChamberSD class with Chamber logical volume in
EDDetectorConstruction::Construct()
(in src/EDDetectorConstruction.cc):// Define sensitive detectors EDChamberSD* chamber1SD = new EDChamberSD("Chamber1SD", "Chamber1HitsCollection"); G4SDManager::GetSDMpointer()->AddNewDetector(chamber1SD); wirePlane1LV->SetSensitiveDetector(chamber1SD);
- Update EDChamberHit class so that it can hold requested data. For each information we have to add a corresponding data member and « setter and « getter » member functions. (See the example of MyHit class in the presentation.):
For accounting the time when a particle hits the chamber, add in include/EDChamberHit.hh:// add setter/getter methods void SetTime(G4double time) { fTime = time; } G4double GetTime() const { return fTime; } // data members G4double fTime;
Then add printing of the added value in
EDChamberHit::Print()
(in src/EDChamberHit.cc).G4cout << "Chamber hit time [s]: " << fTime/s << G4endl;
- Update
EDChamberSD::ProcessHits()
function (in src/EDChamberSD.cc) to create a hit object of EDChamberHit class, retrieve the requested information from G4Step and set it to a newly created hit object (see the example of this function in the presentation.)// Create a new hit object of EDChamberHit type EDChamberHit* newHit = new EDChamberHit(); // Get time from G4Step object G4StepPoint* preStepPoint = step->GetPreStepPoint(); G4double time = preStepPoint->GetGlobalTime(); newHit->SetTime(time); // Add hit in the collection fHitsCollection->insert(newHit); return true;
- Update
EDChamberSD::EndOfEvent()
(in src/EDChamberSD.cc) and add printing hits collection (according to the example in the presentation):G4cout << "\n-------->" << fHitsCollection->GetName() << ": in this event: " << G4endl; G4int nofHits = fHitsCollection->entries(); for ( G4int i=0; i<nofHits; i++ ) { (*fHitsCollection)[i]->Print(); }
- At this stage, the program prints the time accounted in chamber volumes. It remains to complete the
EDChamberHit, EDChamberSD
classes with two more data members:// data members G4int fLayerNumber; G4ThreeVector fPosition;
and their setter/getter methods and update also the remaining code for these new data.The complete code can be found in the provided solution.
Accounting hits in calorimeter:
- Connect the EDEmCalorimeterSD class with EmLayer logical volume in the same way as for EDChamberSD.
- Update EDEmCalorimeterHit class in an analogous way as in case of EDChamberHit, the only difference will be The function for accumulation energy deposit:
// add setter/getter methods void AddEdep(G4double edep) { fEdep += edep; } // data members G4double fEdep;
- In difference from tracker detector type, we create only one hit per each calorimeter layer during an event which is updated with each particle energy deposit in the cell. That’s why we create all hits already in
EDEmCalorimeterSD::Initialize()
(in src/EDEmCalorimeterSD.cc):for (G4int i=0; i<10; ++i) { EDEmCalorimeterHit* newHit = new EDEmCalorimeterHit(); newHit->SetLayerNumber(i); fHitsCollection->insert(newHit); }
Then, in
EDEmCalorimeterSD::ProcessHits()
we need to update the hit of the calorimeter layer where accounting of energy is processed:G4bool EDEmCalorimeterSD::ProcessHits(G4Step* step, G4TouchableHistory* /*history*/) { // Get energy deposit G4double edep = step->GetTotalEnergyDeposit(); if ( edep==0. ) return false; // Get layer number (using touchable) G4TouchableHistory* touchable = (G4TouchableHistory*)(step->GetPreStepPoint() ->GetTouchable()); G4VPhysicalVolume* layerPV = touchable->GetVolume(); G4int layerNumber = layerPV->GetCopyNo(); // Get hit accounting data for this layer EDEmCalorimeterHit* hit = (*fHitsCollection)[layerNumber]; if ( ! hit ) { G4cerr << "Cannot access hit " << layerNumber << G4endl; exit(1); } // Add energy deposit value hit->AddEdep(edep); return true; }
Exercise ++:
The exercises marked as ++ are optional; they are recommended for participants who have already some experience with Geant4 and get some time left for practicing more than the basic exercise proposed above.
- Choose another suitable Geant4 scorer and add it to the previous one.