]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TGeant4/TG4SpecialControls.cxx
Changes by Massimo Masera to allow Recpoints and Clusters to be written
[u/mrichter/AliRoot.git] / TGeant4 / TG4SpecialControls.cxx
... / ...
CommitLineData
1// $Id$ //
2// Category: physics
3//
4// Author: I. Hrivnacova
5//
6// Class TG4VSpecialControls
7// -------------------------
8// See the class description in the header file.
9
10#include "TG4SpecialControls.h"
11#include "TG4GeometryServices.h"
12#include "TG4Limits.h"
13
14#include <G4StepStatus.hh>
15#include <G4ProcessManager.hh>
16#include <G4ProcessVector.hh>
17
18//_____________________________________________________________________________
19TG4SpecialControls::TG4SpecialControls(const G4String& processName)
20 : G4VProcess(processName),
21 TG4Verbose("specialControls"),
22 fSwitchControls(kUnswitch),
23 fLastTrackID(0) {
24//
25 verboseLevel = VerboseLevel();
26 if (VerboseLevel() >0 ) {
27 G4cout << GetProcessName() << " is created "<< G4endl;
28 }
29}
30
31//_____________________________________________________________________________
32TG4SpecialControls::TG4SpecialControls(const TG4SpecialControls& right)
33 : TG4Verbose("specialControls") {
34//
35 TG4Globals::Exception(
36 "TG4SpecialControls is protected from copying.");
37}
38
39//_____________________________________________________________________________
40TG4SpecialControls::~TG4SpecialControls() {
41//
42}
43
44// operators
45
46//_____________________________________________________________________________
47TG4SpecialControls& TG4SpecialControls::operator=(
48 const TG4SpecialControls& right)
49{
50 // check assignement to self
51 if (this == &right) return *this;
52
53 TG4Globals::Exception(
54 "TG4SpecialControls is protected from assigning.");
55
56 return *this;
57}
58
59// private methods
60
61//_____________________________________________________________________________
62void TG4SpecialControls::Reset()
63{
64// Resets the buffers to the initial state.
65// ---
66
67 fSwitchControls = kUnswitch;
68
69 // clear buffers
70 fSwitchedProcesses.clear();
71 fSwitchedControls.clear();
72}
73
74// public methods
75
76//_____________________________________________________________________________
77G4double TG4SpecialControls::PostStepGetPhysicalInteractionLength(
78 const G4Track& track, G4double previousStepSize,
79 G4ForceCondition* condition)
80{
81// Returns the Step-size (actual length) which is allowed
82// by this process.
83// ---
84
85 *condition = NotForced;
86
87 if (track.GetTrackID() != fLastTrackID) {
88 // new track
89 Reset();
90 fLastTrackID = track.GetTrackID();
91 }
92
93 G4double proposedStep = DBL_MAX;
94 //G4double minStep = (1.0e-9)*m;
95 G4double minStep = 0.;
96 // must be greater than DBL_MIN - so that particle can get out of
97 // the boundary
98 // proposedStep = 0.; causes navigator to fall into panic
99
100 G4StepStatus status
101 = track.GetStep()->GetPreStepPoint()->GetStepStatus();
102
103 // get limits
104#ifdef TGEANT4_DEBUG
105 TG4Limits* limits
106 = TG4GeometryServices::Instance()
107 ->GetLimits(track.GetVolume()->GetLogicalVolume()->GetUserLimits());
108
109 if (!limits) {
110 G4String text = "TG4VSpecialControls::PostStepGetPhysicalInteractionLength:\n";
111 text = text + " " + track.GetVolume()->GetLogicalVolume()->GetName();
112 text = text + " has not limits.";
113 TG4Globals::Exception(text);
114 }
115#else
116 TG4Limits* limits
117 = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
118#endif
119
120 if (fSwitchControls != kUnswitch) {
121 if (status == fGeomBoundary) {
122 if (limits->IsControl()) {
123 // particle is exiting a logical volume with special controls
124 // and entering another logical volume with special controls
125 proposedStep = minStep;
126 fSwitchControls = kReswitch;
127 if (VerboseLevel() > 1) {
128 G4cout << "kReswitch" << G4endl;
129 }
130 }
131 else {
132 // particle is exiting a logical volume with special controls
133 // and entering a logical volume without special controls
134 proposedStep = minStep;
135 fSwitchControls = kUnswitch;
136 if (VerboseLevel() > 1) {
137 G4cout << "kUnswitch" << G4endl;
138 }
139 }
140 }
141 }
142 else if (limits->IsControl()) {
143 // particle is entering a logical volume with special controls
144 // that have not yet been set
145 proposedStep = minStep;
146 fSwitchControls = kSwitch;
147 if (VerboseLevel() > 1) {
148 G4cout << "kSwitch" << G4endl;
149 }
150 }
151 return proposedStep;
152}
153
154//_____________________________________________________________________________
155G4VParticleChange* TG4SpecialControls::PostStepDoIt(
156 const G4Track& track, const G4Step& step)
157{
158// Changes processes activation of the current track
159// according to the current user limits.
160// ---
161
162 G4ProcessManager* processManager
163 = track.GetDefinition()->GetProcessManager();
164 G4ProcessVector* processVector = processManager->GetProcessList();
165
166 if ((fSwitchControls==kUnswitch) || (fSwitchControls==kReswitch)) {
167
168 // set processes activation back
169 for (G4int i=0; i<fSwitchedProcesses.length(); i++) {
170 if (VerboseLevel() > 1) {
171 G4cout << "Reset process activation back in "
172 << track.GetVolume()->GetName()
173 << G4endl;
174 }
175 processManager
176 ->SetProcessActivation(fSwitchedProcesses[i],fSwitchedControls[i]);
177 }
178 fSwitchedProcesses.clear();
179 fSwitchedControls.clear();
180 }
181
182 if ((fSwitchControls==kSwitch) || (fSwitchControls==kReswitch)) {
183
184 // set TG4Limits processes controls
185 TG4Limits* limits
186 = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
187
188 for (G4int i=0; i<processVector->length(); i++) {
189
190 TG4G3ControlValue control = limits->GetControl((*processVector)[i]);
191 G4bool activation = processManager->GetProcessActivation(i);
192
193 if (control != kUnset && ! TG4Globals::Compare(activation, control)) {
194
195 // store the current processes controls
196 if (VerboseLevel() > 1) {
197 G4cout << "Something goes to fSwitchedProcesses" << G4endl;
198 }
199 fSwitchedProcesses.insert((*processVector)[i]);
200 fSwitchedControls.push_back(activation);
201
202 // set new process activation
203 if (control == kInActivate) {
204 if (VerboseLevel() > 1) {
205 G4cout << "Set process inactivation for "
206 << (*processVector)[i]->GetProcessName() << " in "
207 << track.GetVolume()->GetName()
208 << G4endl;
209 }
210 processManager->SetProcessActivation(i,false);
211 }
212 else {
213 // ((control == kActivate) || (control == kActivate2))
214 if (VerboseLevel() > 1) {
215 G4cout << "Set process activation for "
216 << (*processVector)[i]->GetProcessName() << " in "
217 << track.GetVolume()->GetName()
218 << G4endl;
219 }
220 processManager->SetProcessActivation(i,true);
221 }
222 }
223 }
224 }
225
226 // processManager->DumpInfo();
227 aParticleChange.Initialize(track);
228 aParticleChange.SetStatusChange(fAlive);
229 return &aParticleChange;
230}
231