20#include <boost/algorithm/string/trim.hpp>
26using Mantid::Types::Core::DateAndTime;
38 "An input workspace.");
40 declareProperty(std::make_unique<FileProperty>(
"Filename",
"",
FileProperty::Save,
".DetCal"),
41 "Path to an ISAW-style .detcal file to save.");
43 declareProperty(
"TimeOffset", 0.0,
"Offsets to be applied to times");
45 "Optional: Only select the specified banks");
46 declareProperty(
"AppendFile",
false,
47 "Append to file if true.\n"
48 "If false, new file (default).");
70 std::vector<std::string> bankNames =
getProperty(
"BankNames");
72 inst = ws->getInstrument();
74 throw std::runtime_error(
"No instrument in the Workspace. Cannot save DetCal file.");
77 std::string bankPart =
"bank";
78 if (
inst->getName() ==
"WISH")
79 bankPart =
"WISHpanel";
81 std::set<int> uniqueBanks;
82 if (bankNames.empty()) {
84 std::vector<IComponent_const_sptr> comps;
85 inst->getChildren(comps,
true);
87 for (
auto &comp : comps) {
88 std::string bankName = comp->getName();
89 boost::trim(bankName);
90 boost::erase_all(bankName, bankPart);
96 uniqueBanks.insert(bank);
99 for (
auto bankName : bankNames) {
100 boost::trim(bankName);
101 boost::erase_all(bankName, bankPart);
107 uniqueBanks.insert(bank);
111 throw std::runtime_error(
"No instrument in PeaksWorkspace. Cannot save peaks file.");
115 double beamline_norm;
117 inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);
123 if (!Poco::File(filename.c_str()).exists())
127 out.open(filename.c_str(), std::ios::app);
129 out.open(filename.c_str());
130 out <<
"# NEW CALIBRATION FILE FORMAT (in NeXus/SNS coordinates):\n";
131 out <<
"# Lengths are in centimeters.\n";
132 out <<
"# Base and up give directions of unit vectors for a local \n";
133 out <<
"# x,y coordinate system on the face of the detector.\n";
136 out <<
"# " << DateAndTime::getCurrentTime().toISO8601String() <<
'\n';
138 out <<
"6 L1 T0_SHIFT\n";
139 out <<
"7 " << std::setw(10);
140 out << std::setprecision(4) << std::fixed << (l1 * 100);
141 out << std::setw(13) << std::setprecision(3) << T0 <<
'\n';
143 out <<
"4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD CenterX "
144 " CenterY CenterZ BaseX BaseY BaseZ UpX UpY "
148 std::set<int>::iterator it;
149 for (it = uniqueBanks.begin(); it != uniqueBanks.end(); ++it) {
152 std::ostringstream mess;
153 if (bankPart ==
"WISHpanel" && bank < 10)
154 mess << bankPart <<
"0" << bank;
156 mess << bankPart << bank;
158 std::string bankName = mess.str();
160 std::shared_ptr<const IComponent> det =
inst->getComponentByName(bankName);
161 if (
inst->getName() ==
"CORELLI")
163 std::vector<Geometry::IComponent_const_sptr> children;
164 std::shared_ptr<const Geometry::ICompAssembly> asmb =
165 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(
inst->getComponentByName(bankName));
166 asmb->getChildren(children,
false);
171 V3D center = det->getPos();
174 double detd = (center -
inst->getSample()->getPos()).norm();
177 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize);
180 int midX = NCOLS / 2;
181 int midY = NROWS / 2;
190 out <<
"5 " << std::setw(6) << std::right << bank <<
" " << std::setw(6) << std::right << NROWS <<
" "
191 << std::setw(6) << std::right << NCOLS <<
" " << std::setw(7) << std::right << std::fixed
192 << std::setprecision(4) << 100.0 * xsize <<
" " << std::setw(7) << std::right << std::fixed
193 << std::setprecision(4) << 100.0 * ysize <<
" "
194 <<
" 0.2000 " << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0 * detd <<
" "
195 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
X() <<
" "
196 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Y() <<
" "
197 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Z() <<
" "
198 << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.
X() <<
" " << std::setw(8)
199 << std::right << std::fixed << std::setprecision(5) << base.
Y() <<
" " << std::setw(8) << std::right
200 << std::fixed << std::setprecision(5) << base.
Z() <<
" " << std::setw(8) << std::right << std::fixed
201 << std::setprecision(5) << up.
X() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5)
202 << up.
Y() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.
Z() <<
" \n";
205 g_log.
warning() <<
"Information about detector module " << bankName <<
" not found and recognised\n";
212 std::shared_ptr<const IComponent> parent =
inst->getComponentByName(bankName);
213 if (parent->type() ==
"RectangularDetector") {
214 std::shared_ptr<const RectangularDetector> RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
216 std::shared_ptr<Detector> pixel = RDet->getAtXY(col, row);
217 return pixel->getPos();
219 std::vector<Geometry::IComponent_const_sptr> children;
220 std::shared_ptr<const Geometry::ICompAssembly> asmb =
221 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
222 asmb->getChildren(children,
false);
223 if (children[0]->
getName() ==
"sixteenpack") {
224 asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
226 asmb->getChildren(children,
false);
230 if (
inst->getName() ==
"WISH")
231 col0 = (col % 2 == 0 ? col / 2 + 75 : (col - 1) / 2);
232 std::shared_ptr<const Geometry::ICompAssembly> asmb2 =
233 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col0]);
234 std::vector<Geometry::IComponent_const_sptr> grandchildren;
235 asmb2->getChildren(grandchildren,
false);
237 return first->getPos();
242 if (bankName ==
"None")
244 std::shared_ptr<const IComponent> parent =
inst->getComponentByName(bankName);
245 if (parent->type() ==
"RectangularDetector") {
246 std::shared_ptr<const RectangularDetector> RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
248 NCOLS = RDet->xpixels();
249 NROWS = RDet->ypixels();
250 xsize = RDet->xsize();
251 ysize = RDet->ysize();
253 std::vector<Geometry::IComponent_const_sptr> children;
254 std::shared_ptr<const Geometry::ICompAssembly> asmb =
255 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
256 asmb->getChildren(children,
false);
257 if (children[0]->
getName() ==
"sixteenpack") {
258 asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
260 asmb->getChildren(children,
false);
262 std::shared_ptr<const Geometry::ICompAssembly> asmb2 =
263 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
264 std::vector<Geometry::IComponent_const_sptr> grandchildren;
265 asmb2->getChildren(grandchildren,
false);
266 NROWS =
static_cast<int>(grandchildren.size());
267 NCOLS =
static_cast<int>(children.size());
270 xsize = first->getDistance(*last);
271 first = grandchildren[0];
272 last = grandchildren[NROWS - 1];
273 ysize = first->getDistance(*last);
#define DECLARE_ALGORITHM(classname)
std::string getName(const IMDDimension &self)
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
@ Save
to specify a file to write to, the file may or may not exist
bool hasProperty(const std::string &name) const
Does the property exist on the object.
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
Saves an instrument with RectangularDetectors to an ISAW .DetCal file.
void sizeBanks(const std::string &bankName, int &NCOLS, int &NROWS, double &xsize, double &ysize)
Kernel::V3D findPixelPos(const std::string &bankName, int col, int row)
find position for rectangular and non-rectangular
void exec() override
Run the algorithm.
Geometry::Instrument_const_sptr inst
Support for a property that holds an array of values.
void notice(const std::string &msg)
Logs at notice level.
void warning(const std::string &msg)
Logs at warning level.
constexpr double X() const noexcept
Get x.
double normalize()
Make a normalized vector (return norm value)
constexpr double Y() const noexcept
Get y.
constexpr double Z() const noexcept
Get z.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
int convert(const std::string &A, T &out)
Convert a string into a number.
@ Input
An input workspace.