Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ElectronRun.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
28 //
29 
30 #include "ElectronRun.hh"
32 #include "G4SDManager.hh"
33 #include "G4VPrimitiveScorer.hh"
34 #include "G4SystemOfUnits.hh"
35 #include <assert.h>
36 
37 ElectronRun::ElectronRun(const G4String& detectorName)
38 {
39  // Get the sensitive detector manager
41 
42  // Get the sensitive detector
43  G4MultiFunctionalDetector* detector =
44  dynamic_cast<G4MultiFunctionalDetector*>(manager->FindSensitiveDetector(detectorName));
45 
46  // Abort if detector doesn't exist
47  assert (0 != detector);
48 
49  G4int i(0);
50 
51  // Loop over primitive scorers registered with the detector
52  for (i=0; i<detector->GetNumberOfPrimitives(); i++) {
53 
54  // Get scorer
55  G4VPrimitiveScorer* scorer = detector->GetPrimitive(i);
56 
57  // Need to form the full collection name = detector name + "/"+ scorer name
58  // to get the collection id number
59  G4String fullCollectionName = detectorName+"/"+scorer->GetName();
60 
61  G4int id = manager->GetCollectionID(fullCollectionName);
62 
63  // Abort if the collection was not added to the sensitive detector manager
64  // when the scorer was registered with G4MultiFunctionalDetector
65  assert (id >= 0);
66 
67  fMap[id] = new G4THitsMap<G4double>(detectorName, scorer->GetName());
68  }
69 }
70 
72 {
73  // Important to clean up the map
74  std::map<G4int, G4THitsMap<G4double>* >::iterator iter = fMap.begin();
75 
76  while (iter != fMap.end()) {
77  delete iter->second;
78  iter++;
79  }
80 }
81 
82 void ElectronRun::RecordEvent(const G4Event* anEvent)
83 {
84  numberOfEvent++;
85 
86  // Get the hits collection
87  G4HCofThisEvent* eventHitCollection = anEvent->GetHCofThisEvent();
88 
89  if (!eventHitCollection) return;
90 
91  // Update our private fMap
92  std::map< G4int, G4THitsMap<G4double>* >::iterator iter = fMap.begin();
93 
94  while (iter != fMap.end()) {
95  G4int id = iter->first;
96 
97  // Get the hit collection corresponding to "id"
98  G4THitsMap<G4double>* eventHitsMap
99  = dynamic_cast< G4THitsMap<G4double>* >(eventHitCollection->GetHC(id));
100 
101  // Expect this to exist
102  assert (0 != eventHitsMap);
103 
104  // Accumulate event data into our G4THitsMap<G4double> map
105  *(iter->second) += *eventHitsMap;
106 
107  iter++;
108  }
109 }
110 
111 void ElectronRun::DumpData(G4String &outputFileSpec) const
112 {
113  // Titles
114  std::vector<G4String> title;
115  title.push_back("Radius");
116 
117  // Output map - energy binning on x axis, theta on y
118  std::map< G4int, std::vector<G4double> > output;
119 
120  G4int nThetaBins = 233;
121 
122  // Energy bins depends on the number of scorers
123  G4int nEnergyBins = fMap.size();
124 
125  G4int i(0), j(0);
126 
127  // Initialise current to 0 in all bins
128  for (i=0; i<nThetaBins; i++) {
129  for (j=0; j<nEnergyBins; j++) {
130  output[i].push_back(0);
131  }
132  }
133 
134  i=0;
135 
136  // Fill the output map
137  std::map< G4int, G4THitsMap<G4double>* >::const_iterator iter = fMap.begin();
138 
139  while (iter != fMap.end()) {
140  G4THitsMap<G4double>* hitMap = iter->second;
141 
142  title.push_back(hitMap->GetName());
143 
144  std::map<G4int,G4double*>* myMap = hitMap->GetMap();
145 
146  for (j=0; j<nThetaBins; j++) {
147  G4double* current = (*myMap)[j];
148  if (0 != current) output[j][i] = (*current);
149  }
150 
151  i++;
152  iter++;
153  }
154 
155  Print(title, output, outputFileSpec);
156 }
157 
158 void ElectronRun::Print(const std::vector<G4String>& title,
159  const std::map< G4int, std::vector<G4double> >&myMap,
160  G4String &outputFileSpec) const
161 {
162  // Print to G4cout and an output file
163  std::ofstream outFile(outputFileSpec);
164 
165  // Print title vector
166  std::vector<G4String>::const_iterator titleIter = title.begin();
167 
168  while (titleIter != title.end()) {
169  G4cout << std::setw(8)<<*titleIter<<" ";
170  titleIter++;
171  }
172 
173  G4cout<<G4endl;
174 
175  // Print current data
176  std::map< G4int, std::vector<G4double> >::const_iterator iter = myMap.begin();
177 
178  while (iter != myMap.end()) {
179  G4cout << std::setw(8)<<std::setprecision(3)<< iter->first<<" ";
180 
181  std::vector<G4double>::const_iterator energyBinIter = iter->second.begin();
182 
183  // The built-in scorers do not automatically account for the area of the cylinder replica rings.
184  // We must account for this now by multiplying our result by the ratio of the area of the full cylinder end
185  // over the area of the actual scoring ring.
186  // In this ratio, PI divides out, as does the width of the scoring rings.
187  // Left with just the number of rings squared divided by the ring index plus 1 squared minus ring index squared.
188  G4int ringNum = iter->first;
189  G4double areaCorrection = 233.*233. / ( (ringNum+1)*(ringNum+1) - ringNum*ringNum );
190  G4int counter = 0;
191 
192  while (energyBinIter != iter->second.end()) {
193  G4double value = *energyBinIter;
194  if (counter < 2) value = value*areaCorrection;
195  G4cout << std::setw(10)<<std::setprecision(5)<< value*mm*mm<<" ";
196  outFile << value*mm*mm;
197  if (counter < 3) outFile <<",";
198  counter++;
199  energyBinIter++;
200  }
201  outFile<<G4endl;
202  G4cout<<G4endl;
203  iter++;
204  }
205 }