Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 // 28 // G4PSFlatSurfaceCurrent 29 #include "G4PSFlatSurfaceCurrent.hh" 30 31 #include "G4SystemOfUnits.hh" 32 #include "G4StepStatus.hh" 33 #include "G4Track.hh" 34 #include "G4VSolid.hh" 35 #include "G4VPhysicalVolume.hh" 36 #include "G4VPVParameterisation.hh" 37 #include "G4UnitsTable.hh" 38 #include "G4GeometryTolerance.hh" 39 #include "G4VScoreHistFiller.hh" 40 41 ////////////////////////////////////////////// 42 // (Description) 43 // This is a primitive scorer class for scor 44 // Current version assumes only for G4Box sha 45 // 46 // Surface is defined at the -Z surface. 47 // Direction -Z +Z 48 // 0 IN || OUT ->|<- | 49 // 1 IN ->| | 50 // 2 OUT |<- | 51 // 52 // Created: 2005-11-14 Tsukasa ASO, Akinori K 53 // 17-Nov-2005 T.Aso, Bug fix for area definit 54 // 31-Mar-2007 T.Aso, Add option for normalizi 55 // 2010-07-22 Introduce Unit specification. 56 // 2020-10-06 Use G4VPrimitivePlotter and fi 57 // vs. Surface Current * track w 58 // 59 ////////////////////////////////////////////// 60 61 G4PSFlatSurfaceCurrent::G4PSFlatSurfaceCurrent 62 63 : G4PSFlatSurfaceCurrent(name, direction, "p 64 {} 65 66 G4PSFlatSurfaceCurrent::G4PSFlatSurfaceCurrent 67 68 69 : G4VPrimitivePlotter(name, depth) 70 , HCID(-1) 71 , fDirection(direction) 72 , EvtMap(nullptr) 73 , weighted(true) 74 , divideByArea(true) 75 { 76 DefineUnitAndCategory(); 77 SetUnit(unit); 78 } 79 80 G4bool G4PSFlatSurfaceCurrent::ProcessHits(G4S 81 { 82 G4StepPoint* preStep = aStep->Ge 83 G4VPhysicalVolume* physVol = preStep-> 84 G4VPVParameterisation* physParam = physVol-> 85 G4VSolid* solid = nullptr; 86 if(physParam != nullptr) 87 { // for parameterized volume 88 G4int idx = 89 ((G4TouchableHistory*) (aStep->GetPreSte 90 ->GetReplicaNumber(indexDepth); 91 solid = physParam->ComputeSolid(idx, physV 92 solid->ComputeDimensions(physParam, idx, p 93 } 94 else 95 { // for ordinary volume 96 solid = physVol->GetLogicalVolume()->GetSo 97 } 98 99 auto boxSolid = (G4Box*) (solid); 100 101 G4int dirFlag = IsSelectedSurface(aStep, box 102 if(dirFlag > 0) 103 { 104 if(fDirection == fCurrent_InOut || fDirect 105 { 106 G4int index = GetInde 107 G4TouchableHandle theTouchable = preStep 108 G4double current = 1.0; 109 if(weighted) 110 current = preStep->GetWeight(); // Cu 111 if(divideByArea) 112 { 113 G4double square = 114 4. * boxSolid->GetXHalfLength() * bo 115 current = current / square; // Normal 116 } 117 EvtMap->add(index, current); 118 119 if(!hitIDMap.empty() && hitIDMap.find(in 120 { 121 auto filler = G4VScoreHistFiller::Inst 122 if(filler == nullptr) 123 { 124 G4Exception("G4PSFlatSurfaceCurrent: 125 JustWarning, 126 "G4TScoreHistFiller is n 127 "not filled."); 128 } 129 else 130 { 131 filler->FillH1(hitIDMap[index], preS 132 } 133 } 134 } 135 } 136 137 return true; 138 } 139 140 G4int G4PSFlatSurfaceCurrent::IsSelectedSurfac 141 { 142 G4TouchableHandle theTouchable = 143 aStep->GetPreStepPoint()->GetTouchableHand 144 G4double kCarTolerance = 145 G4GeometryTolerance::GetInstance()->GetSur 146 147 if(aStep->GetPreStepPoint()->GetStepStatus() 148 { 149 // Entering Geometry 150 G4ThreeVector stppos1 = aStep->GetPreStepP 151 G4ThreeVector localpos1 = 152 theTouchable->GetHistory()->GetTopTransf 153 if(std::fabs(localpos1.z() + boxSolid->Get 154 { 155 return fCurrent_In; 156 } 157 } 158 159 if(aStep->GetPostStepPoint()->GetStepStatus( 160 { 161 // Exiting Geometry 162 G4ThreeVector stppos2 = aStep->GetPostStep 163 G4ThreeVector localpos2 = 164 theTouchable->GetHistory()->GetTopTransf 165 if(std::fabs(localpos2.z() + boxSolid->Get 166 { 167 return fCurrent_Out; 168 } 169 } 170 171 return -1; 172 } 173 174 void G4PSFlatSurfaceCurrent::Initialize(G4HCof 175 { 176 EvtMap = new G4THitsMap<G4double>(detector-> 177 if(HCID < 0) 178 HCID = GetCollectionID(0); 179 HCE->AddHitsCollection(HCID, (G4VHitsCollect 180 } 181 182 void G4PSFlatSurfaceCurrent::clear() { EvtMap- 183 184 void G4PSFlatSurfaceCurrent::PrintAll() 185 { 186 G4cout << " MultiFunctionalDet " << detecto 187 G4cout << " PrimitiveScorer " << GetName() < 188 G4cout << " Number of entries " << EvtMap->e 189 for(const auto& [copy, current] : *(EvtMap-> 190 { 191 G4cout << " copy no.: " << copy << " curr 192 if(divideByArea) 193 { 194 G4cout << *(current) / GetUnitValue() << 195 } 196 else 197 { 198 G4cout << *(current) / GetUnitValue() << 199 } 200 G4cout << G4endl; 201 } 202 } 203 204 void G4PSFlatSurfaceCurrent::SetUnit(const G4S 205 { 206 if(divideByArea) 207 { 208 CheckAndSetUnit(unit, "Per Unit Surface"); 209 } 210 else 211 { 212 if(unit.empty()) 213 { 214 unitName = unit; 215 unitValue = 1.0; 216 } 217 else 218 { 219 G4String msg = "Invalid unit [" + unit + 220 GetUnit() + "] ) for " + 221 G4Exception("G4PSFlatSurfaceCurrent::Set 222 msg); 223 } 224 } 225 } 226 227 void G4PSFlatSurfaceCurrent::DefineUnitAndCate 228 { 229 // Per Unit Surface 230 new G4UnitDefinition("percentimeter2", "perc 231 (1. / cm2)); 232 new G4UnitDefinition("permillimeter2", "perm 233 (1. / mm2)); 234 new G4UnitDefinition("permeter2", "perm2", " 235 } 236