19#include "BDSBeamline.hh"
20#include "BDSBeamlineElement.hh"
21#include "BDSBeamlineBLMBuilder.hh"
23#include "BDSBLMFactory.hh"
24#include "BDSBLMRegistry.hh"
26#include "BDSDetectorConstruction.hh"
27#include "BDSException.hh"
28#include "BDSExtent.hh"
29#include "BDSGeometryFactory.hh"
30#include "BDSParser.hh"
31#include "BDSScorerFactory.hh"
32#include "BDSScorerInfo.hh"
33#include "BDSSDManager.hh"
34#include "BDSSimpleComponent.hh"
35#include "BDSUtilities.hh"
37#include "parser/blmplacement.h"
38#include "parser/scorer.h"
40#include "CLHEP/Units/SystemOfUnits.h"
43#include "G4MultiFunctionalDetector.hh"
44#include "G4RotationMatrix.hh"
45#include "G4SDManager.hh"
46#include "G4ThreeVector.hh"
47#include "G4Transform3D.hh"
48#include "G4VSensitiveDetector.hh"
60 if (blmPlacements.empty())
66 for (
const auto& bp : blmPlacements)
68 if (!bp.geometryFile.empty())
77 std::map<G4String, BDSScorerInfo> scorerRecipes;
78 for (
const auto& scorer : scorers)
81 scorerRecipes.insert(std::make_pair(si.
name, si));
84 std::set<std::set<G4String> > scorerSetsToMake;
86 std::map<std::string, std::pair<std::set<G4String>, G4String> >blmScoringInfo;
87 for (
const auto& bp : blmPlacements)
90 std::set<G4String> requiredScorers;
91 for (
const auto& name : scorersForThisBLM)
93 auto search = scorerRecipes.find(name);
94 if (search == scorerRecipes.end())
95 {
throw BDSException(__METHOD_NAME__,
"scorerQuantity \"" + name +
"\" for blm \"" + bp.name +
"\" not found.");}
97 {requiredScorers.insert(name);}
100 if (requiredScorers.empty())
101 {G4cout <<
"Warning - no scoreQuantity specified for blm \"" << bp.name <<
"\" - it will only be passive material" << G4endl;}
102 scorerSetsToMake.insert(requiredScorers);
106 G4String combinedName =
"";
107 for (
const auto& n : requiredScorers)
109 blmScoringInfo[bp.name] = std::make_pair(requiredScorers, combinedName);
112 G4cout <<
"Unqiue combinations of scorers: " << scorerSetsToMake.size() << G4endl;
114 if (scorerSetsToMake.empty())
115 {G4cout <<
"Warning - all BLMs have no scoreQuantity specified so are only passive material." << G4endl;}
119 std::map<G4String, G4MultiFunctionalDetector*> sensitiveDetectors;
120 std::vector<G4String> uniquePrimitiveScorerNames;
121 std::vector<G4double> scorerUnits;
122 G4SDManager* SDMan = G4SDManager::GetSDMpointer();
123 for (
const auto& ssAndCombinedName : blmScoringInfo)
125 G4String combinedName = ssAndCombinedName.second.second;
127 G4cout << __METHOD_NAME__ <<
"Making unique SD " << combinedName << G4endl;
130 if (sensitiveDetectors.count(combinedName) > 0)
133 G4MultiFunctionalDetector* sd =
new G4MultiFunctionalDetector(
"blm_"+combinedName);
134 for (
const auto& name : ssAndCombinedName.second.first)
136 const auto& recipe = scorerRecipes.at(name);
138 G4VPrimitiveScorer* ps = scorerFactory.
CreateScorer(&recipe,
nullptr, &unit);
139 sd->RegisterPrimitive(ps);
143 uniquePrimitiveScorerNames.emplace_back(
"blm_"+combinedName+
"/"+name);
144 scorerUnits.push_back(unit);
146 sensitiveDetectors[combinedName] = sd;
147 SDMan->AddNewDetector(sd);
154 for (
const auto& bp : blmPlacements)
157 const auto& v = blmScoringInfo.at(bp.name);
158 std::set<G4String> requiredScorers = v.first;
159 G4String combinedName = v.second;
161 auto sdSearch = sensitiveDetectors.find(combinedName);
162 if (sdSearch == sensitiveDetectors.end())
163 {
throw BDSException(__METHOD_NAME__,
"unknown set of scorers");}
164 G4MultiFunctionalDetector* sd = sdSearch->second;
166 BDSBLM* blm = factory.CreateBLM(bp, sd);
168 G4double length = blmExtent.
DZ();
170 {
throw BDSException(__METHOD_NAME__,
"BLM: " + bp.name +
" has 0 extent");}
181 if (
BDS::IsFinite(bp.s) && transform == G4Transform3D::Identity)
183 G4String msg =
"the S coordinate (" + std::to_string(bp.s) +
" m) for blm \"" + bp.name;
184 msg +=
"\" was not found in the beam line - please check";
192 G4ThreeVector halfLengthBeg = G4ThreeVector(0,0,-length*0.5);
193 G4ThreeVector halfLengthEnd = G4ThreeVector(0,0, length*0.5);
194 G4ThreeVector midPos = transform.getTranslation();
195 G4ThreeVector startPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthBeg;
196 G4ThreeVector endPos = midPos + transform * (HepGeom::Point3D<G4double>)halfLengthEnd;
197 G4RotationMatrix* rm =
new G4RotationMatrix(transform.getRotation());
204 new G4RotationMatrix(*rm),
205 new G4RotationMatrix(*rm),
209 new G4RotationMatrix(*rm),
210 new G4RotationMatrix(*rm),
211 new G4RotationMatrix(*rm),
virtual void Initialise()
Factory for building BLMs.
static BDSBLMRegistry * Instance()
Accessor for registry.
A class that holds a fully constructed BDSAcceleratorComponent as well as any information relevant to...
A vector of BDSBeamlineElement instances - a beamline.
void AddBeamlineElement(BDSBeamlineElement *element)
static G4Transform3D CreatePlacementTransform(const GMAD::Placement &placement, const BDSBeamline *beamLine, G4double *S=nullptr, BDSExtent *placementExtent=nullptr, const G4String &objectTypeForErrorMsg="placement")
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4double DZ() const
The difference in a dimension.
BDSExtent GetExtent() const
Accessor - see member for more info.
virtual G4String GetName() const
Accessor - see member for more info.
BDSGeometryExternal * BuildGeometry(G4String componentName, const G4String &formatAndFilePath, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *namedVacuumVolumes=nullptr, G4bool makeSensitive=true, BDSSDType sensitivityType=BDSSDType::energydep, BDSSDType vacuumSensitivityType=BDSSDType::energydepvacuum, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
static BDSGeometryFactory * Instance()
Singleton accessor.
std::vector< GMAD::Scorer > GetScorers() const
Return the parser list of that object.
static BDSParser * Instance()
Access method.
void RegisterPrimitiveScorerNames(const std::vector< G4String > &namesIn, const std::vector< G4double > *units=nullptr)
Loop over a vector and apply above single name function.
Create primitive scorers on demand.
G4VPrimitiveScorer * CreateScorer(const BDSScorerInfo *info, const BDSHistBinMapper *mapper, G4double *unit=nullptr, G4LogicalVolume *worldLV=nullptr)
Main function to create a scorer.
Recipe class for scorer. Checks values.
G4String name
Scorer name.
A BDSAcceleratorComponent wrapper for BDSGeometryComponent.
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.
BDSBeamline * BuildBLMs(const std::vector< GMAD::BLMPlacement > &blmPlacements, const BDSBeamline *parentBeamLine)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())