65 std::string header =
"2 SEQN H K L COL ROW CHAN "
66 " L2 2_THETA AZ WL D IPK "
71 const auto &peaks =
m_ws->getPeaks();
74 throw std::runtime_error(
"No instrument in the Workspace. Cannot save DetCal file.");
75 const auto &detectorInfo =
m_ws->detectorInfo();
79 using bankMap_t = std::map<int, std::vector<size_t>>;
80 using runMap_t = std::map<int, bankMap_t>;
81 std::set<int, std::less<int>> uniqueBanks;
84 std::string bankPart =
"bank";
85 if (
inst->getName() ==
"WISH")
86 bankPart =
"WISHpanel";
89 const auto &componentInfo =
m_ws->componentInfo();
91 size_t const rootIndex = componentInfo.root();
92 auto const topChildren = componentInfo.children(rootIndex);
93 for (
size_t const i : topChildren) {
94 size_t bankParent = componentInfo.findBankParent(i, bankPart);
95 auto const children = componentInfo.children(bankParent);
96 for (
size_t const child : children) {
97 std::string bankName = componentInfo.name(child);
98 boost::trim(bankName);
99 boost::erase_all(bankName, bankPart);
107 uniqueBanks.insert(bank);
111 for (
size_t i = 0; i < peaks.size(); ++i) {
112 const Peak &p = peaks[i];
118 if (bankName.size() <= 4) {
119 g_log.
information() <<
"Could not interpret bank number of peak " << i <<
"(" << bankName <<
")\n";
124 bankPart = bankName.substr(0, 4);
126 if (bankPart ==
"bank")
127 bankName = bankName.substr(4, bankName.size() - 4);
128 else if (bankPart ==
"WISHpanel")
129 bankName = bankName.substr(9, bankName.size() - 9);
133 runMap[run][bank].emplace_back(i);
136 header =
"2 SEQN H K L M N P COL ROW CHAN "
137 " L2 2_THETA AZ WL D IPK "
141 throw std::runtime_error(
"No instrument in PeaksWorkspace. Cannot save peaks file.");
143 if (bankPart !=
"bank" && bankPart !=
"WISHpanel" && bankPart !=
"?") {
144 std::ostringstream mess;
145 mess <<
"Detector module of type " << bankPart <<
" not supported in ISAWPeaks. Cannot save peaks file";
146 throw std::runtime_error(mess.str());
151 double beamline_norm;
153 inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);
157 const bool renumber =
getProperty(
"RenumberPeaks");
160 if (!std::filesystem::exists(filename))
163 int appendPeakNumb = 0;
165 std::ifstream infile(filename.c_str());
167 while (!infile.eof())
169 getline(infile, line);
172 std::stringstream ss(line);
178 appendPeakNumb = std::max(peakNumber, appendPeakNumb);
183 out.open(filename.c_str(), std::ios::app);
184 appendPeakNumb = appendPeakNumb + 1;
186 out.open(filename.c_str());
188 const auto instrumentName =
inst->getName();
189 std::string facilityName;
191 facilityName = ConfigService::Instance().getInstrument(instrumentName).facility().name();
194 <<
" not found at any defined facility. Setting facility "
196 facilityName =
"Unknown";
198 out <<
"Version: 2.0 Facility: " << facilityName;
199 out <<
" Instrument: " << instrumentName <<
" Date: ";
204 Types::Core::DateAndTime expDate =
inst->getValidFromDate() + 1.0;
205 out << expDate.toISO8601String();
210 out <<
"6 L1 T0_SHIFT\n";
211 out <<
"7 " << std::setw(10);
212 out << std::setprecision(4) << std::fixed << (l1 * 100);
213 out << std::setw(12) << std::setprecision(3) << std::fixed;
226 out <<
"4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD CenterX "
227 " CenterY CenterZ BaseX BaseY BaseZ UpX UpY "
230 for (
const auto bank : uniqueBanks) {
232 std::ostringstream mess;
233 if (bankPart ==
"bank")
234 mess <<
"bank" << bank;
235 else if (bankPart ==
"WISHpanel") {
236 mess <<
"WISHpanel" << std::setfill(
'0') << std::setw(2) << bank;
239 std::string bankName = mess.str();
241 std::shared_ptr<const IComponent> det =
inst->getComponentByName(bankName);
242 if (
inst->getName() ==
"CORELLI")
244 const size_t bankIndex = componentInfo.indexOfAny(bankName);
245 const auto children = componentInfo.children(bankIndex);
246 if (!children.empty()) {
247 det.reset(componentInfo.componentID(children[0]),
NoDeleting());
252 V3D center = det->getPos();
255 double detd = (center -
inst->getSample()->getPos()).norm();
258 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize);
260 int midX = NCOLS / 2;
261 int midY = NROWS / 2;
270 out <<
"5 " << std::setw(6) << std::right << bank <<
" " << std::setw(6) << std::right << NROWS <<
" "
271 << std::setw(6) << std::right << NCOLS <<
" " << std::setw(7) << std::right << std::fixed
272 << std::setprecision(4) << 100.0 * xsize <<
" " << std::setw(7) << std::right << std::fixed
273 << std::setprecision(4) << 100.0 * ysize <<
" "
274 <<
" 0.2000 " << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0 * detd <<
" "
275 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
X() <<
" "
276 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Y() <<
" "
277 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Z() <<
" "
278 << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.
X() <<
" " << std::setw(8)
279 << std::right << std::fixed << std::setprecision(5) << base.
Y() <<
" " << std::setw(8) << std::right
280 << std::fixed << std::setprecision(5) << base.
Z() <<
" " << std::setw(8) << std::right << std::fixed
281 << std::setprecision(5) << up.
X() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5)
282 << up.
Y() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.
Z() <<
" \n";
285 g_log.
warning() <<
"Information about detector module " << bankName <<
" not found and recognised\n";
291 if (
m_ws->getConvention() ==
"Crystallography")
296 int sequenceNumber = appendPeakNumb;
297 for (
const auto &runBankMap : runMap) {
299 const int run = runBankMap.first;
300 const auto &bankMap = runBankMap.second;
302 for (
const auto &bankIDs : bankMap) {
304 const int bank = bankIDs.first;
305 const auto &ids = bankIDs.second;
309 out <<
"0 NRUN DETNUM CHI PHI OMEGA MONCNT\n";
310 out <<
"1 " << std::setw(5) << run << std::setw(7) << std::right << bank;
314 Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
317 double phi = angles[2];
318 double chi = angles[1];
319 double omega = angles[0];
321 out << std::setw(8) << std::fixed << std::setprecision(2) << chi <<
" ";
322 out << std::setw(8) << std::fixed << std::setprecision(2) << phi <<
" ";
323 out << std::setw(8) << std::fixed << std::setprecision(2) << omega <<
" ";
327 const size_t first_peak_index = ids[0];
328 const auto &first_peak = peaks[first_peak_index];
329 const double monct = first_peak.getMonitorCount();
330 out << std::setw(12) << static_cast<int>(monct) <<
'\n';
331 out << header <<
'\n';
334 for (
auto wi : ids) {
335 const auto &peak = peaks[wi];
338 std::string firstNumber =
"3";
343 out << firstNumber << std::setw(7) << sequenceNumber;
346 out << firstNumber << std::setw(7) << peak.getPeakNumber() + appendPeakNumb;
352 const V3D mod = peak.getIntMNP();
353 const auto intHKL = peak.getIntHKL();
360 out << std::setw(5) <<
Utils::round(qSign * peak.getH()) << std::setw(5)
365 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getCol()) <<
" ";
367 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getRow()) <<
" ";
369 out << std::setw(8) << std::fixed << std::setprecision(0) << peak.getTOF() <<
" ";
371 out << std::setw(9) << std::fixed << std::setprecision(3) << (peak.getL2() * 100.0) <<
" ";
374 const V3D dir = peak.getDetPos() -
inst->getSample()->getPos();
375 double scattering, azimuth;
379 scattering = dir.
angle(
V3D(0.0, 0.0, 1.0));
384 azimuth = atan2(dir.Y(), dir.X());
386 out << std::setw(9) << std::fixed << std::setprecision(5) << scattering <<
" ";
388 out << std::setw(9) << std::fixed << std::setprecision(5) << azimuth <<
" ";
390 out << std::setw(10) << std::fixed << std::setprecision(6) << peak.getWavelength() <<
" ";
392 out << std::setw(9) << std::fixed << std::setprecision(4) << peak.getDSpacing() <<
" ";
394 out << std::setw(8) << std::fixed << std::setprecision(0) << int(peak.getBinCount()) <<
" ";
396 out << std::setw(10) << std::fixed << std::setprecision(2) << peak.getIntensity() <<
" ";
398 out << std::setw(7) << std::fixed << std::setprecision(2) << peak.getSigmaIntensity() <<
" ";
400 int thisReflag = 310;
401 out << std::setw(5) << thisReflag;
408 const auto &yValues = wsProfile2D->y(wi);
409 for (
size_t j = 0; j < yValues.size(); j++) {
410 out << std::setw(8) << static_cast<int>(yValues[j]);
411 if ((j + 1) % 10 == 0) {
413 if (j + 1 != yValues.size())