Skip to content

Commit 64db0ba

Browse files
committed
* add ability to set the target polarization in the simulation;
separate settings are provided for the electron polarization and the nuclear polarization via new interactive commands /hdgeant4/targetNuclearPolarization <polx> <poly> <polz> and /hdgeant4/targetElectronPolarization <polx> <poly> <polz>. [rtj] * add ability to change the diamond crystal orientation during the simulation via new interactive G4 interface command /hdgeant4/diamondAngles <thetax> <thetay> <thetaz>. [rtj] * these new commands required that hooks be added in various places within the existing code for the getters and setters. [rtj]
1 parent 4a04336 commit 64db0ba

10 files changed

+2400
-9
lines changed

GlueXBeamConversionProcess.cc

Lines changed: 2172 additions & 0 deletions
Large diffs are not rendered by default.

src/CobremsGeneration.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ const double CobremsGeneration::me = 0.510998910e-3;
6262
const double CobremsGeneration::alpha = 7.2973525698e-3;
6363
const double CobremsGeneration::hbarc = 0.1973269718e-15;
6464

65+
std::map<CobremsGeneration*, int> CobremsGeneration::CobremsGenerators;
66+
6567
CobremsGeneration::CobremsGeneration(double Emax_GeV, double Epeak_GeV)
6668
{
6769
// Unique constructor for this class, initialize for the given
@@ -91,6 +93,8 @@ CobremsGeneration::CobremsGeneration(double Emax_GeV, double Epeak_GeV)
9193
<< " primary coherent edge: " << Epeak_GeV << " GeV"
9294
<< std::endl;
9395
#endif
96+
97+
CobremsGenerators[this] = 1;
9498
}
9599

96100
void CobremsGeneration::updateTargetOrientation()
@@ -468,7 +472,10 @@ CobremsGeneration &CobremsGeneration::operator=(const CobremsGeneration &src)
468472
return *this;
469473
}
470474

471-
CobremsGeneration::~CobremsGeneration() { }
475+
CobremsGeneration::~CobremsGeneration()
476+
{
477+
CobremsGenerators.erase(this);
478+
}
472479

