4 // Author: I. Hrivnacova
6 // Class TG4VSpecialControls
7 // -------------------------
8 // See the class description in the header file.
10 #include "TG4SpecialControls.h"
11 #include "TG4GeometryServices.h"
12 #include "TG4Limits.h"
14 #include <G4StepStatus.hh>
15 #include <G4ProcessManager.hh>
16 #include <G4ProcessVector.hh>
18 //_____________________________________________________________________________
19 TG4SpecialControls::TG4SpecialControls(const G4String& processName)
20 : G4VProcess(processName),
21 TG4Verbose("specialControls"),
22 fSwitchControls(kUnswitch),
25 verboseLevel = VerboseLevel();
26 if (VerboseLevel() >0 ) {
27 G4cout << GetProcessName() << " is created "<< G4endl;
31 //_____________________________________________________________________________
32 TG4SpecialControls::TG4SpecialControls(const TG4SpecialControls& right)
33 : TG4Verbose("specialControls") {
35 TG4Globals::Exception(
36 "TG4SpecialControls is protected from copying.");
39 //_____________________________________________________________________________
40 TG4SpecialControls::~TG4SpecialControls() {
46 //_____________________________________________________________________________
47 TG4SpecialControls& TG4SpecialControls::operator=(
48 const TG4SpecialControls& right)
50 // check assignement to self
51 if (this == &right) return *this;
53 TG4Globals::Exception(
54 "TG4SpecialControls is protected from assigning.");
61 //_____________________________________________________________________________
62 void TG4SpecialControls::Reset()
64 // Resets the buffers to the initial state.
67 fSwitchControls = kUnswitch;
70 fSwitchedProcesses.clear();
71 fSwitchedControls.clear();
76 //_____________________________________________________________________________
77 G4double TG4SpecialControls::PostStepGetPhysicalInteractionLength(
78 const G4Track& track, G4double previousStepSize,
79 G4ForceCondition* condition)
81 // Returns the Step-size (actual length) which is allowed
85 *condition = NotForced;
87 if (track.GetTrackID() != fLastTrackID) {
90 fLastTrackID = track.GetTrackID();
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
98 // proposedStep = 0.; causes navigator to fall into panic
101 = track.GetStep()->GetPreStepPoint()->GetStepStatus();
106 = TG4GeometryServices::Instance()
107 ->GetLimits(track.GetVolume()->GetLogicalVolume()->GetUserLimits());
110 G4String text = "TG4VSpecialControls::PostStepGetPhysicalInteractionLength:\n";
111 text = text + " " + track.GetVolume()->GetLogicalVolume()->GetName();
112 text = text + " has not limits.";
113 TG4Globals::Exception(text);
117 = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
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;
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;
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;
154 //_____________________________________________________________________________
155 G4VParticleChange* TG4SpecialControls::PostStepDoIt(
156 const G4Track& track, const G4Step& step)
158 // Changes processes activation of the current track
159 // according to the current user limits.
162 G4ProcessManager* processManager
163 = track.GetDefinition()->GetProcessManager();
164 G4ProcessVector* processVector = processManager->GetProcessList();
166 if ((fSwitchControls==kUnswitch) || (fSwitchControls==kReswitch)) {
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()
176 ->SetProcessActivation(fSwitchedProcesses[i],fSwitchedControls[i]);
178 fSwitchedProcesses.clear();
179 fSwitchedControls.clear();
182 if ((fSwitchControls==kSwitch) || (fSwitchControls==kReswitch)) {
184 // set TG4Limits processes controls
186 = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
188 for (G4int i=0; i<processVector->length(); i++) {
190 TG4G3ControlValue control = limits->GetControl((*processVector)[i]);
191 G4bool activation = processManager->GetProcessActivation(i);
193 if (control != kUnset && ! TG4Globals::Compare(activation, control)) {
195 // store the current processes controls
196 if (VerboseLevel() > 1) {
197 G4cout << "Something goes to fSwitchedProcesses" << G4endl;
199 fSwitchedProcesses.insert((*processVector)[i]);
200 fSwitchedControls.push_back(activation);
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()
210 processManager->SetProcessActivation(i,false);
213 // ((control == kActivate) || (control == kActivate2))
214 if (VerboseLevel() > 1) {
215 G4cout << "Set process activation for "
216 << (*processVector)[i]->GetProcessName() << " in "
217 << track.GetVolume()->GetName()
220 processManager->SetProcessActivation(i,true);
226 // processManager->DumpInfo();
227 aParticleChange.Initialize(track);
228 aParticleChange.SetStatusChange(fAlive);
229 return &aParticleChange;