71 std::vector<std::string> bankNames =
getProperty(
"BankNames");
73 inst = ws->getInstrument();
75 throw std::runtime_error(
"No instrument in the Workspace. Cannot save DetCal file.");
78 std::string bankPart =
"bank";
79 if (
inst->getName() ==
"WISH")
80 bankPart =
"WISHpanel";
82 std::set<int> uniqueBanks;
83 if (bankNames.empty()) {
85 const auto &componentInfo = ws->componentInfo();
86 for (
size_t i = 0; i < componentInfo.size(); ++i) {
87 std::string bankName = componentInfo.name(i);
88 boost::trim(bankName);
89 boost::erase_all(bankName, bankPart);
95 uniqueBanks.insert(bank);
98 for (
auto bankName : bankNames) {
99 boost::trim(bankName);
100 boost::erase_all(bankName, bankPart);
106 uniqueBanks.insert(bank);
112 double beamline_norm;
114 inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);
120 if (!std::filesystem::exists(std::filesystem::path(filename.c_str())))
124 out.open(filename.c_str(), std::ios::app);
126 out.open(filename.c_str());
127 out <<
"# NEW CALIBRATION FILE FORMAT (in NeXus/SNS coordinates):\n";
128 out <<
"# Lengths are in centimeters.\n";
129 out <<
"# Base and up give directions of unit vectors for a local \n";
130 out <<
"# x,y coordinate system on the face of the detector.\n";
133 out <<
"# " << DateAndTime::getCurrentTime().toISO8601String() <<
'\n';
135 out <<
"6 L1 T0_SHIFT\n";
136 out <<
"7 " << std::setw(10);
137 out << std::setprecision(4) << std::fixed << (l1 * 100);
138 out << std::setw(13) << std::setprecision(3) << T0 <<
'\n';
140 out <<
"4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD CenterX "
141 " CenterY CenterZ BaseX BaseY BaseZ UpX UpY "
145 const auto &componentInfo = ws->componentInfo();
146 std::set<int>::iterator it;
147 for (it = uniqueBanks.begin(); it != uniqueBanks.end(); ++it) {
150 std::ostringstream mess;
151 if (bankPart ==
"WISHpanel" && bank < 10)
152 mess << bankPart <<
"0" << bank;
154 mess << bankPart << bank;
156 std::string bankName = mess.str();
158 std::shared_ptr<const IComponent> det =
inst->getComponentByName(bankName);
159 if (
inst->getName() ==
"CORELLI")
161 const size_t bankIndex = componentInfo.indexOfAny(bankName);
162 const auto children = componentInfo.children(bankIndex);
163 if (!children.empty()) {
169 V3D center = det->getPos();
172 double detd = (center -
inst->getSample()->getPos()).norm();
175 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize, componentInfo);
178 int midX = NCOLS / 2;
179 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 const size_t parentIndex = componentInfo.
indexOfAny(bankName);
220 auto children = componentInfo.
children(parentIndex);
221 if (!children.empty() && componentInfo.
name(children[0]) ==
"sixteenpack") {
222 children = componentInfo.
children(children[0]);
226 if (
inst->getName() ==
"WISH")
227 col0 = (col % 2 == 0 ? col / 2 + 75 : (col - 1) / 2);
228 const auto grandchildren = componentInfo.
children(children[col0]);
229 return componentInfo.
position(grandchildren[row - 1]);
235 if (bankName ==
"None")
237 std::shared_ptr<const IComponent> parent =
inst->getComponentByName(bankName);
238 if (parent->type() ==
"RectangularDetector") {
239 std::shared_ptr<const RectangularDetector> RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
241 NCOLS = RDet->xpixels();
242 NROWS = RDet->ypixels();
243 xsize = RDet->xsize();
244 ysize = RDet->ysize();
246 const size_t parentIndex = componentInfo.
indexOfAny(bankName);
247 auto children = componentInfo.
children(parentIndex);
248 if (!children.empty() && componentInfo.
name(children[0]) ==
"sixteenpack") {
249 children = componentInfo.
children(children[0]);
251 const auto grandchildren = componentInfo.
children(children[0]);
252 NROWS =
static_cast<int>(grandchildren.size());
253 NCOLS =
static_cast<int>(children.size());
254 const auto &first = componentInfo.
componentID(children[0]);
255 const auto &last = componentInfo.
componentID(children[NCOLS - 1]);
257 const auto &firstGrand = componentInfo.
componentID(grandchildren[0]);
258 const auto &lastGrand = componentInfo.
componentID(grandchildren[NROWS - 1]);