ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4PSFlatSurfaceFlux.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4PSFlatSurfaceFlux.cc
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 //
26 //
27 //
28 // G4PSFlatSurfaceFlux
29 #include "G4PSFlatSurfaceFlux.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"
40 // (Description)
41 // This is a primitive scorer class for scoring Surface Flux.
42 // Current version assumes only for G4Box shape, and the surface
43 // is fixed on -Z plane.
44 //
45 // Surface is defined at the -Z surface.
46 // Direction -Z +Z
47 // 0 IN || OUT ->|<- |
48 // 1 IN ->| |
49 // 2 OUT |<- |
50 //
51 // Created: 2005-11-14 Tsukasa ASO, Akinori Kimura.
52 //
53 // 18-Nov-2005 T.Aso, To use always positive value for anglefactor.
54 // 29-Mar-2007 T.Aso, Bug fix for momentum direction at outgoing flux.
55 // 2010-07-22 Introduce Unit specification.
56 // 2010-07-22 Add weighted and divideByAre options
58 
60  G4int direction, G4int depth)
61  : G4VPrimitiveScorer(name,depth),HCID(-1),fDirection(direction),EvtMap(0),
62  weighted(true),divideByArea(true)
63 {
65  SetUnit("percm2");
66 }
67 
69  G4int direction,
70  const G4String& unit,
71  G4int depth)
72  : G4VPrimitiveScorer(name,depth),HCID(-1),fDirection(direction),EvtMap(0),
73  weighted(true),divideByArea(true)
74 {
76  SetUnit(unit);
77 }
78 
80 {;}
81 
83 {
84  G4StepPoint* preStep = aStep->GetPreStepPoint();
85  G4VPhysicalVolume* physVol = preStep->GetPhysicalVolume();
86  G4VPVParameterisation* physParam = physVol->GetParameterisation();
87  G4VSolid * solid = 0;
88  if(physParam)
89  { // for parameterized volume
91  ->GetReplicaNumber(indexDepth);
92  solid = physParam->ComputeSolid(idx, physVol);
93  solid->ComputeDimensions(physParam,idx,physVol);
94  }
95  else
96  { // for ordinary volume
97  solid = physVol->GetLogicalVolume()->GetSolid();
98  }
99 
100  G4Box* boxSolid = (G4Box*)(solid);
101 
102  G4int dirFlag =IsSelectedSurface(aStep,boxSolid);
103  if ( dirFlag > 0 ) {
104  if ( fDirection == fFlux_InOut || fDirection == dirFlag ){
105 
106  G4StepPoint* thisStep=0;
107  if ( dirFlag == fFlux_In ){
108  thisStep = preStep;
109  }else if ( dirFlag == fFlux_Out ){
110  thisStep = aStep->GetPostStepPoint();
111  }else{
112  return FALSE;
113  }
114 
115  G4TouchableHandle theTouchable = thisStep->GetTouchableHandle();
116  G4ThreeVector pdirection = thisStep->GetMomentumDirection();
117  G4ThreeVector localdir =
118  theTouchable->GetHistory()->GetTopTransform().TransformAxis(pdirection);
119  //
120  G4double angleFactor = localdir.z();
121  if ( angleFactor < 0 ) angleFactor *= -1.;
122  G4double flux = 1.0;
123  if ( weighted ) flux *=preStep->GetWeight(); // Current (Particle Weight)
124  //
125  G4double square = 4.*boxSolid->GetXHalfLength()*boxSolid->GetYHalfLength();
126  //
127  flux = flux/angleFactor; // Flux with angle.
128  if ( divideByArea ) flux /= square;
129  //
130  G4int index = GetIndex(aStep);
131  EvtMap->add(index,flux);
132  }
133  }
134 #ifdef debug
135  G4cout << " PASSED vol "
136  << index << " trk "<<trkid<<" len " << fFlatSurfaceFlux<<G4endl;
137 #endif
138 
139  return TRUE;
140 }
141 
143 
144  G4TouchableHandle theTouchable =
147 
148  if (aStep->GetPreStepPoint()->GetStepStatus() == fGeomBoundary ){
149  // Entering Geometry
150  G4ThreeVector stppos1= aStep->GetPreStepPoint()->GetPosition();
151  G4ThreeVector localpos1 =
152  theTouchable->GetHistory()->GetTopTransform().TransformPoint(stppos1);
153  if(std::fabs( localpos1.z() + boxSolid->GetZHalfLength())<kCarTolerance ){
154  return fFlux_In;
155  }
156  }
157 
158  if (aStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary ){
159  // Exiting Geometry
160  G4ThreeVector stppos2= aStep->GetPostStepPoint()->GetPosition();
161  G4ThreeVector localpos2 =
162  theTouchable->GetHistory()->GetTopTransform().TransformPoint(stppos2);
163  if(std::fabs( localpos2.z() + boxSolid->GetZHalfLength())<kCarTolerance ){
164  return fFlux_Out;
165  }
166  }
167 
168  return -1;
169 }
170 
172 {
174  GetName());
175  if ( HCID < 0 ) HCID = GetCollectionID(0);
177 }
178 
180 {;}
181 
183  EvtMap->clear();
184 }
185 
187 {;}
188 
190 {
191  G4cout << " MultiFunctionalDet " << detector->GetName() << G4endl;
192  G4cout << " PrimitiveScorer" << GetName() <<G4endl;
193  G4cout << " Number of entries " << EvtMap->entries() << G4endl;
194  std::map<G4int,G4double*>::iterator itr = EvtMap->GetMap()->begin();
195  for(; itr != EvtMap->GetMap()->end(); itr++) {
196  G4cout << " copy no.: " << itr->first
197  << " flux : " << *(itr->second)/GetUnitValue()
198  << " [" << GetUnit() <<"]"
199  << G4endl;
200  }
201 }
202 
204 {
205  if ( divideByArea ) {
206  CheckAndSetUnit(unit,"Per Unit Surface");
207  } else {
208  if (unit == "" ){
209  unitName = unit;
210  unitValue = 1.0;
211  }else{
212  G4String msg = "Invalid unit ["+unit+"] (Current unit is [" +GetUnit()+"] ) for " + GetName();
213  G4Exception("G4PSFlatSurfaceFlux::SetUnit","DetPS0008",JustWarning,msg);
214  }
215  }
216 }
217 
219  // Per Unit Surface
220  new G4UnitDefinition("percentimeter2","percm2","Per Unit Surface",(1./cm2));
221  new G4UnitDefinition("permillimeter2","permm2","Per Unit Surface",(1./mm2));
222  new G4UnitDefinition("permeter2","perm2","Per Unit Surface",(1./m2));
223 }
224 
225