Mantid
Loading...
Searching...
No Matches
IntegratePeakTimeSlices.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 +
7/*
8 * IntegratePeakTimeSlices.cpp
9 *
10 * Created on: May 5, 2011
11 * Author: ruth
12 *
13 *
14 *
15 */
22#include "MantidAPI/IFunction.h"
25
26#include "MantidHistogramData/BinEdges.h"
27
28#include <boost/math/special_functions/round.hpp>
29#include <utility>
30
31using namespace Mantid::Kernel;
32using namespace Mantid::API;
33using namespace Mantid::DataObjects;
34using namespace Mantid::Geometry;
35using namespace Mantid::HistogramData;
36using namespace std;
37namespace Mantid::Crystal {
38
39DECLARE_ALGORITHM(IntegratePeakTimeSlices)
40
41// Attr, m_AttributeValues, and StatBase indicies
42#define IStartRow 0
43#define IStartCol 1
44#define INRows 2
45#define INCol 3
46#define ISSIxx 4
47#define ISSIyy 5
48#define ISSIxy 6
49#define ISSxx 7
50#define ISSyy 8
51#define ISSxy 9
52#define ISSIx 10
53#define ISSIy 11
54#define ISSx 12
55#define ISSy 13
56#define IIntensities 14
57#define ISS1 15
58#define IVariance 16
59#define ITotBoundary 17
60#define INBoundary 18
61#define IVarBoundary 19
62#define NAttributes 20
63
64// Parameter indicies
65#define IBACK 0
66#define ITINTENS 1
67#define IXMEAN 2
68#define IYMEAN 3
69#define IVXX 4
70#define IVYY 5
71#define IVXY 6
72// TODO: Edge Peaks-Return NoPeak(Intensity=0,variance=0) if any center on any
73// slice is out of bounds
74// TODO: Calc ratio for edge peaks, should use the slant of bivariate normal
75// instead of assuming
76// distribution axes are lined up with the row and col vectors
77#define NParameters 7
78
79namespace {
80// # std sigs 0 .25 .5 .75 1 1.25 1.5 2 2.5
81const double probs[9] = {.5f, .5987f, .6915f, .7734f, .8413f, .8944f, .9322f, .9599f, .9772f};
82
83const int MinRowColSpan = 6;
84const int MaxRowColSpan = 36;
85const int MinTimeSpan = 3;
86const double NeighborhoodRadiusDivPeakRadius = 1.5;
87const double MaxNeighborhoodRadius = 10;
88const double NStdDevPeakSpan = 2;
89const double MaxGoodRatioFitvsExpIntenisites = 2.5;
90const double MinGoodRatioFitvsExpIntenisites = .25;
91const double MinGoodIoverSigI = 3.0;
92const double MinVariationInXYvalues = .6; // Peak spans one pixel only
93const double MaxCorrCoeffinXY = .9; // otherwise all data on one line
94} // namespace
95
97 : Algorithm(), m_R0(-1), m_ROW(0.), m_COL(0.), m_cellWidth(0.), m_cellHeight(0.), m_NROWS(0), m_NCOLS(0) {
98 this->deprecatedDate("2024-10-02");
99 m_EdgePeak = false;
100 m_NeighborIDs = new int[3];
101 m_NeighborIDs[0] = 3;
102 m_NeighborIDs[1] = 2;
103 m_AttributeNames[0] = "StartRow";
104 m_AttributeNames[1] = "StartCol";
105 m_AttributeNames[2] = "NRows";
106 m_AttributeNames[3] = "NCols";
107 m_AttributeNames[4] = "SSIxx";
108 m_AttributeNames[5] = "SSIyy";
109 m_AttributeNames[6] = "SSIxy";
110 m_AttributeNames[7] = "SSxx";
111 m_AttributeNames[8] = "SSyy";
112 m_AttributeNames[9] = "SSxy";
113 m_AttributeNames[10] = "SSIx";
114 m_AttributeNames[11] = "SSIy";
115 m_AttributeNames[12] = "SSx";
116 m_AttributeNames[13] = "SSy";
117 m_AttributeNames[14] = "Intensities";
118 m_AttributeNames[15] = " SS1";
119 m_AttributeNames[16] = "Variance";
120 m_AttributeNames[17] = "TotBoundary";
121 m_AttributeNames[18] = "NBoundary";
122 m_AttributeNames[19] = "VarianceBoundary";
123
124 m_ParameterNames[0] = "Background";
125 m_ParameterNames[1] = "Intensity";
126 m_ParameterNames[2] = "Mcol";
127 m_ParameterNames[3] = "Mrow";
128 m_ParameterNames[4] = "SScol";
129 m_ParameterNames[5] = "SSrow";
130 m_ParameterNames[6] = "SSrc";
131
132 std::fill(m_ParameterValues.begin(), m_ParameterValues.end(), 0.0);
133}
134
135double SQRT(double v) {
136 if (v < 0)
137 return -1;
138 return sqrt(v);
139}
142
144 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
145 "A 2D workspace with X values of time of flight");
146
147 declareProperty(std::make_unique<WorkspaceProperty<TableWorkspace>>("OutputWorkspace", "", Direction::Output),
148 "Name of the output table workspace with Log info");
149
151 "Workspace of Peaks");
152
153 declareProperty("PeakIndex", 0, "Index of peak in PeaksWorkspace to integrate");
154
155 declareProperty("PeakQspan", .06, "Max magnitude of Q of Peak to Q of Peak Center, where mod(Q)=1/d");
156
157 declareProperty("CalculateVariances", true, "Calc (co)variances given parameter values versus fit (co)Variances ");
158
159 declareProperty("Ties", "", "Tie parameters(Background,Intensity, Mrow,...) to values/formulas.");
160
161 declareProperty("NBadEdgePixels", 0, "Number of bad Edge Pixels");
162
163 declareProperty("Intensity", 0.0, "Peak Integrated Intensity", Direction::Output);
164
165 declareProperty("SigmaIntensity", 0.0, "Peak Integrated Intensity Error", Direction::Output);
166}
167
178 time_t seconds1;
179
180 seconds1 = time(nullptr);
181
182 double dQ = getProperty("PeakQspan");
183
184 g_log.debug("------------------Start Peak Integrate-------------------");
185
186 if (dQ <= 0) {
187 g_log.error("Negative PeakQspans are not allowed. Use .17/G where G is the "
188 "max unit cell length");
189 throw std::runtime_error("Negative PeakQspans are not allowed in IntegratePeakTimeSlices");
190 }
191
192 MatrixWorkspace_const_sptr inpWkSpace = getProperty("InputWorkspace");
193 if (!inpWkSpace) {
194 g_log.error("Improper Input Workspace");
195 throw std::runtime_error("Improper Input Workspace in IntegratePeakTimeSlices");
196 }
197
198 PeaksWorkspace_sptr peaksW;
199 peaksW = getProperty("Peaks");
200 if (!peaksW) {
201 g_log.error("Improper Peaks Input");
202 throw std::runtime_error("Improper Peaks Input");
203 }
204
205 int indx = getProperty("PeakIndex");
206
207 Peak const &peak = peaksW->getPeak(indx);
208
209 //------------------------------- Get Panel
210 //--------------------------------------
211 std::shared_ptr<const Geometry::IComponent> panel_const =
212 peak.getInstrument()->getComponentByName(peak.getBankName());
213
214 std::shared_ptr<Geometry::IComponent> panel = std::const_pointer_cast<Geometry::IComponent>(panel_const);
215
216 if (!panel || !panel_const) {
217 g_log.error("Cannot get panel for a peak");
218 throw std::runtime_error("Cannot get panel for a peak");
219 }
220
221 BoundingBox box;
222 panel->getBoundingBox(box);
223
224 if (!box.isPointInside(peak.getDetPos())) {
225 g_log.error("Detector pixel is NOT inside the Peaks Bank");
226 throw std::runtime_error("Detector pixel is NOT inside the Peaks Bank");
227 }
228
230
231 g_log.debug() << " Peak Index " << indx << '\n';
232
233 double TotVariance = 0;
234 double TotIntensity = 0;
235 double lastRow = m_ROW;
236 double Row0 = lastRow;
237 double lastCol = m_COL;
238 double Col0 = lastCol;
239 string spec_idList;
240
241 // For quickly looking up workspace index from det id
242 m_wi_to_detid_map = inpWkSpace->getDetectorIDToWorkspaceIndexMap();
243
244 TableWorkspace_sptr TabWS = std::make_shared<TableWorkspace>(0);
245
246 //----------------------------- get Peak extents
247 //------------------------------
248 try {
249 int detID = peak.getDetectorID();
250
251 // Find the workspace index for this detector ID
252 detid2index_map::const_iterator it = m_wi_to_detid_map.find(detID);
253 size_t wsIndx = (it->second);
254
255 double R = CalculatePositionSpan(peak, dQ) / 2;
256
257 R = min<double>(MaxRowColSpan * max<double>(m_cellWidth, m_cellHeight), R);
258 R = max<double>(MinRowColSpan * max<double>(m_cellWidth, m_cellHeight), R);
259
260 R = 2 * R; // Gets a few more background cells.
261 int Chan;
262
263 const auto &X = inpWkSpace->x(wsIndx);
264 int dChan = CalculateTimeChannelSpan(peak, dQ, X, int(wsIndx), Chan);
265
266 dChan = max<int>(dChan, MinTimeSpan);
267
268 double Centy = Row0;
269 double Centx = Col0;
270 IDetector_const_sptr CenterDet = peak.getDetector();
271
272 double neighborRadius; // last radius for finding neighbors
273
274 neighborRadius = min<double>(MaxNeighborhoodRadius, NeighborhoodRadiusDivPeakRadius * R);
275 auto Nneighbors = static_cast<int>(neighborRadius * neighborRadius / m_cellWidth / m_cellHeight * 4);
276
277 Nneighbors = min<int>(Nneighbors, static_cast<int>(inpWkSpace->getNumberHistograms()) - 2);
278 delete[] m_NeighborIDs;
279
280 m_NeighborIDs = new int[Nneighbors + 2];
281 m_NeighborIDs[0] = Nneighbors + 2;
282 m_NeighborIDs[1] = 2;
283 Kernel::V3D Cent = (m_center + m_xvec * (Centx - m_COL) + m_yvec * (Centy - m_ROW));
284
285 getNeighborPixIDs(panel, Cent, neighborRadius, m_NeighborIDs);
286
287 if (m_NeighborIDs[1] < 10) {
288 g_log.error("Not enough neighboring pixels to fit ");
289 throw std::runtime_error("Not enough neighboring pixels to fit ");
290 }
291 int NBadEdgeCells = getProperty("NBadEdgePixels");
292 int MaxChan = -1;
293 double MaxCounts = -1;
294
295 // --------------- Find Time Chan with max counts----------------
296 for (int dir = 1; dir > -2; dir -= 2) {
297 bool done = false;
298 for (int t = 0; t < dChan && !done; t++)
299 if (dir < 0 && t == 0) {
300 Centy = Row0;
301 Centx = Col0;
302 } else if (Chan + dir * t < 0 || Chan + dir * t >= static_cast<int>(X.size()))
303 done = true;
304 else {
305
306 int NN = m_NeighborIDs[1];
307 MatrixWorkspace_sptr Data = WorkspaceFactory::Instance().create(std::string("Workspace2D"), 3, NN, NN);
308
309 auto XXX = std::make_shared<DataModeHandler>(R, R, Centy, Centx, m_cellWidth, m_cellHeight,
310 getProperty("CalculateVariances"), NBadEdgeCells,
311 m_NCOLS - NBadEdgeCells, NBadEdgeCells, m_NROWS - NBadEdgeCells);
312 m_AttributeValues = XXX;
313 XXX->setCurrentRadius(R);
314
315 SetUpData1(Data, inpWkSpace, Chan + dir * t, Chan + dir * t, R, CenterDet->getPos(), spec_idList);
316
317 if (m_AttributeValues->StatBaseVals(ISSIxx) > 0) {
318 if (m_AttributeValues->StatBaseVals(IIntensities) > MaxCounts) {
319 MaxCounts = m_AttributeValues->StatBaseVals(IIntensities);
320 MaxChan = Chan + dir * t;
321 }
322 if (m_AttributeValues->StatBaseVals(IIntensities) > 0) {
323 Centx = m_AttributeValues->StatBaseVals(ISSIx) / m_AttributeValues->StatBaseVals(IIntensities);
324 Centy = m_AttributeValues->StatBaseVals(ISSIy) / m_AttributeValues->StatBaseVals(IIntensities);
325 } else
326 done = true;
327 } else
328 done = true;
329
330 if (t >= 3 && (m_AttributeValues->StatBaseVals(IIntensities) < MaxCounts / 2.0) && MaxCounts >= 0)
331 done = true;
332 }
333 }
334 if (MaxChan > 0)
335 Chan = MaxChan;
336
337 g_log.debug() << " largest Channel,Radius,m_cellWidth,m_cellHeight = " << Chan << " " << R << " " << m_cellWidth
338 << " " << m_cellHeight << '\n';
339
340 if (R < MinRowColSpan / 2 * max<double>(m_cellWidth, m_cellHeight) || dChan < MinTimeSpan) {
341 g_log.error("Not enough rows and cols or time channels ");
342 throw std::runtime_error("Not enough rows and cols or time channels ");
343 }
344
346
347 //------------------------------------- Start the Integrating
348 //-------------------------------
349 double time;
350 int ncells;
351
352 Mantid::API::Progress prog(this, 0.0, 1.0, dChan);
353
354 // Set from attributes replace by m_R0
355 m_R0 = -1;
356 int LastTableRow = -1;
357 auto origAttributeList = std::make_shared<DataModeHandler>();
358 auto lastAttributeList = std::make_shared<DataModeHandler>();
359
360 for (int dir = 1; dir >= -1; dir -= 2) {
361 bool done = false;
362
363 for (int chan = 0; chan < dChan && !done; chan++)
364 if (dir < 0 && chan == 0) {
365 lastRow = Row0;
366 lastCol = Col0;
367 lastAttributeList = origAttributeList;
368 if (TabWS->rowCount() > 0)
369 LastTableRow = 0;
370
371 } else if (Chan + dir * chan < 0 || Chan + dir * chan >= static_cast<int>(X.size()))
372 done = true;
373 else {
374
375 int xchan = Chan + dir * chan;
376
377 size_t topIndex = xchan + 1;
378 if (topIndex >= X.size())
379 topIndex = X.size() - 1;
380
381 time = (X[xchan] + X[topIndex]) / 2.0;
382
383 double Radius = R;
384
385 if (m_R0 > 0)
386 Radius = m_R0;
387
389 WorkspaceFactory::Instance().create(std::string("Workspace2D"), 3, m_NeighborIDs[1], m_NeighborIDs[1]);
390
391 g_log.debug() << " A:chan=" << xchan << " time=" << time << " Radius=" << Radius << "row= " << lastRow
392 << " col=" << lastCol << '\n';
393
394 SetUpData(Data, inpWkSpace, panel, xchan, xchan, lastCol, lastRow, Cent, neighborRadius, Radius, spec_idList);
395
396 m_AttributeValues->setTime(time);
397
398 // if( dir==1 && chan ==0)
399 // origAttributeList= m_AttributeValues;
400
401 ncells = static_cast<int>(m_AttributeValues->StatBaseVals(ISS1));
402
403 std::vector<double> params;
404 std::vector<double> errs;
405 std::vector<std::string> names;
406
407 if (m_AttributeValues->StatBaseVals(ISSIxx) > 0 &&
408 m_AttributeValues->IsEnoughData(m_ParameterValues.data(), g_log) && m_ParameterValues[ITINTENS] > 0) {
409 double chisqOverDOF;
410
411 Fit(Data, chisqOverDOF, done, names, params, errs, lastRow, lastCol, neighborRadius);
412
413 if (!done) // Bivariate error happened
414 {
415
416 if (isGoodFit(params, errs, names, chisqOverDOF)) {
417 LastTableRow = UpdateOutputWS(TabWS, dir, xchan, params, errs, names, chisqOverDOF,
418 m_AttributeValues->time, spec_idList);
419
420 double TotSliceIntensity = m_AttributeValues->StatBaseVals(IIntensities);
421 double TotSliceVariance = m_AttributeValues->StatBaseVals(IVariance);
422
423 updatePeakInformation(params, errs, names, TotVariance, TotIntensity, TotSliceIntensity,
424 TotSliceVariance, chisqOverDOF, ncells);
425
426 lastAttributeList = m_AttributeValues;
427
428 if (dir == 1 && chan == 0)
429 origAttributeList = lastAttributeList;
430 } else
431
432 done = true;
433 }
434
435 } else //(!IsEnoughData() || ParameterValues[ITINTENS] <= 0
436 {
437 done = true;
438 }
439
440 if (done) // try to merge
441 {
442 done = false;
443
444 int chanMin, chanMax;
445 if ((dir == 1 && chan == 0) || lastAttributeList->CellHeight <= 0) {
446 chanMin = xchan;
447 chanMax = xchan + 1;
448 if (dir < 0)
449 chanMax++;
450 auto XXX = std::make_shared<DataModeHandler>(*m_AttributeValues);
451 m_AttributeValues = XXX;
452 if (!X.empty())
453 m_AttributeValues->setTime((X[chanMax] + X[chanMin]) / 2.0);
454
455 } else // lastAttributeList exists
456
457 {
458 chanMin = std::min<int>(xchan, xchan - dir);
459 chanMax = chanMin + 1;
460 if (lastAttributeList->case4)
461 chanMax++;
462
463 auto XXX = std::make_shared<DataModeHandler>(*lastAttributeList);
464 m_AttributeValues = XXX;
465
466 m_AttributeValues->setTime((time + m_AttributeValues->time) / 2.0);
467 }
468
469 if (updateNeighbors(panel, m_AttributeValues->getCurrentCenter(), Cent,
470 m_AttributeValues->getCurrentRadius(), neighborRadius))
471 Cent = m_AttributeValues->getCurrentCenter();
472
473 Data =
474 WorkspaceFactory::Instance().create(std::string("Workspace2D"), 3, m_NeighborIDs[1], m_NeighborIDs[1]);
475
476 SetUpData1(Data, inpWkSpace, chanMin, chanMax, m_AttributeValues->getCurrentRadius(),
477 m_AttributeValues->getCurrentCenter(), spec_idList);
478
479 double chisqOverDOF;
480
481 g_log.debug("Try Merge 2 time slices");
482 if (m_AttributeValues->StatBaseVals(ISSIxx) >= 0 &&
483 m_AttributeValues->IsEnoughData(m_ParameterValues.data(), g_log))
484
485 Fit(Data, chisqOverDOF, done, names, params, errs, lastRow, lastCol, neighborRadius);
486 else
487 chisqOverDOF = -1;
488
489 if (!done && isGoodFit(params, errs, names, chisqOverDOF)) {
490
491 if (LastTableRow >= 0 && LastTableRow < static_cast<int>(TabWS->rowCount()))
492 TabWS->removeRow(LastTableRow);
493 else
494 LastTableRow = -1;
495
496 LastTableRow = UpdateOutputWS(TabWS, dir, (chanMin + chanMax) / 2.0, params, errs, names, chisqOverDOF,
497 m_AttributeValues->time, spec_idList);
498
499 if (lastAttributeList->lastISAWVariance > 0 && lastAttributeList->CellHeight > 0) {
500 TotIntensity -= lastAttributeList->lastISAWIntensity;
501 TotVariance -= lastAttributeList->lastISAWVariance;
502 }
503
504 double TotSliceIntensity = m_AttributeValues->StatBaseVals(IIntensities);
505
506 double TotSliceVariance = m_AttributeValues->StatBaseVals(IVariance);
507
508 updatePeakInformation(params, errs, names, TotVariance, TotIntensity, TotSliceIntensity, TotSliceVariance,
509 chisqOverDOF, static_cast<int>(m_AttributeValues->StatBaseVals(ISS1)));
510
511 // lastAttributeList= m_AttributeValues;
512
513 if (dir == 1 && (chan == 0 || chan == 1)) {
514 m_AttributeValues->case4 = true;
515 origAttributeList = m_AttributeValues;
516 } else
517 LastTableRow = -1;
518
519 } else {
520 auto XXX = std::make_shared<DataModeHandler>();
521 lastAttributeList = XXX;
522 }
523 done = true;
524 }
525
526 // Get ready for the next round
527 Data.reset();
528
529 if (!done) {
530
531 // Now set up the center for this peak
532 int i = findNameInVector("Mrow", names);
533 if (i < 0) {
534 throw std::runtime_error("Inconsistency found in algorithm "
535 "execution. The index for the parameter "
536 "Mrow is negative.");
537 }
538
539 lastRow = boost::math::iround(params[i]);
540 i = findNameInVector("Mcol", names);
541 if (i >= 0)
542 lastCol = boost::math::iround(params[i]);
543 prog.report();
544
545 } else if (dir > 0)
546 prog.report(dChan / 2);
547 else
548 prog.report(dChan);
549
550 params.clear();
551 errs.clear();
552 names.clear();
553 }
554 }
555
556 } catch (std::exception &EE1) {
557 std::cout << "Error in main reason=" << EE1.what() << '\n';
558
559 throw std::runtime_error(" Error IntegratePeakTimeSlices:" + std::string(EE1.what()));
560 } catch (std::string &mess) {
561 throw std::runtime_error("Error IntegratePeakTimeSlices:" + mess);
562
563 } catch (...) {
564 throw std::runtime_error("Error IntegratePeakTimeSlices:");
565 }
566
567 try {
568
569 setProperty("OutputWorkspace", TabWS);
570
571 setProperty("Intensity", TotIntensity);
572 setProperty("SigmaIntensity", SQRT(TotVariance));
573 time_t seconds2;
574
575 seconds2 = time(nullptr);
576 double dif = difftime(seconds2, seconds1);
577 g_log.debug() << "Finished Integr peak number " << indx << " in " << dif << " seconds\n";
578
579 } catch (std::exception &ss) {
580
581 std::cout << "Error occurred XX " << ss.what() << '\n';
582 throw std::runtime_error(ss.what());
583 }
584}
585
595bool IntegratePeakTimeSlices::getNeighborPixIDs(const std::shared_ptr<Geometry::IComponent> &comp,
596 const Kernel::V3D &Center, double &Radius, int *&ArryofID) {
597
598 int N = ArryofID[1];
599 int MaxN = ArryofID[0];
600
601 if (N >= MaxN)
602 return false;
603
605 comp->getBoundingBox(box);
606
607 double minx = Center.X() - Radius;
608 double miny = Center.Y() - Radius;
609 double minz = Center.Z() - Radius;
610 double maxx = Center.X() + Radius;
611 double maxy = Center.Y() + Radius;
612 double maxz = Center.Z() + Radius;
613
614 if (box.xMin() >= maxx)
615 return true;
616
617 if (box.xMax() <= minx)
618 return true;
619 ;
620
621 if (box.yMin() >= maxy)
622 return true;
623
624 if (box.yMax() <= miny)
625 return true;
626
627 if (box.zMin() >= maxz)
628 return true;
629
630 if (box.zMax() <= minz)
631 return true;
632 ;
633
634 auto det = std::dynamic_pointer_cast<Geometry::Detector>(comp);
635
636 if (det) {
637 V3D pos = det->getPos() - Center;
638 if (pos.X() * pos.X() + pos.Y() * pos.Y() + pos.Z() * pos.Z() < Radius * Radius) {
639 ArryofID[N] = det->getID();
640 N++;
641 ArryofID[1] = N;
642 }
643 return true;
644 }
645
646 auto Assembly = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(comp);
647
648 if (!Assembly)
649 return true;
650
651 bool b = true;
652
653 for (int i = 0; i < Assembly->nelements() && b; i++)
654 b = getNeighborPixIDs(Assembly->getChild(i), Center, Radius, ArryofID);
655
656 return b;
657}
658
667bool IntegratePeakTimeSlices::updateNeighbors(const std::shared_ptr<Geometry::IComponent> &comp, const V3D &CentPos,
668 const V3D &oldCenter, double NewRadius, double &neighborRadius) {
669 double DD = (CentPos - oldCenter).norm();
670 bool changed = false;
671 if (DD + NewRadius > neighborRadius) {
672 auto NN = int(NStdDevPeakSpan * NeighborhoodRadiusDivPeakRadius * NewRadius / m_cellWidth * NStdDevPeakSpan *
673 NeighborhoodRadiusDivPeakRadius * NewRadius / m_cellHeight);
674 if (m_NeighborIDs[0] < NN) {
675 delete[] m_NeighborIDs;
676 m_NeighborIDs = new int[NN + 2];
677 m_NeighborIDs[0] = NN + 2;
678 }
679 m_NeighborIDs[1] = 2;
680 neighborRadius = NeighborhoodRadiusDivPeakRadius * NewRadius;
681
682 getNeighborPixIDs(comp, CentPos, neighborRadius, m_NeighborIDs);
683 changed = true;
684
685 } else // big enough neighborhood so
686 neighborRadius -= DD;
687
688 return changed;
689}
690
701double IntegratePeakTimeSlices::CalculatePositionSpan(Peak const &peak, const double dQ) {
702
703 try {
704 double Q = 0, ScatAngle = 0, dScatAngle = 0, DetSpan = 0;
705
706 Q = peak.getQLabFrame().norm();
708 const Geometry::IComponent_const_sptr sample = instr->getSample();
709 V3D pos = peak.getDetPos() - sample->getPos();
710
711 ScatAngle = acos(pos.Z() / pos.norm());
712
713 dScatAngle = 2 * dQ / Q * tan(ScatAngle / 2);
714
715 DetSpan = pos.norm() * dScatAngle; // s=r*theta
716
717 DetSpan = fabs(DetSpan);
718
719 // IDetector_sptr det = peak.getDetector();
720
721 return DetSpan;
722
723 } catch (std::exception &s) {
724 std::cout << "err in getNRowsCols, reason=" << s.what() << '\n';
725 return 0;
726 }
727}
728
743int IntegratePeakTimeSlices::CalculateTimeChannelSpan(Geometry::IPeak const &peak, const double dQ, const HistogramX &X,
744 const int specNum, int &Centerchan) {
745 UNUSED_ARG(specNum);
746 double Q = peak.getQLabFrame().norm(); // getQ( peak)/2/M_PI;
747
748 double time = peak.getTOF();
749 double dtime = dQ / Q * time;
750 int chanCenter = findTimeChannel(X, time);
751
752 Centerchan = chanCenter;
753 int chanLeft = findTimeChannel(X, time - dtime);
754 int chanRight = findTimeChannel(X, time + dtime);
755 int dchan = abs(chanCenter - chanLeft);
756
757 if (abs(chanRight - chanCenter) > dchan)
758 dchan = abs(chanRight - chanCenter);
759
760 dchan = max<int>(3, dchan);
761
762 return dchan + 5; // heuristic should be a lot more
763}
764
781void IntegratePeakTimeSlices::FindPlane(V3D &center, V3D &xvec, V3D &yvec, double &ROW, double &COL, int &NROWS,
782 int &NCOLS, double &pixWidthx, double &pixHeighty,
783 DataObjects::Peak const &peak) const {
784
785 NROWS = NCOLS = -1;
787 V3D detPos = det->getPos();
788
789 center.setX(detPos.X());
790 center.setY(detPos.Y());
791 center.setZ(detPos.Z());
792
793 std::shared_ptr<const Detector> dett = std::dynamic_pointer_cast<const Detector>(det);
794
795 pixWidthx = dett->getWidth();
796 pixHeighty = dett->getHeight();
797
798 Kernel::Quat Qt = dett->getRotation();
799 V3D yaxis0(0.0, 1.0, 0.0);
800
801 Qt.rotate(yaxis0);
802 yaxis0.normalize();
803
804 V3D xaxis0(1, 0, 0);
805 Qt.rotate(xaxis0);
806 xaxis0.normalize();
807
808 xvec.setX(xaxis0.X());
809 xvec.setY(xaxis0.Y());
810 xvec.setZ(xaxis0.Z());
811 yvec.setX(yaxis0.X());
812 yvec.setY(yaxis0.Y());
813 yvec.setZ(yaxis0.Z());
814 ROW = peak.getRow();
815 COL = peak.getCol();
817 if (!inst)
818 throw std::invalid_argument("No instrument for peak");
819 std::shared_ptr<const IComponent> panel = inst->getComponentByName(peak.getBankName());
820
821 std::shared_ptr<const RectangularDetector> ddet = std::dynamic_pointer_cast<const RectangularDetector>(panel);
822
823 if (ddet) {
824 std::pair<int, int> CR = ddet->getXYForDetectorID(det->getID());
825 ROW = CR.second;
826 COL = CR.first;
827 pixWidthx = ddet->xstep();
828 pixHeighty = ddet->ystep();
829
830 NROWS = ddet->ypixels();
831 NCOLS = ddet->xpixels();
832
833 return;
834 }
835 // Get NROWS and NCOLS for other panels
836 NROWS = NCOLS = -1;
837
838 if (!panel)
839 return;
840 std::shared_ptr<const Component> compPanel = std::dynamic_pointer_cast<const Component>(panel);
841 std::shared_ptr<IComponent> panel1(compPanel->base()->clone());
842 BoundingBox B;
843
844 Quat rot = panel1->getRotation();
845
846 rot.inverse();
847
848 panel1->rotate(rot);
849
850 panel1->getBoundingBox(B);
851
852 NROWS = boost::math::iround((B.yMax() - B.yMin()) / pixHeighty);
853 NCOLS = boost::math::iround((B.xMax() - B.xMin()) / pixWidthx);
854}
855
865void IntegratePeakTimeSlices::updateStats(const double intensity, const double variance, const double row,
866 const double col, std::vector<double> &StatBase) {
867
868 StatBase[ISSIxx] += col * col * intensity;
869 StatBase[ISSIyy] += intensity * row * row;
870 StatBase[ISSIxy] += intensity * row * col;
871 StatBase[ISSxx] += col * col;
872 StatBase[ISSyy] += row * row;
873 StatBase[ISSxy] += row * col;
874 StatBase[ISSIx] += intensity * col;
875 StatBase[ISSIy] += intensity * row;
876 StatBase[ISSx] += col;
877 StatBase[ISSy] += row;
878 StatBase[IIntensities] += intensity;
879 StatBase[IVariance] += variance;
880 StatBase[ISS1] += 1;
881}
882
893std::vector<double> DataModeHandler::InitValues(double Varx, double Vary, double b) {
894 std::vector<double> Res(7);
895
896 Res[IVXX] = Varx;
897 Res[IVYY] = Vary;
898 Res[IVXY] = 0;
899 auto nCells = static_cast<int>(StatBase[ISS1]);
900 double Den = StatBase[IIntensities] - b * nCells;
901 Res[IXMEAN] = (StatBase[ISSIx] - b * StatBase[ISSx]) / Den;
902 Res[IYMEAN] = (StatBase[ISSIy] - b * StatBase[ISSy]) / Den;
903 Res[IBACK] = b;
904 Res[ITINTENS] = StatBase[IIntensities] - b * nCells;
905
906 //---- Is Edge Cell ???-------
907 double NstdX = 4 * (currentRadius / CellWidth - EdgeX) / sqrt(Varx);
908 double NstdY = 4 * (currentRadius / CellHeight - EdgeY) / sqrt(Vary);
909 double sigx = 1;
910 double sigy = 1;
911 if (NstdX < 0)
912 sigx = -1;
913 if (NstdY < 0)
914 sigy = -1;
915
916 double x = 1;
917 if (sigy * NstdY < 7 && sigy * NstdY >= 0) // is close to row edge
918 {
919 x = probs[std::lround(sigy * NstdY)];
920 if (sigy < 0)
921 x = 1 - x;
922 double My2 = StatBase[IStartRow];
923 if (Res[IYMEAN] - My2 > My2 + StatBase[INRows] - Res[IYMEAN])
924 My2 += StatBase[INRows];
925 Res[IYMEAN] = Res[IYMEAN] * x + (1 - x) * My2;
926 }
927 double x1 = 1;
928 if (sigx * NstdX < 7 && sigx * NstdX > 0) // is close to x edge
929 {
930 x1 = probs[std::lround(sigx * NstdX)];
931 if (sigx < 0)
932 x1 = 1 - x1;
933 double Mx2 = StatBase[IStartCol];
934 if (Res[IXMEAN] - Mx2 > Mx2 + StatBase[INCol] - Res[IXMEAN])
935 Mx2 += StatBase[INCol];
936 Res[IXMEAN] = Res[IXMEAN] * x1 + (1 - x1) * Mx2;
937 }
938 Res[ITINTENS] /= x * x1;
939
940 return Res;
941}
942
950std::vector<double> DataModeHandler::GetParams(double b) {
951
952 auto nCells = static_cast<int>(StatBase[ISS1]);
953 double Den = StatBase[IIntensities] - b * nCells;
954 double Varx, Vary;
955
956 Varx = VarxHW;
957 Vary = VaryHW;
958
959 double Rx = lastRCRadius / CellWidth - EdgeX;
960 double Ry = lastRCRadius / CellHeight - EdgeY;
961 if (Varx <= 0)
963
964 if (Vary <= 0)
966 // Use
967 if (Rx * Rx < 4 * Varx || Ry * Ry < 4 * Vary) {
968 return InitValues(Varx, Vary, b);
969 }
970 if (Den < 0)
971 return std::vector<double>();
972
973 double Mx = StatBase[ISSIx] - b * StatBase[ISSx];
974 double My = StatBase[ISSIy] - b * StatBase[ISSy];
975
976 double Sxx = (StatBase[ISSIxx] - b * StatBase[ISSxx] - Mx * Mx / Den) / Den;
977 double Syy = (StatBase[ISSIyy] - b * StatBase[ISSyy] - My * My / Den) / Den;
978 double Sxy = (StatBase[ISSIxy] - b * StatBase[ISSxy] - Mx * My / Den) / Den;
979
980 double Intensity = StatBase[IIntensities] - b * nCells;
981 double col = Mx / Den;
982 double row = My / Den;
983 std::vector<double> Result(7);
984 Result[IBACK] = b;
985 Result[ITINTENS] = Intensity;
986 Result[IXMEAN] = col;
987 Result[IYMEAN] = row;
988 Result[IVXX] = Sxx;
989 Result[IVYY] = Syy;
990 Result[IVXY] = Sxy;
991
992 return Result;
993}
994
1001bool DataModeHandler::setStatBase(std::vector<double> const &statBase)
1002
1003{
1004 auto nBoundaryCells = static_cast<int>(statBase[INBoundary]);
1005 this->StatBase = statBase;
1006 double b = 0;
1007 if (nBoundaryCells > 0) {
1008 double TotBoundaryIntensities = statBase[ITotBoundary];
1009 b = TotBoundaryIntensities / nBoundaryCells;
1010 }
1011
1012 auto nCells = static_cast<int>(statBase[ISS1]);
1013 double Den = statBase[IIntensities] - b * nCells;
1014 int k = 0;
1015 while (Den <= 0 && b != 0) {
1016 b = b * .7;
1017 Den = statBase[IIntensities] - b * nCells;
1018
1019 if (k < 8)
1020 k++;
1021 else
1022 b = 0;
1023 }
1024
1025 double Varx, Vary;
1026 Varx = statBase[INCol] / 7; // Range = 3.5 standard deviations
1027 Vary = statBase[INRows] / 7;
1028 Varx *= Varx;
1029 Vary *= Vary;
1030
1031 double Rx = lastRCRadius / CellWidth - EdgeX;
1032 double Ry = lastRCRadius / CellHeight - EdgeY;
1033 if (CellWidth > 0 && currentRadius > 0 && lastCol > 0 && lastRow > 0)
1034 if (Rx * Rx < 4 * std::max(Varx, VarxHW) || HalfWidthAtHalfHeightRadius < 0 ||
1035 Ry * Ry < 4 * std::max(Vary, VaryHW)) // Edge peak so cannot use samples
1036 {
1037 Vx_calc = VarxHW;
1038 Vy_calc = VaryHW;
1039 Vxy_calc = 0;
1040 col_calc = lastCol;
1041 row_calc = lastRow;
1042 back_calc = b;
1043 Intensity_calc = statBase[IIntensities] - b * nCells;
1044 if (Vx_calc <= 0 || Vy_calc <= 0) // EdgePeak but not big enuf
1045 return true;
1046
1047 const double params[] = {back_calc, Intensity_calc, col_calc, row_calc, Vx_calc, Vy_calc, Vxy_calc};
1048 double r = CalcSampleIntensityMultiplier(params);
1049 Intensity_calc *= r;
1050 return true;
1051 }
1052 if (Den <= 0)
1053 Den = 1;
1054
1055 bool done = false;
1056 int ntimes = 0;
1057 double Mx = 0, My = 0, Sxx = 0, Syy = 0, Sxy = 0;
1058
1059 double RangeX = statBase[INCol] / 2;
1060 double RangeY = statBase[INRows] / 2;
1061
1062 while (!done && ntimes < 29) {
1063 Mx = statBase[ISSIx] - b * statBase[ISSx];
1064 My = statBase[ISSIy] - b * statBase[ISSy];
1065 Sxx = (statBase[ISSIxx] - b * statBase[ISSxx] - Mx * Mx / Den) / Den;
1066 Syy = (statBase[ISSIyy] - b * statBase[ISSyy] - My * My / Den) / Den;
1067 Sxy = (statBase[ISSIxy] - b * statBase[ISSxy] - Mx * My / Den) / Den;
1068 ntimes++;
1069 done = false;
1070
1071 if (Sxx <= RangeX / 12 || Syy <= RangeY / 12 || Sxy * Sxy / Sxx / Syy > .9) {
1072 b = b * .95;
1073
1074 if (ntimes + 1 == 29)
1075 b = 0;
1076
1077 Den = statBase[IIntensities] - b * nCells;
1078 if (Den <= 1)
1079 Den = 1;
1080
1081 } else
1082 done = true;
1083 }
1084
1085 back_calc = b;
1086 Intensity_calc = statBase[IIntensities] - b * nCells;
1087 col_calc = Mx / Den;
1088 row_calc = My / Den;
1089 Vx_calc = Sxx;
1090 Vy_calc = Syy;
1091 Vxy_calc = Sxy;
1092 return false;
1093}
1094
1102 double Vx, Vy;
1103 Vx = VarxHW;
1104 Vy = VaryHW;
1105 if (Vx < 0)
1107 if (Vy < 0)
1109
1110 double Rx = lastRCRadius / CellWidth - EdgeX;
1111 double Ry = lastRCRadius / CellHeight - EdgeY;
1112 double mult = 1;
1113 if (Rx * Rx > 4 * Vx)
1114 Vx = std::max(VarxHW, Vx_calc);
1115 else
1116 mult = 1.35;
1117
1118 if (Ry * Ry > 4 * Vy)
1119 Vy = std::max(VaryHW, Vy_calc);
1120 else
1121 mult *= 1.35;
1122
1123 double DD = max<double>(sqrt(Vy) * CellHeight, sqrt(Vx) * CellWidth);
1124 double NewRadius = 1.4 * max<double>(MinRowColSpan * max<double>(CellWidth, CellHeight), 4.5 * DD);
1125 NewRadius = mult * min<double>(baseRCRadius, NewRadius);
1126 // 1.4 is needed to get more background cells. In rectangle the corners were
1127 // background
1128
1129 NewRadius = min<double>(MaxRowColSpan * max<double>(CellWidth, CellHeight), NewRadius);
1130
1131 return NewRadius;
1132}
1133
1143void DataModeHandler::setHeightHalfWidthInfo(const std::vector<double> &xvals, const std::vector<double> &yvals,
1144 const std::vector<double> &counts) {
1145 double minCount, maxCount;
1146 const auto &X = xvals;
1147 const auto &Y = yvals;
1148 const auto &C = counts;
1149 VarxHW = -1;
1150 VaryHW = -1;
1151 auto N = static_cast<int>(X.size());
1152
1154
1155 if (N <= 2)
1156 return;
1157
1158 minCount = maxCount = C[0];
1159 double MaxX = -1;
1160 double MaxY = -1;
1161 int nmax = 0;
1162 double lowX, lowY, highX, highY;
1163 lowX = highX = X[0];
1164 lowY = highY = Y[0];
1165
1166 for (int i = 1; i < N; i++) {
1167 if (X[i] < lowX)
1168 lowX = X[i];
1169 else if (X[i] > highX)
1170 highX = X[i];
1171
1172 if (Y[i] < lowY)
1173 lowY = Y[i];
1174 else if (Y[i] > highY)
1175 highY = Y[i];
1176
1177 if (C[i] > maxCount) {
1178 maxCount = C[i];
1179 MaxX = X[i];
1180 MaxY = Y[i];
1181 nmax = 1;
1182 } else if (C[i] < minCount) {
1183 minCount = C[i];
1184
1185 } else if (C[i] == maxCount) // Get a tolerance on this
1186 {
1187 MaxX += X[i];
1188 MaxY += Y[i];
1189 nmax++;
1190 }
1191 }
1192 if (minCount == maxCount)
1193 return;
1194
1195 MaxX /= nmax;
1196 MaxY /= nmax;
1197
1198 double dCount = std::max(.51, (maxCount - minCount) / 6.2);
1199 double CountUp = (maxCount + minCount) / 2 + dCount;
1200 double CountLow = (maxCount + minCount) / 2 - dCount;
1201 double dSpanx = (highX - lowX) / 6.;
1202 double dSpany = (highY - lowY) / 6.0;
1203
1204 int nMax = 0;
1205 int nMin = 0;
1206 double TotMax = 0;
1207 double TotMin = 0;
1208 double offset = std::max(.2, (maxCount - minCount) / 20);
1209 double TotR_max = 0;
1210 double TotR_min = 0;
1211 double TotRx0 = 0;
1212 double TotRy0 = 0;
1213 double TotCx = 0;
1214 double TotCy = 0;
1215 for (int i = 0; i < N; i++) {
1216 if (C[i] > maxCount - offset) {
1217 TotMax += C[i];
1218 nMax++;
1219 TotR_max += C[i] * sqrt((X[i] - MaxX) * (X[i] - MaxX) + (Y[i] - MaxY) * (Y[i] - MaxY));
1220 }
1221 if (C[i] < minCount + offset)
1222
1223 {
1224 TotMin += C[i];
1225 nMin++;
1226
1227 TotR_min += C[i] * sqrt((X[i] - MaxX) * (X[i] - MaxX) + (Y[i] - MaxY) * (Y[i] - MaxY));
1228 }
1229
1230 if (fabs(MaxY - Y[i]) < 1.2 && fabs(MaxX - X[i]) > 1.2 && C[i] >= CountLow && C[i] <= CountUp &&
1231 fabs(MaxX - X[i]) < dSpanx) {
1232 TotRx0 += (C[i] - minCount) * (X[i] - MaxX) * (X[i] - MaxX);
1233 TotCx += C[i] - minCount;
1234 }
1235
1236 if (fabs(MaxX - X[i]) < 1.2 && fabs(MaxY - Y[i]) > 1.2 && C[i] >= CountLow && C[i] <= CountUp &&
1237 fabs(MaxY - Y[i]) < dSpany) {
1238 TotRy0 += (C[i] - minCount) * (Y[i] - MaxY) * (Y[i] - MaxY);
1239 TotCy += C[i] - minCount;
1240 }
1241 }
1242
1243 if (nMax + nMin == N) // all data are on two levels essentially
1244 {
1245 if (TotMax <= 0)
1246 TotMax = 1;
1247 if (TotMin <= 0)
1248 TotMin = 1;
1249 double AvR = .5 * (TotR_max / TotMax + TotR_min / TotMin);
1250 HalfWidthAtHalfHeightRadius = AvR / .8326;
1251
1254 return;
1255 }
1256
1257 double TotR = 0, nR = -1, nRx = -1, nRy = -1;
1258 double MidVal = (TotMax / nMax + TotMin / nMin) / 2.0;
1259 double TotRx = 0, TotRy = 0;
1260 while ((nR <= 0 || nRy <= 0 || nRx <= 0) && offset < MidVal) {
1261 TotR = 0;
1262 nR = 0;
1263 TotRx = 0;
1264 TotRy = 0;
1265 nRx = 0;
1266 nRy = 0;
1267
1268 for (int i = 0; i < N; i++)
1269 if (C[i] < MidVal + offset && C[i] > MidVal - offset) {
1270 double X1 = X[i] - MaxX;
1271 double Y1 = Y[i] - MaxY;
1272 TotR += sqrt(X1 * X1 + Y1 * Y1);
1273 nR++;
1274 if ((X1 >= -1.2 && X1 <= 1.2) && fabs(Y1) > 1.2 && fabs(Y1) < dSpany) {
1275 nRy++;
1276 TotRy += abs(Y1);
1277 }
1278 if ((Y1 >= -1.2 && Y1 <= 1.2) && fabs(X1) > 1.2 && fabs(X1) < dSpanx) {
1279 nRx++;
1280 TotRx += fabs(X1);
1281 }
1282 }
1283 offset *= 1.1;
1284 }
1285
1286 double AvR = TotR / nR;
1287 HalfWidthAtHalfHeightRadius = AvR / .8326;
1288
1289 if (nRx > 0)
1290 VarxHW = (TotRx / nRx) * (TotRx / nRx) / .8326 / .8326;
1291 else if (TotCx > 0)
1292 VarxHW = TotRx0 * TotRx0 / TotCx / TotCx / .8326 / .8326;
1293 else if (HalfWidthAtHalfHeightRadius > 0)
1295 else
1296 VarxHW = -1;
1297
1298 if (nRy > 0)
1299 VaryHW = (TotRy / nRy) * (TotRy / nRy) / .8326 / .8326;
1300 else if (TotCy > 0)
1301 VaryHW = TotRy0 * TotRy0 / TotCy / TotCy / .8326 / .8326;
1302 else if (HalfWidthAtHalfHeightRadius > 0)
1304 else
1305 VaryHW = -1;
1306}
1327 const std::shared_ptr<Geometry::IComponent> &comp, const int chanMin,
1328 const int chanMax, double CentX, double CentY, Kernel::V3D &CentNghbr,
1329 double &neighborRadius, // from CentDetspec
1330 double Radius, string &spec_idList) {
1331
1332 Kernel::V3D CentPos1 = m_center + m_xvec * (CentX - m_COL) * m_cellWidth + m_yvec * (CentY - m_ROW) * m_cellHeight;
1333
1334 int NBadEdgeCells = getProperty("NBadEdgePixels");
1335
1336 auto X = std::make_shared<DataModeHandler>(Radius, Radius, CentY, CentX, m_cellWidth, m_cellHeight,
1337 getProperty("CalculateVariances"), NBadEdgeCells, m_NCOLS - NBadEdgeCells,
1338 NBadEdgeCells, m_NROWS - NBadEdgeCells);
1339
1341 m_AttributeValues->setCurrentRadius(Radius);
1342 m_AttributeValues->setCurrentCenter(CentPos1);
1343
1344 SetUpData1(Data, inpWkSpace, chanMin, chanMax, Radius, CentPos1, spec_idList);
1345
1346 if (m_AttributeValues->StatBaseVals(ISSIxx) < 0) // Not enough data
1347 return;
1348
1349 double NewRadius = m_AttributeValues->getNewRCRadius();
1350 if (m_R0 > 0) {
1351 NewRadius = m_R0;
1352 } else {
1353 m_R0 = NewRadius;
1354 }
1355
1356 CentX = m_ParameterValues[IXMEAN];
1357 CentY = m_ParameterValues[IYMEAN];
1358 Kernel::V3D CentPos = m_center + m_xvec * (CentX - m_COL) * m_cellWidth + m_yvec * (CentY - m_ROW) * m_cellHeight;
1359
1360 double DD = (CentPos - CentNghbr).norm();
1361
1362 if (DD + NewRadius > neighborRadius) {
1363 auto NN = int(NStdDevPeakSpan * NeighborhoodRadiusDivPeakRadius * NewRadius / m_cellWidth * NStdDevPeakSpan *
1364 NeighborhoodRadiusDivPeakRadius * NewRadius / m_cellHeight);
1365 if (m_NeighborIDs[0] < NN) {
1366 delete[] m_NeighborIDs;
1367 m_NeighborIDs = new int[NN + 2];
1368 m_NeighborIDs[0] = NN + 2;
1369 } // else
1370 // NN= m_NeighborIDs[0]-2;
1371 m_NeighborIDs[1] = 2;
1372 neighborRadius = NeighborhoodRadiusDivPeakRadius * NewRadius;
1373 CentNghbr = CentPos;
1374 getNeighborPixIDs(comp, CentPos, neighborRadius, m_NeighborIDs);
1375
1376 } else // big enough neighborhood so
1377 neighborRadius -= DD;
1378
1379 // if( changed) CentNghbr = CentPos.
1380 auto X1 = std::make_shared<DataModeHandler>(Radius, NewRadius, CentY, CentX, m_cellWidth, m_cellHeight,
1381 getProperty("CalculateVariances"), NBadEdgeCells, m_NCOLS - NBadEdgeCells,
1382 NBadEdgeCells, m_NROWS - NBadEdgeCells);
1383
1384 m_AttributeValues = X1;
1385 m_AttributeValues->setCurrentRadius(NewRadius);
1386 m_AttributeValues->setCurrentCenter(CentPos);
1387 SetUpData1(Data, inpWkSpace, chanMin, chanMax, NewRadius, CentPos, spec_idList);
1388}
1389
1402 API::MatrixWorkspace_const_sptr const &inpWkSpace, const int chanMin,
1403 const int chanMax, double Radius, const Kernel::V3D &CentPos,
1404 string &spec_idList) {
1406 if (m_NeighborIDs[1] < 10) {
1407 return;
1408 }
1409 std::vector<double> StatBase(NAttributes);
1410 std::shared_ptr<Workspace2D> ws = std::dynamic_pointer_cast<Workspace2D>(Data);
1411
1412 int NBadEdges = getProperty("NBadEdgePixels");
1413 spec_idList.clear();
1414
1415 for (int i = 0; i < NAttributes + 2; i++)
1416 StatBase.emplace_back(0);
1417
1418 std::vector<double> yvalB;
1419 std::vector<double> errB;
1420 std::vector<double> xvalB;
1421 std::vector<double> YvalB;
1422
1423 double TotBoundaryIntensities = 0;
1424 int nBoundaryCells = 0;
1425 double TotBoundaryVariances = 0;
1426
1427 double BoundaryRadius = min<double>(.90 * Radius, Radius - 1.5 * max<double>(m_cellWidth, m_cellHeight));
1428 double minRow = 20000, maxRow = -1, minCol = 20000, maxCol = -1;
1429
1430 int jj = 0;
1431
1432 std::vector<double> xRef;
1433 for (int i = 2; i < m_NeighborIDs[1]; i++) {
1434 int DetID = m_NeighborIDs[i];
1435
1436 size_t workspaceIndex;
1437 if (m_wi_to_detid_map.count(DetID) > 0)
1438 workspaceIndex = m_wi_to_detid_map.find(DetID)->second;
1439 else {
1440 throw std::runtime_error("No workspaceIndex for detID=" + std::to_string(DetID));
1441 }
1442
1443 IDetector_const_sptr Det = inpWkSpace->getDetector(workspaceIndex);
1444 V3D pixPos = Det->getPos();
1445
1446 if (i > 2)
1447 spec_idList += ",";
1448
1449 V3D dist = pixPos - CentPos;
1450 if (dist.scalar_prod(dist) < Radius * Radius)
1451
1452 {
1453 spec_idList += std::to_string(inpWkSpace->getSpectrum(workspaceIndex).getSpectrumNo());
1454
1455 double R1 = dist.scalar_prod(m_yvec);
1456 double R1a = R1 / m_cellHeight;
1457
1458 double row = m_ROW + R1a;
1459
1460 double C1 = dist.scalar_prod(m_xvec);
1461 double C1a = C1 / m_cellWidth;
1462
1463 double col = m_COL + C1a;
1464
1465 if (row > NBadEdges && col > NBadEdges && (m_NROWS < 0 || row < m_NROWS - NBadEdges) &&
1466 (m_NCOLS < 0 || col < m_NCOLS - NBadEdges)) {
1467 const auto &histogram = inpWkSpace->y(workspaceIndex);
1468
1469 const auto &histoerrs = inpWkSpace->e(workspaceIndex);
1470 double intensity = 0;
1471 double variance = 0;
1472 for (int chan = chanMin; chan <= chanMax; chan++) {
1473 intensity += histogram[chan];
1474 variance += histoerrs[chan] * histoerrs[chan];
1475 }
1476
1477 yvalB.emplace_back(intensity);
1478 double sigma = 1;
1479
1480 errB.emplace_back(sigma);
1481 xvalB.emplace_back(col);
1482 YvalB.emplace_back(row);
1483
1484 xRef.emplace_back(static_cast<double>(jj));
1485 jj++;
1486
1487 updateStats(intensity, variance, row, col, StatBase);
1488
1489 if ((pixPos - CentPos).norm() > BoundaryRadius) {
1490 TotBoundaryIntensities += intensity;
1491 nBoundaryCells++;
1492
1493 TotBoundaryVariances += variance;
1494 }
1495
1496 if (row < minRow)
1497 minRow = row;
1498 if (col < minCol)
1499 minCol = col;
1500 if (row > maxRow)
1501 maxRow = row;
1502 if (col > maxCol)
1503 maxCol = col;
1504
1505 } // if not bad edge
1506
1507 } // peak within radius
1508 } // for each neighbor
1509
1510 m_AttributeValues->EdgeY =
1511 max<double>(0.0, max<double>(-m_ROW + minRow + Radius / m_cellHeight, -maxRow + m_ROW + Radius / m_cellHeight));
1512 m_AttributeValues->EdgeX =
1513 max<double>(0.0, max<double>(-m_COL + minCol + Radius / m_cellWidth, -maxCol + m_COL + Radius / m_cellWidth));
1514 if (m_AttributeValues->EdgeY <= 1)
1515 m_AttributeValues->EdgeY = 0;
1516 if (m_AttributeValues->EdgeX <= 1)
1517 m_AttributeValues->EdgeX = 0;
1518
1519 auto pX = Kernel::make_cow<HistogramData::HistogramX>(std::move(xRef));
1520 Data->setX(0, pX);
1521 Data->setX(1, pX);
1522 Data->setX(2, pX);
1523
1524 ws->setCounts(0, yvalB);
1525 ws->setCountStandardDeviations(0, errB);
1526 ws->setCounts(1, xvalB);
1527 ws->setCounts(2, YvalB);
1528 m_AttributeValues->setHeightHalfWidthInfo(xvalB, YvalB, yvalB);
1529
1530 StatBase[IStartRow] = minRow;
1531 StatBase[IStartCol] = minCol;
1532 StatBase[INRows] = maxRow - minRow + 1;
1533 StatBase[INCol] = maxCol - minCol + 1;
1534
1535 StatBase[ITotBoundary] = TotBoundaryIntensities;
1536 StatBase[INBoundary] = nBoundaryCells;
1537 StatBase[IVarBoundary] = TotBoundaryVariances;
1538 m_EdgePeak = m_AttributeValues->setStatBase(StatBase);
1539
1540 m_ParameterValues[IBACK] = m_AttributeValues->getInitBackground();
1541 m_ParameterValues[ITINTENS] = m_AttributeValues->getInitIntensity();
1544 m_ParameterValues[IVXX] = m_AttributeValues->getInitVarx();
1545 m_ParameterValues[IVYY] = m_AttributeValues->getInitVary();
1546 m_ParameterValues[IVXY] = m_AttributeValues->getInitVarxy();
1547}
1548
1555int IntegratePeakTimeSlices::findTimeChannel(const HistogramX &X, const double time) {
1556 int sgn = 1;
1557
1558 if (X[0] > X[1])
1559 sgn = -1;
1560
1561 if (sgn * (X[0] - time) >= 0)
1562 return 0;
1563
1564 if (sgn * (time - X[X.size() - 1u]) >= 0)
1565 return static_cast<int>(X.size()) - 1;
1566
1567 size_t end = X.size() - 1u;
1568 for (size_t i = 0; i < end; i++) {
1569 if (sgn * (time - X[i]) >= 0 && sgn * (X[i + 1u] - time) >= 0)
1570 return static_cast<int>(i);
1571 }
1572
1573 return -1;
1574}
1575
1583bool DataModeHandler::isEdgePeak(const double *params, int nparams) {
1585 double Vary = Varx;
1586 if (nparams > 4) {
1587 Varx = params[IVXX];
1588 Vary = params[IVYY];
1589 }
1590
1591 if (Varx <= 0 || Vary <= 0 || HalfWidthAtHalfHeightRadius <= 0)
1592 return true;
1593
1594 double Rx = lastRCRadius / CellWidth - EdgeX; // span from center in x direction
1595 double Ry = lastRCRadius / CellHeight - EdgeY; // span from center in y direction
1596
1597 return Rx * Rx < NStdDevPeakSpan * NStdDevPeakSpan * std::max(Varx, VarxHW) ||
1598 Ry * Ry < NStdDevPeakSpan * NStdDevPeakSpan * std::max(Vary, VaryHW);
1599}
1600
1607
1608 std::ostringstream fun_str;
1609
1610 fun_str << "name=BivariateNormal,";
1611
1612 if (m_AttributeValues->CalcVariances())
1613 fun_str << "CalcVariances=1";
1614 else
1615 fun_str << "CalcVariances=-1";
1616
1617 int NN = NParameters;
1618 if (m_AttributeValues->CalcVariances())
1619 NN -= 3;
1620
1621 for (int i = 0; i < NN; i++) {
1622 fun_str << "," << m_ParameterNames[i] << "=" << m_ParameterValues[i];
1623 }
1624
1625 return fun_str.str();
1626}
1627
1636int IntegratePeakTimeSlices::findNameInVector(std::string const &oneName, std::vector<std::string> const &nameList)
1637
1638{
1639 const auto it = std::find(nameList.cbegin(), nameList.cend(), oneName);
1640 if (it != nameList.cend()) {
1641 return static_cast<int>(std::distance(nameList.cbegin(), it));
1642 }
1643 return -1;
1644}
1645
1652
1653 this->baseRCRadius = handler.baseRCRadius;
1654 this->lastRCRadius = handler.lastRCRadius;
1656 this->calcNewRCRadius = handler.calcNewRCRadius;
1657 this->lastRow = handler.lastRow;
1658 this->lastCol = handler.lastCol;
1659 this->time = handler.time;
1660 this->CellWidth = handler.CellWidth;
1661 this->CellHeight = handler.CellHeight;
1662 this->currentRadius = handler.currentRadius;
1663 this->currentPosition = handler.currentPosition;
1664 this->StatBase = handler.StatBase;
1665 this->EdgeX = handler.EdgeX;
1666 this->EdgeY = handler.EdgeY;
1667 this->CalcVariance = handler.CalcVariance;
1668 this->VarxHW = handler.VarxHW;
1669 this->VaryHW = handler.VaryHW;
1670 this->MaxRow = handler.MaxRow;
1671 this->MaxCol = handler.MaxCol;
1672 this->MinRow = handler.MinRow;
1673 this->MinCol = handler.MinCol;
1674 this->lastISAWIntensity = handler.lastISAWIntensity;
1675 this->lastISAWVariance = handler.lastISAWIntensity;
1676 this->back_calc = handler.back_calc;
1677 this->Intensity_calc = handler.Intensity_calc;
1678 this->row_calc = handler.row_calc;
1679 this->col_calc = handler.col_calc;
1680 this->Vx_calc = handler.Vx_calc;
1681 this->Vy_calc = handler.Vy_calc;
1682 this->Vxy_calc = handler.Vxy_calc;
1683 this->case4 = handler.case4;
1684}
1699void DataModeHandler::CalcVariancesFromData(double background, double meanx, double meany, double &Varxx, double &Varxy,
1700 double &Varyy, const std::vector<double> &StatBase) {
1701
1702 double Den = StatBase[IIntensities] - background * StatBase[ISS1];
1703 Varxx = (StatBase[ISSIxx] - 2 * meanx * StatBase[ISSIx] + meanx * meanx * StatBase[IIntensities] -
1704 background * (StatBase[ISSxx] - 2 * meanx * StatBase[ISSx] + meanx * meanx * StatBase[ISS1])) /
1705 Den;
1706
1707 Varyy = (StatBase[ISSIyy] - 2 * meany * StatBase[ISSIy] + meany * meany * StatBase[IIntensities] -
1708 background * (StatBase[ISSyy] - 2 * meany * StatBase[ISSy] + meany * meany * StatBase[ISS1])) /
1709 Den;
1710
1711 Varxy =
1712 (StatBase[ISSIxy] - meanx * StatBase[ISSIy] - meany * StatBase[ISSIx] + meanx * meany * StatBase[IIntensities] -
1713 background *
1714 (StatBase[ISSxy] - meanx * StatBase[ISSy] - meany * StatBase[ISSx] + meanx * meany * StatBase[ISS1])) /
1715 Den;
1716
1717 if (CalcVariances()) {
1718
1719 Varxx = std::min(Varxx, 1.21 * getInitVarx()); // copied from BiVariateNormal
1720 Varxx = std::max(Varxx, .79 * getInitVarx());
1721 Varyy = std::min(Varyy, 1.21 * getInitVary());
1722 Varyy = std::max(Varyy, .79 * getInitVary());
1723 }
1724}
1731std::string DataModeHandler::CalcConstraints(std::vector<std::pair<double, double>> &Bounds, bool CalcVariances) {
1732 double TotIntensity = StatBase[IIntensities];
1733 double ncells = StatBase[ISS1];
1734 double Variance = StatBase[IVariance];
1735 double TotBoundaryIntensities = StatBase[ITotBoundary];
1736 double TotBoundaryVariances = StatBase[IVarBoundary];
1737
1738 double nBoundaryCells = StatBase[INBoundary];
1739 double back = TotBoundaryIntensities / nBoundaryCells;
1740 double backVar = std::max(nBoundaryCells / 50.0, TotBoundaryVariances) / nBoundaryCells / nBoundaryCells;
1741 double IntensVar = Variance + ncells * ncells * backVar;
1742
1743 double relError = .25;
1744
1745 if (back_calc != back)
1746 relError = .45;
1747
1748 int N = NParameters;
1749 if (CalcVariances)
1750 N = N - 3;
1751
1752 double NSigs = NStdDevPeakSpan;
1753 if (back_calc > 0)
1754 NSigs = std::max(NStdDevPeakSpan,
1755 7 - 5 * back_calc / back); // background too high
1756 ostringstream str;
1757
1758 NSigs *= max<double>(1.0, Intensity_calc / (TotIntensity - ncells * back_calc));
1759 str << max<double>(0.0, back_calc - NSigs * (1 + relError) * sqrt(backVar)) << "<Background<"
1760 << (back + NSigs * (1.8 + relError) * sqrt(backVar)) << ","
1761 << max<double>(0.0, Intensity_calc - NSigs * (1 + relError) * sqrt(IntensVar)) << "<Intensity<"
1762 << Intensity_calc + NSigs * (1 + relError) * sqrt(IntensVar);
1763
1764 double min = max<double>(0.0, back_calc - NSigs * (1 + relError) * sqrt(backVar));
1765 double maxx = back + NSigs * (1.8 + relError) * sqrt(backVar);
1766 Bounds.emplace_back(min, maxx);
1767 Bounds.emplace_back(max<double>(0.0, Intensity_calc - NSigs * (1 + relError) * sqrt(IntensVar)),
1768 Intensity_calc + NSigs * (1 + relError) * sqrt(IntensVar));
1769 double relErr1 = relError * .75;
1770 double val = col_calc;
1771 double minn = std::max(MinCol - .5, (1 - relErr1) * val);
1772 maxx = std::min((1 + relErr1) * val, MaxCol + .5);
1773
1774 str << "," << minn << "<"
1775 << "Mcol"
1776 << "<" << maxx;
1777 Bounds.emplace_back(minn, maxx);
1778
1779 val = row_calc;
1780
1781 minn = std::max(MinRow - .5, (1 - relErr1) * val);
1782 maxx = std::min((1 + relErr1) * val, MaxRow + .5);
1783 str << "," << minn << "<"
1784 << "Mrow"
1785 << "<" << maxx;
1786 Bounds.emplace_back(minn, maxx);
1787
1788 if (N >= 5) {
1789 val = Vx_calc;
1790 double valmin = val;
1791 double valmax = val;
1792 if (VarxHW > 0) {
1793 valmin = std::min(val, VarxHW);
1794 valmax = std::max(val, VarxHW);
1795 }
1796
1797 relErr1 *= .6; // Edge peaks: need to restrict sigmas.
1798 str << "," << (1 - relErr1) * valmin << "<"
1799 << "SScol"
1800 << "<" << (1 + relErr1) * valmax;
1801 Bounds.emplace_back((1 - relErr1) * valmin, (1 + relErr1) * valmax);
1802
1803 val = Vy_calc;
1804 valmin = val;
1805 valmax = val;
1806 if (VaryHW > 0) {
1807 valmin = std::min(val, VaryHW);
1808 valmax = std::max(val, VaryHW);
1809 }
1810 str << "," << (1 - relErr1) * valmin << "<"
1811 << "SSrow"
1812 << "<" << (1 + relErr1) * valmax;
1813 Bounds.emplace_back((1 - relErr1) * valmin, (1 + relErr1) * valmax);
1814 }
1815
1816 return str.str();
1817}
1818
1833void IntegratePeakTimeSlices::Fit(const MatrixWorkspace_sptr &Data, double &chisqOverDOF, bool &done,
1834 std::vector<string> &names, std::vector<double> &params, std::vector<double> &errs,
1835 double lastRow, double lastCol, double neighborRadius) {
1836
1837 bool CalcVars = m_AttributeValues->CalcVariances();
1838 std::vector<std::pair<double, double>> Bounds;
1839 std::string Constraints = m_AttributeValues->CalcConstraints(Bounds, CalcVars);
1840 auto fit_alg = createChildAlgorithm("Fit");
1841 std::string fun_str = CalculateFunctionProperty_Fit();
1842
1843 std::string SSS(" Fit string ");
1844 SSS += fun_str;
1845 g_log.debug(SSS);
1846 g_log.debug() << " TotCount=" << m_AttributeValues->StatBase[IIntensities] << '\n';
1847
1848 fit_alg->setPropertyValue("Function", fun_str);
1849
1850 fit_alg->setProperty("InputWorkspace", Data);
1851 fit_alg->setProperty("WorkspaceIndex", 0);
1852 fit_alg->setProperty("StartX", 0.0);
1853 fit_alg->setProperty("EndX", 0.0 + static_cast<double>(m_NeighborIDs[1]));
1854 fit_alg->setProperty("MaxIterations", 5000);
1855 fit_alg->setProperty("CreateOutput", true);
1856
1857 fit_alg->setProperty("Output", "out");
1858
1859 fit_alg->setProperty("MaxIterations", 50);
1860
1861 std::string tie = getProperty("Ties");
1862 if (tie.length() > static_cast<size_t>(0))
1863 fit_alg->setProperty("Ties", tie);
1864 if (Constraints.length() > static_cast<size_t>(0))
1865 fit_alg->setProperty("Constraints", Constraints);
1866 try {
1867 fit_alg->executeAsChildAlg();
1868
1869 chisqOverDOF = fit_alg->getProperty("OutputChi2overDoF");
1870 std::string outputStatus = fit_alg->getProperty("OutputStatus");
1871 g_log.debug() << "Chisq/OutputStatus=" << chisqOverDOF << "/" << outputStatus << '\n';
1872
1873 names.clear();
1874 params.clear();
1875 errs.clear();
1876 ITableWorkspace_sptr RRes = fit_alg->getProperty("OutputParameters");
1877 for (int prm = 0; prm < static_cast<int>(RRes->rowCount()) - 1; prm++) {
1878 names.emplace_back(RRes->getRef<string>("Name", prm));
1879 params.emplace_back(RRes->getRef<double>("Value", prm));
1880 double error = RRes->getRef<double>("Error", prm);
1881 errs.emplace_back(error);
1882 }
1883 if (names.size() < 5) {
1884 names.emplace_back(m_ParameterNames[IVXX]);
1885 names.emplace_back(m_ParameterNames[IVYY]);
1886 names.emplace_back(m_ParameterNames[IVXY]);
1887 double Varxx, Varxy, Varyy;
1888 m_AttributeValues->CalcVariancesFromData(params[IBACK], params[IXMEAN], params[IYMEAN], Varxx, Varxy, Varyy,
1889 m_AttributeValues->StatBase);
1890 params.emplace_back(Varxx);
1891 params.emplace_back(Varyy);
1892 params.emplace_back(Varxy);
1893 errs.emplace_back(0);
1894 errs.emplace_back(0);
1895 errs.emplace_back(0);
1896 }
1897
1898 } catch (std::exception &Ex1) // ties or something else went wrong in BivariateNormal
1899 {
1900 done = true;
1901 g_log.error() << "Bivariate Error for PeakNum=" << static_cast<int>(getProperty("PeakIndex")) << ":"
1902 << std::string(Ex1.what()) << '\n';
1903 } catch (...) {
1904 done = true;
1905 g_log.error() << "Bivariate Error A for peakNum=" << static_cast<int>(getProperty("PeakIndex")) << '\n';
1906 }
1907 if (!done) // Bivariate error happened
1908 {
1909
1910 g_log.debug() << " Thru Algorithm: chiSq=" << setw(7) << chisqOverDOF << '\n';
1911 g_log.debug() << " Row,Col Radius=" << lastRow << "," << lastCol << "," << neighborRadius << '\n';
1912
1913 double sqrtChisq = -1;
1914 if (chisqOverDOF >= 0)
1915 sqrtChisq = (chisqOverDOF);
1916
1917 sqrtChisq =
1918 max<double>(sqrtChisq, m_AttributeValues->StatBaseVals(IIntensities) / m_AttributeValues->StatBaseVals(ISS1));
1919 sqrtChisq = SQRT(sqrtChisq);
1920
1921 for (size_t kk = 0; kk < params.size(); kk++) {
1922 g_log.debug() << " Parameter " << setw(8) << names[kk] << " " << setw(8) << params[kk];
1923 // if (names[kk].substr(0, 2) != string("SS"))
1924 g_log.debug() << "(" << setw(8) << (errs[kk] * sqrtChisq) << ")";
1925 if (Bounds.size() > kk) {
1926 pair<double, double> upLow = Bounds[kk];
1927 g_log.debug() << " Bounds(" << upLow.first << "," << upLow.second << ")";
1928 }
1929 g_log.debug() << '\n';
1930 }
1931
1932 double intensity = m_AttributeValues->CalcISAWIntensity(params.data());
1933 g_log.debug() << "IsawIntensity= " << intensity << '\n';
1934 }
1935}
1936
1953void IntegratePeakTimeSlices::PreFit(const MatrixWorkspace_sptr &Data, double &chisqOverDOF, bool &done,
1954 std::vector<string> &names, std::vector<double> &params, std::vector<double> &errs,
1955 double lastRow, double lastCol, double neighborRadius) {
1956
1957 double background = m_ParameterValues[IBACK];
1958 int N = 3;
1959 if (background <= 0) {
1960 background = 0;
1961 N = 1;
1962 }
1963 bool CalcVars = m_AttributeValues->CalcVariances();
1964 int NParams = 4;
1965 if (!CalcVars)
1966 NParams += 3;
1967
1968 double minChiSqOverDOF = -1;
1969 double Bestparams[7];
1970 std::string Bestnames[7];
1971 for (int i = 0; i < N; i++) {
1972 Fit(Data, chisqOverDOF, done, names, params, errs, lastRow, lastCol, neighborRadius);
1973 g_log.debug() << "-----------------------" << i << "--------------------------\n";
1974 if ((minChiSqOverDOF < 0 || chisqOverDOF < minChiSqOverDOF) && (chisqOverDOF > 0) && !done) {
1975 for (int j = 0; j < NParams; j++) {
1976 Bestparams[j] = m_ParameterValues[j];
1977 Bestnames[j] = m_ParameterNames[j];
1978 }
1979 minChiSqOverDOF = chisqOverDOF;
1980 }
1981
1982 // Next round, reduce background
1983 background = background / 2;
1984 if (i + 1 == N - 1)
1985 background = 0;
1986
1987 std::vector<double> prms = m_AttributeValues->GetParams(background);
1988
1989 for (int j = 0; j < NParams; j++)
1990 m_ParameterValues[j] = prms[j];
1991 }
1992 vector<std::string> ParNames(m_ParameterNames, m_ParameterNames + NParams);
1993 for (int i = 0; i < NParams; i++) {
1994 int k = findNameInVector(Bestnames[i], ParNames);
1995 if (k >= 0 && k < NParams)
1996 m_ParameterValues[k] = Bestparams[k];
1997 }
1998
1999 Fit(Data, chisqOverDOF, done, names, params, errs, lastRow, lastCol, neighborRadius);
2000}
2001
2012bool IntegratePeakTimeSlices::isGoodFit(std::vector<double> const &params, std::vector<double> const &errs,
2013 std::vector<std::string> const &names, double chisqOverDOF) {
2014 int Ibk = findNameInVector("Background", names);
2015 if (Ibk < 0)
2016 throw std::runtime_error("Irrecoverable inconsistency found. The index for the "
2017 "parameter 'Background' is lower than zero.");
2018
2019 int IIntensity = findNameInVector("Intensity", names);
2020 if (IIntensity < 0)
2021 throw std::runtime_error("Irrecoverable inconsistency found. The index for the "
2022 "parameter 'Intensity' is lower than zero.");
2023
2024 if (chisqOverDOF < 0) {
2025
2026 g_log.debug() << " Bad Slice- negative chiSq= " << chisqOverDOF << '\n';
2027 ;
2028 return false;
2029 }
2030
2031 int NBadEdgeCells = getProperty("NBadEdgePixels");
2032 NBadEdgeCells = static_cast<int>(.6 * NBadEdgeCells);
2033 if (params[IXMEAN] < NBadEdgeCells || params[IYMEAN] < NBadEdgeCells || params[IXMEAN] > m_NCOLS - NBadEdgeCells ||
2034 params[IYMEAN] > m_NROWS - NBadEdgeCells)
2035 return false;
2036
2037 auto ncells = static_cast<int>(m_AttributeValues->StatBaseVals(ISS1));
2038
2039 if (m_AttributeValues->StatBaseVals(IIntensities) <= 0 ||
2040 (m_AttributeValues->StatBaseVals(IIntensities) - params[Ibk] * ncells) <= 0) {
2041
2042 g_log.debug() << " Bad Slice. Negative Counts= "
2043 << m_AttributeValues->StatBaseVals(IIntensities) - params[Ibk] * ncells << '\n';
2044 ;
2045 return false;
2046 }
2047
2048 double x = params[IIntensity] / (m_AttributeValues->StatBaseVals(IIntensities) - params[Ibk] * ncells);
2049
2050 if ((x < MinGoodRatioFitvsExpIntenisites || x > MaxGoodRatioFitvsExpIntenisites) &&
2051 !m_EdgePeak) // The fitted intensity should be close to tot intensity -
2052 // background
2053 {
2054 g_log.debug() << " Bad Slice. Fitted Intensity & Observed "
2055 "Intensity(-back) too different. ratio="
2056 << x << '\n';
2057
2058 return false;
2059 }
2060
2061 bool GoodNums = true;
2062 bool paramBad = false;
2063 auto BadParamNum = static_cast<size_t>(-1);
2064 for (size_t i = 0; i < errs.size(); i++)
2065 if (errs[i] != errs[i]) {
2066 GoodNums = false;
2067 paramBad = false;
2068 BadParamNum = i;
2069 } else if (errs[i] < 0) {
2070 GoodNums = false;
2071 paramBad = false;
2072 BadParamNum = i;
2073 } else if (params[i] != params[i]) {
2074 GoodNums = false;
2075 paramBad = true;
2076 BadParamNum = i;
2077 }
2078
2079 if (!GoodNums) {
2080 std::string obj = " parameter ";
2081 if (!paramBad)
2082 obj = " error ";
2083 g_log.debug() << " Bad Slice." << obj << BadParamNum << " is not a number\n";
2084 return false;
2085 }
2086
2087 GoodNums = true;
2088
2089 std::string Err("back ground is negative");
2090 if (params[Ibk] < -.002)
2091 GoodNums = false;
2092
2093 if (GoodNums)
2094 Err = "Intensity is negative";
2095 if (params[IIntensity] < 0)
2096 GoodNums = false;
2097
2098 double IsawIntensity = m_AttributeValues->CalcISAWIntensity(params.data());
2099 double IsawVariance = m_AttributeValues->CalcISAWIntensityVariance(params.data(), errs.data(), chisqOverDOF);
2100 if (GoodNums)
2101 Err = "Isaw Variance is negative";
2102 if (IsawVariance > 0) {
2103 if (GoodNums)
2104 Err = "I/sigI > 3";
2105 if (IsawIntensity * IsawIntensity / IsawVariance < MinGoodIoverSigI * MinGoodIoverSigI)
2106 GoodNums = false;
2107 } else
2108 GoodNums = false;
2109
2110 if (!GoodNums)
2111
2112 {
2113 g_log.debug() << Err << '\n';
2114
2115 return false;
2116 }
2117
2118 // Check weak peak. Max theoretical height should be more than 3
2119
2120 double maxPeakHeightTheoretical =
2121 params[ITINTENS] / 2 / M_PI / sqrt(params[IVXX] * params[IVYY] - params[IVXY] * params[IVXY]);
2122
2123 double AvHeight =
2124 m_AttributeValues->StatBaseVals(IIntensities) / m_AttributeValues->StatBaseVals(ISS1) - params[IBACK];
2125
2126 if (maxPeakHeightTheoretical < 2 * AvHeight || AvHeight < 0 || maxPeakHeightTheoretical < 0) {
2127
2128 g_log.debug() << " Bad Slice. Peak too small= " << maxPeakHeightTheoretical << "/" << AvHeight << '\n';
2129 return false;
2130 }
2131
2132 double Nrows = std::max(m_AttributeValues->StatBase[INRows], m_AttributeValues->StatBase[INCol]);
2133 if (maxPeakHeightTheoretical < 1 && (params[IVXX] > Nrows * Nrows / 4 || params[IVYY] > Nrows * Nrows / 4)) {
2134 g_log.debug() << "Peak is too flat \n";
2135 return false;
2136 }
2137
2138 // Exponential too steep, i.e. intensities at pixels 1 from center are <3*
2139 // intensity center
2140 if (params[IVXX] + params[IVYY] > 2.6 * (params[IVXX] * params[IVYY] - params[IVXY] * params[IVXY])) {
2141 g_log.debug() << " Bad Slice. Too steep of an exponential\n";
2142 return false;
2143 }
2144
2145 return true;
2146}
2147
2154bool DataModeHandler::IsEnoughData(const double *ParameterValues, Kernel::Logger & /*unused*/) {
2155 // Check if flat
2156 double Varx, Vary, Cov;
2157
2158 if (StatBase.empty())
2159 return false;
2160
2161 double ncells = static_cast<int>(StatBase[IIntensities]);
2162 if (ncells <= 0)
2163 return false;
2164
2165 double meanx = StatBase[ISSIx] / ncells;
2166 double meany = StatBase[ISSIy] / ncells;
2167
2168 if (!CalcVariances()) {
2169 Varx = ParameterValues[IVXX];
2170 Vary = ParameterValues[IVYY];
2171 Cov = ParameterValues[IVXY];
2172
2173 } else
2174 CalcVariancesFromData(ParameterValues[0], meanx, meany, Varx, Cov, Vary, StatBase);
2175
2176 if (Varx < MinVariationInXYvalues || Vary < MinVariationInXYvalues) // All data essentially the same.
2177 return false;
2178
2179 if (Cov * Cov > MaxCorrCoeffinXY * Varx * Vary) // All data on a obtuse line
2180 return false;
2181
2182 return true;
2183}
2184
2197double IntegratePeakTimeSlices::CalculateIsawIntegrateError(const double background, const double backError,
2198 const double ChiSqOverDOF, const double TotVariance,
2199 const int ncells) {
2200
2201 double B = TotVariance / ncells;
2202 if (B < ChiSqOverDOF)
2203 B = ChiSqOverDOF;
2204
2205 double Variance = TotVariance + (backError * backError * B) * ncells * ncells + background * ncells;
2206
2207 return SQRT(Variance);
2208}
2209
2216 // TabWS->setName("Log Table");
2217 TabWS->addColumn("double", "Time");
2218 TabWS->addColumn("double", "Channel");
2219 TabWS->addColumn("double", "Background");
2220 TabWS->addColumn("double", "Intensity");
2221 TabWS->addColumn("double", "Mcol");
2222 TabWS->addColumn("double", "Mrow");
2223 TabWS->addColumn("double", "SScol");
2224 TabWS->addColumn("double", "SSrow");
2225 TabWS->addColumn("double", "SSrc");
2226 TabWS->addColumn("double", "NCells");
2227 TabWS->addColumn("double", "ChiSqrOverDOF");
2228 TabWS->addColumn("double", "TotIntensity");
2229 TabWS->addColumn("double", "BackgroundError");
2230 TabWS->addColumn("double", "FitIntensityError");
2231 TabWS->addColumn("double", "ISAWIntensity");
2232 TabWS->addColumn("double", "ISAWIntensityError");
2233 TabWS->addColumn("double", "TotalBoundary");
2234 TabWS->addColumn("double", "NBoundaryCells");
2235 TabWS->addColumn("double", "Start Row");
2236 TabWS->addColumn("double", "End Row");
2237 TabWS->addColumn("double", "Start Col");
2238 TabWS->addColumn("double", "End Col");
2239 TabWS->addColumn("double", "TotIntensityError");
2240 TabWS->addColumn("str", "SpecIDs");
2241}
2242
2261 std::vector<double> const &params, std::vector<double> const &errs,
2262 std::vector<std::string> const &names, const double Chisq,
2263 const double time, string spec_idList) {
2264 int Ibk = findNameInVector("Background", names);
2265 int IIntensity = findNameInVector("Intensity", names);
2266 int IVx = findNameInVector("SScol", names);
2267 int IVy = findNameInVector("SSrow", names);
2268 int IVxy = findNameInVector("SSrc", names);
2269 int Irow = findNameInVector("Mrow", names);
2270 int Icol = findNameInVector("Mcol", names);
2271
2272 if (Ibk < 0 || IIntensity < 0 || IVx < 0 || IVy < 0 || IVxy < 0 || Irow < 0 || Icol < 0) {
2273 throw std::runtime_error("Inconsistency found when updating output "
2274 "workspace. None of the indices for the "
2275 "parameters 'Background', 'Intensity', 'SScol', "
2276 "'SSrow', 'SSrc', 'Mrow', 'Mcol' can be "
2277 "negative.");
2278 }
2279
2280 int newRowIndex = 0;
2281
2282 if (dir > 0)
2283 newRowIndex = static_cast<int>(TabWS->rowCount());
2284
2285 auto TableRow = static_cast<int>(TabWS->insertRow(newRowIndex));
2286
2287 auto ncells = static_cast<int>(m_AttributeValues->StatBaseVals(ISS1));
2288 double chisq = max<double>(Chisq, m_AttributeValues->StatBaseVals(IIntensities) / max<int>(ncells, 1));
2289
2290 TabWS->getRef<double>(std::string("Background"), TableRow) = params[Ibk];
2291 TabWS->getRef<double>(std::string("Channel"), TableRow) = chan;
2292
2293 TabWS->getRef<double>(std::string("Intensity"), TableRow) = params[IIntensity];
2294 TabWS->getRef<double>(std::string("FitIntensityError"), TableRow) = errs[IIntensity] * sqrt(chisq);
2295 TabWS->getRef<double>(std::string("Mcol"), TableRow) = params[Icol];
2296 TabWS->getRef<double>(std::string("Mrow"), TableRow) = params[Irow];
2297
2298 TabWS->getRef<double>(std::string("SScol"), TableRow) = params[IVx];
2299 TabWS->getRef<double>(std::string("SSrow"), TableRow) = params[IVy];
2300
2301 TabWS->getRef<double>(std::string("SSrc"), TableRow) = params[IVxy];
2302 TabWS->getRef<double>(std::string("NCells"), TableRow) = ncells;
2303 TabWS->getRef<double>(std::string("ChiSqrOverDOF"), TableRow) = chisq;
2304
2305 TabWS->getRef<double>(std::string("TotIntensity"), TableRow) = m_AttributeValues->StatBaseVals(IIntensities);
2306 TabWS->getRef<double>(std::string("BackgroundError"), TableRow) = errs[Ibk] * SQRT(chisq);
2307 TabWS->getRef<double>(std::string("ISAWIntensity"), TableRow) = m_AttributeValues->CalcISAWIntensity(params.data());
2308 // m_AttributeValues->StatBaseVals(IIntensities)
2309 // -
2310 // params[Ibk]
2311 // * ncells;
2312
2313 TabWS->getRef<double>(std::string("ISAWIntensityError"), TableRow) =
2314 sqrt(m_AttributeValues->CalcISAWIntensityVariance(params.data(), errs.data(), Chisq));
2315
2316 // CalculateIsawIntegrateError(
2317 // params[Ibk], errs[Ibk], chisq, m_AttributeValues->StatBaseVals(IVariance),
2318 // ncells);
2319
2320 TabWS->getRef<double>(std::string("Time"), TableRow) = time;
2321
2322 TabWS->getRef<double>(std::string("TotalBoundary"), TableRow) = m_AttributeValues->StatBaseVals(ITotBoundary);
2323 TabWS->getRef<double>(std::string("NBoundaryCells"), TableRow) = m_AttributeValues->StatBaseVals(INBoundary);
2324
2325 TabWS->getRef<double>(std::string("Start Row"), TableRow) = m_AttributeValues->StatBaseVals(IStartRow);
2326 TabWS->getRef<double>(std::string("End Row"), TableRow) =
2327 m_AttributeValues->StatBaseVals(IStartRow) + m_AttributeValues->StatBaseVals(INRows) - 1;
2328
2329 TabWS->getRef<double>(std::string("Start Col"), TableRow) = m_AttributeValues->StatBaseVals(IStartCol);
2330 TabWS->getRef<double>(std::string("End Col"), TableRow) =
2331 m_AttributeValues->StatBaseVals(IStartCol) + m_AttributeValues->StatBaseVals(INCol) - 1;
2332 TabWS->getRef<double>(std::string("TotIntensityError"), TableRow) = SQRT(m_AttributeValues->StatBaseVals(IVariance));
2333 TabWS->getRef<string>(std::string("SpecIDs"), TableRow) = std::move(spec_idList);
2334
2335 return newRowIndex;
2336}
2337
2352void IntegratePeakTimeSlices::updatePeakInformation(std::vector<double> const &params, std::vector<double> const &errs,
2353 std::vector<std::string> const &names, double &TotVariance,
2354 double &TotIntensity, double const TotSliceIntensity,
2355 double const TotSliceVariance, double const chisqdivDOF,
2356 const int ncells) {
2357 UNUSED_ARG(TotSliceIntensity);
2358 UNUSED_ARG(TotSliceVariance);
2359 UNUSED_ARG(names);
2360 UNUSED_ARG(ncells);
2361
2362 double err = 0;
2363 double intensity = 0;
2364
2365 err = m_AttributeValues->CalcISAWIntensityVariance(params.data(), errs.data(), chisqdivDOF);
2366
2367 intensity = m_AttributeValues->CalcISAWIntensity(params.data());
2368 TotIntensity += intensity;
2369
2370 TotVariance += err;
2371 g_log.debug() << "TotIntensity/TotVariance=" << TotIntensity << "/" << TotVariance << '\n';
2372}
2373
2383 if (!CalcVariance)
2384 return false;
2385
2386 const double param[7] = {back_calc, Intensity_calc, col_calc, row_calc, Vx_calc, Vy_calc, Vxy_calc};
2387 return !isEdgePeak(param, 7);
2388}
2389
2399double DataModeHandler::CalcISAWIntensity(const double *params) {
2400
2401 double ExperimentalIntensity = StatBase[IIntensities] - params[IBACK] * StatBase[ISS1];
2402
2403 double r = CalcSampleIntensityMultiplier(params);
2404
2405 double alpha = .5 * (r - 1.0);
2406 alpha = std::min(1.0, alpha);
2407
2408 lastISAWIntensity = ExperimentalIntensity * r; //*( 1-alpha )+ alpha * FitIntensity;
2409 return lastISAWIntensity;
2410}
2421double DataModeHandler::CalcISAWIntensityVariance(const double *params, const double *errs, double chiSqOvDOF) {
2422
2423 auto ncells = static_cast<int>(StatBase[ISS1]);
2424 double B = StatBase[IVariance] / ncells;
2425 if (B < chiSqOvDOF)
2426 B = chiSqOvDOF;
2427
2428 double ExperimVar = StatBase[IVariance];
2429 double IntensityBackError = errs[IBACK] * sqrt(B);
2430
2431 ExperimVar += IntensityBackError * IntensityBackError * ncells * ncells + params[IBACK] * ncells;
2432
2433 double r = CalcSampleIntensityMultiplier(params);
2434 double alpha = .5 * (r - 1.0);
2435 alpha = std::min(1.0, alpha);
2436
2437 lastISAWVariance = ExperimVar * r * r; //*( 1 - alpha ) + alpha * FitVar;
2438 return lastISAWVariance;
2439}
2440
2449double DataModeHandler::CalcSampleIntensityMultiplier(const double *params) const {
2450 auto minRow = static_cast<int>(StatBase[IStartRow]);
2451 int maxRow = minRow + static_cast<int>(StatBase[INRows]) - 1;
2452 auto minCol = static_cast<int>(StatBase[IStartCol]);
2453 int maxCol = minCol + static_cast<int>(StatBase[INCol]) - 1;
2454 double r = 1;
2455
2456 if (params[IVXX] <= 0 || params[IVYY] <= 0)
2457 return 1.0;
2458
2459 // NstdX iand NstdY are the number of 1/4 standard deviations. Elements of
2460 // probs are in
2461 // 1/4 standard deviations
2462 double NstdX = 4 * min<double>(params[IXMEAN] - minCol, maxCol - params[IXMEAN]) / sqrt(params[IVXX]);
2463
2464 double NstdY = 4 * min<double>(params[IYMEAN] - minRow, maxRow - params[IYMEAN]) / sqrt(params[IVYY]);
2465
2466 double sgn = 1;
2467 if (NstdX < 0) {
2468 sgn = -1;
2469 }
2470 double P = 1;
2471 if (sgn * NstdX < 9) {
2472 auto xx = static_cast<int>(sgn * NstdX);
2473 double a = probs[xx];
2474 double b = 1;
2475 if (xx + 1 <= 8)
2476 b = probs[xx + 1];
2477 P = a + (b - a) * (sgn * NstdX - xx);
2478 }
2479 if (NstdX >= 7.5)
2480 r = 1.0;
2481 else if (sgn > 0)
2482 r = 1 / P;
2483 else
2484 r = 1 / (1 - P);
2485
2486 if (NstdY < 0) {
2487 sgn = -1;
2488 }
2489 P = 1;
2490 if (sgn * NstdY < 9) {
2491 auto xx = static_cast<int>(sgn * NstdY);
2492 double a = probs[xx];
2493 double b = 1;
2494 if (xx + 1 <= 8)
2495 b = probs[xx + 1];
2496 P = a + (b - a) * (sgn * NstdY - xx);
2497 }
2498 if (NstdY >= 7.5)
2499 r *= 1.0;
2500 else if (sgn > 0)
2501 r *= 1 / P;
2502 else
2503 r *= 1 / (1 - P);
2504
2505 r = std::max(r, 1.0);
2506 return r;
2507}
2508
2509} // namespace Mantid::Crystal
2510// Attr indicies
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double sigma
Definition GetAllEi.cpp:156
double error
#define IVYY
#define IVarBoundary
#define IStartRow
#define ISS1
#define ISSIxx
#define ISSy
#define ISSyy
#define IBACK
#define INBoundary
#define ISSIx
#define INCol
#define IYMEAN
#define ISSIxy
#define ISSIy
#define ISSIyy
#define ITINTENS
#define NAttributes
#define IXMEAN
#define INRows
#define ITotBoundary
#define ISSx
#define IVariance
#define IVXX
#define ISSxy
#define IIntensities
#define IStartCol
#define ISSxx
#define NParameters
#define IVXY
#define fabs(x)
Definition Matrix.cpp:22
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
double obj
the value of the quadratic function
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:76
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
void deprecatedDate(const std::string &)
The date the algorithm was deprecated on.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
TableRow represents a row in a TableWorkspace.
Definition TableRow.h:39
A property class for workspaces.
Integrates each time slice using the BivariateNormal formula, adding the results to the peak object.
void setHeightHalfWidthInfo(const MantidVec &xvals, const MantidVec &yvals, const MantidVec &counts)
For edge peaks, the sample standard deviations do not work.
double CalcISAWIntensity(const double *params)
Calculates the Intensity designed for Edge Peaks.
double CalcISAWIntensityVariance(const double *params, const double *errs, double chiSqOvDOF)
Calculates the Error in the Intensity designed for Edge Peaks.
std::vector< double > InitValues(double Varx, double Vary, double b)
Returns init values with background and variances replaced by arguments.
bool isEdgePeak(const double *params, int nparams)
Determines if a Peak is an edge peak.
bool CalcVariances()
Determines whether the Variances can be calculated.
double getNewRCRadius()
Calculates the new radius for neighborhoods so as to include almost all of a peak.
void CalcVariancesFromData(double background, double meanx, double meany, double &Varxx, double &Varxy, double &Varyy, const std::vector< double > &StatBase)
Utility method to calculate variances from data given background and means.
double CalcSampleIntensityMultiplier(const double *params) const
For Edge Peaks.
std::vector< double > GetParams(double b)
Calculates the initial values of the parameters given background b.
bool IsEnoughData(const double *ParameterValues, Kernel::Logger &)
Calculates if there is enough data to for there to be a peak.
std::string CalcConstraints(std::vector< std::pair< double, double > > &Bounds, bool CalcVariances)
Calculates the string form of the constraints to be sent to the Fit Algorithm and also saves it in a ...
bool setStatBase(std::vector< double > const &StatBase)
Sets the Accumulated data values into this class, then updates other information like initial values.
void SetUpData1(API::MatrixWorkspace_sptr &Data, API::MatrixWorkspace_const_sptr const &inpWkSpace, const int chanMin, const int chanMax, double Radius, const Kernel::V3D &CentPos, std::string &spec_idList)
Prepares the data for futher analysis adding meta data and marking data on the edges of detectors.
void FindPlane(Kernel::V3D &center, Kernel::V3D &xvec, Kernel::V3D &yvec, double &ROW, double &COL, int &NROWS, int &NCOLS, double &pixWidthx, double &pixHeighty, DataObjects::Peak const &peak) const
For NonFlat banks, this determines the data of a small planar region approximating the instrument clo...
void Fit(const API::MatrixWorkspace_sptr &Data, double &chisqOverDOF, bool &done, std::vector< std::string > &names, std::vector< double > &params, std::vector< double > &errs, double lastRow, double lastCol, double neighborRadius)
Sets up data for the Fit Algorithm call and invokes it.
int CalculateTimeChannelSpan(Geometry::IPeak const &peak, const double dQ, const Mantid::HistogramData::HistogramX &X, const int specNum, int &Centerchan)
Calculates the span of channels needed to encompass all data around the peak with Q values within dQ ...
double m_COL
for Describing the Column(or 0) describing the center of the
double CalculatePositionSpan(DataObjects::Peak const &peak, const double dQ)
Calculates the span in rows and columns needed to include all data within dQ of the specified peak.
double CalculateIsawIntegrateError(const double background, const double backError, const double ChiSqOverDOF, const double TotVariance, const int ncells)
Calculates the error in integration closest to the latest ISAW calculations.
void exec() override
Executes this algorithm.
std::string CalculateFunctionProperty_Fit()
Calculates the string for the Function Property of the Fit Algorithm.
Kernel::V3D m_center
for Describing the Plane at the Peak
Kernel::V3D m_yvec
for Describing the Plane at the Peak
Kernel::V3D m_xvec
for Describing the Plane at the Peak
void SetUpData(API::MatrixWorkspace_sptr &Data, API::MatrixWorkspace_const_sptr const &inpWkSpace, const std::shared_ptr< Geometry::IComponent > &comp, const int chanMin, const int chanMax, double CentX, double CentY, Kernel::V3D &CentNghbr, double &neighborRadius, double Radius, std::string &spec_idList)
Initial phase at converting Detector data to workspace data that will be sent to the Fit Function,...
std::shared_ptr< DataModeHandler > m_AttributeValues
void init() override
Virtual method - must be overridden by concrete algorithm.
double m_ROW
for Describing the Row(or 0) describing the center of the Peak
double m_cellHeight
for Describing the Plane at the Peak
bool getNeighborPixIDs(const std::shared_ptr< Geometry::IComponent > &comp, const Kernel::V3D &Center, double &Radius, int *&ArryofID)
Finds all neighbors within a given Radius of the Center on the given component.
int findNameInVector(std::string const &oneName, std::vector< std::string > const &nameList)
Utility to find a name in a vector of strings.
double m_R0
for Weak Peaks, these can be set using info from close
void updateStats(const double intensity, const double variance, const double row, const double col, std::vector< double > &StatBase)
Updates the cumulative statistics for the data being considered.
void InitializeColumnNamesInTableWorkspace(DataObjects::TableWorkspace_sptr &TabWS)
Initializes the column names in the output table workspace.
bool updateNeighbors(const std::shared_ptr< Geometry::IComponent > &comp, const Kernel::V3D &CentPos, const Kernel::V3D &oldCenter, double NewRadius, double &neighborRadius)
Checks and updates if needed the list of m_NeighborIDs.
int UpdateOutputWS(DataObjects::TableWorkspace_sptr &TabWS, const int dir, const double chan, std::vector< double > const &params, std::vector< double > const &errs, std::vector< std::string > const &names, const double Chisq, const double time, std::string spec_idList)
Updates the information in the output OutputWorkspace.
void PreFit(const API::MatrixWorkspace_sptr &Data, double &chisqOverDOF, bool &done, std::vector< std::string > &names, std::vector< double > &params, std::vector< double > &errs, double lastRow, double lastCol, double neighborRadius)
Tests several starting points in the Marquardt algorithm then calls Fit.
bool isGoodFit(std::vector< double > const &params, std::vector< double > const &errs, std::vector< std::string > const &names, double chisqOverDOF)
Determines if the list of parameters and errors represent a "good" fit.
int findTimeChannel(const Mantid::HistogramData::HistogramX &X, const double time)
Finds the time channel with the given time in.
void updatePeakInformation(std::vector< double > const &params, std::vector< double > const &errs, std::vector< std::string > const &names, double &TotVariance, double &TotIntensity, double const TotSliceIntensity, double const TotSliceVariance, double const chisqdivDOF, const int ncells)
Updates m_AttributeValues with this peak information from this time slice.
A generic fitting algorithm.
Definition Fit.h:78
Structure describing a single-crystal peak.
Definition Peak.h:34
int getCol() const override
For RectangularDetectors only, returns the column (x) of the pixel of the detector or -1 if not found...
Definition Peak.cpp:335
Geometry::Instrument_const_sptr getInstrument() const
Return a shared ptr to the instrument for this peak.
Definition Peak.cpp:320
int getRow() const override
For RectangularDetectors only, returns the row (y) of the pixel of the detector or -1 if not found.
Definition Peak.cpp:326
Mantid::Kernel::V3D getQLabFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
Definition Peak.cpp:451
int getDetectorID() const override
Get the ID of the detector at the center of the peak
Definition Peak.cpp:265
Geometry::IDetector_const_sptr getDetector() const
Return a shared ptr to the detector at center of peak.
Definition Peak.cpp:317
virtual Mantid::Kernel::V3D getDetPos() const
Return the detector position vector.
Definition Peak.cpp:720
const std::string & getBankName() const
Find the name of the bank that is the parent of the detector.
Definition Peak.cpp:347
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition BoundingBox.h:33
bool isPointInside(const Kernel::V3D &point) const
Is the given point within the bounding box?
double xMax() const
Return the maximum value of X.
Definition BoundingBox.h:79
double zMin() const
Return the minimum value of Z.
Definition BoundingBox.h:85
double zMax() const
Return the maximum value of Z.
Definition BoundingBox.h:87
double yMax() const
Return the maximum value of Y.
Definition BoundingBox.h:83
double xMin() const
Return the minimum value of X.
Definition BoundingBox.h:77
double yMin() const
Return the minimum value of Y.
Definition BoundingBox.h:81
Structure describing a single-crystal peak.
Definition IPeak.h:26
virtual double getTOF() const =0
virtual Mantid::Kernel::V3D getQLabFrame() const =0
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Class for quaternions.
Definition Quat.h:39
void inverse()
Inverse a quaternion (in the sense of rotation inversion)
Definition Quat.cpp:376
void rotate(V3D &) const
Rotate a vector.
Definition Quat.cpp:397
std::vector< double > getRotation(bool check_normalisation=false, bool throw_on_errors=false) const
returns the rotation matrix defined by this quaternion as an 9-point
Definition Quat.cpp:453
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition V3D.h:34
constexpr double scalar_prod(const V3D &v) const noexcept
Calculates the cross product.
Definition V3D.h:280
constexpr double X() const noexcept
Get x.
Definition V3D.h:238
double normalize()
Make a normalized vector (return norm value)
Definition V3D.cpp:129
constexpr double Y() const noexcept
Get y.
Definition V3D.h:239
void setZ(const double zz) noexcept
Set is z position.
Definition V3D.h:236
double norm() const noexcept
Definition V3D.h:269
void setX(const double xx) noexcept
Set is x position.
Definition V3D.h:224
void setY(const double yy) noexcept
Set is y position.
Definition V3D.h:230
constexpr double Z() const noexcept
Get z.
Definition V3D.h:240
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition IComponent.h:167
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
Definition IDetector.h:102
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54