473480
double CobremsGeneration::CoherentEnhancement(double x)
474481
{

src/CobremsGeneration.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <string>
2626
#include <vector>
27+
#include <map>
2728

2829
#if BOOST_PYTHON_WRAPPING
2930
#include <boost/python.hpp>
@@ -36,6 +37,8 @@ class CobremsGeneration {
3637
CobremsGeneration &operator=(const CobremsGeneration &src);
3738
~CobremsGeneration();
3839

40+
static std::map<CobremsGeneration*, int> CobremsGenerators;
41+
3942
void setBeamEnergy(double Ebeam_GeV);
4043
void setBeamErms(double Erms_GeV);
4144
void setBeamEmittance(double emit_m_r);
@@ -274,8 +277,8 @@ inline void CobremsGeneration::setTargetThetaz(double thetaz) {
274277
}
275278

276279
inline void CobremsGeneration::setTargetOrientation(double thetax,
277-
double thetay,
278-
double thetaz) {
280+
double thetay,
281+
double thetaz) {
279282
fTargetThetax = thetax;
280283
fTargetThetay = thetay;
281284
fTargetThetaz = thetaz;

src/GlueXBeamConversionProcess.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ GlueXBeamConversionProcess::GlueXBeamConversionProcess(const G4String &name,
134134
fAdaptiveSampler(0),
135135
isInitialised(false),
136136
fTargetZ(0),
137-
fTargetA(0)
137+
fTargetA(0),
138+
fTargetPol{{0,0,0},{0,0,0}}
138139
{
139140
verboseLevel = 0;
140141

@@ -1214,7 +1215,9 @@ void GlueXBeamConversionProcess::GenerateBetheHeitlerProcess(const G4Step &step)
12141215
pOut.AllPol();
12151216
nOut.AllPol();
12161217
const TThreeVectorReal zero3vector(0,0,0);
1217-
nIn.SetPol(TThreeVectorReal(zero3vector));
1218+
nIn.SetPol(TThreeVectorReal(fTargetPol.nucl[0],
1219+
fTargetPol.nucl[1],
1220+
fTargetPol.nucl[2]));
12181221
nIn.SetMom(TThreeVectorReal(zero3vector));
12191222
const G4Track *track = step.GetTrack();
12201223
LDouble_t kin = track->GetKineticEnergy()/GeV;
@@ -1706,7 +1709,9 @@ void GlueXBeamConversionProcess::GenerateTripletProcess(const G4Step &step)
17061709
pOut.AllPol();
17071710
eOut3.AllPol();
17081711
const TThreeVectorReal zero3vector(0,0,0);
1709-
eIn.SetPol(TThreeVectorReal(zero3vector));
1712+
eIn.SetPol(TThreeVectorReal(fTargetPol.elec[0],
1713+
fTargetPol.elec[1],
1714+
fTargetPol.elec[2]));
17101715
eIn.SetMom(TThreeVectorReal(zero3vector));
17111716
const G4Track *track = step.GetTrack();
17121717
LDouble_t kin = track->GetKineticEnergy()/GeV;

src/GlueXBeamConversionProcess.hh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ class GlueXBeamConversionProcess: public G4VEmProcess
8585
void prepareAdaptiveSampler();
8686

8787
void setConverterMaterial(double Z, double A);
88+
void getConverterMaterial(double &Z, double &A) const;
89+
90+
public:
91+
void setTargetPolarization(double nucl[3], double elec[3]);
92+
void getTargetPolarization(double nucl[3], double elec[3]) const;
8893

8994
private:
9095
GlueXBeamConversionProcess() = delete;
@@ -101,12 +106,44 @@ class GlueXBeamConversionProcess: public G4VEmProcess
101106

102107
double fTargetZ;
103108
double fTargetA;
109+
struct target_polarization_t {
110+
double nucl[3];
111+
double elec[3];
112+
} fTargetPol;
104113
};
105114

115+
inline void GlueXBeamConversionProcess::getConverterMaterial(double &Z, double &A) const
116+
{
117+
Z = fTargetZ;
118+
A = fTargetA;
119+
}
120+
106121
inline void GlueXBeamConversionProcess::setConverterMaterial(double Z, double A)
107122
{
108123
fTargetZ = Z;
109124
fTargetA = A;
110125
}
111126

127+
inline void GlueXBeamConversionProcess::getTargetPolarization(double nucl[3],
128+
double elec[3]) const
129+
{
130+
nucl[0] = fTargetPol.nucl[0];
131+
nucl[1] = fTargetPol.nucl[1];
132+
nucl[2] = fTargetPol.nucl[2];
133+
elec[0] = fTargetPol.elec[0];
134+
elec[1] = fTargetPol.elec[1];
135+
elec[2] = fTargetPol.elec[2];
136+
}
137+
138+
inline void GlueXBeamConversionProcess::setTargetPolarization(double nucl[3],
139+
double elec[3])
140+
{
141+
fTargetPol.nucl[0] = nucl[0];
142+
fTargetPol.nucl[1] = nucl[1];
143+
fTargetPol.nucl[2] = nucl[2];
144+
fTargetPol.elec[0] = elec[0];
145+
fTargetPol.elec[1] = elec[1];
146+
fTargetPol.elec[2] = elec[2];
147+
}
148+
112149
#endif

src/GlueXDetectorMessenger.cc

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
#include "G4UIcmdWithAString.hh"
1313
#include "G4UIcmdWithADoubleAndUnit.hh"
1414
#include "G4UIcmdWithoutParameter.hh"
15+
#include "G4UIcmdWith3Vector.hh"
1516
#include "G4GeometryManager.hh"
17+
#include "G4RunManager.hh"
18+
#include "GlueXPhysicsList.hh"
19+
#include "GlueXPrimaryGeneratorAction.hh"
20+
#include "GlueXBeamConversionProcess.hh"
1621

1722
GlueXDetectorMessenger::GlueXDetectorMessenger(GlueXDetectorConstruction* myDet)
1823
:myDetector(myDet)
@@ -32,7 +37,7 @@ GlueXDetectorMessenger::GlueXDetectorMessenger(GlueXDetectorConstruction* myDet)
3237

3338
StepMaxCmd = new G4UIcmdWithADoubleAndUnit("/hdgeant4/det/stepMax",this);
3439
StepMaxCmd->SetGuidance("Define a step max");
35-
StepMaxCmd->SetParameterName("stepMax",false);
40+
StepMaxCmd->SetParameterName("stepMax",true,true);
3641
StepMaxCmd->SetUnitCategory("Length");
3742
StepMaxCmd->AvailableForStates(G4State_Idle);
3843

@@ -45,6 +50,30 @@ GlueXDetectorMessenger::GlueXDetectorMessenger(GlueXDetectorConstruction* myDet)
4550
CloseGeomCmd = new G4UIcmdWithoutParameter("/hdgeant4/closeGeometry",this);
4651
CloseGeomCmd->SetGuidance("Explicitly close the geometry.");
4752
CloseGeomCmd->AvailableForStates(G4State_Idle);
53+
54+
RadiatorAnglesCmd = new G4UIcmdWith3Vector("/hdgeant4/diamondAngles",this);
55+
RadiatorAnglesCmd->SetGuidance("Control the diamond radiator orientation.");
56+
RadiatorAnglesCmd->SetGuidance("Arguments are theta_x, theta_y, theta_z");
57+
RadiatorAnglesCmd->SetGuidance(" in radians, applied in the order theta_x,");
58+
RadiatorAnglesCmd->SetGuidance(" followed by theta_y, followed by theta_z.");
59+
RadiatorAnglesCmd->SetParameterName("theta_x","theta_y","theta_z",true,true);
60+
RadiatorAnglesCmd->AvailableForStates(G4State_Idle);
61+
62+
TargetNuclPolCmd = new G4UIcmdWith3Vector("/hdgeant4/targetNuclearPolarization",this);
63+
TargetNuclPolCmd->SetGuidance("Control the primary target nuclear polarization.");
64+
TargetNuclPolCmd->SetGuidance("Arguments are pol_x, pol_y, pol_z");
65+
TargetNuclPolCmd->SetGuidance(" in fractions, normalized to a unit vector");
66+
TargetNuclPolCmd->SetGuidance(" for 100% polarization.");
67+
TargetNuclPolCmd->SetParameterName("pol_x","pol_y","pol_z",true,true);
68+
TargetNuclPolCmd->AvailableForStates(G4State_Idle);
69+
70+
TargetElecPolCmd = new G4UIcmdWith3Vector("/hdgeant4/targetElectronPolarization",this);
71+
TargetElecPolCmd->SetGuidance("Control the primary target electron polarization.");
72+
TargetElecPolCmd->SetGuidance("Arguments are pol_x, pol_y, pol_z");
73+
TargetElecPolCmd->SetGuidance(" in fractions, normalized to a unit vector");
74+
TargetElecPolCmd->SetGuidance(" for 100% polarization.");
75+
TargetElecPolCmd->SetParameterName("pol_x","pol_y","pol_z",true,true);
76+
TargetElecPolCmd->AvailableForStates(G4State_Idle);
4877
}
4978

5079
GlueXDetectorMessenger::~GlueXDetectorMessenger()
@@ -53,6 +82,10 @@ GlueXDetectorMessenger::~GlueXDetectorMessenger()
5382
delete StepMaxCmd;
5483
delete detDir;
5584
delete hdgeant4Dir;
85+
delete OpenGeomCmd;
86+
delete RadiatorAnglesCmd;
87+
delete TargetNuclPolCmd;
88+
delete TargetElecPolCmd;
5689
}
5790

5891
void GlueXDetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
@@ -62,11 +95,121 @@ void GlueXDetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
6295
}
6396
else if (command == StepMaxCmd) {
6497
myDetector->SetMaxStep(StepMaxCmd->GetNewDoubleValue(newValue));
98+
std::cout << "MaxStep is now " << StepMaxCmd->GetCurrentValue() << std::endl;
6599
}
66100
else if (command == OpenGeomCmd) {
67101
G4GeometryManager::GetInstance()->OpenGeometry();
68102
}
69103
else if (command == CloseGeomCmd) {
70104
G4GeometryManager::GetInstance()->CloseGeometry();
71105
}
106+
else if (command == RadiatorAnglesCmd) {
107+
G4ThreeVector angles(RadiatorAnglesCmd->GetNew3VectorValue(newValue));
108+
std::map<CobremsGeneration*, int>::iterator igen;
109+
int assigned(0);
110+
for (igen = CobremsGeneration::CobremsGenerators.begin();
111+
igen != CobremsGeneration::CobremsGenerators.end();
112+
igen++)
113+
{
114+
igen->first->setTargetOrientation(angles[0], angles[1], angles[2]);
115+
std::cout << "radiator angles are now "
116+
<< RadiatorAnglesCmd->GetCurrentValue() << std::endl;
117+
assigned += igen->second;
118+
}
119+
if (!assigned) {
120+
std::cerr << "CobremsGeneration has not been started yet, you must start"
121+
<< " up the photon beam generator before attempting to set"
122+
<< " the radiator orientation." << std::endl;
123+
}
124+
}
125+
else if (command == TargetNuclPolCmd) {
126+
G4ThreeVector polar(RadiatorAnglesCmd->GetNew3VectorValue(newValue));
127+
const GlueXPhysicsList *phy = dynamic_cast<const GlueXPhysicsList*>
128+
(G4RunManager::GetRunManager()->GetUserPhysicsList());
129+
GlueXBeamConversionProcess *con = (GlueXBeamConversionProcess*)
130+
phy->getBeamConversionProcess();
131+
if (con != 0 && polar.mag() <= 1) {
132+
double nucl[3];
133+
double elec[3];
134+
con->getTargetPolarization(nucl, elec);
135+
nucl[0] = polar[0];
136+
nucl[1] = polar[1];
137+
nucl[2] = polar[2];
138+
con->setTargetPolarization(nucl, elec);
139+
}
140+
else {
141+
std::cerr << "polarization vector normalization >1, assignment failed."
142+
<< std::endl;
143+
}
144+
std::cout << "target nuclear polarization vector is now "
145+
<< TargetNuclPolCmd->GetCurrentValue() << std::endl;
146+
}
147+
else if (command == TargetElecPolCmd) {
148+
G4ThreeVector polar(RadiatorAnglesCmd->GetNew3VectorValue(newValue));
149+
const GlueXPhysicsList *phy = dynamic_cast<const GlueXPhysicsList*>
150+
(G4RunManager::GetRunManager()->GetUserPhysicsList());
151+
GlueXBeamConversionProcess *con = (GlueXBeamConversionProcess*)
152+
phy->getBeamConversionProcess();
153+
if (con != 0 && polar.mag() <= 1) {
154+
double nucl[3];
155+
double elec[3];
156+
con->getTargetPolarization(nucl, elec);
157+
elec[0] = polar[0];
158+
elec[1] = polar[1];
159+
elec[2] = polar[2];
160+
con->setTargetPolarization(nucl, elec);
161+
}
162+
else {
163+
std::cerr << "polarization vector normalization >1, assignment failed."
164+
<< std::endl;
165+
}
166+
std::cout << "target electron polarization vector is now "
167+
<< TargetElecPolCmd->GetCurrentValue() << std::endl;
168+
}
169+
}
170+
171+
G4String GlueXDetectorMessenger::GetCurrentValue(G4UIcommand* command)
172+
{
173+
G4String cv;
174+
if (command == StepMaxCmd) {
175+
cv = StepMaxCmd->ConvertToString(myDetector->GetMaxStep(cm));
176+
}
177+
else if (command == RadiatorAnglesCmd) {
178+
G4ThreeVector angles;
179+
std::map<CobremsGeneration*, int>::iterator igen;
180+
for (igen = CobremsGeneration::CobremsGenerators.begin();
181+
igen != CobremsGeneration::CobremsGenerators.end();
182+
igen++)
183+
{
184+
angles[0] = igen->first->getTargetThetax();
185+
angles[1] = igen->first->getTargetThetay();
186+
angles[2] = igen->first->getTargetThetaz();
187+
cv = RadiatorAnglesCmd->ConvertToString(angles);
188+
}
189+
}
190+
else if (command == TargetNuclPolCmd) {
191+
const GlueXPhysicsList *phy = dynamic_cast<const GlueXPhysicsList*>
192+
(G4RunManager::GetRunManager()->GetUserPhysicsList());
193+
if (phy != 0) {
194+
GlueXBeamConversionProcess *con = (GlueXBeamConversionProcess*)
195+
phy->getBeamConversionProcess();
196+
double nucl[3];
197+
double elec[3];
198+
con->getTargetPolarization(nucl, elec);
199+
cv = TargetNuclPolCmd->ConvertToString(G4ThreeVector(nucl[0], nucl[1], nucl[2]));
200+
}
201+
}
202+
else if (command == TargetElecPolCmd) {
203+
const GlueXPhysicsList *phy = dynamic_cast<const GlueXPhysicsList*>
204+
(G4RunManager::GetRunManager()->GetUserPhysicsList());
205+
if (phy != 0) {
206+
GlueXBeamConversionProcess *con = (GlueXBeamConversionProcess*)
207+
phy->getBeamConversionProcess();
208+
double nucl[3];
209+
double elec[3];
210+
con->getTargetPolarization(nucl, elec);
211+
cv = TargetElecPolCmd->ConvertToString(G4ThreeVector(elec[0], elec[1], elec[2]));
212+
}
213+
}
214+
return cv;
72215
}

