Mantid
Loading...
Searching...
No Matches
RefinePowderInstrumentParameters3.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
9#include "MantidAPI/Axis.h"
10#include "MantidAPI/TableRow.h"
11#include "MantidAPI/TextAxis.h"
14
15#include <iomanip>
16#include <utility>
17
18using namespace Mantid::API;
19using namespace Mantid::CurveFitting;
21using namespace Mantid::DataObjects;
22using namespace Mantid::Kernel;
23using namespace std;
24
26
28
29//----------------------------------------------------------------------------------------------
33 : m_dataWS(), m_wsIndex(-1), m_paramTable(), m_fitMode(MONTECARLO), m_stdMode(CONSTANT), m_numWalkSteps(-1),
34 m_randomSeed(-1), m_profileParameters(), m_positionFunc(), m_dampingFactor(0.), m_bestChiSq(0.),
35 m_bestChiSqStep(-1), m_bestChiSqGroup(-1) {}
36
37//----------------------------------------------------------------------------------------------
41 // Peak position workspace
43 std::make_unique<WorkspaceProperty<Workspace2D>>("InputPeakPositionWorkspace", "Anonymous", Direction::Input),
44 "Data workspace containing workspace positions in TOF agains dSpacing.");
45
46 // Workspace Index
47 declareProperty("WorkspaceIndex", 0, "Workspace Index of the peak positions in PeakPositionWorkspace.");
48
49 // Output workspace
51 std::make_unique<WorkspaceProperty<Workspace2D>>("OutputPeakPositionWorkspace", "Anonymous2", Direction::Output),
52 "Output data workspace containing refined workspace positions in TOF "
53 "agains dSpacing.");
54
55 // Input Table workspace containing instrument profile parameters
56 declareProperty(std::make_unique<WorkspaceProperty<TableWorkspace>>("InputInstrumentParameterWorkspace", "Anonymous3",
58 "INput tableWorkspace containg instrument's parameters.");
59
60 // Output table workspace containing the refined parameters
61 declareProperty(std::make_unique<WorkspaceProperty<TableWorkspace>>("OutputInstrumentParameterWorkspace",
62 "Anonymous4", Direction::Output),
63 "Output tableworkspace containing instrument's fitted parameters. ");
64
65 // Refinement algorithm
66 vector<string> algoptions{"OneStepFit", "MonteCarlo"};
67 auto validator = std::make_shared<Kernel::StringListValidator>(algoptions);
68 declareProperty("RefinementAlgorithm", "MonteCarlo", validator, "Algorithm to refine the instrument parameters.");
69
70 // Random walk steps
71 declareProperty("RandomWalkSteps", 10000, "Number of Monte Carlo random walk steps. ");
72
73 // Random seed
74 declareProperty("MonteCarloRandomSeed", 0, "Random seed for Monte Carlo simulation. ");
75
76 // Method to calcualte the standard error of peaks
77 vector<string> stdoptions{"ConstantValue", "UseInputValue"};
78 auto listvalidator = std::make_shared<Kernel::StringListValidator>(stdoptions);
79 declareProperty("StandardError", "ConstantValue", listvalidator,
80 "Algorithm to calculate the standard error of peak positions.");
81
82 // Damping factor
83 declareProperty("Damping", 1.0,
84 "Damping factor for (1) minimizer 'Damped "
85 "Gauss-Newton'. (2) Monte Carlo. ");
86
87 // Anealing temperature
88 declareProperty("AnnealingTemperature", 1.0, "Starting annealing temperature.");
89
90 // Monte Carlo iterations
91 declareProperty("MonteCarloIterations", 100, "Number of iterations in Monte Carlo random walk.");
92
93 // Output
94 declareProperty("ChiSquare", DBL_MAX, Direction::Output);
95}
96
97//----------------------------------------------------------------------------------------------
101 // 1. Process input
103
104 // 2. Parse input table workspace
106
107 // 3. Set up main function for peak positions
108 m_positionFunc = std::make_shared<ThermalNeutronDtoTOFFunction>();
109 m_positionFunc->initialize();
110
111 // 3. Fit
112 // a) Set up parameter value
114
115 // b) Generate some global useful value and Calculate starting chi^2
116 API::FunctionDomain1DVector domain(m_dataWS->x(m_wsIndex).rawData());
117 API::FunctionValues rawvalues(domain);
118 m_positionFunc->function(domain, rawvalues);
119
120 // d) Calcualte statistic
122
123 // b) Fit by type
124 double finalchi2 = DBL_MAX;
125 switch (m_fitMode) {
126 case FIT:
127 // Fit by non-Monte Carlo method
128 g_log.notice("Fit by non Monte Carlo algorithm. ");
129 finalchi2 = execFitParametersNonMC();
130 break;
131
132 case MONTECARLO:
133 // Fit by Monte Carlo method
134 g_log.notice("Fit by Monte Carlo algorithm.");
135 finalchi2 = execFitParametersMC();
136 break;
137
138 default:
139 // Unsupported
140 throw runtime_error("Unsupported fit mode.");
141 break;
142 }
143
144 // 4. Process the output
145 TableWorkspace_sptr fitparamtable = genOutputProfileTable(m_profileParameters, startchi2, finalchi2);
146 setProperty("OutputInstrumentParameterWorkspace", fitparamtable);
147
148 Workspace2D_sptr outdataws = genOutputWorkspace(domain, rawvalues);
149 setProperty("OutputPeakPositionWorkspace", outdataws);
150
151 setProperty("ChiSquare", finalchi2);
152}
153
154//----------------------------------------------------------------------------------------------
158 // Data Workspace
159 m_dataWS = getProperty("InputPeakPositionWorkspace");
160
161 m_wsIndex = getProperty("WorkspaceIndex");
162 if (m_wsIndex < 0 || m_wsIndex >= static_cast<int>(m_dataWS->getNumberHistograms())) {
163 throw runtime_error("Input workspace index is out of range.");
164 }
165
166 // Parameter TableWorkspace
167 m_paramTable = getProperty("InputInstrumentParameterWorkspace");
168
169 // Fit mode
170 string fitmode = getProperty("RefinementAlgorithm");
171 if (fitmode == "OneStepFit")
172 m_fitMode = FIT;
173 else if (fitmode == "MonteCarlo")
175 else {
176 m_fitMode = FIT;
177 throw runtime_error("Input RefinementAlgorithm is not supported.");
178 }
179
180 // Stanard error mode
181 string stdmode = getProperty("StandardError");
182 if (stdmode == "ConstantValue")
184 else if (stdmode == "UseInputValue")
186 else {
188 throw runtime_error("Input StandardError (mode) is not supported.");
189 }
190
191 // Monte Carlo
192 m_numWalkSteps = getProperty("RandomWalkSteps");
193 if (m_numWalkSteps <= 0)
194 throw runtime_error("Monte Carlo walk steps cannot be less or equal to 0. ");
195
196 m_randomSeed = getProperty("MonteCarloRandomSeed");
197
198 m_dampingFactor = getProperty("Damping");
199}
200
201//----------------------------------------------------------------------------------------------
205 m_profileParameters.clear();
206
208}
209
210//----------------------------------------------------------------------------------------------
214 map<string, Parameter> &parammap) {
215 // 1. Process Table column names
216 std::vector<std::string> colnames = tablews->getColumnNames();
217 map<string, size_t> colnamedict;
218 convertToDict(colnames, colnamedict);
219
220 int iname = getStringIndex(colnamedict, "Name");
221 int ivalue = getStringIndex(colnamedict, "Value");
222 int ifit = getStringIndex(colnamedict, "FitOrTie");
223 int imin = getStringIndex(colnamedict, "Min");
224 int imax = getStringIndex(colnamedict, "Max");
225 int istep = getStringIndex(colnamedict, "StepSize");
226
227 if (iname < 0 || ivalue < 0 || ifit < 0)
228 throw runtime_error("TableWorkspace does not have column Name, Value and/or Fit.");
229
230 // 3. Parse
231 size_t numrows = tablews->rowCount();
232 for (size_t irow = 0; irow < numrows; ++irow) {
233 string parname = tablews->cell<string>(irow, iname);
234 double parvalue = tablews->cell<double>(irow, ivalue);
235 string fitq = tablews->cell<string>(irow, ifit);
236
237 double minvalue;
238 if (imin >= 0)
239 minvalue = tablews->cell<double>(irow, imin);
240 else
241 minvalue = -DBL_MAX;
242
243 double maxvalue;
244 if (imax >= 0)
245 maxvalue = tablews->cell<double>(irow, imax);
246 else
247 maxvalue = DBL_MAX;
248
249 double stepsize;
250 if (istep >= 0)
251 stepsize = tablews->cell<double>(irow, istep);
252 else
253 stepsize = 1.0;
254
255 Parameter newpar;
256 newpar.name = parname;
257 newpar.curvalue = parvalue;
258 newpar.minvalue = minvalue;
259 newpar.maxvalue = maxvalue;
260 newpar.stepsize = stepsize;
261
262 // If empty string, fit is default to be false
263 bool fit = false;
264 if (!fitq.empty()) {
265 if (fitq[0] == 'F' || fitq[0] == 'f')
266 fit = true;
267 }
268 newpar.fit = fit;
269
270 parammap.emplace(parname, newpar);
271 }
272}
273
274//----------------------------------------------------------------------------------------------
279 // 1. Set up constraints
281
282 // 2. Fit function
283 // FIXME powerfit should be a user option before freezing this algorithm
284 // FIXME powdefit = True introduce segmentation fault
285 bool powerfit = false;
286 double chi2 = fitFunction(m_positionFunc, m_dataWS, m_wsIndex, powerfit);
287
288 // 2. Summary
289 stringstream sumss;
290 sumss << "Non-Monte Carlo Results: Best Chi^2 = " << chi2;
291 g_log.notice(sumss.str());
292
293 return chi2;
294}
295
296//----------------------------------------------------------------------------------------------
300 // 1. Monte Carlo simulation
302
303 // 2. Summary
304 stringstream sumss;
305 sumss << "Monte Carlo Results: Best Chi^2 = " << chisq << " @ Step " << m_bestChiSqStep << ", Group "
307 g_log.notice(sumss.str());
308
309 return chisq;
310}
311
312//----------------------------------------------------------------------------------------------
318double RefinePowderInstrumentParameters3::doSimulatedAnnealing(map<string, Parameter> inparammap) {
319 // 1. Prepare/initialization
320 // Data structure
321 size_t numpts = m_dataWS->y(m_wsIndex).size();
322
323 vector<double> vecY(numpts, 0.0);
324
325 // Monte Carlo strategy and etc.
326 vector<vector<string>> mcgroups;
327 setupRandomWalkStrategy(inparammap, mcgroups);
328
329 int randomseed = getProperty("MonteCarloRandomSeed");
330 srand(randomseed);
331
332 double temperature = getProperty("AnnealingTemperature");
333 if (temperature < 1.0E-10)
334 throw runtime_error("Annealing temperature is too low.");
335
336 int maxiterations = getProperty("MonteCarloIterations");
337 if (maxiterations <= 0)
338 throw runtime_error("Max iteration cannot be 0 or less.");
339
340 // Book keeping
341 map<string, Parameter> parammap;
342 duplicateParameters(inparammap, parammap);
343 // vector<pair<double, map<string, Parameter> > > bestresults;
344 map<string, Parameter> bestresult;
345 // size_t maxnumresults = 10;
346
347 // 2. Set up parameters and get initial values
348 m_bestChiSq = DBL_MAX;
349 m_bestChiSqStep = -1;
350 m_bestChiSqGroup = -1;
351
352 double chisq0 = calculateFunction(parammap, vecY);
354 g_log.notice() << "[DBx510] Starting Chi^2 = " << chisq0 << " (homemade) " << chisq0x << " (Levenber-marquadt)\n";
355
356 bookKeepMCResult(parammap, chisq0, -1, -1,
357 bestresult); // bestresults, maxnumresults);
358
359 // 3. Monte Carlo starts
360 double chisqx = chisq0;
361 int numrecentacceptance = 0;
362 int numrecentsteps = 0;
363
364 map<string, Parameter> propparammap; // parameters with proposed value
365 duplicateParameters(parammap, propparammap);
366
367 for (int istep = 0; istep < maxiterations; ++istep) {
368 for (int igroup = 0; igroup < static_cast<int>(mcgroups.size()); ++igroup) {
369 // a) Propose value
370 proposeNewValues(mcgroups[igroup], parammap, propparammap,
371 chisqx); // , prevbetterchi2);
372
373 // b) Calcualte function and chi^2
374 double propchisq = calculateFunction(propparammap, vecY);
375
376 /*
377 stringstream dbss;
378 dbss << "[DBx541] New Chi^2 = " << propchisq << '\n';
379 vector<string> paramnames = m_positionFunc->getParameterNames();
380 for (size_t i = 0; i < paramnames.size(); ++i)
381 {
382 string parname = paramnames[i];
383 double curvalue = parammap[parname].value;
384 double propvalue = propparammap[parname].value;
385 dbss << parname << ":\t\t" << setw(20) << propvalue << "\t\t<-----\t\t"
386 << curvalue << "\t Delta = "
387 << curvalue-propvalue << '\n';
388 }
389 g_log.notice(dbss.str());
390 */
391
392 // c) Determine to accept change
393 bool acceptpropvalues = acceptOrDenyChange(propchisq, chisqx, temperature);
394
395 // d) Change current chi^2, apply change, and book keep
396 if (acceptpropvalues) {
398 chisqx = propchisq;
399 bookKeepMCResult(parammap, chisqx, istep, igroup,
400 bestresult); // s, maxnumresults);
401 }
402
403 // e) MC strategy control
404 ++numrecentacceptance;
405 ++numrecentsteps;
406 }
407
408 // f) Annealing
409 if (numrecentsteps >= 10) {
410 double acceptratio = static_cast<double>(numrecentacceptance) / static_cast<double>(numrecentsteps);
411 if (acceptratio < 0.2) {
412 // i) Low acceptance, need to raise temperature
413 temperature *= 2.0;
414 } else if (acceptratio >= 0.8) {
415 // ii) Temperature too high to accept too much new change
416 temperature /= 2.0;
417 }
418
419 // iii) Reset counters
420 numrecentacceptance = 0;
421 numrecentsteps = 0;
422 }
423 }
424
425 // 4. Apply the best result
426 // sort(bestresults.begin(), bestresults.end());
428 double chisqf = m_bestChiSq;
429
430 g_log.warning() << "[DBx544] Best Chi^2 From MC = " << m_bestChiSq << '\n';
431
432 // 5. Use regular minimzer to try to get a better result
433 string fitstatus;
434 double fitchisq;
435 bool goodfit = doFitFunction(m_positionFunc, m_dataWS, m_wsIndex, "Levenberg-MarquardtMD", 1000, fitchisq, fitstatus);
436
437 bool restoremcresult = false;
438 if (goodfit) {
439 map<string, Parameter> nullmap;
440 fitchisq = calculateFunction(nullmap, vecY);
441 if (fitchisq > chisqf) {
442 // Fit is unable to achieve a better solution
443 restoremcresult = true;
444 } else {
445 m_bestChiSq = fitchisq;
446 }
447 } else {
448 // Fit is bad
449 restoremcresult = true;
450 }
451
452 g_log.warning() << "[DBx545] Restore MC Result = " << restoremcresult << '\n';
453
454 if (restoremcresult) {
456 }
457 chisqf = m_bestChiSq;
458
459 // 6. Final result
461 map<string, Parameter> emptymap;
462 double chisqf0 = calculateFunction(emptymap, vecY);
463 g_log.notice() << "Best Chi^2 (L-V) = " << chisqfx << ", (homemade) = " << chisqf0 << '\n';
464 g_log.warning() << "Data Size = " << m_dataWS->x(m_wsIndex).size()
465 << ", Number of parameters = " << m_positionFunc->getParameterNames().size() << '\n';
466
467 return chisqf;
468}
469
470//----------------------------------------------------------------------------------------------
479 map<string, Parameter> &curparammap,
480 map<string, Parameter> &newparammap, double currchisq) {
481 for (const auto &paramname : mcgroup) {
482 // random number between -1 and 1
483 double randomnumber = 2 * static_cast<double>(rand()) / static_cast<double>(RAND_MAX) - 1.0;
484
485 // parameter information
486 Parameter param = curparammap[paramname];
487 double stepsize =
488 m_dampingFactor * currchisq * (param.curvalue * param.mcA1 + param.mcA0) * randomnumber / m_bestChiSq;
489
490 g_log.debug() << "Parameter " << paramname << " Step Size = " << stepsize << " From " << param.mcA0 << ", "
491 << param.mcA1 << ", " << param.curvalue << ", " << m_dampingFactor << '\n';
492
493 // drunk walk or random walk
494 double newvalue;
495 // Random walk. No preference on direction
496 newvalue = param.curvalue + stepsize;
497
498 /*
499 if (m_walkStyle == RANDOMWALK)
500 {
501
502 }
503 else if (m_walkStyle == DRUNKENWALK)
504 {
505 // Drunken walk. Prefer to previous successful move direction
506 int prevRightDirection;
507 if (prevBetterRwp)
508 prevRightDirection = 1;
509 else
510 prevRightDirection = -1;
511
512 double randirint =
513 static_cast<double>(rand())/static_cast<double>(RAND_MAX);
514
515 // FIXME Here are some MAGIC numbers
516 if (randirint < 0.1)
517 {
518 // Negative direction to previous direction
519 stepsize =
520 -1.0*fabs(stepsize)*static_cast<double>(param.movedirection*prevRightDirection);
521 }
522 else if (randirint < 0.4)
523 {
524 // No preferance
525 stepsize = stepsize;
526 }
527 else
528 {
529 // Positive direction to previous direction
530 stepsize =
531 fabs(stepsize)*static_cast<double>(param.movedirection*prevRightDirection);
532 }
533
534 newvalue = param.value + stepsize;
535 }
536 else
537 {
538 newvalue = DBL_MAX;
539 throw runtime_error("Unrecoganized walk style. ");
540 }
541 */
542
543 // restriction
544 if (param.nonnegative && newvalue < 0) {
545 // If not allowed to be negative
546 newvalue = fabs(newvalue);
547 }
548
549 // apply to new parameter map
550 newparammap[paramname].curvalue = newvalue;
551
552 // record some trace
553 Parameter &p = curparammap[paramname];
554 if (stepsize > 0) {
555 p.movedirection = 1;
556 ++p.numpositivemove;
557 } else if (stepsize < 0) {
558 p.movedirection = -1;
559 ++p.numnegativemove;
560 } else {
561 p.movedirection = -1;
562 ++p.numnomove;
563 }
564 p.sumstepsize += fabs(stepsize);
565 if (fabs(stepsize) > p.maxabsstepsize)
566 p.maxabsstepsize = fabs(stepsize);
567
568 g_log.debug() << "[DBx257] " << paramname << "\t"
569 << "Proposed value = " << setw(15) << newvalue << " (orig = " << param.curvalue
570 << ", step = " << stepsize << "), totRwp = " << currchisq << '\n';
571 }
572}
573
574//----------------------------------------------------------------------------------------------
581bool RefinePowderInstrumentParameters3::acceptOrDenyChange(double curchisq, double newchisq, double temperature) {
582 bool accept;
583
584 if (newchisq < curchisq) {
585 // Lower Rwp. Take the change
586 accept = true;
587 } else {
588 // Higher Rwp. Take a chance to accept
589 double dice = static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
590 double bar = exp(-(newchisq - curchisq) / (curchisq * temperature));
591 accept = dice < bar;
592 }
593
594 return accept;
595}
596
597//----------------------------------------------------------------------------------------------
600void RefinePowderInstrumentParameters3::bookKeepMCResult(map<string, Parameter> parammap, double chisq, int istep,
601 int igroup, map<string, Parameter> &bestparammap)
602// vector<pair<double, map<string, Parameter> > >& bestresults,
603// size_t maxnumresults)
604{
605 // 1. Check whether input Chi^2 is the best Chi^2
606 bool recordparameter = false;
607
608 if (chisq < m_bestChiSq) {
609 m_bestChiSq = chisq;
610 m_bestChiSqStep = istep;
611 m_bestChiSqGroup = igroup;
612
613 recordparameter = true;
614 }
615
616 // 2. Record for the best parameters
617 if (bestparammap.empty()) {
618 // No record yet
619 duplicateParameters(std::move(parammap), bestparammap);
620 } else if (recordparameter) {
621 // Replace the record
622 }
623
624 // 2. Determine whether to add this entry to records
625 /*
626 bool addentry = true;
627 if (bestresults.size() >= maxnumresults && chisq > bestresults.back().first)
628 addentry = false;
629
630 // 3. Add entry
631 if (addentry)
632 {
633 map<string, Parameter> storemap;
634 duplicateParameters(parammap, storemap);
635 bestresults.emplace_back(chisq, storemap);
636 sort(bestresults.begin(), bestresults.end());
637 }
638 */
639}
640
641//----------------------------------------------------------------------------------------------
645 vector<vector<string>> &mcgroups) {
646 stringstream dboutss;
647 dboutss << "Monte Carlo minimizer refines: ";
648
649 // 1. Monte Carlo groups
650 // a. Instrument gemetry
651 vector<string> geomparams;
652 addParameterToMCMinimize(geomparams, "Dtt1", parammap);
653 addParameterToMCMinimize(geomparams, "Dtt1t", parammap);
654 addParameterToMCMinimize(geomparams, "Dtt2t", parammap);
655 addParameterToMCMinimize(geomparams, "Zero", parammap);
656 addParameterToMCMinimize(geomparams, "Zerot", parammap);
657 addParameterToMCMinimize(geomparams, "Width", parammap);
658 addParameterToMCMinimize(geomparams, "Tcross", parammap);
659 mcgroups.emplace_back(geomparams);
660
661 dboutss << "Geometry parameters: ";
662 for (auto &geomparam : geomparams)
663 dboutss << geomparam << "\t\t";
664 dboutss << '\n';
665
666 g_log.notice(dboutss.str());
667
668 // 2. Dictionary for each parameter for non-negative, mcX0, mcX1
669 parammap["Width"].mcA0 = 0.0;
670 parammap["Width"].mcA1 = 1.0;
671 parammap["Width"].nonnegative = true;
672
673 parammap["Tcross"].mcA0 = 0.0;
674 parammap["Tcross"].mcA1 = 1.0;
675 parammap["Tcross"].nonnegative = true;
676
677 parammap["Zero"].mcA0 = 5.0;
678 parammap["Zero"].mcA1 = 0.0;
679 parammap["Zero"].nonnegative = false;
680
681 parammap["Zerot"].mcA0 = 5.0;
682 parammap["Zerot"].mcA1 = 0.0;
683 parammap["Zerot"].nonnegative = false;
684
685 parammap["Dtt1"].mcA0 = 5.0;
686 parammap["Dtt1"].mcA1 = 0.0;
687 parammap["Dtt1"].nonnegative = true;
688
689 parammap["Dtt1t"].mcA0 = 5.0;
690 parammap["Dtt1t"].mcA1 = 0.0;
691 parammap["Dtt1t"].nonnegative = true;
692
693 parammap["Dtt2t"].mcA0 = 0.1;
694 parammap["Dtt2t"].mcA1 = 1.0;
695 parammap["Dtt2t"].nonnegative = false;
696
697 // 3. Reset
698 map<string, Parameter>::iterator mapiter;
699 for (mapiter = parammap.begin(); mapiter != parammap.end(); ++mapiter) {
700 mapiter->second.movedirection = 1;
701 mapiter->second.sumstepsize = 0.0;
702 mapiter->second.numpositivemove = 0;
703 mapiter->second.numnegativemove = 0;
704 mapiter->second.numnomove = 0;
705 mapiter->second.maxabsstepsize = -0.0;
706 }
707}
708
709//----------------------------------------------------------------------------------------------
718void RefinePowderInstrumentParameters3::addParameterToMCMinimize(vector<string> &parnamesforMC, const string &parname,
719 map<string, Parameter> parammap) {
720 map<string, Parameter>::iterator pariter;
721 pariter = parammap.find(parname);
722 if (pariter == parammap.end()) {
723 stringstream errss;
724 errss << "Parameter " << parname << " does not exisit Le Bail function parameters. ";
725 g_log.error(errss.str());
726 throw runtime_error(errss.str());
727 }
728
729 if (pariter->second.fit)
730 parnamesforMC.emplace_back(parname);
731}
732
733//----------------------------------------------------------------------------------------------
740double RefinePowderInstrumentParameters3::calculateFunction(const map<string, Parameter> &parammap,
741 vector<double> &vecY) {
742 // 1. Implement parameter values to m_positionFunc
743 if (!parammap.empty())
745
746 // 2. Calculate
747 const auto &vecX = m_dataWS->x(m_wsIndex).rawData();
748 // Check
749 if (vecY.size() != vecX.size())
750 throw runtime_error("vecY must be initialized with proper size!");
751
752 m_positionFunc->function1D(vecY, vecX);
753
754 // 3. Calcualte error
755 double chisq = calculateFunctionChiSquare(vecY, m_dataWS->y(m_wsIndex).rawData(), m_dataWS->e(m_wsIndex).rawData());
756
757 return chisq;
758}
759
760//----------------------------------------------------------------------------------------------
763double calculateFunctionChiSquare(const vector<double> &modelY, const vector<double> &dataY,
764 const vector<double> &dataE) {
765 // 1. Check
766 if (modelY.size() != dataY.size() || dataY.size() != dataE.size())
767 throw runtime_error("Input model, data and error have different size.");
768
769 // 2. Calculation
770 double chisq = 0.0;
771 size_t numpts = modelY.size();
772 for (size_t i = 0; i < numpts; ++i) {
773 if (dataE[i] > 1.0E-5) {
774 double temp = (modelY[i] - dataY[i]) / dataE[i];
775 chisq += temp * temp;
776 }
777 }
778
779 return chisq;
780}
781
782//----------------------------------------------------------------------------------------------
786 const Workspace2D_sptr &dataws, int wsindex) {
787 // 1. Record the fitting information
788 vector<string> parnames = function->getParameterNames();
789 vector<bool> vecFix(parnames.size(), false);
790
791 for (size_t i = 0; i < parnames.size(); ++i) {
792 bool fixed = !function->isActive(i);
793 vecFix[i] = fixed;
794 if (!fixed)
795 function->fix(i);
796 }
797
798 // 2. Fit with zero iteration
799 double chi2;
800 string fitstatus;
801 const std::string minimizer = "Levenberg-MarquardtMD";
802 bool fitOK = doFitFunction(function, dataws, wsindex, minimizer, 0, chi2, fitstatus);
803
804 if (!fitOK) {
805 g_log.warning() << "Fit by " << minimizer << " with 0 iterations failed, with reason: " << fitstatus << "\n";
806 }
807
808 // 3. Restore the fit/fix setup
809 for (size_t i = 0; i < parnames.size(); ++i) {
810 if (!vecFix[i])
811 function->unfix(i);
812 }
813
814 return chi2;
815}
816
817//----------------------------------------------------------------------------------------------
829 int wsindex, bool powerfit) {
830 // 1. Store original
831 map<string, pair<double, double>> start_paramvaluemap, paramvaluemap1, paramvaluemap2, paramvaluemap3;
832 storeFunctionParameterValue(function, start_paramvaluemap);
833
834 // 2. Calculate starting chi^2
835 double startchisq = calculateFunctionError(function, dataws, wsindex);
836 g_log.notice() << "[DBx436] Starting Chi^2 = " << startchisq << ", Power-Fit is " << powerfit << '\n';
837
838 // 3. Fitting
839 int numiters;
840 double final_chi2 = DBL_MAX;
841
842 if (powerfit) {
843 // a) Use Simplex to fit
844 string minimizer = "Simplex";
845 double chi2simplex;
846 string fitstatussimplex;
847 numiters = 10000;
848 bool fitgood1 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2simplex, fitstatussimplex);
849
850 if (fitgood1)
851 storeFunctionParameterValue(function, paramvaluemap1);
852 else
853 chi2simplex = DBL_MAX;
854
855 // b) Continue Levenberg-Marquardt following Simplex
856 minimizer = "Levenberg-MarquardtMD";
857 double chi2lv2;
858 string fitstatuslv2;
859 numiters = 1000;
860 bool fitgood2 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2lv2, fitstatuslv2);
861 if (fitgood2)
862 storeFunctionParameterValue(function, paramvaluemap2);
863 else
864 chi2lv2 = DBL_MAX;
865
866 // c) Fit by L.V. solely
867 map<string, Parameter> tempparmap;
868 restoreFunctionParameterValue(start_paramvaluemap, function, tempparmap);
869 double chi2lv1;
870 string fitstatuslv1;
871 bool fitgood3 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2lv1, fitstatuslv1);
872 if (fitgood3)
873 storeFunctionParameterValue(function, paramvaluemap3);
874 else
875 chi2lv1 = DBL_MAX;
876
877 // 4. Compare best
878 g_log.notice() << "Fit Result: Chi2s: Simplex = " << chi2simplex << ", "
879 << "Levenberg 1 = " << chi2lv2 << ", Levenberg 2 = " << chi2lv1 << '\n';
880
881 if (fitgood1 || fitgood2 || fitgood3) {
882 // At least one good fit
883 if (fitgood1 && chi2simplex <= chi2lv2 && chi2simplex <= chi2lv1) {
884 final_chi2 = chi2simplex;
885 restoreFunctionParameterValue(paramvaluemap1, function, m_profileParameters);
886 } else if (fitgood2 && chi2lv2 <= chi2lv1) {
887 restoreFunctionParameterValue(paramvaluemap2, function, m_profileParameters);
888 final_chi2 = chi2lv2;
889 } else if (fitgood3) {
890 final_chi2 = chi2lv1;
891 restoreFunctionParameterValue(paramvaluemap3, function, m_profileParameters);
892 } else {
893 throw runtime_error("This situation is impossible to happen!");
894 }
895 } // END of Choosing Results
896 } else {
897 // 3B) Simple fit
898 string minimizer = "Levenberg-MarquardtMD";
899 string fitstatus;
900 numiters = 1000;
901 bool fitgood = doFitFunction(function, dataws, wsindex, minimizer, numiters, final_chi2, fitstatus);
902 if (fitgood) {
903 storeFunctionParameterValue(function, paramvaluemap1);
904 restoreFunctionParameterValue(paramvaluemap1, function, m_profileParameters);
905 } else {
906 g_log.warning() << "Fit by " << minimizer << " failed. Reason: " << fitstatus << "\n";
907 }
908 }
909
910 return final_chi2;
911}
912
913//----------------------------------------------------------------------------------------------
918 int wsindex, const string &minimizer, int numiters, double &chi2,
919 string &fitstatus) {
920 // 0. Debug output
921 stringstream outss;
922 outss << "Fit function: " << m_positionFunc->asString() << "\nData To Fit: \n";
923 for (size_t i = 0; i < dataws->x(0).size(); ++i)
924 outss << dataws->x(wsindex)[i] << "\t\t" << dataws->y(wsindex)[i] << "\t\t" << dataws->e(wsindex)[i] << "\n";
925 g_log.information() << outss.str();
926
927 // 1. Create and setup fit algorithm
928 auto fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true);
929 fitalg->initialize();
930
931 fitalg->setProperty("Function", function);
932 fitalg->setProperty("InputWorkspace", dataws);
933 fitalg->setProperty("WorkspaceIndex", wsindex);
934 fitalg->setProperty("Minimizer", minimizer);
935 fitalg->setProperty("CostFunction", "Least squares");
936 fitalg->setProperty("MaxIterations", numiters);
937 fitalg->setProperty("CalcErrors", true);
938
939 // 2. Fit
940 bool successfulfit = fitalg->execute();
941 if (!fitalg->isExecuted() || !successfulfit) {
942 // Early return due to bad fit
943 g_log.warning("Fitting to instrument geometry function failed. ");
944 chi2 = DBL_MAX;
945 fitstatus = "Minimizer throws exception.";
946 return false;
947 }
948
949 // 3. Understand solution
950 chi2 = fitalg->getProperty("OutputChi2overDoF");
951 string tempfitstatus = fitalg->getProperty("OutputStatus");
952 fitstatus = tempfitstatus;
953
954 bool goodfit = fitstatus == "success";
955
956 stringstream dbss;
957 dbss << "Fit Result (GSL): Chi^2 = " << chi2 << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit
958 << '\n';
959 vector<string> funcparnames = function->getParameterNames();
960 for (size_t i = 0; i < funcparnames.size(); ++i)
961 dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i]) << " +/- "
962 << function->getError(i) << "\n";
963 g_log.debug() << dbss.str();
964
965 return goodfit;
966}
967
968//----------------------------------------------------------------------------------------------
972 double startchi2, double finalchi2) {
973 // 1. Create TableWorkspace
974 auto tablews = std::make_shared<TableWorkspace>();
975
976 tablews->addColumn("str", "Name");
977 tablews->addColumn("double", "Value");
978 tablews->addColumn("str", "FitOrTie");
979 tablews->addColumn("double", "Min");
980 tablews->addColumn("double", "Max");
981 tablews->addColumn("double", "StepSize");
982 tablews->addColumn("double", "Error");
983
984 // 2. For chi^2
985 addOrReplace(parameters, "Chi2_Init", startchi2);
986 addOrReplace(parameters, "Chi2_Result", finalchi2);
987
988 // 3. Set values
989 map<string, Parameter>::iterator pariter;
990 for (pariter = parameters.begin(); pariter != parameters.end(); ++pariter) {
991 Parameter &param = pariter->second;
992 TableRow newrow = tablews->appendRow();
993
994 string fitortie;
995 if (param.fit)
996 fitortie = "fit";
997 else
998 fitortie = "tie";
999
1000 newrow << param.name << param.curvalue << fitortie << param.minvalue << param.maxvalue << param.stepsize
1001 << param.fiterror;
1002 }
1003
1004 return tablews;
1005}
1006
1007//----------------------------------------------------------------------------------------------
1015void RefinePowderInstrumentParameters3::addOrReplace(map<string, Parameter> &parameters, const string &parname,
1016 double parvalue) {
1017 auto pariter = parameters.find(parname);
1018 if (pariter != parameters.end()) {
1019 parameters[parname].curvalue = parvalue;
1020 } else {
1021 Parameter newparameter;
1022 newparameter.name = parname;
1023 newparameter.curvalue = parvalue;
1024 parameters.emplace(parname, newparameter);
1025 }
1026}
1027
1028//----------------------------------------------------------------------------------------------
1032 const FunctionValues &rawvalues) {
1033 // 1. Create and set up output workspace
1034 size_t lenx = m_dataWS->x(m_wsIndex).size();
1035 size_t leny = m_dataWS->y(m_wsIndex).size();
1036
1037 Workspace2D_sptr outws =
1038 std::dynamic_pointer_cast<Workspace2D>(WorkspaceFactory::Instance().create("Workspace2D", 6, lenx, leny));
1039
1040 outws->getAxis(0)->setUnit("dSpacing");
1041
1042 auto tAxis = std::make_unique<TextAxis>(outws->getNumberHistograms());
1043 tAxis->setLabel(0, "Data");
1044 tAxis->setLabel(1, "Model");
1045 tAxis->setLabel(2, "DiffDM");
1046 tAxis->setLabel(3, "Start");
1047 tAxis->setLabel(4, "DiffDS");
1048 tAxis->setLabel(5, "Zdiff");
1049 outws->replaceAxis(1, std::move(tAxis));
1050
1051 // 3. Re-calculate values
1052 FunctionValues funcvalues(domain);
1053 m_positionFunc->function(domain, funcvalues);
1054
1055 // 4. Add values
1056 // a) X axis
1057 for (size_t iws = 0; iws < outws->getNumberHistograms(); ++iws) {
1058 outws->mutableX(iws) = domain.toVector();
1059 }
1060
1061 // b) Y axis
1062 const auto &dataY = m_dataWS->y(m_wsIndex);
1063 outws->setSharedY(0, m_dataWS->sharedY(m_wsIndex));
1064 outws->mutableY(1) = funcvalues.toVector();
1065 outws->mutableY(2) = dataY - funcvalues.toVector();
1066 outws->mutableY(3) = rawvalues.toVector();
1067 outws->mutableY(4) = dataY - rawvalues.toVector();
1068
1069 // 5. Zscore
1070 vector<double> zscore = Kernel::getZscore(outws->y(2).rawData());
1071 outws->mutableY(5) = zscore;
1072
1073 return outws;
1074}
1075
1076//----------------------------------------------------------------------------------------------
1080 map<string, Parameter> params) {
1081 // 1. Prepare
1082 vector<string> funparamnames = function->getParameterNames();
1083
1084 // 2. Set up
1085 stringstream msgss;
1086 msgss << "Set Instrument Function Parameter : \n";
1087
1088 for (const auto &parname : funparamnames) {
1089 auto paramiter = params.find(parname);
1090
1091 if (paramiter != params.end()) {
1092 // Found, set up the parameter
1093 Parameter &param = paramiter->second;
1094 function->setParameter(parname, param.curvalue);
1095
1096 msgss << setw(10) << parname << " = " << param.curvalue << '\n';
1097 } else {
1098 // Not found and thus quit
1099 stringstream errss;
1100 errss << "Peak profile parameter " << parname << " is not found in input parameters. ";
1101 g_log.error(errss.str());
1102 throw runtime_error(errss.str());
1103 }
1104 } // ENDFOR parameter name
1105
1106 g_log.information(msgss.str());
1107}
1108
1146//----------------------------------------------------------------------------------------------
1151 map<string, Parameter> params) {
1152 // 1. Prepare
1153 vector<string> funparamnames = m_positionFunc->getParameterNames();
1154
1155 // 2. Set up
1156 std::map<std::string, Parameter>::iterator paramiter;
1157 for (size_t i = 0; i < funparamnames.size(); ++i) {
1158 string parname = funparamnames[i];
1159 paramiter = params.find(parname);
1160
1161 if (paramiter != params.end()) {
1162 // Found, set up the parameter
1163 Parameter &param = paramiter->second;
1164 if (param.fit) {
1165 // If fit. Unfix it and set up constraint
1166 function->unfix(i);
1167
1168 double lowerbound = param.minvalue;
1169 double upperbound = param.maxvalue;
1170 if (lowerbound >= -DBL_MAX * 0.1 || upperbound <= DBL_MAX * 0.1) {
1171 // If there is a boundary
1172 auto bc =
1173 std::make_unique<Constraints::BoundaryConstraint>(function.get(), parname, lowerbound, upperbound, false);
1174 function->addConstraint(std::move(bc));
1175 }
1176 } else {
1177 // If fix.
1178 function->fix(i);
1179 }
1180 } else {
1181 // Not found and thus quit
1182 stringstream errss;
1183 errss << "Peak profile parameter " << parname << " is not found in input parameters. ";
1184 g_log.error(errss.str());
1185 throw runtime_error(errss.str());
1186 }
1187 } // ENDFOR parameter name
1188
1189 g_log.notice() << "Fit function:\n" << function->asString() << "\n";
1190}
1191
1192//================================= External Functions
1193//=========================================
1194
1195//----------------------------------------------------------------------------------------------
1200void duplicateParameters(map<string, Parameter> source, map<string, Parameter> &target) {
1201 target.clear();
1202
1203 map<string, Parameter>::iterator miter;
1204 for (miter = source.begin(); miter != source.end(); ++miter) {
1205 string parname = miter->first;
1206 Parameter param = miter->second;
1207 Parameter newparam;
1208 newparam = param;
1209 target.emplace(parname, newparam);
1210 }
1211}
1212
1213//----------------------------------------------------------------------------------------------
1218void copyParametersValues(map<string, Parameter> source, map<string, Parameter> &target) {
1219 // 1. Check
1220 if (source.size() != target.size())
1221 throw runtime_error("Source and Target should have the same size.");
1222
1223 // 2. Copy the value
1224 map<string, Parameter>::iterator miter;
1225 map<string, Parameter>::iterator titer;
1226 for (miter = source.begin(); miter != source.end(); ++miter) {
1227 string parname = miter->first;
1228 Parameter param = miter->second;
1229 double paramvalue = param.curvalue;
1230
1231 titer = target.find(parname);
1232 if (titer == target.end())
1233 throw runtime_error("Source and target should have exactly the same keys.");
1234
1235 titer->second.curvalue = paramvalue;
1236 }
1237}
1238
1239//----------------------------------------------------------------------------------------------
1242void convertToDict(vector<string> strvec, map<string, size_t> &lookupdict) {
1243 lookupdict.clear();
1244
1245 for (size_t i = 0; i < strvec.size(); ++i)
1246 lookupdict.emplace(strvec[i], i);
1247}
1248
1249//----------------------------------------------------------------------------------------------
1252int getStringIndex(map<string, size_t> lookupdict, const string &key) {
1253 map<string, size_t>::iterator fiter;
1254 fiter = lookupdict.find(key);
1255
1256 int returnvalue;
1257
1258 if (fiter == lookupdict.end()) {
1259 // does not exist
1260 returnvalue = -1;
1261 } else {
1262 // exist
1263 returnvalue = static_cast<int>(fiter->second);
1264 }
1265
1266 return returnvalue;
1267}
1268
1269//----------------------------------------------------------------------------------------------
1272void storeFunctionParameterValue(const IFunction_sptr &function, map<string, pair<double, double>> &parvaluemap) {
1273 parvaluemap.clear();
1274
1275 vector<string> parnames = function->getParameterNames();
1276 for (size_t i = 0; i < parnames.size(); ++i) {
1277 string &parname = parnames[i];
1278 double parvalue = function->getParameter(i);
1279 double parerror = function->getError(i);
1280 parvaluemap.emplace(parname, make_pair(parvalue, parerror));
1281 }
1282}
1283
1284//----------------------------------------------------------------------------------------------
1289void restoreFunctionParameterValue(map<string, pair<double, double>> parvaluemap, const IFunction_sptr &function,
1290 map<string, Parameter> &parammap) {
1291 vector<string> parnames = function->getParameterNames();
1292
1293 for (auto &parname : parnames) {
1294 map<string, pair<double, double>>::iterator miter;
1295 miter = parvaluemap.find(parname);
1296
1297 if (miter != parvaluemap.end()) {
1298 double parvalue = miter->second.first;
1299 double parerror = miter->second.second;
1300
1301 // 1. Function
1302 function->setParameter(parname, parvalue);
1303
1304 // 2. Parameter map
1305 auto pariter = parammap.find(parname);
1306 if (pariter != parammap.end()) {
1307 // Find the entry
1308 pariter->second.curvalue = parvalue;
1309 pariter->second.fiterror = parerror;
1310 }
1311 }
1312 }
1313}
1314
1315} // namespace Mantid::CurveFitting::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#define fabs(x)
Definition: Matrix.cpp:22
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
Kernel::Logger & g_log
Definition: Algorithm.h:451
Implements FunctionDomain1D with its own storage in form of a std::vector.
std::vector< double > toVector() const
Convert to a vector.
A class to store values calculated by a function.
std::vector< double > toVector() const
Return the calculated values as a vector.
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
A property class for workspaces.
double fitFunction(const API::IFunction_sptr &function, const DataObjects::Workspace2D_sptr &dataws, int wsindex, bool powerfit)
Fit function by non MC minimzer(s)
double calculateFunction(const std::map< std::string, Parameter > &parammap, std::vector< double > &vecY)
Implement parameter values, calculate function and its chi square.
enum Mantid::CurveFitting::Algorithms::RefinePowderInstrumentParameters3::@3 m_fitMode
Fit mode.
double execFitParametersMC()
Refine instrument parameters by Monte Carlo/simulated annealing method.
void addParameterToMCMinimize(std::vector< std::string > &parnamesforMC, const std::string &parname, std::map< std::string, Parameter > parammap)
Add parameter (to a vector of string/name) for MC random walk.
double calculateFunctionError(const API::IFunction_sptr &function, const DataObjects::Workspace2D_sptr &dataws, int wsindex)
Calculate Chi^2 of the a function with all parameters are fixed.
void bookKeepMCResult(std::map< std::string, Parameter > parammap, double chisq, int istep, int igroup, std::map< std::string, Parameter > &bestparammap)
Book keep the best fitting result.
DataObjects::TableWorkspace_sptr genOutputProfileTable(std::map< std::string, Parameter > parameters, double startchi2, double finalchi2)
Construct an output TableWorkspace for refined peak profile parameters.
DataObjects::Workspace2D_sptr genOutputWorkspace(const API::FunctionDomain1DVector &domain, const API::FunctionValues &rawvalues)
Construct output.
Functions::ThermalNeutronDtoTOFFunction_sptr m_positionFunc
My function for peak positions.
void setFunctionParameterValues(const API::IFunction_sptr &function, std::map< std::string, Parameter > params)
Set parameter values to function from Parameter map.
double doSimulatedAnnealing(std::map< std::string, Parameter > inparammap)
Do MC/simulated annealing to refine parameters.
bool doFitFunction(const API::IFunction_sptr &function, const DataObjects::Workspace2D_sptr &dataws, int wsindex, const std::string &minimizer, int numiters, double &chi2, std::string &fitstatus)
Fit function (single step)
double execFitParametersNonMC()
Fit instrument parameters by non Monte Carlo algorithm.
enum Mantid::CurveFitting::Algorithms::RefinePowderInstrumentParameters3::@4 m_stdMode
Standard error mode.
DataObjects::Workspace2D_sptr m_dataWS
Data workspace containg peak positions.
void parseTableWorkspace(const DataObjects::TableWorkspace_sptr &tablews, std::map< std::string, Parameter > &parammap)
Parse table workspace to a map of Parameters.
void setupRandomWalkStrategy(std::map< std::string, Parameter > &parammap, std::vector< std::vector< std::string > > &mcgroups)
Set up Monte Carlo random walk strategy.
void proposeNewValues(const std::vector< std::string > &mcgroup, std::map< std::string, Parameter > &curparammap, std::map< std::string, Parameter > &newparammap, double currchisq)
Propose new parameters.
DataObjects::TableWorkspace_sptr m_paramTable
TableWorkspace containing peak parameters value and fit information.
std::map< std::string, Parameter > m_profileParameters
Data structure (map of Parameters) to hold parameters.
void addOrReplace(std::map< std::string, Parameter > &parameters, const std::string &parname, double parvalue)
Add a parameter to parameter map.
void setFunctionParameterFitSetups(const API::IFunction_sptr &function, std::map< std::string, Parameter > params)
Set parameter fitting setup (boundary, fix or unfix) to function from Parameter map.
bool acceptOrDenyChange(double curchisq, double newchisq, double temperature)
Determine whether the proposed value should be accepted or denied.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition: IFunction.h:732
double calculateFunctionChiSquare(const std::vector< double > &modelY, const std::vector< double > &dataY, const std::vector< double > &dataE)
Calculate Chi^2.
void duplicateParameters(std::map< std::string, Parameter > source, std::map< std::string, Parameter > &target)
Copy parameters from source to target.
void convertToDict(std::vector< std::string > strvec, std::map< std::string, size_t > &lookupdict)
Convert a vector to a lookup map (dictionary)
int getStringIndex(std::map< std::string, size_t > lookupdict, const std::string &key)
Get the index from lookup dictionary (map)
void restoreFunctionParameterValue(std::map< std::string, std::pair< double, double > > parvaluemap, const API::IFunction_sptr &function, std::map< std::string, Parameter > &parammap)
Restore function parameter values to a map.
void copyParametersValues(std::map< std::string, Parameter > source, std::map< std::string, Parameter > &target)
Copy parameters values from source to target.
void storeFunctionParameterValue(const API::IFunction_sptr &function, std::map< std::string, std::pair< double, double > > &parvaluemap)
Store function parameter values to a map.
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
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::vector< double > getZscore(const std::vector< TYPE > &data)
Return the Z score values for a dataset.
Definition: Statistics.cpp:81
STL namespace.
LeBailFit : Algorithm to do Le Bail Fit.
Definition: LeBailFit.h:37
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54