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());
254 V3D center = componentInfo.position(componentInfo.indexOf(det->getComponentID()));
257 double detd = (center -
inst->getSample()->getPos()).norm();
260 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize);
262 int midX = NCOLS / 2;
263 int midY = NROWS / 2;
272 out <<
"5 " << std::setw(6) << std::right << bank <<
" " << std::setw(6) << std::right << NROWS <<
" "
273 << std::setw(6) << std::right << NCOLS <<
" " << std::setw(7) << std::right << std::fixed
274 << std::setprecision(4) << 100.0 * xsize <<
" " << std::setw(7) << std::right << std::fixed
275 << std::setprecision(4) << 100.0 * ysize <<
" "
276 <<
" 0.2000 " << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0 * detd <<
" "
277 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
X() <<
" "
278 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Y() <<
" "
279 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.
Z() <<
" "
280 << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.
X() <<
" " << std::setw(8)
281 << std::right << std::fixed << std::setprecision(5) << base.
Y() <<
" " << std::setw(8) << std::right
282 << std::fixed << std::setprecision(5) << base.
Z() <<
" " << std::setw(8) << std::right << std::fixed
283 << std::setprecision(5) << up.
X() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5)
284 << up.
Y() <<
" " << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.
Z() <<
" \n";
287 g_log.
warning() <<
"Information about detector module " << bankName <<
" not found and recognised\n";
293 if (
m_ws->getConvention() ==
"Crystallography")
298 int sequenceNumber = appendPeakNumb;
299 for (
const auto &runBankMap : runMap) {
301 const int run = runBankMap.first;
302 const auto &bankMap = runBankMap.second;
304 for (
const auto &bankIDs : bankMap) {
306 const int bank = bankIDs.first;
307 const auto &ids = bankIDs.second;
311 out <<
"0 NRUN DETNUM CHI PHI OMEGA MONCNT\n";
312 out <<
"1 " << std::setw(5) << run << std::setw(7) << std::right << bank;
316 Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
319 double phi = angles[2];
320 double chi = angles[1];
321 double omega = angles[0];
323 out << std::setw(8) << std::fixed << std::setprecision(2) << chi <<
" ";
324 out << std::setw(8) << std::fixed << std::setprecision(2) << phi <<
" ";
325 out << std::setw(8) << std::fixed << std::setprecision(2) << omega <<
" ";
329 const size_t first_peak_index = ids[0];
330 const auto &first_peak = peaks[first_peak_index];
331 const double monct = first_peak.getMonitorCount();
332 out << std::setw(12) << static_cast<int>(monct) <<
'\n';
333 out << header <<
'\n';
336 for (
auto wi : ids) {
337 const auto &peak = peaks[wi];
340 std::string firstNumber =
"3";
345 out << firstNumber << std::setw(7) << sequenceNumber;
348 out << firstNumber << std::setw(7) << peak.getPeakNumber() + appendPeakNumb;
354 const V3D mod = peak.getIntMNP();
355 const auto intHKL = peak.getIntHKL();
362 out << std::setw(5) <<
Utils::round(qSign * peak.getH()) << std::setw(5)
367 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getCol()) <<
" ";
369 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getRow()) <<
" ";
371 out << std::setw(8) << std::fixed << std::setprecision(0) << peak.getTOF() <<
" ";
373 out << std::setw(9) << std::fixed << std::setprecision(3) << (peak.getL2() * 100.0) <<
" ";
376 const V3D dir = peak.getDetPos() -
inst->getSample()->getPos();
377 double scattering, azimuth;
381 scattering = dir.
angle(
V3D(0.0, 0.0, 1.0));
386 azimuth = atan2(dir.Y(), dir.X());
388 out << std::setw(9) << std::fixed << std::setprecision(5) << scattering <<
" ";
390 out << std::setw(9) << std::fixed << std::setprecision(5) << azimuth <<
" ";
392 out << std::setw(10) << std::fixed << std::setprecision(6) << peak.getWavelength() <<
" ";
394 out << std::setw(9) << std::fixed << std::setprecision(4) << peak.getDSpacing() <<
" ";
396 out << std::setw(8) << std::fixed << std::setprecision(0) << int(peak.getBinCount()) <<
" ";
398 out << std::setw(10) << std::fixed << std::setprecision(2) << peak.getIntensity() <<
" ";
400 out << std::setw(7) << std::fixed << std::setprecision(2) << peak.getSigmaIntensity() <<
" ";
402 int thisReflag = 310;
403 out << std::setw(5) << thisReflag;
410 const auto &yValues = wsProfile2D->y(wi);
411 for (
size_t j = 0; j < yValues.size(); j++) {
412 out << std::setw(8) << static_cast<int>(yValues[j]);
413 if ((j + 1) % 10 == 0) {
415 if (j + 1 != yValues.size())