1 #include <fwk/CentralConfig.h>
2 #include <det/VManager.h>
3 #include <sdet/SManagerRegister.h>
5 #include <utl/ErrorLogger.h>
6 #include <utl/Reader.h>
7 #include <utl/UTMPoint.h>
9 #include <utl/Vector.h>
11 #include <utl/Plane.h>
12 #include <utl/GeometryUtilities.h>
14 #include <fwk/CoordinateSystemRegistry.h>
16 #include <evt/Event.h>
17 #include <evt/ShowerSimData.h>
19 #include <fwk/RunController.h>
20 #include <fwk/LocalCoordinateSystem.h>
22 #include <det/Detector.h>
23 #include <sdet/SDetector.h>
24 #include <sdet/Station.h>
26 #include <sdet/SDenseStationListXMLManager.h>
28 #include <boost/range/iterator_range.hpp>
48 fDenseStationList.clear();
50 const string stationString =
"denseStation";
52 for (
auto cB = fBranch.GetFirstChild(); cB; cB = cB.GetNextSibling()) {
53 if (cB.GetName() != stationString)
55 const auto atts = cB.GetAttributes();
56 const auto id = FindComponent<int>(
"id", atts);
57 const auto it = fDenseStationList.find(
id);
58 if (it == fDenseStationList.end())
59 fDenseStationList.insert(fDenseStationList.end(), id);
62 warn <<
"Found multiple instances of dense station " <<
id <<
". "
63 "Only the first one will be used.";
71 SDenseStationListXMLManager::GetData(
int& returnData,
72 const string& componentProperty,
73 const string& componentName,
74 const IndexMap& componentIndex)
77 if (componentName !=
"stationList" || !IsDense(componentIndex))
80 if (componentProperty ==
"isUUB") {
82 auto isUUBB = fBranch.GetChild(
"isUUB");
84 isUUBB.GetData(returnData);
85 }
else if (componentProperty ==
"hasSmallPMT") {
87 auto hasSmallPMTB = fBranch.GetChild(
"hasSmallPMT");
89 hasSmallPMTB.GetData(returnData);
90 }
else if (componentProperty ==
"hasScintillator") {
92 auto hasScintillatorB = fBranch.GetChild(
"hasScintillator");
94 hasScintillatorB.GetData(returnData);
95 }
else if (componentProperty ==
"groupId")
97 else if (componentProperty ==
"zone")
98 fBranch.GetChild(
"UTMInfo").GetChild(
"zone").GetData(returnData);
103 FindComponent<string>(
"stationId", componentIndex);
109 SDenseStationListXMLManager::GetData(
double& returnData,
110 const string& componentProperty,
111 const string& componentName,
112 const IndexMap& componentIndex)
115 if (componentName !=
"stationList" || !IsDense(componentIndex))
118 if (componentProperty ==
"northing" ||
119 componentProperty ==
"easting" ||
120 componentProperty ==
"altitude") {
122 const auto&
event = RunController::GetInstance().GetCurrentEvent();
124 fDenseStations.Validate(event);
126 const auto id = FindComponent<int>(
"stationId", componentIndex);
128 if (!fDenseStations.HasStation(
id)) {
136 if (GetData(deltaPhi,
"deltaPhi",
"stationList", componentIndex) == eNotFound)
139 if (GetData(r,
"r",
"stationList", componentIndex) == eNotFound)
142 fDenseStations.AddStation(
id, r, deltaPhi);
145 const auto& pos = fDenseStations.GetStation(
id);
146 if (componentProperty ==
"northing")
147 returnData = pos.fNorthing;
148 else if (componentProperty ==
"easting")
149 returnData = pos.fEasting;
150 else if (componentProperty ==
"altitude")
151 returnData = pos.fHeight;
157 }
else if (componentProperty ==
"axis1" || componentProperty ==
"axis2") {
164 const auto it = componentIndex.find(
"stationId");
166 if (it != componentIndex.end()) {
168 const IndexMap atts({{
"id", it->second }});
170 auto stationB = fBranch.GetChild(
"denseStation", atts);
174 auto componentB = stationB.GetChild(componentProperty);
178 componentB.GetData(returnData);
184 info <<
"Could not interpret the request with "
185 "component property = '" << componentProperty <<
"', "
186 "component name = '" << componentName <<
"', index ";
187 for (
const auto& kv : componentIndex)
188 info <<
" (" << kv.first <<
", " << kv.second <<
')';
199 SDenseStationListXMLManager::GetData(
string& returnData,
200 const string& componentProperty,
201 const string& componentName,
202 const IndexMap& componentIndex)
205 if (componentName !=
"stationList" || !IsDense(componentIndex))
208 if (componentProperty ==
"name")
209 returnData =
"DenseStation" + FindComponent<string>(
"stationId", componentIndex);
210 else if (componentProperty ==
"commission")
211 returnData =
"2000-01-01T00:00:00Z";
212 else if (componentProperty ==
"decommission")
213 returnData =
"2030-01-01T00:00:00Z";
215 auto componentB = fBranch.GetChild(
"UTMInfo").GetChild(componentProperty);
217 componentB.GetData(returnData);
227 SDenseStationListXMLManager::GetData(vector<int>& returnData,
228 const string& componentProperty,
229 const string& componentName,
230 const IndexMap& componentIndex)
233 if (componentName !=
"stationList")
236 if (componentProperty ==
"denseStationList") {
237 GetFullStationList(returnData);
239 }
else if (componentProperty ==
"stationGroup") {
240 if (IsDense(componentIndex)) {
244 }
else if (componentProperty ==
"crown") {
245 if (IsDense(componentIndex)) {
256 SDenseStationListXMLManager::GetData(vector<bool>& returnData,
257 const string& componentProperty,
258 const string& componentName,
259 const IndexMap& componentIndex)
262 if (componentName !=
"stationList" || !IsDense(componentIndex))
265 if (componentProperty ==
"inGrid") {
275 SDenseStationListXMLManager::GetFullStationList(vector<int>& returnList)
278 returnList.assign(fDenseStationList.begin(), fDenseStationList.end());
283 SDenseStationListXMLManager::IsDense(
const IndexMap& componentIndex)
286 const auto id = FindComponent<int>(
"stationId", componentIndex);
287 return fDenseStationList.find(
id) != fDenseStationList.end();
295 SDenseStationListXMLManager::DenseStations::Validate(
const Event& event)
298 if (fEventId.empty())
311 "Attempt to generate a dense array failed because "
312 "no simulated shower is present in the event."
315 const auto& simShower =
event.GetSimShower();
317 if (!simShower.HasGeometry())
319 "Attempt to generate a dense array failed because "
320 "the shower core position has not been set."
323 const auto& showerCS = simShower.GetShowerCoordinateSystem();
324 const Point observationCore(0,0,0, showerCS);
325 fShowerDirection = simShower.GetDirection();
332 const Line showerAxis(observationCore, fShowerDirection);
333 const auto& sDet = det::Detector::GetInstance().GetSDetector();
336 double minDistance = numeric_limits<double>::infinity();
337 for (
const auto&
s : sDet.StationsRange()) {
340 const double d =
Distance(showerAxis,
s.GetPosition());
341 if (d < minDistance) {
352 info <<
"Reference height for dense stations taken from closest station "
353 "id = " << closestStation->
GetId();
359 const auto& refPos = closestStation->
GetPosition();
360 const auto& groundCS = LocalCoordinateSystem::Create(refPos);
361 const Vector groundNormal(0,0,1, groundCS);
362 fGroundPlane =
Plane(refPos, groundNormal);
364 fBaseX =
Vector(1,0,0, showerCS);
365 fBaseY =
Vector(0,1,0, showerCS);
368 const auto& pampaCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
370 #define DUMP(_x_) #_x_ " (" << _x_.GetX(pampaCS) << ", " << _x_.GetY(pampaCS) << ", " << _x_.GetZ(pampaCS) << ")\n"
371 info <<
"trigger calculation:\n"
372 <<
DUMP(observationCore)
373 <<
DUMP(fShowerDirection)
375 <<
DUMP(groundNormal)
384 fEventId =
event.GetHeader().GetId();
389 SDenseStationListXMLManager::DenseStations::AddStation(
const int id,
const double r,
const double deltaPhi)
392 const double x = r * cos(deltaPhi);
393 const double y = r * sin(deltaPhi);
394 const Vector rho = x * fBaseX + y * fBaseY;
395 const Point stationInShowerPlane = fGroundCore + rho;
396 const Point stationInGroundPlane =
398 const UTMPoint utm(stationInGroundPlane, ReferenceEllipsoid::eWGS84);
400 fStations.insert({id, neh});
double Plane(const utl::Point &point, const utl::Vector &normal, const utl::Photon &photonIn, utl::Photon &photonOut)
Detector description interface for Station-related data.
evt::Header & GetHeader()
Class to hold and convert a point in geodetic coordinates.
bool HasSimShower() const
#define INFO(message)
Macro for logging informational messages.
Manager to return station positions for array defined in shower coordinates.
void Init()
Initialise the registry.
double GetNorthing() const
Get the northing.
Line Intersection(const Plane &p1, const Plane &p2)
utl::Point GetPosition() const
Tank position.
double GetHeight() const
Get the height.
#define REGISTER_S_MANAGER(_name_, _Type_)
double GetEasting() const
Get the easting.
#define WARNING(message)
Macro for logging warning messages.
Base class for exceptions arising because required info not present in the Event. ...
double Distance(const Point &p, const sdet::Station &s)
std::map< std::string, std::string > IndexMap
int GetId() const
Station ID.
Status
Specifies success or (eventually) various possible failure modes.