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//----------------------------------------------------------------------------------------------
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 (const 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;
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 map<string, pair<double, double>> paramvaluemap2, paramvaluemap3;
844 // a) Use Simplex to fit
845 string minimizer = "Simplex";
846 double chi2simplex;
847 string fitstatussimplex;
848 numiters = 10000;
849 bool fitgood1 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2simplex, fitstatussimplex);
850
851 if (fitgood1)
852 storeFunctionParameterValue(function, paramvaluemap1);
853 else
854 chi2simplex = DBL_MAX;
855
856 // b) Continue Levenberg-Marquardt following Simplex
857 minimizer = "Levenberg-MarquardtMD";
858 double chi2lv2;
859 string fitstatuslv2;
860 numiters = 1000;
861 bool fitgood2 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2lv2, fitstatuslv2);
862 if (fitgood2)
863 storeFunctionParameterValue(function, paramvaluemap2);
864 else
865 chi2lv2 = DBL_MAX;
866
867 // c) Fit by L.V. solely
868 map<string, Parameter> tempparmap;
869 restoreFunctionParameterValue(start_paramvaluemap, function, tempparmap);
870 double chi2lv1;
871 string fitstatuslv1;
872 bool fitgood3 = doFitFunction(function, dataws, wsindex, minimizer, numiters, chi2lv1, fitstatuslv1);
873 if (fitgood3)
874 storeFunctionParameterValue(function, paramvaluemap3);
875 else
876 chi2lv1 = DBL_MAX;
877
878 // 4. Compare best
879 g_log.notice() << "Fit Result: Chi2s: Simplex = " << chi2simplex << ", "
880 << "Levenberg 1 = " << chi2lv2 << ", Levenberg 2 = " << chi2lv1 << '\n';
881
882 if (fitgood1 || fitgood2 || fitgood3) {
883 // At least one good fit
884 if (fitgood1 && chi2simplex <= chi2lv2 && chi2simplex <= chi2lv1) {
885 final_chi2 = chi2simplex;
886 restoreFunctionParameterValue(paramvaluemap1, function, m_profileParameters);
887 } else if (fitgood2 && chi2lv2 <= chi2lv1) {
888 restoreFunctionParameterValue(paramvaluemap2, function, m_profileParameters);
889 final_chi2 = chi2lv2;
890 } else if (fitgood3) {
891 final_chi2 = chi2lv1;
892 restoreFunctionParameterValue(paramvaluemap3, function, m_profileParameters);
893 } else {
894 throw runtime_error("This situation is impossible to happen!");
895 }
896 } // END of Choosing Results
897 } else {
898 // 3B) Simple fit
899 string minimizer = "Levenberg-MarquardtMD";
900 string fitstatus;
901 numiters = 1000;
902 bool fitgood = doFitFunction(function, dataws, wsindex, minimizer, numiters, final_chi2, fitstatus);
903 if (fitgood) {
904 storeFunctionParameterValue(function, paramvaluemap1);
905 restoreFunctionParameterValue(paramvaluemap1, function, m_profileParameters);
906 } else {
907 g_log.warning() << "Fit by " << minimizer << " failed. Reason: " << fitstatus << "\n";
908 }
909 }
910
911 return final_chi2;
912}
913
914//----------------------------------------------------------------------------------------------
919 int wsindex, const string &minimizer, int numiters, double &chi2,
920 string &fitstatus) {
921 // 0. Debug output
922 stringstream outss;
923 outss << "Fit function: " << m_positionFunc->asString() << "\nData To Fit: \n";
924 for (size_t i = 0; i < dataws->x(0).size(); ++i)
925 outss << dataws->x(wsindex)[i] << "\t\t" << dataws->y(wsindex)[i] << "\t\t" << dataws->e(wsindex)[i] << "\n";
926 g_log.information() << outss.str();
927
928 // 1. Create and setup fit algorithm
929 auto fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true);
930 fitalg->initialize();
931
932 fitalg->setProperty("Function", function);
933 fitalg->setProperty("InputWorkspace", dataws);
934 fitalg->setProperty("WorkspaceIndex", wsindex);
935 fitalg->setProperty("Minimizer", minimizer);
936 fitalg->setProperty("CostFunction", "Least squares");
937 fitalg->setProperty("MaxIterations", numiters);
938 fitalg->setProperty("CalcErrors", true);
939
940 // 2. Fit
941 bool successfulfit = fitalg->execute();
942 if (!fitalg->isExecuted() || !successfulfit) {
943 // Early return due to bad fit
944 g_log.warning("Fitting to instrument geometry function failed. ");
945 chi2 = DBL_MAX;
946 fitstatus = "Minimizer throws exception.";
947 return false;
948 }
949
950 // 3. Understand solution
951 chi2 = fitalg->getProperty("OutputChi2overDoF");
952 string tempfitstatus = fitalg->getProperty("OutputStatus");
953 fitstatus = tempfitstatus;
954
955 bool goodfit = fitstatus == "success";
956
957 stringstream dbss;
958 dbss << "Fit Result (GSL): Chi^2 = " << chi2 << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit
959 << '\n';
960 vector<string> funcparnames = function->getParameterNames();
961 for (size_t i = 0; i < funcparnames.size(); ++i)
962 dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i]) << " +/- "
963 << function->getError(i) << "\n";
964 g_log.debug() << dbss.str();
965
966 return goodfit;
967}
968
969//----------------------------------------------------------------------------------------------
973 double startchi2, double finalchi2) {
974 // 1. Create TableWorkspace
975 auto tablews = std::make_shared<TableWorkspace>();
976
977 tablews->addColumn("str", "Name");
978 tablews->addColumn("double", "Value");
979 tablews->addColumn("str", "FitOrTie");
980 tablews->addColumn("double", "Min");
981 tablews->addColumn("double", "Max");
982 tablews->addColumn("double", "StepSize");
983 tablews->addColumn("double", "Error");
984
985 // 2. For chi^2
986 addOrReplace(parameters, "Chi2_Init", startchi2);
987 addOrReplace(parameters, "Chi2_Result", finalchi2);
988
989 // 3. Set values
990 map<string, Parameter>::iterator pariter;
991 for (pariter = parameters.begin(); pariter != parameters.end(); ++pariter) {
992 const Parameter &param = pariter->second;
993 TableRow newrow = tablews->appendRow();
994
995 string fitortie;
996 if (param.fit)
997 fitortie = "fit";
998 else
999 fitortie = "tie";
1000
1001 newrow << param.name << param.curvalue << fitortie << param.minvalue << param.maxvalue << param.stepsize
1002 << param.fiterror;
1003 }
1004
1005 return tablews;
1006}
1007
1008//----------------------------------------------------------------------------------------------
1016void RefinePowderInstrumentParameters3::addOrReplace(map<string, Parameter> &parameters, const string &parname,
1017 double parvalue) {
1018 auto pariter = parameters.find(parname);
1019 if (pariter != parameters.end()) {
1020 parameters[parname].curvalue = parvalue;
1021 } else {
1022 Parameter newparameter;
1023 newparameter.name = parname;
1024 newparameter.curvalue = parvalue;
1025 parameters.emplace(parname, newparameter);
1026 }
1027}
1028
1029//----------------------------------------------------------------------------------------------
1033 const FunctionValues &rawvalues) {
1034 // 1. Create and set up output workspace
1035 size_t lenx = m_dataWS->x(m_wsIndex).size();
1036 size_t leny = m_dataWS->y(m_wsIndex).size();
1037
1038 Workspace2D_sptr outws =
1039 std::dynamic_pointer_cast<Workspace2D>(WorkspaceFactory::Instance().create("Workspace2D", 6, lenx, leny));
1040
1041 outws->getAxis(0)->setUnit("dSpacing");
1042
1043 auto tAxis = std::make_unique<TextAxis>(outws->getNumberHistograms());
1044 tAxis->setLabel(0, "Data");
1045 tAxis->setLabel(1, "Model");
1046 tAxis->setLabel(2, "DiffDM");
1047 tAxis->setLabel(3, "Start");
1048 tAxis->setLabel(4, "DiffDS");
1049 tAxis->setLabel(5, "Zdiff");
1050 outws->replaceAxis(1, std::move(tAxis));
1051
1052 // 3. Re-calculate values
1053 FunctionValues funcvalues(domain);
1054 m_positionFunc->function(domain, funcvalues);
1055
1056 // 4. Add values
1057 // a) X axis
1058 for (size_t iws = 0; iws < outws->getNumberHistograms(); ++iws) {
1059 outws->mutableX(iws) = domain.toVector();
1060 }
1061
1062 // b) Y axis
1063 const auto &dataY = m_dataWS->y(m_wsIndex);
1064 outws->setSharedY(0, m_dataWS->sharedY(m_wsIndex));
1065 outws->mutableY(1) = funcvalues.toVector();
1066 outws->mutableY(2) = dataY - funcvalues.toVector();
1067 outws->mutableY(3) = rawvalues.toVector();
1068 outws->mutableY(4) = dataY - rawvalues.toVector();
1069
1070 // 5. Zscore
1071 vector<double> zscore = Kernel::getZscore(outws->y(2).rawData());
1072 outws->mutableY(5) = zscore;
1073
1074 return outws;
1075}
1076
1077//----------------------------------------------------------------------------------------------
1081 map<string, Parameter> params) {
1082 // 1. Prepare
1083 vector<string> funparamnames = function->getParameterNames();
1084
1085 // 2. Set up
1086 stringstream msgss;
1087 msgss << "Set Instrument Function Parameter : \n";
1088
1089 for (const auto &parname : funparamnames) {
1090 auto paramiter = params.find(parname);
1091
1092 if (paramiter != params.end()) {
1093 // Found, set up the parameter
1094 Parameter &param = paramiter->second;
1095 function->setParameter(parname, param.curvalue);
1096
1097 msgss << setw(10) << parname << " = " << param.curvalue << '\n';
1098 } else {
1099 // Not found and thus quit
1100 stringstream errss;
1101 errss << "Peak profile parameter " << parname << " is not found in input parameters. ";
1102 g_log.error(errss.str());
1103 throw runtime_error(errss.str());
1104 }
1105 } // ENDFOR parameter name
1106
1107 g_log.information(msgss.str());
1108}
1109
1147//----------------------------------------------------------------------------------------------
1152 map<string, Parameter> params) {
1153 // 1. Prepare
1154 vector<string> funparamnames = m_positionFunc->getParameterNames();
1155
1156 // 2. Set up
1157 std::map<std::string, Parameter>::iterator paramiter;
1158 for (size_t i = 0; i < funparamnames.size(); ++i) {
1159 string parname = funparamnames[i];
1160 paramiter = params.find(parname);
1161
1162 if (paramiter != params.end()) {
1163 // Found, set up the parameter
1164 const Parameter &param = paramiter->second;
1165 if (param.fit) {
1166 // If fit. Unfix it and set up constraint
1167 function->unfix(i);
1168
1169 double lowerbound = param.minvalue;
1170 double upperbound = param.maxvalue;
1171 if (lowerbound >= -DBL_MAX * 0.1 || upperbound <= DBL_MAX * 0.1) {
1172 // If there is a boundary
1173 auto bc =
1174 std::make_unique<Constraints::BoundaryConstraint>(function.get(), parname, lowerbound, upperbound, false);
1175 function->addConstraint(std::move(bc));
1176 }
1177 } else {
1178 // If fix.
1179 function->fix(i);
1180 }
1181 } else {
1182 // Not found and thus quit
1183 stringstream errss;
1184 errss << "Peak profile parameter " << parname << " is not found in input parameters. ";
1185 g_log.error(errss.str());
1186 throw runtime_error(errss.str());
1187 }
1188 } // ENDFOR parameter name
1189
1190 g_log.notice() << "Fit function:\n" << function->asString() << "\n";
1191}
1192
1193//================================= External Functions
1194//=========================================
1195
1196//----------------------------------------------------------------------------------------------
1201void duplicateParameters(const map<string, Parameter> &source, map<string, Parameter> &target) {
1202 target.clear();
1203
1204 map<string, Parameter>::const_iterator miter;
1205 for (miter = source.begin(); miter != source.end(); ++miter) {
1206 string parname = miter->first;
1207 Parameter param = miter->second;
1208 Parameter newparam;
1209 newparam = param;
1210 target.emplace(parname, newparam);
1211 }
1212}
1213
1214//----------------------------------------------------------------------------------------------
1219void copyParametersValues(const map<string, Parameter> &source, map<string, Parameter> &target) {
1220 // 1. Check
1221 if (source.size() != target.size())
1222 throw runtime_error("Source and Target should have the same size.");
1223
1224 // 2. Copy the value
1225 for (auto miter = source.begin(); miter != source.end(); ++miter) {
1226 string parname = miter->first;
1227 Parameter param = miter->second;
1228 double paramvalue = param.curvalue;
1229
1230 auto titer = target.find(parname);
1231 if (titer == target.end())
1232 throw runtime_error("Source and target should have exactly the same keys.");
1233
1234 titer->second.curvalue = paramvalue;
1235 }
1236}
1237
1238//----------------------------------------------------------------------------------------------
1241void convertToDict(vector<string> strvec, map<string, size_t> &lookupdict) {
1242 lookupdict.clear();
1243
1244 for (size_t i = 0; i < strvec.size(); ++i)
1245 lookupdict.emplace(strvec[i], i);
1246}
1247
1248//----------------------------------------------------------------------------------------------
1251int getStringIndex(map<string, size_t> lookupdict, const string &key) {
1252 map<string, size_t>::iterator fiter;
1253 fiter = lookupdict.find(key);
1254
1255 int returnvalue;
1256
1257 if (fiter == lookupdict.end()) {
1258 // does not exist
1259 returnvalue = -1;
1260 } else {
1261 // exist
1262 returnvalue = static_cast<int>(fiter->second);
1263 }
1264
1265 return returnvalue;
1266}
1267
1268//----------------------------------------------------------------------------------------------
1271void storeFunctionParameterValue(const IFunction_sptr &function, map<string, pair<double, double>> &parvaluemap) {
1272 parvaluemap.clear();
1273
1274 vector<string> parnames = function->getParameterNames();
1275 for (size_t i = 0; i < parnames.size(); ++i) {
1276 string &parname = parnames[i];
1277 double parvalue = function->getParameter(i);
1278 double parerror = function->getError(i);
1279 parvaluemap.emplace(parname, make_pair(parvalue, parerror));
1280 }
1281}
1282
1283//----------------------------------------------------------------------------------------------
1288void restoreFunctionParameterValue(map<string, pair<double, double>> parvaluemap, const IFunction_sptr &function,
1289 map<string, Parameter> &parammap) {
1290 vector<string> parnames = function->getParameterNames();
1291
1292 for (auto &parname : parnames) {
1293 map<string, pair<double, double>>::iterator miter;
1294 miter = parvaluemap.find(parname);
1295
1296 if (miter != parvaluemap.end()) {
1297 double parvalue = miter->second.first;
1298
1299 // 1. Function
1300 function->setParameter(parname, parvalue);
1301
1302 // 2. Parameter map
1303 auto pariter = parammap.find(parname);
1304 if (pariter != parammap.end()) {
1305 // Find the entry
1306 pariter->second.curvalue = parvalue;
1307 pariter->second.fiterror = miter->second.second;
1308 }
1309 }
1310 }
1311}
1312
1313} // namespace Mantid::CurveFitting::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#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.
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
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.
const 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:145
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
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:743
void duplicateParameters(const std::map< std::string, Parameter > &source, std::map< std::string, Parameter > &target)
Copy parameters from source to target.
double calculateFunctionChiSquare(const std::vector< double > &modelY, const std::vector< double > &dataY, const std::vector< double > &dataE)
Calculate Chi^2.
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 storeFunctionParameterValue(const API::IFunction_sptr &function, std::map< std::string, std::pair< double, double > > &parvaluemap)
Store function parameter values to a map.
void copyParametersValues(const std::map< std::string, Parameter > &source, std::map< std::string, Parameter > &target)
Copy parameters values from source to target.
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.
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