18#include "BDSAcceleratorModel.hh"
19#include "BDSCollimatorJaw.hh"
20#include "BDSBeamPipeInfo.hh"
21#include "BDSColours.hh"
23#include "BDSException.hh"
24#include "BDSMaterials.hh"
25#include "BDSSDType.hh"
26#include "BDSUtilities.hh"
30#include "G4GenericTrap.hh"
31#include "G4LogicalVolume.hh"
32#include "G4PVPlacement.hh"
33#include "G4VisAttributes.hh"
41 G4double horizontalWidthIn,
43 G4double yHalfHeightIn,
45 G4double xSizeRightIn,
46 G4double leftJawTiltIn,
47 G4double rightJawTiltIn,
48 G4bool buildLeftJawIn,
49 G4bool buildRightJawIn,
50 G4Material* collimatorMaterialIn,
51 G4Material* vacuumMaterialIn,
53 const G4String& objectType):
54BDSCollimator(nameIn, lengthIn, horizontalWidthIn, objectType, collimatorMaterialIn, vacuumMaterialIn,
55 xHalfGapIn, yHalfHeightIn, xHalfGapIn, yHalfHeightIn, colourIn),
56 xSizeLeft(xSizeLeftIn),
57 xSizeRight(xSizeRightIn),
59 jawTiltLeft(leftJawTiltIn),
60 jawTiltRight(rightJawTiltIn),
61 yHalfHeight(yHalfHeightIn),
62 buildLeftJaw(buildLeftJawIn),
63 buildRightJaw(buildRightJawIn),
73 {buildAperture =
false;}
78 if (std::abs(xSizeLeft) > 0.5*horizontalWidth)
80 G4cerr << __METHOD_NAME__ <<
"jcol \"" << name
81 <<
"\" left jaw offset is greater the element half width, jaw "
82 <<
"will not be constructed" << G4endl;
85 if (std::abs(xSizeRight) > 0.5*horizontalWidth)
87 G4cerr << __METHOD_NAME__ <<
"jcol \"" << name
88 <<
"\" right jaw offset is greater the element half width, jaw "
89 <<
"will not be constructed" << G4endl;
90 buildRightJaw =
false;
95 {yHalfHeight = 0.5*horizontalWidth;}
100BDSCollimatorJaw::~BDSCollimatorJaw()
119 vacuumWidth = 0.5 * (leftJawHalfGap + rightJawHalfGap);
122 G4double leftJawCentre = 0.5*leftJawWidth + leftJawHalfGap;
123 G4double rightJawCentre = 0.5*rightJawWidth + rightJawHalfGap;
124 G4double vacuumCentre = 0.5*(leftJawHalfGap - rightJawHalfGap);
126 leftJawPos = G4ThreeVector(leftJawCentre, 0, 0);
127 rightJawPos = G4ThreeVector(-rightJawCentre, 0, 0);
128 vacuumOffset = G4ThreeVector(vacuumCentre, 0, 0);
134 G4double totalGap = leftJawHalfGap + rightJawHalfGap;
136 {
throw BDSException(__METHOD_NAME__,
"gap too small (<1um) for \"" +
name +
"\"");}
139 {
throw BDSException(__METHOD_NAME__,
"horizontalWidth too small for the total gap width in \"" +
name +
"\"");}
142 {
throw BDSException(__METHOD_NAME__,
"insufficient ysize for \"" +
name +
"\"");}
145 {
throw BDSException(__METHOD_NAME__,
"no jaws being built for \"" +
name +
"\"");}
154 {
throw BDSException(__METHOD_NAME__,
"left jaw too thin given horizontalWidth and aperture for \"" +
name +
"\"");}
156 {
throw BDSException(__METHOD_NAME__,
"right jaw too thin given horizontalWidth and aperture for \"" +
name +
"\"");}
159 {
throw BDSException(__METHOD_NAME__,
"|jawTiltLeft| is over pi/4 radians for \"" +
name +
"\"");}
161 {
throw BDSException(__METHOD_NAME__,
"|jawTiltRight| is over pi/4 radians for \"" +
name +
"\"");}
168 G4double gapIn = totalGap - tiltShiftLeft + tiltShiftRight;
169 G4double gapOut = totalGap + tiltShiftLeft - tiltShiftRight;
170 if (gapIn <= 0 || gapOut <= 0)
171 {
throw BDSException(__METHOD_NAME__,
"the tilts plus centre gap will cause the jaws to collide in \"" +
name +
"\"");}
174 if (std::min(gapIn, gapOut) * 0.5 -
lengthSafety < 1e-3)
175 {
throw BDSException(__METHOD_NAME__,
"insufficient aperture between jaws in \"" +
name +
"\"");}
190 containerSolid =
new G4Box(
name +
"_container_solid",
195 containerLogicalVolume =
new G4LogicalVolume(containerSolid,
197 name +
"_container_lv");
207 G4VisAttributes* collimatorVisAttr =
new G4VisAttributes(*
colour);
216 G4VSolid* leftJawSolid =
nullptr;
224 leftJawSolid =
new G4Para(
name +
"_leftjaw_solid",
232 leftJawSolid =
new G4Box(
name +
"_leftjaw_solid",
240 G4LogicalVolume* leftJawLV =
new G4LogicalVolume(leftJawSolid,
242 name +
"_leftjaw_lv");
243 leftJawLV->SetVisAttributes(collimatorVisAttr);
246 leftJawLV->SetUserLimits(collUserLimits);
251 BDSAcceleratorModel::Instance()->
VolumeSet(
"collimators")->insert(leftJawLV);
256 G4PVPlacement* leftJawPV =
new G4PVPlacement(
nullptr,
259 name +
"_leftjaw_pv",
260 containerLogicalVolume,
268 G4VSolid* rightJawSolid =
nullptr;
277 rightJawSolid =
new G4Para(
name +
"_rightjaw_solid",
285 rightJawSolid =
new G4Box(
name +
"_rightjaw_solid",
293 G4LogicalVolume* rightJawLV =
new G4LogicalVolume(rightJawSolid,
295 name +
"_rightjaw_lv");
296 rightJawLV->SetVisAttributes(collimatorVisAttr);
297 rightJawLV->SetUserLimits(collUserLimits);
299 BDSAcceleratorModel::Instance()->
VolumeSet(
"collimators")->insert(rightJawLV);
304 G4PVPlacement* rightJawPV =
new G4PVPlacement(
nullptr,
307 name +
"_rightjaw_pv",
308 containerLogicalVolume,
332 G4PVPlacement* collimatorPV =
new G4PVPlacement(
nullptr,
336 containerLogicalVolume,
352 G4double tiltShiftLeftDownstream = std::tan(tiltLeft) *
chordLength * 0.5;
353 G4double tiltShiftRightDownstream = std::tan(tiltRight) *
chordLength * 0.5;
355 G4double xGapLeftUpstream = leftJawHalfGap - tiltShiftLeftDownstream;
356 G4double xGapLeftDownstream = leftJawHalfGap + tiltShiftLeftDownstream;
357 G4double xGapRightUpstream = -rightJawHalfGap - tiltShiftRightDownstream;
358 G4double xGapRightDownstream = -rightJawHalfGap + tiltShiftRightDownstream;
374 vacuumOffset = G4ThreeVector(0, 0, 0);
386 G4LogicalVolume* vacuumLV =
new G4LogicalVolume(
vacuumSolid,
388 name +
"_vacuum_lv");
397 G4PVPlacement* vacPV =
new G4PVPlacement(
nullptr,
401 containerLogicalVolume,
G4UserLimits * userLimits
Cache of user limits.
void SetAcceleratorVacuumLogicalVolume(G4LogicalVolume *accVacLVIn)
const G4String name
Const protected member variable that may not be changed by derived classes.
static G4bool sensitiveOuter
Useful variable often used in construction.
static G4double lengthSafety
Useful variable often used in construction.
static G4bool checkOverlaps
Useful variable often used in construction.
static G4double lengthSafetyLarge
G4double chordLength
Protected member variable that can be modified by derived classes.
static G4VisAttributes * containerVisAttr
Useful variable often used in construction.
static G4bool sensitiveVacuum
Useful variable often used in construction.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
G4bool buildAperture
Build aperture or not.
virtual void Build() override
Override function in BDSCollimator for totally different construction.
G4double xSizeRight
Offset of jaw 2.
virtual void BuildContainerLogicalVolume() override
Override function in BDSCollimator for different size based container.
G4double xSizeLeft
Offset of jaw 1.
G4double jawTiltLeft
Tilt of jaw 1 (angle in x-z plane)
G4double jawTiltRight
Tilt of jaw 2 (angle in x-z plane)
void Calculations()
Calculate offsets and sizes.
G4double yHalfHeight
Half height of each jaw.
G4bool buildRightJaw
Build right jaw or not.
virtual void CheckParameters() override
G4double xHalfGap
Half gap separation between jaws.
G4bool buildLeftJaw
Build left jaw or not.
BDSCollimatorJaw()=delete
Private default constructor to force the use of the supplied one.
G4LogicalVolume * collimatorLV
In case of no aperture, cache this volume for derived classes to place inside.
Base class for collimators with common construction.
G4UserLimits * CollimatorUserLimits()
Return either default user limits or custom ones based on optional minimumKineticEnergy.
G4Material * vacuumMaterial
Vacuum material.
G4double horizontalWidth
Horizontal width.
G4VSolid * vacuumSolid
Geometrical objects:
G4Material * collimatorMaterial
Material.
G4VSolid * collimatorSolid
Geometrical objects:
G4Colour * colour
Colour of collimator.
G4Colour * GetColour(G4double red, G4double green, G4double blue, G4double alpha=1)
Get a cached anonymous colour by values.
static BDSColours * Instance()
singleton pattern
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
void SetExtent(const BDSExtent &extIn)
Set extent.
void RegisterVisAttributes(G4VisAttributes *visAttribute)
void RegisterSolid(G4VSolid *solid)
void RegisterSensitiveVolume(G4LogicalVolume *sensitiveVolume, BDSSDType sensitivityType)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())