27#include <boost/container/flat_set.hpp>
28#include <boost/property_tree/ptree.hpp>
29#include <boost/property_tree/xml_parser.hpp>
31#include <boost/math/special_functions/round.hpp>
48Logger logger(
"SCDCalibratePanels2");
60 "Workspace of Indexed Peaks");
63 auto mustBeNonNegative = std::make_shared<BoundedValidator<double>>();
64 mustBeNonNegative->setLower(0.0);
65 declareProperty(
"RecalculateUB",
true,
"Recalculate UB matrix using given lattice constants");
66 declareProperty(
"a",
EMPTY_DBL(), mustBeNonNegative,
67 "Lattice Parameter a (Leave empty to use lattice constants "
68 "in peaks workspace)");
69 declareProperty(
"b",
EMPTY_DBL(), mustBeNonNegative,
70 "Lattice Parameter b (Leave empty to use lattice constants "
71 "in peaks workspace)");
72 declareProperty(
"c",
EMPTY_DBL(), mustBeNonNegative,
73 "Lattice Parameter c (Leave empty to use lattice constants "
74 "in peaks workspace)");
75 declareProperty(
"alpha",
EMPTY_DBL(), mustBeNonNegative,
76 "Lattice Parameter alpha in degrees (Leave empty to use "
77 "lattice constants in peaks workspace)");
78 declareProperty(
"beta",
EMPTY_DBL(), mustBeNonNegative,
79 "Lattice Parameter beta in degrees (Leave empty to use "
80 "lattice constants in peaks workspace)");
81 declareProperty(
"gamma",
EMPTY_DBL(), mustBeNonNegative,
82 "Lattice Parameter gamma in degrees (Leave empty to use "
83 "lattice constants in peaks workspace)");
84 const std::string LATTICE(
"Lattice Constants");
85 setPropertyGroup(
"RecalculateUB", LATTICE);
86 setPropertyGroup(
"a", LATTICE);
87 setPropertyGroup(
"b", LATTICE);
88 setPropertyGroup(
"c", LATTICE);
89 setPropertyGroup(
"alpha", LATTICE);
90 setPropertyGroup(
"beta", LATTICE);
91 setPropertyGroup(
"gamma", LATTICE);
92 setPropertySettings(
"a", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
93 setPropertySettings(
"b", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
94 setPropertySettings(
"c", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
95 setPropertySettings(
"alpha", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
96 setPropertySettings(
"beta", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
97 setPropertySettings(
"gamma", std::make_unique<EnabledWhenProperty>(
"RecalculateUB",
IS_DEFAULT));
99 declareProperty(
"Tolerance", 0.15, mustBeNonNegative,
"Peak indexing tolerance");
109 const std::string CALIBRATION(
"Calibration Options");
113 declareProperty(
"CalibrateL1",
true,
"Change the L1(source to sample) distance");
114 declareProperty(
"SearchRadiusL1", 0.1, mustBeNonNegative,
115 "Search radius of delta L1 in meters, which is used to constrain optimization search space"
116 "when calibrating L1");
118 setPropertySettings(
"SearchRadiusL1", std::make_unique<EnabledWhenProperty>(
"CalibrateL1",
IS_EQUAL_TO,
"1"));
120 setPropertyGroup(
"CalibrateL1", CALIBRATION);
121 setPropertyGroup(
"SearchRadiusL1", CALIBRATION);
125 declareProperty(
"CalibrateBanks",
false,
"Calibrate position and orientation of each bank.");
127 "SearchRadiusTransBank", 5e-2, mustBeNonNegative,
128 "This is the search radius (in meter) when calibrating component translations, used to constrain optimization"
129 "search space when calibration translation of banks");
130 declareProperty(
"SearchradiusRotXBank", 1.0, mustBeNonNegative,
131 "This is the search radius (in deg) when calibrating component reorientation, used to constrain "
132 "optimization search space");
133 declareProperty(
"SearchradiusRotYBank", 1.0, mustBeNonNegative,
134 "This is the search radius (in deg) when calibrating component reorientation, used to constrain "
135 "optimization search space");
136 declareProperty(
"SearchradiusRotZBank", 1.0, mustBeNonNegative,
137 "This is the search radius (in deg) when calibrating component reorientation, used to constrain "
138 "optimization search space");
139 declareProperty(
"CalibrateSize",
false,
"Calibrate detector size for each bank.");
140 declareProperty(
"SearchRadiusSize", 0.0, mustBeNonNegative,
141 "This is the search radius (unit less) of scale factor around at value 1.0 "
142 "when calibrating component size if it is a rectangualr detector.");
143 declareProperty(
"FixAspectRatio",
true,
144 "If true, the scaling factor for detector along X- and Y-axis "
145 "must be the same. Otherwise, the 2 scaling factors are free.");
146 declareProperty(
"BankName",
"",
147 "If given, only the specified bank/component will be calibrated."
148 "Otherwise, all banks will be calibrated.");
151 setPropertySettings(
"BankName", std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
152 setPropertySettings(
"SearchRadiusTransBank",
153 std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
154 setPropertySettings(
"SearchradiusRotXBank",
155 std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
156 setPropertySettings(
"SearchradiusRotYBank",
157 std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
158 setPropertySettings(
"SearchradiusRotZBank",
159 std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
160 setPropertySettings(
"CalibrateSize", std::make_unique<EnabledWhenProperty>(
"CalibrateBanks",
IS_EQUAL_TO,
"1"));
161 setPropertySettings(
"SearchRadiusSize", std::make_unique<EnabledWhenProperty>(
"CalibrateSize",
IS_EQUAL_TO,
"1"));
162 setPropertySettings(
"FixAspectRatio", std::make_unique<EnabledWhenProperty>(
"CalibrateSize",
IS_EQUAL_TO,
"1"));
164 setPropertyGroup(
"CalibrateBanks", CALIBRATION);
165 setPropertyGroup(
"BankName", CALIBRATION);
166 setPropertyGroup(
"SearchRadiusTransBank", CALIBRATION);
167 setPropertyGroup(
"SearchradiusRotXBank", CALIBRATION);
168 setPropertyGroup(
"SearchradiusRotYBank", CALIBRATION);
169 setPropertyGroup(
"SearchradiusRotZBank", CALIBRATION);
170 setPropertyGroup(
"CalibrateSize", CALIBRATION);
171 setPropertyGroup(
"SearchRadiusSize", CALIBRATION);
172 setPropertyGroup(
"FixAspectRatio", CALIBRATION);
177 declareProperty(
"CalibrateT0",
false,
"Calibrate the T0 (initial TOF)");
178 declareProperty(
"SearchRadiusT0", 10.0, mustBeNonNegative,
179 "Search radius of T0 (in ms), used to constrain optimization search space");
181 setPropertySettings(
"SearchRadiusT0", std::make_unique<EnabledWhenProperty>(
"CalibrateT0",
IS_EQUAL_TO,
"1"));
183 setPropertyGroup(
"CalibrateT0", CALIBRATION);
184 setPropertyGroup(
"SearchRadiusT0", CALIBRATION);
188 declareProperty(
"TuneSamplePosition",
false,
"Fine tunning sample position");
189 declareProperty(
"SearchRadiusSamplePos", 0.1, mustBeNonNegative,
190 "Search radius of sample position change (in meters), used to constrain optimization search space");
192 setPropertySettings(
"SearchRadiusSamplePos",
193 std::make_unique<EnabledWhenProperty>(
"TuneSamplePosition",
IS_EQUAL_TO,
"1"));
195 setPropertyGroup(
"TuneSamplePosition", CALIBRATION);
196 setPropertyGroup(
"SearchRadiusSamplePos", CALIBRATION);
200 "The workspace containing the calibration table.");
202 const std::vector<std::string> detcalExts{
".DetCal",
".Det_Cal"};
205 "Path to an ISAW-style .detcal file to save.");
208 "Path to an Mantid .xml description(for LoadParameterFile) file to "
212 "Path to an .csv file which contains the Calibration Table");
214 const std::string OUTPUT(
"Output");
215 setPropertyGroup(
"OutputWorkspace", OUTPUT);
216 setPropertyGroup(
"DetCalFilename", OUTPUT);
217 setPropertyGroup(
"XmlFilename", OUTPUT);
218 setPropertyGroup(
"CSVFilename", OUTPUT);
222 declareProperty(
"VerboseOutput",
false,
"Toggle of child algorithm console output.");
223 declareProperty(
"ProfileL1",
false,
"Perform profiling of objective function with given input for L1");
224 declareProperty(
"ProfileBanks",
false,
"Perform profiling of objective function with given input for Banks");
225 declareProperty(
"ProfileT0",
false,
"Perform profiling of objective function with given input for T0");
226 declareProperty(
"ProfileL1T0",
false,
"Perform profiling of objective function along L1 and T0");
228 const std::string ADVCNTRL(
"Advanced Option");
229 setPropertyGroup(
"VerboseOutput", ADVCNTRL);
230 setPropertyGroup(
"ProfileL1", ADVCNTRL);
231 setPropertyGroup(
"ProfileBanks", ADVCNTRL);
232 setPropertyGroup(
"ProfileT0", ADVCNTRL);
233 setPropertyGroup(
"ProfileL1T0", ADVCNTRL);
236 auto mustBePositive = std::make_shared<Kernel::BoundedValidator<int>>();
237 mustBePositive->setLower(0);
238 declareProperty(
"MaxFitIterations", 500, mustBePositive,
239 "Stop after this number of iterations if a good fit is not found");
248 std::map<std::string, std::string> issues;
261 (!pws->sample().hasOrientedLattice())) {
262 issues[
"RecalculateUB"] =
"Lattice constants are needed for peak "
263 "workspace without a UB mattrix";
268 throw std::runtime_error(
"calibrationTableColumnTypes and calibrationTableColumnTypes have different size.");
296 bool calibrateBanks =
getProperty(
"CalibrateBanks");
297 bool tuneSamplePos =
getProperty(
"TuneSamplePosition");
304 const std::string DetCalFilename =
getProperty(
"DetCalFilename");
305 const std::string XmlFilename =
getProperty(
"XmlFilename");
306 const std::string CSVFilename =
getProperty(
"CSVFilename");
310 double sizesearchradius =
getProperty(
"SearchRadiusSize");
311 bool fixdetxyratio =
getProperty(
"FixAspectRatio");
317 std::vector<std::pair<std::string, bool>> criteria{{
"BankName",
true}};
318 m_pws->sort(criteria);
350 g_log.
notice() <<
"** Calibrating L1 (moderator) as requested\n";
354 if (calibrateBanks) {
355 g_log.
notice() <<
"** Calibrating L2 and orientation (bank) as requested\n";
356 optimizeBanks(m_pws, pws_original, docalibsize, sizesearchradius, fixdetxyratio);
359 if (calibrateL1 && calibrateBanks) {
360 g_log.
notice() <<
"** Calibrating L1 (moderator) after bank adjusted\n";
378 if (calibrateT0 && !calibrateL1) {
383 g_log.
notice() <<
"** Calibrating T0 only as requested\n";
387 if (tuneSamplePos && !calibrateL1) {
388 g_log.
notice() <<
"** Tunning sample position only as requested\n";
392 if (calibrateT0 && tuneSamplePos && !calibrateL1) {
393 g_log.
warning() <<
"** You have chosen to calibrate T0 and sample position while ignoring"
394 <<
" L1, which means an iterative search outside this calibration is needed"
395 <<
" in order to find the minimum.\n";
399 g_log.
notice() <<
"-- Generate calibration table\n";
400 Instrument_sptr instCalibrated = std::const_pointer_cast<Geometry::Instrument>(m_pws->getInstrument());
405 if (!XmlFilename.empty()) {
409 if (!DetCalFilename.empty()) {
413 if (!CSVFilename.empty()) {
433 double original_L1 = std::abs(pws->getInstrument()->getSource()->getPos().Z());
436 bool tuneSamplepos =
getProperty(
"TuneSamplePosition");
442 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
444 std::vector<double> tofs =
captureTOF(pws_original);
445 objf->setPeakWorkspace(pws,
"moderator", tofs);
446 fitL1_alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(objf));
449 std::ostringstream tie_str;
450 tie_str <<
"DeltaX=0.0,DeltaY=0.0,"
451 <<
"RotX=0.0,RotY=0.0,RotZ=0.0";
452 if (!tuneSamplepos) {
453 tie_str <<
",DeltaSampleX=0.0,DeltaSampleY=0.0,DeltaSampleZ=0.0";
456 tie_str <<
",DeltaT0=" <<
m_T0;
458 std::ostringstream constraint_str;
460 r_L1 = std::abs(r_L1);
461 constraint_str << -r_L1 <<
"<DeltaZ<" << r_L1;
465 r_dT0 = std::abs(r_dT0);
466 constraint_str <<
"," << -r_dT0 <<
"<DeltaT0<" << r_dT0;
469 double r_dsp =
getProperty(
"SearchRadiusSamplePos");
470 r_dsp = std::abs(r_dsp);
471 constraint_str <<
"," << -r_dsp <<
"<DeltaSampleX<" << r_dsp
472 <<
"," << -r_dsp <<
"<DeltaSampleY<" << r_dsp
473 <<
"," << -r_dsp <<
"<DeltaSampleZ<" << r_dsp;
476 fitL1_alg->setProperty(
"Ties", tie_str.str());
477 fitL1_alg->setProperty(
"Constraints", constraint_str.str());
478 fitL1_alg->setProperty(
"InputWorkspace", l1ws);
479 fitL1_alg->setProperty(
"CreateOutput",
true);
480 fitL1_alg->setProperty(
"Output",
"fit");
481 fitL1_alg->executeAsChildAlg();
484 std::ostringstream calilog;
485 double chi2OverDOF = fitL1_alg->getProperty(
"OutputChi2overDoF");
488 double dL1_optimized = rst->getRef<
double>(
"Value", 2);
491 double dT0_optimized = rst->getRef<
double>(
"Value", 6);
497 double dsx_optimized = rst->getRef<
double>(
"Value", 7);
498 double dsy_optimized = rst->getRef<
double>(
"Value", 8);
499 double dsz_optimized = rst->getRef<
double>(
"Value", 9);
503 pws->getInstrument()->getSource()->getName(), pws);
504 m_T0 = dT0_optimized;
506 "sample-position", pws);
508 int npks = pws->getNumberPeaks();
509 calilog <<
"-- Fit L1 results using " << npks <<
" peaks:\n"
510 <<
" dL1: " << dL1_optimized <<
" \n"
511 <<
" L1 " << original_L1 <<
" -> " << -pws->getInstrument()->getSource()->getPos().Z() <<
" \n"
512 <<
" dT0 = " <<
m_T0 <<
" (ms)\n"
513 <<
" dSamplePos = (" << dsx_optimized <<
"," << dsy_optimized <<
"," << dsz_optimized <<
")\n"
514 <<
" chi2/DOF = " << chi2OverDOF <<
"\n";
528 const bool &docalibsize,
const double &sizesearchradius,
529 const bool &fixdetxyratio) {
532 for (
int i = 0; i < static_cast<int>(
m_BankNames.size()); ++i) {
535 const std::string bankname = *std::next(
m_BankNames.begin(), i);
536 const std::string pwsBankiName =
"_pws_" + bankname;
542 std::stringstream ss;
543 ss <<
"i = " << i <<
" m bank name = " << bankname;
545 ss <<
" ... True ...";
547 ss <<
" ... Stop ...";
558 std::vector<double> tofs =
captureTOF(pwsBanki_original);
562 int nBankPeaks = pwsBanki->getNumberPeaks();
565 std::ostringstream msg_npeakCheckFail;
566 msg_npeakCheckFail <<
"-- Bank " << bankname <<
" have only " << nBankPeaks <<
" (<" <<
MINIMUM_PEAKS_PER_BANK
567 <<
") Peaks, skipping\n";
578 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
579 objf->setPeakWorkspace(pwsBanki, bankname, tofs);
580 fitBank_alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(objf));
584 double searchRadiusRotX =
getProperty(
"SearchradiusRotXBank");
585 searchRadiusRotX = std::abs(searchRadiusRotX);
586 double searchRadiusRotY =
getProperty(
"SearchradiusRotYBank");
587 searchRadiusRotY = std::abs(searchRadiusRotY);
588 double searchRadiusRotZ =
getProperty(
"SearchradiusRotZBank");
589 searchRadiusRotZ = std::abs(searchRadiusRotZ);
591 double searchRadiusTran =
getProperty(
"SearchRadiusTransBank");
592 searchRadiusTran = std::abs(searchRadiusTran);
594 std::ostringstream tie_str;
595 tie_str <<
"DeltaSampleX=0.0,DeltaSampleY=0.0,DeltaSampleZ=0.0,"
596 <<
"DeltaT0=" <<
m_T0;
597 std::ostringstream constraint_str;
600 tie_str <<
",RotX=0.0";
602 constraint_str << -searchRadiusRotX <<
"<RotX<" << searchRadiusRotX <<
",";
606 tie_str <<
",RotY=0.0";
608 constraint_str << -searchRadiusRotY <<
"<RotY<" << searchRadiusRotY <<
",";
612 tie_str <<
",RotZ=0.0";
614 constraint_str << -searchRadiusRotZ <<
"<RotZ<" << searchRadiusRotZ <<
",";
618 tie_str <<
",DeltaX=0.0,DeltaY=0.0,DeltaZ=0.0";
620 constraint_str << -searchRadiusTran <<
"<DeltaX<" << searchRadiusTran <<
","
621 << -searchRadiusTran <<
"<DeltaY<" << searchRadiusTran <<
","
622 << -searchRadiusTran <<
"<DeltaZ<" << searchRadiusTran;
628 std::shared_ptr<const Geometry::RectangularDetector> rectDet =
629 std::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
633 std::ostringstream scaleconstraints;
634 std::ostringstream scaleties;
635 if (rectDet && docalibsize) {
637 scaleconstraints << scales.first - sizesearchradius <<
" <=ScaleX<" << scales.first + sizesearchradius;
639 scaleties <<
"ScaleX=ScaleY";
641 scaleconstraints <<
"," << scales.second - sizesearchradius <<
" <=ScaleY<" << scales.second + sizesearchradius;
645 scaleties <<
"ScaleX=" << scales.first <<
", ScaleY=" << scales.second;
649 std::string fitconstraint{constraint_str.str()};
650 if (scaleconstraints.str() !=
"") {
651 if (fitconstraint ==
"")
652 fitconstraint += scaleconstraints.str();
654 fitconstraint +=
"," + scaleconstraints.str();
656 std::string fittie{tie_str.str()};
657 if (scaleties.str() !=
"") {
659 fittie += scaleties.str();
661 fittie +=
"," + scaleties.str();
664 g_log.
information(
"Fitting " + bankname +
": constraint = " + fitconstraint +
"\n\t tie = " + fittie);
668 fitBank_alg->setProperty(
"Ties", fittie);
669 if (fitconstraint !=
"")
670 fitBank_alg->setProperty(
"Constraints", fitconstraint);
671 fitBank_alg->setProperty(
"InputWorkspace", wsBankCali);
672 fitBank_alg->setProperty(
"CreateOutput",
true);
673 fitBank_alg->setProperty(
"Output",
"fit");
676 fitBank_alg->executeAsChildAlg();
679 double chi2OverDOF = fitBank_alg->getProperty(
"OutputChi2overDoF");
681 double dx = rstFitBank->getRef<
double>(
"Value", 0);
682 double dy = rstFitBank->getRef<
double>(
"Value", 1);
683 double dz = rstFitBank->getRef<
double>(
"Value", 2);
684 double drx = rstFitBank->getRef<
double>(
"Value", 3);
685 double dry = rstFitBank->getRef<
double>(
"Value", 4);
686 double drz = rstFitBank->getRef<
double>(
"Value", 5);
687 double scalex = rstFitBank->getRef<
double>(
"Value", 10);
688 double scaley = rstFitBank->getRef<
double>(
"Value", 11);
691 std::string bn = bankname;
692 std::ostringstream calilog;
693 if (pws->getInstrument()->getName().compare(
"CORELLI") == 0) {
694 bn.append(
"/sixteenpack");
697 if (rectDet && docalibsize) {
706 V3D dtrans(dx, dy, dz);
707 V3D drots(drx, dry, drz);
708 calilog <<
"-- Fit " << bn <<
" results using " << nBankPeaks <<
" peaks:\n"
709 <<
" d(x,y,z) = " << dtrans <<
"\n"
710 <<
" r(x,y,z) = " << drots <<
"\n"
711 <<
" scale(x, y) = " <<
scalex <<
", " <<
scaley <<
" chi2/DOF = " << chi2OverDOF <<
"\n";
746 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
748 std::vector<double> tofs =
captureTOF(pws_original);
749 objf->setPeakWorkspace(pws,
"none", tofs);
750 fitT0_alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(objf));
753 std::ostringstream tie_str;
754 tie_str <<
"DeltaX=0.0,DeltaY=0.0,DeltaZ=0.0,"
755 <<
"RotX=0.0,RotY=0.0,RotZ=0.0,"
756 <<
"DeltaSampleX=0.0,DeltaSampleY=0.0,DeltaSampleZ=0.0";
757 std::ostringstream constraint_str;
759 r_dT0 = std::abs(r_dT0);
760 constraint_str << -r_dT0 <<
"<DeltaT0<" << r_dT0;
763 fitT0_alg->setProperty(
"Ties", tie_str.str());
764 fitT0_alg->setProperty(
"Constraints", constraint_str.str());
765 fitT0_alg->setProperty(
"InputWorkspace", t0ws);
766 fitT0_alg->setProperty(
"CreateOutput",
true);
767 fitT0_alg->setProperty(
"Output",
"fit");
768 fitT0_alg->executeAsChildAlg();
771 std::ostringstream calilog;
772 double chi2OverDOF = fitT0_alg->getProperty(
"OutputChi2overDoF");
774 double dT0_optimized = rst->getRef<
double>(
"Value", 6);
777 m_T0 = dT0_optimized;
778 int npks = pws->getNumberPeaks();
780 calilog <<
"-- Fit T0 results using " << npks <<
" peaks:\n"
781 <<
" dT0 = " <<
m_T0 <<
" (ms)\n"
782 <<
" chi2/DOF = " << chi2OverDOF <<
"\n";
799 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
801 std::vector<double> tofs =
captureTOF(pws_original);
802 objf->setPeakWorkspace(pws,
"none", tofs);
803 fitSamplePos_alg->setProperty(
"Function", std::dynamic_pointer_cast<IFunction>(objf));
806 std::ostringstream tie_str;
807 tie_str <<
"DeltaX=0.0,DeltaY=0.0,DeltaZ=0.0,"
808 <<
"RotX=0.0,RotY=0.0,RotZ=0.0,"
809 <<
"DeltaT0=" <<
m_T0;
810 std::ostringstream constraint_str;
811 double r_dsp =
getProperty(
"SearchRadiusSamplePos");
812 r_dsp = std::abs(r_dsp);
813 constraint_str << -r_dsp <<
"<DeltaSampleX<" << r_dsp <<
"," << -r_dsp <<
"<DeltaSampleY<" << r_dsp <<
"," << -r_dsp
814 <<
"<DeltaSampleZ<" << r_dsp;
817 fitSamplePos_alg->setProperty(
"Ties", tie_str.str());
818 fitSamplePos_alg->setProperty(
"Constraints", constraint_str.str());
819 fitSamplePos_alg->setProperty(
"InputWorkspace", samplePosws);
820 fitSamplePos_alg->setProperty(
"CreateOutput",
true);
821 fitSamplePos_alg->setProperty(
"Output",
"fit");
822 fitSamplePos_alg->executeAsChildAlg();
825 std::ostringstream calilog;
826 double chi2OverDOF = fitSamplePos_alg->getProperty(
"OutputChi2overDoF");
828 double dsx_optimized = rst->getRef<
double>(
"Value", 7);
829 double dsy_optimized = rst->getRef<
double>(
"Value", 8);
830 double dsz_optimized = rst->getRef<
double>(
"Value", 9);
834 "sample-position", pws);
835 int npks = pws->getNumberPeaks();
837 calilog <<
"-- Tune SamplePos results using " << npks <<
" peaks:\n"
838 <<
" deltaSamplePos = (" << dsx_optimized <<
"," << dsy_optimized <<
"," << dsz_optimized <<
")\n"
839 <<
" chi2/DOF = " << chi2OverDOF <<
"\n";
863 (pws->sample().hasOrientedLattice())) {
883 calcUB_alg->setProperty(
"PeaksWorkspace", pws);
884 calcUB_alg->setProperty(
"a",
m_a);
885 calcUB_alg->setProperty(
"b",
m_b);
886 calcUB_alg->setProperty(
"c",
m_c);
887 calcUB_alg->setProperty(
"alpha",
m_alpha);
888 calcUB_alg->setProperty(
"beta",
m_beta);
889 calcUB_alg->setProperty(
"gamma",
m_gamma);
890 calcUB_alg->executeAsChildAlg();
897 idxpks_alg->setProperty(
"PeaksWorkspace", pws);
898 idxpks_alg->setProperty(
"RoundHKLs",
true);
899 idxpks_alg->setProperty(
"Tolerance", tol);
900 idxpks_alg->executeAsChildAlg();
912 fltpk_alg->setProperty(
"InputWorkspace", pws);
913 fltpk_alg->setProperty(
"FilterVariable",
"h^2+k^2+l^2");
914 fltpk_alg->setProperty(
"Operator",
">");
915 fltpk_alg->setProperty(
"FilterValue", 0.0);
916 fltpk_alg->setProperty(
"OutputWorkspace",
"pws_filtered");
917 fltpk_alg->executeAsChildAlg();
930 std::vector<double> tofs;
932 for (
int i = 0; i < pws->getNumberPeaks(); ++i) {
933 tofs.emplace_back(pws->getPeak(i).getTOF());
945 auto peaksWorkspace = std::dynamic_pointer_cast<DataObjects::PeaksWorkspace>(pws);
947 throw std::invalid_argument(
"a PeaksWorkspace is required to retrieve bank names");
948 int npeaks =
static_cast<int>(pws->getNumberPeaks());
949 for (
int i = 0; i < npeaks; ++i) {
950 std::string bname = peaksWorkspace->getPeak(i).getBankName();
965 const std::string &bankname,
966 const std::string &outputwsn) {
969 fltpk_alg->setProperty(
"InputWorkspace", pws);
970 fltpk_alg->setProperty(
"BankName", bankname);
971 fltpk_alg->setProperty(
"Criterion",
"=");
972 fltpk_alg->setProperty(
"OutputWorkspace", outputwsn);
973 fltpk_alg->executeAsChildAlg();
987 int npeaks = pws->getNumberPeaks();
995 auto &spectrum = mws->getSpectrum(0);
996 auto &xvector = spectrum.mutableX();
997 auto &yvector = spectrum.mutableY();
998 auto &evector = spectrum.mutableE();
1001 double totalSigmaInt = 0.0;
1002 for (
int i = 0; i < npeaks; ++i) {
1003 totalSigmaInt += pws->getPeak(i).getSigmaIntensity();
1005 double totalInt = 0.0;
1006 for (
int i = 0; i < npeaks; ++i) {
1007 totalInt += pws->getPeak(i).getIntensity();
1009 double totalCnt = 0.0;
1010 for (
int i = 0; i < npeaks; ++i) {
1011 totalCnt += pws->getPeak(i).getBinCount();
1015 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1016 for (
int i = 0; i < npeaks; ++i) {
1018 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1022 if (totalSigmaInt > 0.0) {
1023 wgt = 1.0 / pws->getPeak(i).getSigmaIntensity();
1024 }
else if (totalInt > 0.0) {
1025 wgt = 1.0 / pws->getPeak(i).getIntensity();
1026 }
else if (totalCnt > 0.0) {
1027 wgt = 1.0 / pws->getPeak(i).getBinCount();
1030 for (
int j = 0; j < 3; ++j) {
1031 xvector[i * 3 + j] = i * 3 + j;
1032 yvector[i * 3 + j] = qv[j];
1033 evector[i * 3 + j] = wgt;
1055 double scalex,
double scaley,
const std::string &cmptName,
1061 mv_alg->setProperty(
"ComponentName", cmptName);
1062 mv_alg->setProperty(
"X", dx);
1063 mv_alg->setProperty(
"Y", dy);
1064 mv_alg->setProperty(
"Z", dz);
1065 mv_alg->setProperty(
"RelativePosition",
true);
1066 mv_alg->executeAsChildAlg();
1073 rot_alg->setProperty(
"ComponentName", cmptName);
1074 rot_alg->setProperty(
"X", 1.0);
1075 rot_alg->setProperty(
"Y", 0.0);
1076 rot_alg->setProperty(
"Z", 0.0);
1077 rot_alg->setProperty(
"Angle", drx);
1078 rot_alg->setProperty(
"RelativeRotation",
true);
1079 rot_alg->executeAsChildAlg();
1082 rot_alg->setProperty(
"ComponentName", cmptName);
1083 rot_alg->setProperty(
"X", 0.0);
1084 rot_alg->setProperty(
"Y", 1.0);
1085 rot_alg->setProperty(
"Z", 0.0);
1086 rot_alg->setProperty(
"Angle", dry);
1087 rot_alg->setProperty(
"RelativeRotation",
true);
1088 rot_alg->executeAsChildAlg();
1091 rot_alg->setProperty(
"ComponentName", cmptName);
1092 rot_alg->setProperty(
"X", 0.0);
1093 rot_alg->setProperty(
"Y", 0.0);
1094 rot_alg->setProperty(
"Z", 1.0);
1095 rot_alg->setProperty(
"Angle", drz);
1096 rot_alg->setProperty(
"RelativeRotation",
true);
1097 rot_alg->executeAsChildAlg();
1102 resizeAlg->initialize();
1103 resizeAlg->setProperty(
"Workspace", pws);
1104 resizeAlg->setProperty(
"ComponentName", cmptName);
1105 resizeAlg->setProperty(
"ScaleX",
scalex);
1106 resizeAlg->setProperty(
"ScaleY",
scaley);
1107 resizeAlg->execute();
1122 g_log.
notice() <<
"Generate a TableWorkspace to store calibration results.\n";
1131 V3D sourceRelPos = source->getRelativePos();
1135 sourceRow << instrument->getSource()->getName() << sourceRelPos.
X() << sourceRelPos.
Y() << sourceRelPos.
Z() << 1.0
1136 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0;
1142 if (instrument->getName().compare(
"CORELLI") == 0)
1143 bankName.append(
"/sixteenpack");
1145 std::shared_ptr<const IComponent> bank = instrument->getComponentByName(bankName);
1147 Quat relRot = bank->getRelativeRot();
1148 V3D pos1 = bank->getRelativePos();
1151 double deg, xAxis, yAxis, zAxis;
1160 bankRow << bankName << pos1.
X() << pos1.
Y() << pos1.
Z() << xAxis << yAxis << zAxis << deg << scales.first
1187 const boost::container::flat_set<std::string> &AllBankNames,
1191 using boost::property_tree::ptree;
1196 parafile.put(
"<xmlattr>.instrument", instrument->getName());
1197 parafile.put(
"<xmlattr>.valid-from", instrument->getValidFromDate().toISO8601String());
1201 ptree src_dx, src_dy, src_dz;
1202 ptree src_dx_val, src_dy_val, src_dz_val;
1205 V3D sourceRelPos = source->getRelativePos();
1207 src_dx_val.put(
"<xmlattr>.val", sourceRelPos.
X());
1208 src_dy_val.put(
"<xmlattr>.val", sourceRelPos.
Y());
1209 src_dz_val.put(
"<xmlattr>.val", sourceRelPos.
Z());
1210 src_dx.put(
"<xmlattr>.name",
"x");
1211 src_dy.put(
"<xmlattr>.name",
"y");
1212 src_dz.put(
"<xmlattr>.name",
"z");
1213 src.put(
"<xmlattr>.name", source->getName());
1215 src_dx.add_child(
"value", src_dx_val);
1216 src_dy.add_child(
"value", src_dy_val);
1217 src_dz.add_child(
"value", src_dz_val);
1218 src.add_child(
"parameter", src_dx);
1219 src.add_child(
"parameter", src_dy);
1220 src.add_child(
"parameter", src_dz);
1222 parafile.add_child(
"component-link", src);
1227 ptree property_root;
1228 property_root.put(
"<xmlattr>.name", instrument->getName());
1231 tof0.put(
"<xmlattr>.name",
"T0");
1232 tof0_val.put(
"<xmlattr>.val",
m_T0);
1233 tof0.add_child(
"value", tof0_val);
1234 property_root.add_child(
"parameter", tof0);
1235 parafile.add_child(
"component-link", property_root);
1239 ptree samplePos_dx, samplePos_dy, samplePos_dz;
1240 ptree samplePos_dx_val, samplePos_dy_val, samplePos_dz_val;
1242 std::shared_ptr<const IComponent> sp = instrument->getComponentByName(
"sample-position");
1243 V3D sppos = sp->getRelativePos();
1244 samplePos_dx_val.put(
"<xmlattr>.val", sppos.
X());
1245 samplePos_dy_val.put(
"<xmlattr>.val", sppos.
Y());
1246 samplePos_dz_val.put(
"<xmlattr>.val", sppos.
Z());
1247 samplePos_dx.put(
"<xmlattr>.name",
"x");
1248 samplePos_dy.put(
"<xmlattr>.name",
"y");
1249 samplePos_dz.put(
"<xmlattr>.name",
"z");
1250 samplePos.put(
"<xmlattr>.name",
"sample-position");
1252 samplePos_dx.add_child(
"value", samplePos_dx_val);
1253 samplePos_dy.add_child(
"value", samplePos_dy_val);
1254 samplePos_dz.add_child(
"value", samplePos_dz_val);
1255 samplePos.add_child(
"parameter", samplePos_dx);
1256 samplePos.add_child(
"parameter", samplePos_dy);
1257 samplePos.add_child(
"parameter", samplePos_dz);
1259 parafile.add_child(
"component-link", samplePos);
1262 for (
auto bankName : AllBankNames) {
1264 if (instrument->getName().compare(
"CORELLI") == 0)
1265 bankName.append(
"/sixteenpack");
1267 std::shared_ptr<const IComponent> bank = instrument->getComponentByName(bankName);
1268 auto bankFullName = bank->getFullName();
1270 Quat relRot = bank->getRelativeRot();
1272 V3D pos1 = bank->getRelativePos();
1277 ptree bank_dx, bank_dy, bank_dz;
1278 ptree bank_dx_val, bank_dy_val, bank_dz_val;
1279 ptree bank_drotx, bank_droty, bank_drotz;
1280 ptree bank_drotx_val, bank_droty_val, bank_drotz_val;
1281 ptree bank_sx, bank_sy;
1282 ptree bank_sx_val, bank_sy_val;
1285 bank_dx_val.put(
"<xmlattr>.val", pos1.
X());
1286 bank_dy_val.put(
"<xmlattr>.val", pos1.
Y());
1287 bank_dz_val.put(
"<xmlattr>.val", pos1.
Z());
1288 bank_dx.put(
"<xmlattr>.name",
"x");
1289 bank_dy.put(
"<xmlattr>.name",
"y");
1290 bank_dz.put(
"<xmlattr>.name",
"z");
1292 bank_drotx_val.put(
"<xmlattr>.val", relRotAngles[0]);
1293 bank_droty_val.put(
"<xmlattr>.val", relRotAngles[1]);
1294 bank_drotz_val.put(
"<xmlattr>.val", relRotAngles[2]);
1295 bank_drotx.put(
"<xmlattr>.name",
"rotx");
1296 bank_droty.put(
"<xmlattr>.name",
"roty");
1297 bank_drotz.put(
"<xmlattr>.name",
"rotz");
1299 bank_sx_val.put(
"<xmlattr>.val", scales.first);
1300 bank_sy_val.put(
"<xmlattr>.val", scales.second);
1301 bank_sx.put(
"<xmlattr>.name",
"scalex");
1302 bank_sy.put(
"<xmlattr>.name",
"scaley");
1304 bank_root.put(
"<xmlattr>.name", bankFullName);
1307 bank_dx.add_child(
"value", bank_dx_val);
1308 bank_dy.add_child(
"value", bank_dy_val);
1309 bank_dz.add_child(
"value", bank_dz_val);
1311 bank_drotx.add_child(
"value", bank_drotx_val);
1312 bank_droty.add_child(
"value", bank_droty_val);
1313 bank_drotz.add_child(
"value", bank_drotz_val);
1315 bank_sx.add_child(
"value", bank_sx_val);
1316 bank_sy.add_child(
"value", bank_sy_val);
1318 bank_root.add_child(
"parameter", bank_drotx);
1320 bank_root.add_child(
"parameter", bank_droty);
1321 bank_root.add_child(
"parameter", bank_drotz);
1322 bank_root.add_child(
"parameter", bank_dx);
1323 bank_root.add_child(
"parameter", bank_dy);
1324 bank_root.add_child(
"parameter", bank_dz);
1325 bank_root.add_child(
"parameter", bank_sx);
1326 bank_root.add_child(
"parameter", bank_sy);
1328 parafile.add_child(
"component-link", bank_root);
1332 root.add_child(
"parameter-file", parafile);
1334 g_log.
notice() <<
"\tSaving parameter file as " << FileName <<
"\n";
1335 boost::property_tree::write_xml(FileName, root, std::locale(),
1336 boost::property_tree::xml_writer_settings<std::string>(
' ', 2));
1350 boost::container::flat_set<std::string> &AllBankName,
1351 std::shared_ptr<Instrument> &instrument,
double T0) {
1352 g_log.
notice() <<
"Saving DetCal file in " << filename <<
"\n";
1354 bool tuneSamplePos =
getProperty(
"TuneSamplePosition");
1355 if (tuneSamplePos) {
1357 <<
"DetCal format cannot retain sample position info, therefore the calibrated "
1358 <<
"sample position will be lost if DetCal format is the only output!\n";
1362 const size_t number_spectra = instrument->getNumberDetectors();
1365 wksp->setInstrument(instrument);
1366 wksp->rebuildSpectraMapping(
true );
1369 std::vector<std::string> banknames(AllBankName.begin(), AllBankName.end());
1373 alg->setProperty(
"InputWorkspace", wksp);
1374 alg->setProperty(
"Filename", filename);
1375 alg->setProperty(
"TimeOffset", T0);
1376 alg->setProperty(
"BankNames", banknames);
1377 alg->executeAsChildAlg();
1389 alg->setProperty(
"InputWorkspace", tws);
1390 alg->setProperty(
"Filename", FileName);
1391 alg->setPropertyValue(
"CommentIndicator",
"#");
1392 alg->setPropertyValue(
"Separator",
"CSV");
1393 alg->setProperty(
"ColumnHeader",
true);
1394 alg->setProperty(
"AppendToFile",
false);
1395 alg->executeAsChildAlg();
1406 g_log.
notice() <<
"START of profiling objective func along L1\n";
1416 std::ostringstream msgrst;
1417 msgrst.precision(12);
1418 msgrst <<
"dL1\tresidual\n";
1421 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1423 std::vector<double> tofs =
captureTOF(pws_original);
1424 objf->setPeakWorkspace(pws,
"moderator", tofs);
1427 const int n_peaks = pws->getNumberPeaks();
1428 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1431 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1432 for (
int i = 0; i < n_peaks; ++i) {
1433 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1435 for (
int j = 0; j < 3; ++j) {
1436 target[i * 3 + j] = qv[j];
1440 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1444 double deltaL1 = -4e-2;
1445 while (deltaL1 < 4e-2) {
1446 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1447 objf->setParameter(
"DeltaZ", deltaL1);
1448 objf->setParameter(
"DeltaT0", 0.0);
1449 objf->function1D(out.get(), xValues, 1);
1452 double residual = 0.0;
1453 for (
int i = 0; i < n_peaks * 3; ++i) {
1454 residual += (out[i] - target[i]) * (out[i] - target[i]);
1456 residual = std::sqrt(residual) / (n_peaks - 1);
1458 msgrst << deltaL1 <<
"\t" << residual <<
"\n";
1461 g_log.
notice() << deltaL1 <<
" -- " << residual <<
"\n";
1469 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_L1.csv";
1470 std::ofstream profL1File;
1471 profL1File.open(filenamebase.string());
1472 profL1File << msgrst.str();
1475 << filenamebase <<
"\n"
1476 <<
"END of profiling objective func along L1\n";
1487 g_log.
notice() <<
"START of profiling all banks along six degree of freedom\n";
1498 for (
int bankIndex = 0; bankIndex < static_cast<int>(
m_BankNames.size()); ++bankIndex) {
1501 const std::string bankname = *std::next(
m_BankNames.begin(), bankIndex);
1502 const std::string pwsBankiName =
"_pws_" + bankname;
1508 std::vector<double> tofs =
captureTOF(pwsBanki_original);
1512 int nBankPeaks = pwsBanki->getNumberPeaks();
1515 std::ostringstream msg_npeakCheckFail;
1516 msg_npeakCheckFail <<
"-- Cannot profile Bank " << bankname <<
" have only " << nBankPeaks <<
" (<"
1524 std::ostringstream msgrst;
1525 msgrst.precision(12);
1526 msgrst <<
"dx\tdy\tdz\ttheta\tphi\trogang\tresidual\n";
1528 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1529 objf->setPeakWorkspace(pwsBanki, bankname, tofs);
1531 const int n_peaks = pwsBanki->getNumberPeaks();
1532 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1534 auto ubmatrix = pwsBanki->sample().getOrientedLattice().getUB();
1535 for (
int i = 0; i < n_peaks; ++i) {
1536 V3D qv = ubmatrix * pwsBanki->getPeak(i).getIntHKL();
1538 for (
int j = 0; j < 3; ++j) {
1539 target[i * 3 + j] = qv[j];
1543 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1546 for (
double dx = -1e-2; dx < 1e-2; dx += 2e-2 / 20.0) {
1548 for (
double dy = -1e-2; dy < 1e-2; dy += 2e-2 / 20.0) {
1550 for (
double dz = -1e-2; dz < 1e-2; dz += 2e-2 / 20.0) {
1552 for (
double theta = 0.0; theta <
PI; theta +=
PI / 20.0) {
1554 for (
double phi = 0.0; phi < 2 *
PI; phi += 2 *
PI / 20.0) {
1556 for (
double ang = -5.0; ang < 5.0; ang += 5.0 / 20.0) {
1559 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1560 objf->setParameter(
"DeltaX", dx);
1561 objf->setParameter(
"DeltaY", dy);
1562 objf->setParameter(
"DeltaZ", dz);
1563 objf->setParameter(
"Theta", theta);
1564 objf->setParameter(
"Phi", phi);
1565 objf->setParameter(
"DeltaRotationAngle", ang);
1566 objf->setParameter(
"DeltaT0", 0.0);
1567 objf->function1D(out.get(), xValues, 1);
1569 double residual = 0.0;
1570 for (
int i = 0; i < n_peaks * 3; ++i) {
1571 residual += (out[i] - target[i]) * (out[i] - target[i]);
1573 residual = std::sqrt(residual) / (n_peaks - 6);
1575 msgrst << dx <<
"\t" << dy <<
"\t" << dz <<
"\t" << theta <<
"\t" << phi <<
"\t" << ang <<
"\t"
1576 << residual <<
"\n";
1579 g_log.
notice() <<
"--" << bankname <<
": " << residual <<
"\n";
1589 const std::string csvname =
"profileSCDCalibratePanels2_" + bankname +
".csv";
1590 auto filenamebase = std::filesystem::temp_directory_path() / csvname;
1591 std::ofstream profBankFile;
1592 profBankFile.open(filenamebase.string());
1593 profBankFile << msgrst.str();
1594 profBankFile.close();
1597 std::ostringstream msg;
1598 msg <<
"Profile of " << bankname <<
" is saved at:\n"
1599 << filenamebase <<
"\n"
1600 <<
"END of profiling objective func for " << bankname <<
"\n";
1615 g_log.
notice() <<
"START of profiling objective func along T0\n";
1625 std::ostringstream msgrst;
1626 msgrst.precision(12);
1627 msgrst <<
"dT0\tresidual\n";
1630 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1632 std::vector<double> tofs =
captureTOF(pws_original);
1633 objf->setPeakWorkspace(pws,
"none", tofs);
1636 const int n_peaks = pws->getNumberPeaks();
1637 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1638 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1639 for (
int i = 0; i < n_peaks; ++i) {
1640 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1642 for (
int j = 0; j < 3; ++j) {
1643 target[i * 3 + j] = qv[j];
1647 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1650 double deltaT0 = -10;
1651 while (deltaT0 < 10) {
1652 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1653 objf->setParameter(
"DeltaT0", deltaT0);
1654 objf->function1D(out.get(), xValues, 1);
1657 double residual = 0.0;
1658 for (
int i = 0; i < n_peaks * 3; ++i) {
1659 residual += (out[i] - target[i]) * (out[i] - target[i]);
1661 residual = std::sqrt(residual) / (n_peaks - 1);
1663 msgrst << deltaT0 <<
"\t" << residual <<
"\n";
1666 g_log.
notice() << deltaT0 <<
" -- " << residual <<
"\n";
1674 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_T0.csv";
1675 std::ofstream profL1File;
1676 profL1File.open(filenamebase.string());
1677 profL1File << msgrst.str();
1680 << filenamebase <<
"\n"
1681 <<
"END of profiling objective func along T0\n";
1692 g_log.
notice() <<
"START of profiling objective func along L1 and T0\n";
1698 g_log.
notice() <<
"deltaL1 -- deltaT0 -- residual\n";
1702 std::ostringstream msgrst;
1703 msgrst.precision(12);
1704 msgrst <<
"dL1\tdT0\tresidual\n";
1707 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1709 std::vector<double> tofs =
captureTOF(pws_original);
1710 objf->setPeakWorkspace(pws,
"moderator", tofs);
1713 const int n_peaks = pws->getNumberPeaks();
1714 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1715 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1716 for (
int i = 0; i < n_peaks; ++i) {
1717 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1719 for (
int j = 0; j < 3; ++j) {
1720 target[i * 3 + j] = qv[j];
1724 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1727 for (
double deltaL1 = -4e-2; deltaL1 < 4e-2; deltaL1 += 1e-4) {
1728 for (
double deltaT0 = -4.0; deltaT0 < 4.0; deltaT0 += 1e-2) {
1729 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1730 objf->setParameter(
"DeltaZ", deltaL1);
1731 objf->setParameter(
"DeltaT0", deltaT0);
1732 objf->function1D(out.get(), xValues, 1);
1735 double residual = 0.0;
1736 for (
int i = 0; i < n_peaks * 3; ++i) {
1737 residual += (out[i] - target[i]) * (out[i] - target[i]);
1739 residual = std::sqrt(residual) / (n_peaks - 2);
1742 g_log.
notice() << deltaL1 <<
" -- " << deltaT0 <<
" -- " << residual <<
"\n";
1745 msgrst << deltaL1 <<
"\t" << deltaT0 <<
"\t" << residual <<
"\n";
1750 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_L1T0.csv";
1751 std::ofstream profL1File;
1752 profL1File.open(filenamebase.string());
1753 profL1File << msgrst.str();
1758 << filenamebase <<
"\n"
1759 <<
"END of profiling objective func along L1 and T0\n";
1774std::pair<double, double>
1776 const std::string &bankname,
1779 std::pair<double, double> scales{1.0, 1.0};
1783 std::shared_ptr<const Geometry::RectangularDetector> rectDet =
1784 std::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
1788 auto scalexparams =
pmap.getDouble(rectDet->getName(),
"scalex");
1789 auto scaleyparams =
pmap.getDouble(rectDet->getName(),
"scaley");
1790 if (!scalexparams.empty())
1791 scales.first = scalexparams[0];
1792 if (!scaleyparams.empty())
1793 scales.second = scaleyparams[0];
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
@ OptionalSave
to specify a file to write to but an empty string is
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
SCDCalibratePanels2 : Using input peakworkspace with indexation results to calibrate each individual ...
Mantid::API::IPeaksWorkspace_sptr removeUnindexedPeaks(const Mantid::API::IPeaksWorkspace_sptr &pws)
Remove unindexed peaks from workspace.
void adjustComponent(double dx, double dy, double dz, double drx, double dry, double drz, double scalex, double scaley, const std::string &cmptName, Mantid::API::IPeaksWorkspace_sptr &pws)
Helper functions for adjusting components.
void saveIsawDetCal(const std::string &filename, boost::container::flat_set< std::string > &AllBankName, std::shared_ptr< Geometry::Instrument > &instrument, double T0)
Save to ISAW type det calibration output for backward compatiblity.
Mantid::API::ITableWorkspace_sptr generateCalibrationTable(std::shared_ptr< Geometry::Instrument > &instrument, const Geometry::ParameterMap &pmap)
Generate a Table workspace to store the calibration results.
void profileBanks(Mantid::API::IPeaksWorkspace_sptr const &pws, const Mantid::API::IPeaksWorkspace_sptr &pws_original)
Profiling obj func along six degree of freedom, which can be very slow.
void optimizeT0(Mantid::API::IPeaksWorkspace_sptr pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Private function for calibrating T0.
void optimizeL1(Mantid::API::IPeaksWorkspace_sptr pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Private function for calibrating L1.
double m_a
unique vars for a given instance of calibration
void optimizeSamplePos(Mantid::API::IPeaksWorkspace_sptr pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Private function for fine tunning sample position.
const std::vector< std::string > calibrationTableColumnTypes
void getBankNames(const Mantid::API::IPeaksWorkspace_sptr &pws)
Private function for getting names of banks to be calibrated.
boost::container::flat_set< std::string > m_BankNames
const int MINIMUM_PEAKS_PER_BANK
static constexpr double Tolerance
void updateUBMatrix(const Mantid::API::IPeaksWorkspace_sptr &pws)
Update the UB matrix.
void optimizeBanks(Mantid::API::IPeaksWorkspace_sptr pws, const Mantid::API::IPeaksWorkspace_sptr &pws_original, const bool &docalibsize, const double &sizesearchradius, const bool &fixdetxyratio)
Private function for calibrating banks.
void parseLatticeConstant(const Mantid::API::IPeaksWorkspace_sptr &pws)
Private function dedicated for parsing lattice constant.
const std::vector< std::string > calibrationTableColumnNames
void saveXmlFile(const std::string &FileName, const boost::container::flat_set< std::string > &AllBankNames, std::shared_ptr< Geometry::Instrument > &instrument, const Geometry::ParameterMap &pmap)
Save to xml file for Mantid to load by manual crafting.
void exec() override
Overwrites Algorithm method.
void profileT0(Mantid::API::IPeaksWorkspace_sptr &pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Profile obj func along T0 axis.
Mantid::API::IPeaksWorkspace_sptr selectPeaksByBankName(const Mantid::API::IPeaksWorkspace_sptr &pws, const std::string &bankname, const std::string &outputwsn)
Helper function for selecting peaks based on given bank name.
std::map< std::string, std::string > validateInputs() override
Private validator for inputs.
std::pair< double, double > getRectangularDetectorScaleFactors(std::shared_ptr< Geometry::Instrument > &instrument, const std::string &bankname, const Geometry::ParameterMap &pmap)
Retrieve "scalex" and "scaley" from a workspace's parameter map if the component is rectangular detec...
std::string mCalibBankName
void saveCalibrationTable(const std::string &FileName, Mantid::API::ITableWorkspace_sptr const &tws)
Save the calibration table to a CSV file.
Mantid::API::MatrixWorkspace_sptr getIdealQSampleAsHistogram1D(const Mantid::API::IPeaksWorkspace_sptr &pws)
Helper function that calculates the ideal qSample based on integer HKL.
void profileL1(Mantid::API::IPeaksWorkspace_sptr &pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Profile related functions.
void profileL1T0(Mantid::API::IPeaksWorkspace_sptr &pws, Mantid::API::IPeaksWorkspace_sptr pws_original)
Profile obj func along L1 and T0 axis.
std::vector< double > captureTOF(const Mantid::API::IPeaksWorkspace_sptr &pws)
Cache TOF equivalent to those measured from experiment.
Class to implement UB matrix.
double alpha() const
Get lattice parameter.
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
double c() const
Get lattice parameter.
double beta() const
Get lattice parameter.
double b() const
Get lattice parameter.
double gamma() const
Get lattice parameter.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
void notice(const std::string &msg)
Logs at notice level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
void getAngleAxis(double &_deg, double &_ax0, double &_ax1, double &ax2) const
Extracts the angle of roatation and axis.
std::vector< double > getEulerAngles(const std::string &convention) const
Calculate the Euler angles that are equivalent to this Quaternion.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
constexpr double Z() const noexcept
Get z.
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Generate a tableworkspace to store the calibration results.
adjust instrument component position and orientation
: detector size scale at y-direction
@ Input
An input workspace.
@ Output
An output workspace.