-
Notifications
You must be signed in to change notification settings - Fork 122
/
InstrumentDefinitionParser.h
293 lines (226 loc) · 12.3 KB
/
InstrumentDefinitionParser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#ifndef MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSER_H_
#define MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSER_H_
#include <string>
#include <vector>
#include <Poco/AutoPtr.h>
#include <Poco/DOM/Document.h>
#include "MantidKernel/System.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/V3D.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/IDFObject.h"
namespace Poco
{
namespace XML
{
class Element;
}
}
namespace Mantid
{
namespace Kernel
{
class ProgressBase;
}
namespace Geometry
{
class ICompAssembly;
class IComponent;
class Instrument;
class ObjComponent;
class Object;
/** Creates an instrument data from a XML instrument description file
@author Nick Draper, Tessella Support Services plc
@date 19/11/2007
@author Anders Markvardsen, ISIS, RAL
@date 7/3/2008
Copyright © 2007-2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
*/
class DLLExport InstrumentDefinitionParser
{
public:
InstrumentDefinitionParser();
~InstrumentDefinitionParser();
/// Caching
enum CachingOption{NoneApplied, ReadAdjacent, ReadFallBack, WroteCacheAdjacent, WroteCacheTemp };
/// Set up parser
void initialize(const std::string & filename, const std::string & instName, const std::string & xmlText);
/// Set up parser.
void initialize(IDFObject_const_sptr xmlFile, IDFObject_const_sptr expectedCacheFile, const std::string & instName, const std::string & xmlText);
/// Parse XML contents
boost::shared_ptr<Instrument> parseXML(Kernel::ProgressBase * prog);
/// Add/overwrite any parameters specified in instrument with param values specified in <component-link> XML elements
void setComponentLinks(boost::shared_ptr<Geometry::Instrument>& instrument, Poco::XML::Element* pElem);
std::string getMangledName();
/// Get parent component element of location element
static Poco::XML::Element* getParentComponent(const Poco::XML::Element* pLocElem);
/// get name of location element
static std::string getNameOfLocationElement(const Poco::XML::Element* pElem, const Poco::XML::Element* pCompElem);
/// Save DOM tree to xml file
void saveDOM_Tree(std::string& outFilename);
/// Getter the the applied caching option.
CachingOption getAppliedCachingOption() const;
private:
/// Static reference to the logger class
static Kernel::Logger& g_log;
/// Set location (position) of comp as specified in XML location element
void setLocation(Geometry::IComponent* comp, const Poco::XML::Element* pElem, const double angleConvertConst,
const bool deltaOffsets=false);
/// Calculate the position of comp relative to its parent from info provided by \<location\> element
Kernel::V3D getRelativeTranslation(const Geometry::IComponent* comp, const Poco::XML::Element* pElem,
const double angleConvertConst, const bool deltaOffsets=false);
/// Check the validity range and add it to the instrument object
void setValidityRange(const Poco::XML::Element* pRootElem);
/// Reads the contents of the \<defaults\> element to set member variables,
void readDefaults(Poco::XML::Element* defaults);
/// Structure for holding detector IDs
struct IdList
{
/// Used to count the number of detector encounted so far
int counted;
/// list of detector IDs
std::vector<int> vec;
/// name of idlist
std::string idname;
///Constructor
IdList() : counted(0) {};
/// return true if empty
bool empty() { return vec.empty();};
/// reset idlist
void reset() { counted=0; vec.clear();};
};
/// Method for populating IdList
void populateIdList(Poco::XML::Element* pElem, IdList& idList);
std::vector<std::string> buildExcludeList(const Poco::XML::Element* const location);
/// Add XML element to parent assuming the element contains other component elements
void appendAssembly(Geometry::ICompAssembly* parent, const Poco::XML::Element* pLocElem, const Poco::XML::Element* pCompElem, IdList& idList);
/// Return true if assembly, false if not assembly and throws exception if string not in assembly
bool isAssembly(std::string) const;
/// Add XML element to parent assuming the element contains no other component elements
void appendLeaf(Geometry::ICompAssembly* parent, const Poco::XML::Element* pLocElem, const Poco::XML::Element* pCompElem, IdList& idList);
/// Append \<locations\> in a locations element
void appendLocations(Geometry::ICompAssembly* parent, const Poco::XML::Element*pLocElems, const Poco::XML::Element* pCompElem, IdList& idList);
/// Set parameter/logfile info (if any) associated with component
void setLogfile(const Geometry::IComponent* comp, const Poco::XML::Element* pElem,
InstrumentParameterCache& logfileCache);
/// Parse position of facing element to V3D
Kernel::V3D parseFacingElementToV3D(Poco::XML::Element* pElem);
/// Set facing of comp as specified in XML facing element
void setFacing(Geometry::IComponent* comp, const Poco::XML::Element* pElem);
/// Make the shape defined in 1st argument face the component in the second argument
void makeXYplaneFaceComponent(Geometry::IComponent* &in, const Geometry::ObjComponent* facing);
/// Make the shape defined in 1st argument face the position in the second argument
void makeXYplaneFaceComponent(Geometry::IComponent* &in, const Kernel::V3D& facingPoint);
/// Reads in or creates the geometry cache ('vtp') file
CachingOption setupGeometryCache();
/// If appropriate, creates a second instrument containing neutronic detector positions
void createNeutronicInstrument();
/// Takes as input a \<type\> element containing a <combine-components-into-one-shape>, and
/// adjust the \<type\> element by replacing its containing \<component\> elements with \<cuboid\>'s
/// (note for now this will only work for \<cuboid\>'s and when necessary this can be extended).
void adjust(Poco::XML::Element* pElem, std::map<std::string,bool>& isTypeAssembly,
std::map<std::string,Poco::XML::Element*>& getTypeElement);
/// Take as input a \<locations\> element. Such an element is a short-hand notation for a sequence of \<location\> elements.
/// This method return this sequence as a xml string
std::string convertLocationsElement(const Poco::XML::Element* pElem);
/// Just to avoid replication of code here throw text string to throw when too many 'end' attribute of \<locations\> tag
std::string throwTooManyEndAttributeInLocations(const std::string& tx1, const std::string& tx2);
public: //for testing
/// return absolute position of point which is set relative to the
/// coordinate system of the input component
Kernel::V3D getAbsolutPositionInCompCoorSys(Geometry::ICompAssembly* comp, Kernel::V3D);
private:
/// Checks if the proposed cache file can be read from.
bool canUseProposedCacheFile(IDFObject_const_sptr cache) const;
/// Reads from a cache file.
void applyCache(IDFObject_const_sptr cacheToApply);
/// Write out a cache file.
CachingOption writeAndApplyCache(IDFObject_const_sptr usedCache);
/// This method returns the parent appended which its child components and also name of type of the last child component
std::string getShapeCoorSysComp(Geometry::ICompAssembly* parent,
Poco::XML::Element* pLocElem, std::map<std::string,Poco::XML::Element*>& getTypeElement,
Geometry::ICompAssembly*& endAssembly);
/// Returns a translated and rotated \<cuboid\> element
std::string translateRotateXMLcuboid(Geometry::ICompAssembly* comp, const Poco::XML::Element* cuboidEle,
const std::string& cuboidName);
/// Returns a translated and rotated \<cuboid\> element
std::string translateRotateXMLcuboid(Geometry::ICompAssembly* comp, const std::string& cuboidXML,
const std::string& cuboidName);
/// Return a subelement of an XML element
Poco::XML::Element* getShapeElement(const Poco::XML::Element* pElem, const std::string& name);
/// Get position coordinates from XML element
Kernel::V3D parsePosition(Poco::XML::Element* pElem);
/// Input xml file
IDFObject_const_sptr m_xmlFile;
/// Input vtp file
IDFObject_const_sptr m_cacheFile;
/// Name of the instrument
std::string m_instName;
/// XML document loaded
Poco::AutoPtr<Poco::XML::Document> pDoc;
/// Root element of the parsed XML
Poco::XML::Element* pRootElem;
/** Holds all the xml elements that have a \<parameter\> child element.
* Added purely for the purpose of computing speed and is used in setLogFile() for the purpose
* of quickly accessing if a component have a parameter/logfile associated with it or not
* - instead of using the comparatively slow poco call getElementsByTagName() (or getChildElement)
*/
std::vector<Poco::XML::Element*> hasParameterElement;
/// has hasParameterElement been set - used when public method setComponentLinks is used
bool hasParameterElement_beenSet;
/** map which holds names of types and whether or not they are categorized as being
* assemblies, which means whether the type element contains component elements
*/
std::map<std::string,bool> isTypeAssembly;
/// map which maps the type name to a shared pointer to a geometric shape
std::map<std::string, boost::shared_ptr<Geometry::Object> > mapTypeNameToShape;
/// Container to hold all detectors and monitors added to the instrument. Used for 'facing' these to component specified under \<defaults\>. NOTE: Seems unused, ever.
std::vector< Geometry::ObjComponent* > m_facingComponent;
/// True if defaults->components-are-facing is set in instrument def. file
bool m_haveDefaultFacing;
/// Hold default facing position
Kernel::V3D m_defaultFacing;
/// map which holds names of types and pointers to these type for fast retrieval in code
std::map<std::string,Poco::XML::Element*> getTypeElement;
/// For convenience added pointer to instrument here
boost::shared_ptr<Geometry::Instrument> m_instrument;
/// Flag to indicate whether offsets given in spherical coordinates are to be added to the current
/// position (true) or are a vector from the current position (false, default)
bool m_deltaOffsets;
/// when this const equals 1 it means that angle=degree (default) is set in IDF
/// otherwise if this const equals 180/pi it means that angle=radian is set in IDF
double m_angleConvertConst;
bool m_indirectPositions; ///< Flag to indicate whether IDF contains physical & neutronic positions
/// A map containing the neutronic position for each detector. Used when m_indirectPositions is true.
std::map<Geometry::IComponent*,Poco::XML::Element*> m_neutronicPos;
/** Stripped down vector that holds position in terms of spherical coordinates,
* Needed when processing instrument definition files that use the 'Ariel format'
*/
struct SphVec
{
///@cond Exclude from doxygen documentation
double r,theta,phi;
SphVec() : r(0.0), theta(0.0), phi(0.0) {}
SphVec(const double& r, const double& theta, const double& phi) : r(r), theta(theta), phi(phi) {}
///@endcond
};
/// Map to store positions of parent components in spherical coordinates
std::map<const Geometry::IComponent*,SphVec> m_tempPosHolder;
/// Caching applied.
CachingOption m_cachingOption;
};
} // namespace Geometry
} // namespace Mantid
#endif /* MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSER_H_ */