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 (
m_ws->getInstrumentName() ==
"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 =
m_ws->getInstrumentName();
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();
243 bankIndex = componentInfo.indexOfAny(bankName);
244 }
catch (
const std::invalid_argument &) {
249 const auto children = componentInfo.children(bankIndex);
250 if (!children.empty()) {
251 bankIndex = children[0];
256 V3D center = componentInfo.position(bankIndex);
259 double detd = (center - componentInfo.samplePosition()).norm();
262 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize);
264 int midX = NCOLS / 2;
265 int midY = NROWS / 2;
274 out <<
"5 " << std::setw(6) << std::right << bank <<
" " << std::setw(6) << std::right << NROWS <<
" "
275 << std::setw(6) << std::right << NCOLS <<
" " << std::setw(7) << std::right << std::fixed
276 << std::setprecision(4) << 100.0 * xsize <<
" " << std::setw(7) << std::right << std::fixed
277 << std::setprecision(4) << 100.0 * ysize <<
" "
278 <<
" 0.2000 " << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0 * detd <<
" "
279 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
X() <<
" "
280 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Y() <<
" "
281 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Z() <<
" "
282 << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.
X() <<
" " << std::setw(8)
283 << std::right << std::fixed << std::setprecision(5) << base.
Y() <<
" " << std::setw(8) << std::right
284 << std::fixed << std::setprecision(5) << base.
Z() <<
" " << std::setw(8) << std::right << std::fixed
285 << std::setprecision(5) << up.
X() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5)
286 << up.
Y() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.
Z() <<
" \n";
289 g_log.
warning() <<
"Information about detector module " << bankName <<
" not found and recognised\n";
295 if (
m_ws->getConvention() ==
"Crystallography")
300 int sequenceNumber = appendPeakNumb;
301 for (
const auto &runBankMap : runMap) {
303 const int run = runBankMap.first;
304 const auto &bankMap = runBankMap.second;
306 for (
const auto &bankIDs : bankMap) {
308 const int bank = bankIDs.first;
309 const auto &ids = bankIDs.second;
313 out <<
"0 NRUN DETNUM CHI PHI OMEGA MONCNT\n";
314 out <<
"1 " << std::setw(5) << run << std::setw(7) << std::right << bank;
318 Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
321 double phi = angles[2];
322 double chi = angles[1];
323 double omega = angles[0];
325 out << std::setw(8) << std::fixed << std::setprecision(2) << chi <<
" ";
326 out << std::setw(8) << std::fixed << std::setprecision(2) << phi <<
" ";
327 out << std::setw(8) << std::fixed << std::setprecision(2) << omega <<
" ";
331 const size_t first_peak_index = ids[0];
332 const auto &first_peak = peaks[first_peak_index];
333 const double monct = first_peak.getMonitorCount();
334 out << std::setw(12) << static_cast<int>(monct) <<
'\n';
335 out << header <<
'\n';
338 for (
auto wi : ids) {
339 const auto &peak = peaks[wi];
342 std::string firstNumber =
"3";
347 out << firstNumber << std::setw(7) << sequenceNumber;
350 out << firstNumber << std::setw(7) << peak.getPeakNumber() + appendPeakNumb;
356 const V3D mod = peak.getIntMNP();
357 const auto intHKL = peak.getIntHKL();
364 out << std::setw(5) <<
Utils::round(qSign * peak.getH()) << std::setw(5)
369 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getCol()) <<
" ";
371 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getRow()) <<
" ";
373 out << std::setw(8) << std::fixed << std::setprecision(0) << peak.getTOF() <<
" ";
375 out << std::setw(9) << std::fixed << std::setprecision(3) << (peak.getL2() * 100.0) <<
" ";
378 const V3D dir = peak.getDetPos() -
inst->getSample()->getPos();
379 double scattering, azimuth;
383 scattering = dir.
angle(
V3D(0.0, 0.0, 1.0));
388 azimuth = atan2(dir.Y(), dir.X());
390 out << std::setw(9) << std::fixed << std::setprecision(5) << scattering <<
" ";
392 out << std::setw(9) << std::fixed << std::setprecision(5) << azimuth <<
" ";
394 out << std::setw(10) << std::fixed << std::setprecision(6) << peak.getWavelength() <<
" ";
396 out << std::setw(9) << std::fixed << std::setprecision(4) << peak.getDSpacing() <<
" ";
398 out << std::setw(8) << std::fixed << std::setprecision(0) << int(peak.getBinCount()) <<
" ";
400 out << std::setw(10) << std::fixed << std::setprecision(2) << peak.getIntensity() <<
" ";
402 out << std::setw(7) << std::fixed << std::setprecision(2) << peak.getSigmaIntensity() <<
" ";
404 int thisReflag = 310;
405 out << std::setw(5) << thisReflag;
412 const auto &yValues = wsProfile2D->y(wi);
413 for (
size_t j = 0; j < yValues.size(); j++) {
414 out << std::setw(8) << static_cast<int>(yValues[j]);
415 if ((j + 1) % 10 == 0) {
417 if (j + 1 != yValues.size())