src/GlueXDetectorMessenger.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class G4UIdirectory;
1717
class G4UIcmdWithAString;
1818
class G4UIcmdWithADoubleAndUnit;
1919
class G4UIcmdWithoutParameter;
20+
class G4UIcmdWith3Vector;
2021

2122
class GlueXDetectorMessenger: public G4UImessenger
2223
{
@@ -27,6 +28,7 @@ class GlueXDetectorMessenger: public G4UImessenger
2728
~GlueXDetectorMessenger();
2829

2930
void SetNewValue(G4UIcommand*, G4String);
31+
G4String GetCurrentValue(G4UIcommand*);
3032

3133
private:
3234
GlueXDetectorConstruction* myDetector;
@@ -37,6 +39,9 @@ class GlueXDetectorMessenger: public G4UImessenger
3739
G4UIcmdWithADoubleAndUnit* StepMaxCmd;
3840
G4UIcmdWithoutParameter* OpenGeomCmd;
3941
G4UIcmdWithoutParameter* CloseGeomCmd;
42+
G4UIcmdWith3Vector* RadiatorAnglesCmd;
43+
G4UIcmdWith3Vector* TargetNuclPolCmd;
44+
G4UIcmdWith3Vector* TargetElecPolCmd;
4045
};
4146

4247
#endif

