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);
1269 Quat relRot = bank->getRelativeRot();
1271 V3D pos1 = bank->getRelativePos();
1276 ptree bank_dx, bank_dy, bank_dz;
1277 ptree bank_dx_val, bank_dy_val, bank_dz_val;
1278 ptree bank_drotx, bank_droty, bank_drotz;
1279 ptree bank_drotx_val, bank_droty_val, bank_drotz_val;
1280 ptree bank_sx, bank_sy;
1281 ptree bank_sx_val, bank_sy_val;
1284 bank_dx_val.put(
"<xmlattr>.val", pos1.
X());
1285 bank_dy_val.put(
"<xmlattr>.val", pos1.
Y());
1286 bank_dz_val.put(
"<xmlattr>.val", pos1.
Z());
1287 bank_dx.put(
"<xmlattr>.name",
"x");
1288 bank_dy.put(
"<xmlattr>.name",
"y");
1289 bank_dz.put(
"<xmlattr>.name",
"z");
1291 bank_drotx_val.put(
"<xmlattr>.val", relRotAngles[0]);
1292 bank_droty_val.put(
"<xmlattr>.val", relRotAngles[1]);
1293 bank_drotz_val.put(
"<xmlattr>.val", relRotAngles[2]);
1294 bank_drotx.put(
"<xmlattr>.name",
"rotx");
1295 bank_droty.put(
"<xmlattr>.name",
"roty");
1296 bank_drotz.put(
"<xmlattr>.name",
"rotz");
1298 bank_sx_val.put(
"<xmlattr>.val", scales.first);
1299 bank_sy_val.put(
"<xmlattr>.val", scales.second);
1300 bank_sx.put(
"<xmlattr>.name",
"scalex");
1301 bank_sy.put(
"<xmlattr>.name",
"scaley");
1303 bank_root.put(
"<xmlattr>.name", bankName);
1306 bank_dx.add_child(
"value", bank_dx_val);
1307 bank_dy.add_child(
"value", bank_dy_val);
1308 bank_dz.add_child(
"value", bank_dz_val);
1310 bank_drotx.add_child(
"value", bank_drotx_val);
1311 bank_droty.add_child(
"value", bank_droty_val);
1312 bank_drotz.add_child(
"value", bank_drotz_val);
1314 bank_sx.add_child(
"value", bank_sx_val);
1315 bank_sy.add_child(
"value", bank_sy_val);
1317 bank_root.add_child(
"parameter", bank_drotx);
1319 bank_root.add_child(
"parameter", bank_droty);
1320 bank_root.add_child(
"parameter", bank_drotz);
1321 bank_root.add_child(
"parameter", bank_dx);
1322 bank_root.add_child(
"parameter", bank_dy);
1323 bank_root.add_child(
"parameter", bank_dz);
1324 bank_root.add_child(
"parameter", bank_sx);
1325 bank_root.add_child(
"parameter", bank_sy);
1327 parafile.add_child(
"component-link", bank_root);
1331 root.add_child(
"parameter-file", parafile);
1333 g_log.
notice() <<
"\tSaving parameter file as " << FileName <<
"\n";
1334 boost::property_tree::write_xml(FileName, root, std::locale(),
1335 boost::property_tree::xml_writer_settings<std::string>(
' ', 2));
1349 boost::container::flat_set<std::string> &AllBankName,
1350 std::shared_ptr<Instrument> &instrument,
double T0) {
1351 g_log.
notice() <<
"Saving DetCal file in " << filename <<
"\n";
1353 bool tuneSamplePos =
getProperty(
"TuneSamplePosition");
1354 if (tuneSamplePos) {
1356 <<
"DetCal format cannot retain sample position info, therefore the calibrated "
1357 <<
"sample position will be lost if DetCal format is the only output!\n";
1361 const size_t number_spectra = instrument->getNumberDetectors();
1364 wksp->setInstrument(instrument);
1365 wksp->rebuildSpectraMapping(
true );
1368 std::vector<std::string> banknames(AllBankName.begin(), AllBankName.end());
1372 alg->setProperty(
"InputWorkspace", wksp);
1373 alg->setProperty(
"Filename", filename);
1374 alg->setProperty(
"TimeOffset", T0);
1375 alg->setProperty(
"BankNames", banknames);
1376 alg->executeAsChildAlg();
1388 alg->setProperty(
"InputWorkspace", tws);
1389 alg->setProperty(
"Filename", FileName);
1390 alg->setPropertyValue(
"CommentIndicator",
"#");
1391 alg->setPropertyValue(
"Separator",
"CSV");
1392 alg->setProperty(
"ColumnHeader",
true);
1393 alg->setProperty(
"AppendToFile",
false);
1394 alg->executeAsChildAlg();
1405 g_log.
notice() <<
"START of profiling objective func along L1\n";
1415 std::ostringstream msgrst;
1416 msgrst.precision(12);
1417 msgrst <<
"dL1\tresidual\n";
1420 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1422 std::vector<double> tofs =
captureTOF(pws_original);
1423 objf->setPeakWorkspace(pws,
"moderator", tofs);
1426 const int n_peaks = pws->getNumberPeaks();
1427 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1430 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1431 for (
int i = 0; i < n_peaks; ++i) {
1432 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1434 for (
int j = 0; j < 3; ++j) {
1435 target[i * 3 + j] = qv[j];
1439 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1443 double deltaL1 = -4e-2;
1444 while (deltaL1 < 4e-2) {
1445 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1446 objf->setParameter(
"DeltaZ", deltaL1);
1447 objf->setParameter(
"DeltaT0", 0.0);
1448 objf->function1D(out.get(), xValues, 1);
1451 double residual = 0.0;
1452 for (
int i = 0; i < n_peaks * 3; ++i) {
1453 residual += (out[i] - target[i]) * (out[i] - target[i]);
1455 residual = std::sqrt(residual) / (n_peaks - 1);
1457 msgrst << deltaL1 <<
"\t" << residual <<
"\n";
1460 g_log.
notice() << deltaL1 <<
" -- " << residual <<
"\n";
1468 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_L1.csv";
1469 std::ofstream profL1File;
1470 profL1File.open(filenamebase.string());
1471 profL1File << msgrst.str();
1474 << filenamebase <<
"\n"
1475 <<
"END of profiling objective func along L1\n";
1486 g_log.
notice() <<
"START of profiling all banks along six degree of freedom\n";
1497 for (
int bankIndex = 0; bankIndex < static_cast<int>(
m_BankNames.size()); ++bankIndex) {
1500 const std::string bankname = *std::next(
m_BankNames.begin(), bankIndex);
1501 const std::string pwsBankiName =
"_pws_" + bankname;
1507 std::vector<double> tofs =
captureTOF(pwsBanki_original);
1511 int nBankPeaks = pwsBanki->getNumberPeaks();
1514 std::ostringstream msg_npeakCheckFail;
1515 msg_npeakCheckFail <<
"-- Cannot profile Bank " << bankname <<
" have only " << nBankPeaks <<
" (<"
1523 std::ostringstream msgrst;
1524 msgrst.precision(12);
1525 msgrst <<
"dx\tdy\tdz\ttheta\tphi\trogang\tresidual\n";
1527 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1528 objf->setPeakWorkspace(pwsBanki, bankname, tofs);
1530 const int n_peaks = pwsBanki->getNumberPeaks();
1531 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1533 auto ubmatrix = pwsBanki->sample().getOrientedLattice().getUB();
1534 for (
int i = 0; i < n_peaks; ++i) {
1535 V3D qv = ubmatrix * pwsBanki->getPeak(i).getIntHKL();
1537 for (
int j = 0; j < 3; ++j) {
1538 target[i * 3 + j] = qv[j];
1542 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1545 for (
double dx = -1e-2; dx < 1e-2; dx += 2e-2 / 20.0) {
1547 for (
double dy = -1e-2; dy < 1e-2; dy += 2e-2 / 20.0) {
1549 for (
double dz = -1e-2; dz < 1e-2; dz += 2e-2 / 20.0) {
1551 for (
double theta = 0.0; theta <
PI; theta +=
PI / 20.0) {
1553 for (
double phi = 0.0; phi < 2 *
PI; phi += 2 *
PI / 20.0) {
1555 for (
double ang = -5.0; ang < 5.0; ang += 5.0 / 20.0) {
1558 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1559 objf->setParameter(
"DeltaX", dx);
1560 objf->setParameter(
"DeltaY", dy);
1561 objf->setParameter(
"DeltaZ", dz);
1562 objf->setParameter(
"Theta", theta);
1563 objf->setParameter(
"Phi", phi);
1564 objf->setParameter(
"DeltaRotationAngle", ang);
1565 objf->setParameter(
"DeltaT0", 0.0);
1566 objf->function1D(out.get(), xValues, 1);
1568 double residual = 0.0;
1569 for (
int i = 0; i < n_peaks * 3; ++i) {
1570 residual += (out[i] - target[i]) * (out[i] - target[i]);
1572 residual = std::sqrt(residual) / (n_peaks - 6);
1574 msgrst << dx <<
"\t" << dy <<
"\t" << dz <<
"\t" << theta <<
"\t" << phi <<
"\t" << ang <<
"\t"
1575 << residual <<
"\n";
1578 g_log.
notice() <<
"--" << bankname <<
": " << residual <<
"\n";
1588 const std::string csvname =
"profileSCDCalibratePanels2_" + bankname +
".csv";
1589 auto filenamebase = std::filesystem::temp_directory_path() / csvname;
1590 std::ofstream profBankFile;
1591 profBankFile.open(filenamebase.string());
1592 profBankFile << msgrst.str();
1593 profBankFile.close();
1596 std::ostringstream msg;
1597 msg <<
"Profile of " << bankname <<
" is saved at:\n"
1598 << filenamebase <<
"\n"
1599 <<
"END of profiling objective func for " << bankname <<
"\n";
1614 g_log.
notice() <<
"START of profiling objective func along T0\n";
1624 std::ostringstream msgrst;
1625 msgrst.precision(12);
1626 msgrst <<
"dT0\tresidual\n";
1629 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1631 std::vector<double> tofs =
captureTOF(pws_original);
1632 objf->setPeakWorkspace(pws,
"none", tofs);
1635 const int n_peaks = pws->getNumberPeaks();
1636 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1637 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1638 for (
int i = 0; i < n_peaks; ++i) {
1639 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1641 for (
int j = 0; j < 3; ++j) {
1642 target[i * 3 + j] = qv[j];
1646 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1649 double deltaT0 = -10;
1650 while (deltaT0 < 10) {
1651 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1652 objf->setParameter(
"DeltaT0", deltaT0);
1653 objf->function1D(out.get(), xValues, 1);
1656 double residual = 0.0;
1657 for (
int i = 0; i < n_peaks * 3; ++i) {
1658 residual += (out[i] - target[i]) * (out[i] - target[i]);
1660 residual = std::sqrt(residual) / (n_peaks - 1);
1662 msgrst << deltaT0 <<
"\t" << residual <<
"\n";
1665 g_log.
notice() << deltaT0 <<
" -- " << residual <<
"\n";
1673 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_T0.csv";
1674 std::ofstream profL1File;
1675 profL1File.open(filenamebase.string());
1676 profL1File << msgrst.str();
1679 << filenamebase <<
"\n"
1680 <<
"END of profiling objective func along T0\n";
1691 g_log.
notice() <<
"START of profiling objective func along L1 and T0\n";
1697 g_log.
notice() <<
"deltaL1 -- deltaT0 -- residual\n";
1701 std::ostringstream msgrst;
1702 msgrst.precision(12);
1703 msgrst <<
"dL1\tdT0\tresidual\n";
1706 auto objf = std::make_shared<SCDCalibratePanels2ObjFunc>();
1708 std::vector<double> tofs =
captureTOF(pws_original);
1709 objf->setPeakWorkspace(pws,
"moderator", tofs);
1712 const int n_peaks = pws->getNumberPeaks();
1713 std::unique_ptr<double[]> target(
new double[n_peaks * 3]);
1714 auto ubmatrix = pws->sample().getOrientedLattice().getUB();
1715 for (
int i = 0; i < n_peaks; ++i) {
1716 V3D qv = ubmatrix * pws->getPeak(i).getIntHKL();
1718 for (
int j = 0; j < 3; ++j) {
1719 target[i * 3 + j] = qv[j];
1723 const double xValues[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
1726 for (
double deltaL1 = -4e-2; deltaL1 < 4e-2; deltaL1 += 1e-4) {
1727 for (
double deltaT0 = -4.0; deltaT0 < 4.0; deltaT0 += 1e-2) {
1728 std::unique_ptr<double[]> out(
new double[n_peaks * 3]);
1729 objf->setParameter(
"DeltaZ", deltaL1);
1730 objf->setParameter(
"DeltaT0", deltaT0);
1731 objf->function1D(out.get(), xValues, 1);
1734 double residual = 0.0;
1735 for (
int i = 0; i < n_peaks * 3; ++i) {
1736 residual += (out[i] - target[i]) * (out[i] - target[i]);
1738 residual = std::sqrt(residual) / (n_peaks - 2);
1741 g_log.
notice() << deltaL1 <<
" -- " << deltaT0 <<
" -- " << residual <<
"\n";
1744 msgrst << deltaL1 <<
"\t" << deltaT0 <<
"\t" << residual <<
"\n";
1749 auto filenamebase = std::filesystem::temp_directory_path() /
"profileSCDCalibratePanels2_L1T0.csv";
1750 std::ofstream profL1File;
1751 profL1File.open(filenamebase.string());
1752 profL1File << msgrst.str();
1757 << filenamebase <<
"\n"
1758 <<
"END of profiling objective func along L1 and T0\n";
1773std::pair<double, double>
1775 const std::string &bankname,
1778 std::pair<double, double> scales{1.0, 1.0};
1782 std::shared_ptr<const Geometry::RectangularDetector> rectDet =
1783 std::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
1787 auto scalexparams =
pmap.getDouble(rectDet->getName(),
"scalex");
1788 auto scaleyparams =
pmap.getDouble(rectDet->getName(),
"scaley");
1789 if (!scalexparams.empty())
1790 scales.first = scalexparams[0];
1791 if (!scaleyparams.empty())
1792 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.