312 if (!eventWS && !histoWS) {
313 throw std::runtime_error(
"IntegrateEllipsoidsV1 needs either a "
314 "EventWorkspace or Workspace2D as input.");
318 if (eventWS && eventWS->getNumberEvents() <= 0) {
319 throw std::runtime_error(
"IntegrateEllipsoidsV1 does not work for empty event lists");
324 throw std::runtime_error(
"Could not read the peaks workspace");
328 double radius_s =
getProperty(
"SatelliteRegionRadius");
333 double sate_peak_radius =
getProperty(
"SatellitePeakSize");
334 double back_inner_radius =
getProperty(
"BackgroundInnerSize");
335 double sate_back_inner_radius =
getProperty(
"SatelliteBackgroundInnerSize");
336 double back_outer_radius =
getProperty(
"BackgroundOuterSize");
337 double sate_back_outer_radius =
getProperty(
"SatelliteBackgroundOuterSize");
339 bool integrateEdge =
getProperty(
"IntegrateIfOnEdge");
340 bool adaptiveQBackground =
getProperty(
"AdaptiveQBackground");
341 double adaptiveQMultiplier =
getProperty(
"AdaptiveQMultiplier");
342 double adaptiveQBackgroundMultiplier = 0.0;
343 bool useOnePercentBackgroundCorrection =
getProperty(
"UseOnePercentBackgroundCorrection");
344 bool getUB =
getProperty(
"GetUBFromPeaksWorkspace");
347 if (!(in_peak_ws->sample().hasOrientedLattice()) && getUB) {
348 throw std::runtime_error(
"Peaks workspace needs a oriented lattice for "
349 "GetUBFromPeaksWorkspace is true");
352 if (adaptiveQBackground)
353 adaptiveQBackgroundMultiplier = adaptiveQMultiplier;
354 if (!integrateEdge) {
361 g_log.
error(
"Can't execute MaskBTP algorithm for this instrument to set "
362 "edge for IntegrateIfOnEdge option");
368 if (peak_ws != in_peak_ws)
369 peak_ws = in_peak_ws->clone();
373 std::vector<Peak> &peaks = peak_ws->getPeaks();
374 size_t n_peaks = peak_ws->getNumberPeaks();
375 size_t indexed_count = 0;
376 std::vector<V3D> peak_q_list;
377 std::vector<std::pair<std::pair<double, double>,
V3D>> qList;
378 std::vector<V3D> hkl_vectors;
379 std::vector<V3D> mnp_vectors;
381 for (
size_t i = 0; i < n_peaks; i++)
383 V3D hkl(peaks[i].getIntHKL());
384 V3D mnp(peaks[i].getIntMNP());
386 if (mnp[0] != 0 && ModDim == 0)
388 if (mnp[1] != 0 && ModDim == 1)
390 if (mnp[2] != 0 && ModDim == 2)
395 peak_q_list.emplace_back(peaks[i].getQLabFrame());
396 qList.emplace_back(std::pair<double, double>(1., 1.),
V3D(peaks[i].getQLabFrame()));
397 hkl_vectors.emplace_back(hkl);
398 mnp_vectors.emplace_back(mnp);
410 if (getUB & peak_ws->sample().hasOrientedLattice()) {
411 if (indexed_count < 1)
412 throw std::runtime_error(
"At least one indexed peak required.");
413 OrientedLattice lattice = peak_ws->mutableSample().getOrientedLattice();
414 auto goniometerMatrix = peak_ws->run().getGoniometerMatrix();
416 UB = goniometerMatrix * lattice.
getUB();
417 modUB = goniometerMatrix * lattice.
getModUB();
422 if (indexed_count < 3)
423 throw std::runtime_error(
"At least three linearly independent indexed peaks are needed.");
425 if (peak_ws->sample().hasOrientedLattice()) {
426 OrientedLattice lattice = peak_ws->mutableSample().getOrientedLattice();
437 UBinv *= (1.0 / (2.0 * M_PI));
439 std::vector<double> PeakRadiusVector(n_peaks, peak_radius);
440 std::vector<double> BackgroundInnerRadiusVector(n_peaks, back_inner_radius);
441 std::vector<double> BackgroundOuterRadiusVector(n_peaks, back_outer_radius);
443 if (back_outer_radius > radius_m)
444 throw std::runtime_error(
"BackgroundOuterSize must be less than or equal to the RegionRadius");
446 if (back_inner_radius >= back_outer_radius)
447 throw std::runtime_error(
"BackgroundInnerSize must be less BackgroundOuterSize");
449 if (peak_radius > back_inner_radius)
450 throw std::runtime_error(
"PeakSize must be less than or equal to the BackgroundInnerSize");
455 useOnePercentBackgroundCorrection);
463 const size_t numSpectra = wksp->getNumberHistograms();
464 Progress prog(
this, 0.5, 1.0, numSpectra);
476 std::vector<double> principalaxis1, principalaxis2, principalaxis3;
477 std::vector<double> sateprincipalaxis1, sateprincipalaxis2, sateprincipalaxis3;
478 for (
size_t i = 0; i < n_peaks; i++) {
479 const V3D hkl(peaks[i].getIntHKL());
480 const V3D mnp(peaks[i].getIntMNP());
483 const V3D peak_q = peaks[i].getQLabFrame();
485 const double lenQpeak = adaptiveQMultiplier != 0.0 ? peak_q.
norm() : 0.0;
487 double adaptiveRadius = adaptiveQMultiplier * lenQpeak + peak_radius;
488 if (mnp !=
V3D(0, 0, 0))
489 adaptiveRadius = adaptiveQMultiplier * lenQpeak + sate_peak_radius;
491 if (adaptiveRadius <= 0.0) {
492 g_log.
error() <<
"Error: Radius for integration sphere of peak " << i <<
" is negative = " << adaptiveRadius
494 peaks[i].setIntensity(0.0);
495 peaks[i].setSigmaIntensity(0.0);
496 PeakRadiusVector[i] = 0.0;
497 BackgroundInnerRadiusVector[i] = 0.0;
498 BackgroundOuterRadiusVector[i] = 0.0;
502 double adaptiveBack_inner_radius;
503 double adaptiveBack_outer_radius;
504 if (mnp ==
V3D(0, 0, 0)) {
505 adaptiveBack_inner_radius = adaptiveQBackgroundMultiplier * lenQpeak + back_inner_radius;
506 adaptiveBack_outer_radius = adaptiveQBackgroundMultiplier * lenQpeak + back_outer_radius;
508 adaptiveBack_inner_radius = adaptiveQBackgroundMultiplier * lenQpeak + sate_back_inner_radius;
509 adaptiveBack_outer_radius = adaptiveQBackgroundMultiplier * lenQpeak + sate_back_outer_radius;
511 PeakRadiusVector[i] = adaptiveRadius;
512 BackgroundInnerRadiusVector[i] = adaptiveBack_inner_radius;
513 BackgroundOuterRadiusVector[i] = adaptiveBack_outer_radius;
517 E1Vec, peak_q, hkl, mnp, specify_size, adaptiveRadius, adaptiveBack_inner_radius, adaptiveBack_outer_radius,
518 axes_radii, inti, sigi);
519 peaks[i].setIntensity(inti);
520 peaks[i].setSigmaIntensity(sigi);
521 peaks[i].setPeakShape(shape);
522 if (axes_radii.size() == 3) {
523 if (inti / sigi > cutoffIsigI || cutoffIsigI ==
EMPTY_DBL()) {
524 if (mnp ==
V3D(0, 0, 0)) {
525 principalaxis1.emplace_back(axes_radii[0]);
526 principalaxis2.emplace_back(axes_radii[1]);
527 principalaxis3.emplace_back(axes_radii[2]);
529 sateprincipalaxis1.emplace_back(axes_radii[0]);
530 sateprincipalaxis2.emplace_back(axes_radii[1]);
531 sateprincipalaxis3.emplace_back(axes_radii[2]);
536 peaks[i].setIntensity(0.0);
537 peaks[i].setSigmaIntensity(0.0);
540 if (principalaxis1.size() > 1) {
554 if (sateprincipalaxis1.size() > 1) {
558 <<
" minimum " << satestats1.
minimum <<
" maximum " << satestats1.
maximum <<
" median "
559 << satestats1.
median <<
"\n";
563 <<
" minimum " << satestats2.
minimum <<
" maximum " << satestats2.
maximum <<
" median "
564 << satestats2.
median <<
"\n";
568 <<
" minimum " << satestats3.
minimum <<
" maximum " << satestats3.
maximum <<
" median "
569 << satestats3.
median <<
"\n";
572 constexpr size_t histogramNumber = 3;
574 principalaxis1.size(), principalaxis1.size());
575 Workspace2D_sptr wsProfile2D = std::dynamic_pointer_cast<Workspace2D>(wsProfile);
576 AnalysisDataService::Instance().addOrReplace(
"EllipsoidAxes", wsProfile2D);
579 Points points(principalaxis1.size(), LinearGenerator(0, 1));
580 wsProfile2D->setHistogram(0, points, Counts(std::move(principalaxis1)));
581 wsProfile2D->setHistogram(1, points, Counts(std::move(principalaxis2)));
582 wsProfile2D->setHistogram(2, points, Counts(std::move(principalaxis3)));
585 principalaxis1.clear();
586 principalaxis2.clear();
587 principalaxis3.clear();
588 sateprincipalaxis1.clear();
589 sateprincipalaxis2.clear();
590 sateprincipalaxis3.clear();
592 peak_radius = std::max(std::max(stats1.
mean, stats2.
mean), stats3.
mean) +
595 back_inner_radius = peak_radius;
596 back_outer_radius = peak_radius * 1.25992105;
599 for (
size_t i = 0; i < n_peaks; i++) {
600 V3D hkl(peaks[i].getIntHKL());
601 V3D mnp(peaks[i].getIntMNP());
603 const V3D peak_q = peaks[i].getQLabFrame();
606 back_outer_radius, axes_radii, inti, sigi);
607 peaks[i].setIntensity(inti);
608 peaks[i].setSigmaIntensity(sigi);
609 if (axes_radii.size() == 3) {
610 if (mnp ==
V3D(0, 0, 0)) {
611 principalaxis1.emplace_back(axes_radii[0]);
612 principalaxis2.emplace_back(axes_radii[1]);
613 principalaxis3.emplace_back(axes_radii[2]);
615 sateprincipalaxis1.emplace_back(axes_radii[0]);
616 sateprincipalaxis2.emplace_back(axes_radii[1]);
617 sateprincipalaxis3.emplace_back(axes_radii[2]);
621 peaks[i].setIntensity(0.0);
622 peaks[i].setSigmaIntensity(0.0);
625 if (principalaxis1.size() > 1) {
627 principalaxis1.size(), principalaxis1.size());
628 Workspace2D_sptr wsProfile2D2 = std::dynamic_pointer_cast<Workspace2D>(wsProfile2);
629 AnalysisDataService::Instance().addOrReplace(
"EllipsoidAxes_2ndPass", wsProfile2D2);
631 Points profilePoints(principalaxis1.size(), LinearGenerator(0, 1));
632 wsProfile2D->setHistogram(0, profilePoints, Counts(std::move(principalaxis1)));
633 wsProfile2D->setHistogram(1, profilePoints, Counts(std::move(principalaxis2)));
634 wsProfile2D->setHistogram(2, profilePoints, Counts(std::move(principalaxis3)));
641 peak_ws->mutableRun().addProperty(
"PeaksIntegrated", 1,
true);
643 peak_ws->mutableRun().addProperty(
"PeakRadius", PeakRadiusVector,
true);
644 peak_ws->mutableRun().addProperty(
"BackgroundInnerRadius", BackgroundInnerRadiusVector,
true);
645 peak_ws->mutableRun().addProperty(
"BackgroundOuterRadius", BackgroundOuterRadiusVector,
true);