src/GlueXPhysicsList.hh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class GlueXPhysicsList: public G4VModularPhysicsList
5353
virtual void DoProcessReordering();
5454
virtual void CheckProcessOrdering();
5555

56+
G4VEmProcess *getBeamConversionProcess() const;
57+
G4VEmProcess *getBernardConversionProcess() const;
58+
G4OpticalPhysics *getOpticalPhysicsProcess() const;
59+
5660
protected:
5761
GlueXUserOptions *fOptions;
5862

@@ -72,4 +76,19 @@ class GlueXPhysicsList: public G4VModularPhysicsList
7276
#endif
7377
};
7478

79+
inline G4VEmProcess *GlueXPhysicsList::getBeamConversionProcess() const
80+
{
81+
return fBeamConversion;
82+
}
83+
84+
inline G4VEmProcess *GlueXPhysicsList::getBernardConversionProcess() const
85+
{
86+
return fBernardConversion;
87+
}
88+
89+
inline G4OpticalPhysics *GlueXPhysicsList::getOpticalPhysicsProcess() const
90+
{
91+
return fOpticalPhysics;
92+
}
93+
7594
#endif

src/GlueXPrimaryGeneratorAction.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ GlueXPrimaryGeneratorAction::~GlueXPrimaryGeneratorAction()
569569
}
570570
}
571571

572-
const CobremsGeneration *GlueXPrimaryGeneratorAction::GetCobremsGeneration() const
572+
const CobremsGeneration *GlueXPrimaryGeneratorAction::GetCobremsGeneration()
573573
{
574574
return fCobremsGeneration;
575575
}

0 commit comments

Comments
 (0)