74const std::string LOG_CHARGE_NAME(
"proton_charge");
76const std::vector<std::string> binningModeNames{
"Logarithmic",
"Linear"};
80const std::vector<std::string> unitNames{
"dSpacing",
"TOF",
"MomentumTransfer"};
81enum class BinUnit { DSPACE,
TOF, Q, enum_count };
84const std::string ENTRY_TOP_LEVEL(
"entry");
87double getFocussedPostion(
const detid_t detid,
const std::vector<double> &difc_focus,
88 std::map<detid_t, size_t> &detIDToSpecNum) {
89 if (detIDToSpecNum.contains(detid)) {
90 return difc_focus[detIDToSpecNum[detid]];
96std::vector<double> calculate_difc_focused(
const double l1,
const std::vector<double> &l2s,
97 const std::vector<double> &polars) {
98 constexpr double deg2rad = std::numbers::pi_v<double> / 180.;
100 std::vector<double>
difc;
102 std::transform(l2s.cbegin(), l2s.cend(), polars.cbegin(), std::back_inserter(
difc),
103 [l1,
deg2rad](
const auto &
l2,
const auto &polar) {
104 return 1. / Kernel::Units::tofToDSpacingFactor(l1, l2, deg2rad * polar, 0.);
128 return "Algorithm to focus powder diffraction data into a number of histograms according to a grouping "
129 "scheme defined in a CalFile.";
138 const std::vector<std::string> exts{
".nxs.h5",
".nxs",
"_event.nxs"};
141 "The name of the Event NeXus file to read, including its full or relative path. "
142 "The file name is typically of the form INST_####_event.nxs.");
145 "To only include events after the provided start time, in seconds (relative to the start of the run).");
149 "To only include events before the provided stop time, in seconds (relative to the start of the run).");
152 "Input workspace specifying \"splitters\", i.e. time intervals and targets for event filtering. "
153 "Currently only a single output workspace is supported.");
155 "Flag indicating whether in SplitterWorkspace the times are absolute or "
156 "relative. If true, they are relative to the run start time.");
159 "For development testing. Changes how the splitters are processed. If true then use ProcessBankSplitTask "
160 "otherwise loop over ProcessBankTask.");
162 "Find time-of-flight when neutron was at the sample position. This is only necessary for fast logs "
163 "(i.e. more frequent than proton on target pulse).");
166 "If true, events will be splitting using full time values (tof+pulsetime) rather than just pulsetime.");
167 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
168 mustBePositive->setLower(0);
170 "Filter bad pulses in the same way that :ref:`algm-FilterBadPulses` does.");
171 auto range = std::make_shared<BoundedValidator<double>>();
172 range->setBounds(0., 100.);
174 "The percentage of the average to use as the lower bound when filtering bad pulses.");
177 "A GroupingWorkspace giving the grouping info. If not provided then the grouping from the "
178 "calibration file will be used if provided, else a default grouping of one group per bank.");
179 const std::vector<std::string> cal_exts{
".h5",
".hd5",
".hdf",
".cal"};
181 "The .cal file containing the position correction factors. Either this or OffsetsWorkspace needs to "
183 auto mustBePosArr = std::make_shared<Kernel::ArrayBoundedValidator<double>>();
184 mustBePosArr->setLower(0.0);
186 "Minimum x-value for the output binning");
188 "Bin size for output data");
190 "Minimum x-value for the output binning");
192 "The units of the input X min, max and delta values. Output will always be TOF");
194 "Specify binning behavior ('Logarithmic')");
197 "If specified, only these logs will be loaded from the file. Setting this will automatically override the "
198 "default LogBlockList");
201 std::vector<std::string>{
"Phase\\*",
"Speed\\*",
"BL\\*:Chop:\\*",
"chopper\\*TDC"}),
202 "If specified, these logs will not be loaded from the file. Set as empty list ``[]`` to disable");
205 "An output workspace.");
208 const std::string CHUNKING_PARAM_GROUP(
"Chunking-temporary");
209 auto positiveIntValidator = std::make_shared<Mantid::Kernel::BoundedValidator<int>>();
210 positiveIntValidator->setLower(1);
213 "Number of elements of time-of-flight or detector-id to read at a time. This is a maximum");
217 "Number of events to read in a single thread. Higher means less threads are created.");
223 "The bank for which to read data; if specified, others will be blank");
227 auto mandatoryDblValidator = std::make_shared<MandatoryValidator<double>>();
228 auto positiveDblValidator = std::make_shared<Mantid::Kernel::BoundedValidator<double>>();
229 positiveDblValidator->setLower(0);
230 auto l1Validator = std::make_shared<CompositeValidator>();
231 l1Validator->add(mandatoryDblValidator);
232 l1Validator->add(positiveDblValidator);
234 auto mandatoryDblArrayValidator = std::make_shared<MandatoryValidator<std::vector<double>>>();
235 auto positionArrayValidator = std::make_shared<CompositeValidator>();
236 positionArrayValidator->add(mandatoryDblArrayValidator);
237 positionArrayValidator->add(mustBePosArr);
239 "The primary distance :math:`\\ell_1` from beam to sample");
242 "The secondary distances :math:`\\ell_2` from sample to focus group");
245 "The effective polar angle (:math:`2\\theta`) of each focus group");
248 "The effective azimuthal angle :math:`\\phi` for each focus group");
252 std::map<std::string, std::string> errors;
257 if (disk_chunk < grainsize_events) {
273 const auto num_l2s = l2s.size();
276 errors[
PropertyNames::L2] = strmakef(
"L2S has inconsistent length %zu", num_l2s);
282 if (num_l2s != phi.size()) {
283 errors[
PropertyNames::L2] = strmakef(
"L2S has inconsistent length %zu", num_l2s);
294 const auto numMin = xmins.size();
295 const auto numMax = xmaxs.size();
296 const auto numDelta = deltas.size();
298 if (std::any_of(deltas.cbegin(), deltas.cend(), [](
double d) { return !std::isfinite(d) || d == 0; }))
300 else if (!(numDelta == 1 || numDelta == num_l2s))
303 if (!(numMin == 1 || numMin == num_l2s))
305 if (!(numMax == 1 || numMax == num_l2s))
318 std::vector<std::string> bankEntryNames;
319 std::vector<std::string> bankNames;
322 const std::size_t num_banks_to_read = bankEntryNames.size();
323 g_log.
debug() <<
"Total banks to read: " << num_banks_to_read <<
"\n";
332 std::map<size_t, std::set<detid_t>> grouping;
341 }
catch (std::exception &e) {
342 g_log.
warning() <<
"Error while loading meta data: " << e.what() <<
'\n';
345 auto periodLog = std::make_unique<const TimeSeriesProperty<int>>(
"period_log");
350 g_log.
information() <<
"User provided LogAllowList, default LogBlockList being ignored\n";
353 LoadEventNexus::runLoadNexusLogs<MatrixWorkspace_sptr>(filename, wksp, *
this,
false, nPeriods, periodLog, allow_logs,
356 LoadEventNexus::loadInstrument<MatrixWorkspace_sptr>(filename, wksp, ENTRY_TOP_LEVEL,
this, &descriptor);
361 if (!cal_filename.empty()) {
362 calibrationWS = this->
loadCalFile(wksp, cal_filename, groupingWS);
366 const auto groupIds = groupingWS->getGroupIDs(
false);
367 num_hist = groupIds.size();
368 g_log.
information() <<
"Using grouping workspace with " << num_hist <<
" groups\n";
369 for (
size_t outputindex = 0; outputindex < groupIds.size(); ++outputindex) {
370 const auto detids = groupingWS->getDetectorIDsOfGroup(groupIds[outputindex]);
371 grouping[outputindex] = std::set<detid_t>(detids.begin(), detids.end());
378 this->
progress(.0,
"Create output workspace");
387 std::vector<double> setPhi(l2s.size(), 0.0);
391 const std::vector<double> azimuthals(setPhi);
392 const std::vector<specnum_t> specids;
393 const auto difc_focused = calculate_difc_focused(l1, l2s, polars);
398 this->
progress(.05,
"Determining pulse indices");
400 this->
progress(.07,
"Reading events");
403 std::map<size_t, std::set<detid_t>> bank_detids;
404 for (
size_t bankIndex = 0; bankIndex < num_banks_to_read; ++bankIndex) {
406 bank_detids[bankIndex] = wksp->getInstrument()->getDetectorIDsInBank(bankNames.at(bankIndex));
407 }
catch (std::exception &e) {
408 g_log.
warning() <<
"Error getting detector IDs for " << bankNames.at(bankIndex) <<
": " << e.what() <<
"\n";
413 if (!grouping.empty()) {
414 for (
const auto &
group : grouping) {
415 for (
const auto &detid :
group.second) {
421 grouping[0] = std::set<detid_t>{};
422 for (
const auto &[i, detids] : bank_detids) {
423 grouping[0].insert(detids.begin(), detids.end());
424 for (
const auto &detid : detids) {
431 this->
progress(.1,
"Creating calibration constants");
444 this->
progress(.15,
"Set instrument geometry");
448 this->
progress(.17,
"Convert bins to TOF");
457 g_log.
debug() << (DISK_CHUNK / GRAINSIZE_EVENTS) <<
" threads per chunk\n";
461 if (!frequency_log) {
462 throw std::runtime_error(
"Frequency log not found in workspace run");
464 m_pulse_times = std::make_shared<std::vector<Mantid::Types::Core::DateAndTime>>(frequency_log->timesAsVector());
466 if (timeSplitter.empty()) {
471 auto loader = std::make_shared<NexusLoader>(
is_time_filtered, pulse_indices);
473 auto progress = std::make_shared<API::Progress>(
this, .17, .9, num_banks_to_read);
474 ProcessBankTask task(bankEntryNames, h5file, loader, processingData, calibFactory,
static_cast<size_t>(DISK_CHUNK),
475 static_cast<size_t>(GRAINSIZE_EVENTS),
progress);
477 if (num_banks_to_read > 1) {
478 tbb::parallel_for(tbb::blocked_range<size_t>(0, num_banks_to_read), task);
480 task(tbb::blocked_range<size_t>(0, 1));
490 wksp->mutableRun().setTimeROI(filterROI);
491 wksp->mutableRun().removeDataOutsideTimeROI();
496 std::vector<std::string> wsNames;
497 std::vector<int> workspaceIndices;
498 std::vector<MatrixWorkspace_sptr> workspaces;
499 std::vector<SpectraProcessingData> processingDatas;
500 for (
const int &splitter_target : timeSplitter.outputWorkspaceIndices()) {
501 std::string ws_name = ws_basename +
"_" + timeSplitter.getWorkspaceIndexName(splitter_target);
502 wsNames.push_back(std::move(ws_name));
503 workspaceIndices.push_back(splitter_target);
504 workspaces.emplace_back(wksp->clone());
508 auto progress = std::make_shared<API::Progress>(
this, .17, .9, num_banks_to_read * workspaceIndices.size());
510 g_log.
information() <<
"Using ProcessBankSplitFullTimeTask for splitter processing\n";
515 if (!filterROI.useAll()) {
516 combined_time_roi.update_intersection(filterROI);
521 auto loader = std::make_shared<NexusLoader>(
is_time_filtered, pulse_indices);
523 const auto &splitterMap = timeSplitter.getSplittersMap();
526 static_cast<size_t>(DISK_CHUNK),
static_cast<size_t>(GRAINSIZE_EVENTS),
530 if (num_banks_to_read > 1) {
531 tbb::parallel_for(tbb::blocked_range<size_t>(0, num_banks_to_read), task);
533 task(tbb::blocked_range<size_t>(0, 1));
537 g_log.
information() <<
"Using ProcessBankSplitTask for splitter processing\n";
541 std::vector<PulseROI> pulse_indices;
542 auto loader = std::make_shared<NexusLoader>(
is_time_filtered, pulse_indices, target_to_pulse_indices);
544 ProcessBankSplitTask task(bankEntryNames, h5file, loader, workspaceIndices, processingDatas, calibFactory,
545 static_cast<size_t>(DISK_CHUNK),
static_cast<size_t>(GRAINSIZE_EVENTS),
progress);
547 if (num_banks_to_read > 1) {
548 tbb::parallel_for(tbb::blocked_range<size_t>(0, num_banks_to_read), task);
550 task(tbb::blocked_range<size_t>(0, 1));
556 tbb::blocked_range<size_t>(0, workspaceIndices.size()),
557 [&](
const tbb::blocked_range<size_t> &target_indices) {
558 for (size_t target_index = target_indices.begin(); target_index != target_indices.end(); ++target_index) {
559 const int splitter_target = workspaceIndices[target_index];
561 auto splitter_roi = timeSplitter.getTimeROI(splitter_target);
563 auto target_roi = filterROI;
564 if (target_roi.useAll())
565 target_roi = std::move(splitter_roi);
566 else if (!splitter_roi.useAll())
567 target_roi.update_intersection(splitter_roi);
570 MatrixWorkspace_sptr target_wksp = workspaces[target_index];
572 const auto pulse_indices = this->determinePulseIndices(target_roi);
573 auto loader = std::make_shared<NexusLoader>(is_time_filtered, pulse_indices);
575 ProcessBankTask task(bankEntryNames, h5file, loader, processingDatas[target_index], calibFactory,
576 static_cast<size_t>(DISK_CHUNK), static_cast<size_t>(GRAINSIZE_EVENTS), progress);
578 if (num_banks_to_read > 1) {
579 tbb::parallel_for(tbb::blocked_range<size_t>(0, num_banks_to_read), task);
581 task(tbb::blocked_range<size_t>(0, 1));
591 for (
size_t idx = 0; idx < workspaceIndices.size(); ++idx) {
596 auto target_roi = timeSplitter.getTimeROI(workspaceIndices[idx]);
597 if (target_roi.useAll())
598 target_roi = filterROI;
599 else if (!filterROI.useAll())
600 target_roi.update_intersection(filterROI);
603 workspaces[idx]->mutableRun().setTimeROI(target_roi);
604 workspaces[idx]->mutableRun().removeDataOutsideTimeROI();
605 AnalysisDataService::Instance().addOrReplace(wsNames[idx], workspaces[idx]);
610 groupws->setAlwaysStoreInADS(
true);
611 groupws->setProperty(
"InputWorkspaces", wsNames);
612 groupws->setProperty(
"OutputWorkspace", ws_basename);
615 if (!groupws->isExecuted()) {
616 throw std::runtime_error(
"Failed to group output workspaces");
626 std::vector<std::string> &bankEntryNames,
627 std::vector<std::string> &bankNames) {
630 std::set<std::string>
const classEntries = descriptor.
allAddressesOfType(
"NXevent_data");
631 if (classEntries.empty()) {
632 throw std::runtime_error(
"No NXevent_data entries found in file");
635 const int bankNum = getProperty(PropertyNames::BANK_NUMBER);
637 const std::regex classRegex(
"(/entry/)([^/]*)");
639 for (
const std::string &classEntry : classEntries) {
640 if (std::regex_match(classEntry, groups, classRegex)) {
641 const std::string entry_name(groups[2].str());
642 if (classEntry.ends_with(
"bank_error_events")) {
644 }
else if (classEntry.ends_with(
"bank_unmapped_events")) {
647 auto underscore_pos = entry_name.find_first_of(
'_');
648 const auto bankName = entry_name.substr(0, underscore_pos);
654 bankEntryNames.push_back(entry_name);
655 bankNames.push_back(bankName);
664 const bool linearBins = bool(binmode == BinningMode::LINEAR);
665 const std::string binUnits = getPropertyValue(PropertyNames::BIN_UNITS);
666 std::vector<double> x_delta = getProperty(PropertyNames::X_DELTA);
667 std::vector<double> x_min = getProperty(PropertyNames::X_MIN);
668 std::vector<double> x_max = getProperty(PropertyNames::X_MAX);
669 const bool raggedBins = (x_delta.size() != 1 || x_min.size() != 1 || x_max.size() != 1);
671 constexpr bool resize_xnew{
true};
672 constexpr bool full_bins_only{
false};
675 HistogramData::BinEdges XValues(0);
677 const std::vector<double> params{x_min[0], x_delta[0], x_max[0]};
681 const std::vector<double> params{x_min[0], -1. * std::abs(x_delta[0]), x_max[0]};
685 wksp->initialize(num_hist, HistogramData::Histogram(XValues, HistogramData::Counts(XValues.size() - 1, 0.0)));
689 if (x_delta.size() == 1)
690 x_delta.resize(num_hist, x_delta[0]);
691 if (x_min.size() == 1)
692 x_min.resize(num_hist, x_min[0]);
693 if (x_max.size() == 1)
694 x_max.resize(num_hist, x_max[0]);
696 for (
size_t i = 1; i < num_hist; ++i) {
697 HistogramData::BinEdges XValues_new(0);
700 const std::vector<double> params{x_min[i], x_delta[i], x_max[i]};
704 const std::vector<double> params{x_min[i], -1. * std::abs(x_delta[i]), x_max[i]};
708 wksp->setHistogram(i, HistogramData::Histogram(XValues_new, HistogramData::Counts(XValues_new.size() - 1, 0.0)));
712 wksp->getAxis(0)->setUnit(binUnits);
713 wksp->setYUnit(
"Counts");
719 const size_t numSpectra = outputWS->getNumberHistograms();
720 for (
size_t i = 0; i < numSpectra; ++i) {
721 const auto &spectrum = outputWS->getSpectrum(i);
722 processingData.
binedges.emplace_back(&spectrum.readX());
723 processingData.
counts.emplace_back(spectrum.dataY().size());
725 return processingData;
730 const size_t numSpectra = outputWS->getNumberHistograms();
731 for (
size_t i = 0; i < numSpectra; ++i) {
732 auto &spectrum = outputWS->getSpectrum(i);
733 auto &y_values = spectrum.dataY();
735 processingData.
counts[i].cbegin(), processingData.
counts[i].cend(), y_values.begin(),
736 [](
const std::atomic_uint32_t &val) { return static_cast<double>(val.load(std::memory_order_relaxed)); });
737 auto &e_values = spectrum.dataE();
738 std::transform(processingData.
counts[i].cbegin(), processingData.
counts[i].cend(), e_values.begin(),
739 [](
const std::atomic_uint32_t &val) {
740 return std::sqrt(static_cast<double>(val.load(std::memory_order_relaxed)));
746 const std::vector<double> &difc_focus) {
747 const auto detInfo = wksp->detectorInfo();
749 for (
auto iter = detInfo.cbegin(); iter != detInfo.cend(); ++iter) {
750 if (!iter->isMonitor()) {
751 const auto difc_focussed = getFocussedPostion(
static_cast<detid_t>(iter->detid()), difc_focus, detIDToSpecNum);
755 m_calibration.emplace(
static_cast<detid_t>(iter->detid()),
756 difc_focussed / detInfo.difcUncalibrated(iter->index()));
761void AlignAndFocusPowderSlim::initCalibrationConstantsFromCalWS(
const std::vector<double> &difc_focus,
763 for (
size_t row = 0; row < calibrationWS->rowCount(); ++row) {
764 const detid_t detid = calibrationWS->cell<
int>(row, 0);
765 const double detc = calibrationWS->cell<
double>(row, 1);
766 const auto difc_focussed = getFocussedPostion(detid, difc_focus, detIDToSpecNum);
770 m_calibration.emplace(detid, difc_focussed / detc);
775 const std::string &filename,
777 const bool load_grouping = !groupingWS;
779 auto alg = createChildAlgorithm(
"LoadDiffCal");
780 alg->setProperty(
"InputWorkspace", inputWS);
781 alg->setPropertyValue(
"Filename", filename);
782 alg->setProperty<
bool>(
"MakeCalWorkspace",
true);
783 alg->setProperty<
bool>(
"MakeGroupingWorkspace", load_grouping);
784 alg->setProperty<
bool>(
"MakeMaskWorkspace",
true);
785 alg->setPropertyValue(
"WorkspaceName",
"temp");
786 alg->executeAsChildAlg();
789 g_log.
debug() <<
"Loading grouping workspace from calibration file\n";
790 groupingWS = alg->getProperty(
"OutputGroupingWorkspace");
796 m_masked = maskWS->getMaskedDetectors();
797 g_log.
debug() <<
"Masked detectors: " << m_masked.size() <<
'\n';
799 return calibrationWS;
808 const auto detInfo = wksp->detectorInfo();
810 const double L1 = detInfo.l1();
812 if (this->getProperty(PropertyNames::CORRECTION_TO_SAMPLE)) {
814 for (
auto iter = detInfo.cbegin(); iter != detInfo.cend(); ++iter) {
815 if (!iter->isMonitor()) {
816 const double path_correction = L1 / (L1 + iter->l2()) * 1000.0;
817 m_scale_at_sample.emplace(
static_cast<detid_t>(iter->detid()), path_correction);
822 for (
auto iter = detInfo.cbegin(); iter != detInfo.cend(); ++iter) {
823 if (!iter->isMonitor()) {
824 m_scale_at_sample.emplace(
static_cast<detid_t>(iter->detid()), 1000.0);
832 const std::vector<specnum_t> &specids,
const std::vector<double> &l2s,
const std::vector<double> &azimuthals) {
834 editAlg->setLoggingOffset(1);
835 editAlg->setProperty(
"Workspace", wksp);
837 editAlg->setProperty(
"PrimaryFlightPath", l1);
839 editAlg->setProperty(
"Polar", polars);
840 if (!specids.empty())
841 editAlg->setProperty(
"SpectrumIDs", specids);
843 editAlg->setProperty(
"L2", l2s);
844 if (!azimuthals.empty())
845 editAlg->setProperty(
"Azimuthal", azimuthals);
846 editAlg->executeAsChildAlg();
848 wksp = editAlg->getProperty(
"Workspace");
854 if (wksp->getAxis(0)->unit()->unitID() ==
"TOF") {
860 convertUnits->setProperty(
"InputWorkspace", wksp);
861 convertUnits->setPropertyValue(
"Target",
"TOF");
862 convertUnits->executeAsChildAlg();
863 wksp = convertUnits->getProperty(
"OutputWorkspace");
877 const auto startOfRun = wksp->run().startTime();
880 double filter_time_start_sec = getProperty(PropertyNames::FILTER_TIMESTART);
881 double filter_time_stop_sec = getProperty(PropertyNames::FILTER_TIMESTOP);
883 this->progress(.15,
"Creating time filtering");
884 g_log.
information() <<
"Filtering pulses from " << filter_time_start_sec <<
" to " << filter_time_stop_sec <<
"s\n";
887 roi.
addROI(startOfRun + (filter_time_start_sec ==
EMPTY_DBL() ? 0.0 : filter_time_start_sec),
888 startOfRun + filter_time_stop_sec);
889 }
catch (
const std::runtime_error &e) {
890 throw std::invalid_argument(
"Invalid time range for filtering: " + std::string(e.what()));
895 if (getProperty(PropertyNames::FILTER_BAD_PULSES)) {
896 this->progress(.16,
"Filtering bad pulses");
899 const auto [min_pcharge, max_pcharge, mean] =
900 wksp->run().getBadPulseRange(LOG_CHARGE_NAME, getProperty(PropertyNames::FILTER_BAD_PULSES_LOWER_CUTOFF));
901 g_log.
information() <<
"Filtering bad pulses; pcharge outside of " << min_pcharge <<
" to " << max_pcharge <<
'\n';
903 const auto run_start = wksp->getFirstPulseTime();
904 const auto run_stop = wksp->getLastPulseTime();
922std::vector<PulseROI> AlignAndFocusPowderSlim::determinePulseIndices(
const TimeROI &filterROI) {
924 std::vector<PulseROI> pulse_indices;
926 pulse_indices.emplace_back(0, std::numeric_limits<size_t>::max());
928 is_time_filtered =
true;
930 if (pulse_indices.empty())
931 throw std::invalid_argument(
"No valid pulse time indices found for filtering");
934 return pulse_indices;
945std::vector<std::pair<int, PulseROI>>
946AlignAndFocusPowderSlim::determinePulseIndicesTargets(
const TimeROI &filterROI,
const TimeSplitter &timeSplitter) {
947 std::vector<PulseROI> pulse_indices;
949 pulse_indices.emplace_back(0, std::numeric_limits<size_t>::max());
952 if (pulse_indices.empty())
953 throw std::invalid_argument(
"No valid pulse time indices found for filtering");
959 std::vector<std::pair<int, PulseROI>> intersected_target_pulse_indices;
960 auto pulse_it = pulse_indices.cbegin();
961 for (
const auto &target_pair : target_to_pulse_indices) {
963 while (pulse_it != pulse_indices.cend() && pulse_it->second <= target_pair.second.first) {
967 auto check_it = pulse_it;
968 while (check_it != pulse_indices.cend() && check_it->first < target_pair.second.second) {
970 size_t start_index = std::max(check_it->first, target_pair.second.first);
971 size_t stop_index = std::min(check_it->second, target_pair.second.second);
972 if (start_index < stop_index) {
973 intersected_target_pulse_indices.emplace_back(target_pair.first,
PulseROI(start_index, stop_index));
979 return intersected_target_pulse_indices;
983AlignAndFocusPowderSlim::timeSplitterFromSplitterWorkspace(
const Types::Core::DateAndTime &filterStartTime) {
986 std::dynamic_pointer_cast<DataObjects::SplittersWorkspace>(tempws);
988 std::dynamic_pointer_cast<DataObjects::TableWorkspace>(tempws);
991 if (!splittersWorkspace && !splitterTableWorkspace && !matrixSplitterWS)
994 const bool isSplittersRelativeTime = this->getProperty(PropertyNames::SPLITTER_RELATIVE);
997 if (splittersWorkspace) {
999 }
else if (splitterTableWorkspace) {
1001 TimeSplitter(splitterTableWorkspace, isSplittersRelativeTime ? filterStartTime : DateAndTime::GPS_EPOCH);
1003 time_splitter =
TimeSplitter(matrixSplitterWS, isSplittersRelativeTime ? filterStartTime : DateAndTime::GPS_EPOCH);
1006 return time_splitter;
#define DECLARE_ALGORITHM(classname)
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool isDefault(const std::string &name) const
A specialized class for dealing with file properties.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
Base Workspace Abstract Class.
AlignAndFocusPowderSlim : TODO: DESCRIPTION.
std::vector< int64_t > loadSize
How much to load in the file.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
std::vector< std::pair< size_t, size_t > > determinePulseIndices(const Kernel::TimeROI &filterROI)
Determine the pulse indices for a given workspace and time ROI.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
SpectraProcessingData initializeSpectraProcessingData(const API::MatrixWorkspace_sptr &outputWS)
std::vector< int64_t > loadStart
Index to load start at in the file.
std::shared_ptr< std::vector< Types::Core::DateAndTime > > m_pulse_times
std::map< detid_t, double > m_calibration
detid: 1/difc
void storeSpectraProcessingData(const SpectraProcessingData &processingData, const API::MatrixWorkspace_sptr &outputWS)
void init() override
Initialize the algorithm's properties.
std::set< detid_t > m_masked
DataObjects::TimeSplitter timeSplitterFromSplitterWorkspace(const Types::Core::DateAndTime &)
std::map< detid_t, size_t > detIDToSpecNum
void determineBanksToLoad(const Mantid::Nexus::NexusDescriptor &descriptor, std::vector< std::string > &bankEntryNames, std::vector< std::string > &bankNames)
std::map< detid_t, double > m_scale_at_sample
Multiplicative 0<value<1 to move neutron TOF at sample.
void initScaleAtSample(const API::MatrixWorkspace_sptr &wksp)
For fast logs, calculate the sample position correction.
const std::string category() const override
Algorithm's category for identification.
std::vector< std::pair< int, std::pair< size_t, size_t > > > determinePulseIndicesTargets(const Kernel::TimeROI &filterROI, const DataObjects::TimeSplitter &timeSplitter)
Determine the pulse indices for a given workspace, time ROI, and time splitter.
API::MatrixWorkspace_sptr editInstrumentGeometry(API::MatrixWorkspace_sptr &wksp, const double l1, const std::vector< double > &polars, const std::vector< specnum_t > &specids, const std::vector< double > &l2s, const std::vector< double > &azimuthals)
int version() const override
Algorithm's version for identification.
const std::vector< std::string > seeAlso() const override
Function to return all of the seeAlso (these are not validated) algorithms related to this algorithm....
void initializeOutputWorkspace(const API::MatrixWorkspace_sptr &wksp, size_t num_hist)
void initCalibrationConstantsFromCalWS(const std::vector< double > &difc_focus, const API::ITableWorkspace_sptr calibrationWS)
const API::ITableWorkspace_sptr loadCalFile(const API::Workspace_sptr &inputWS, const std::string &filename, DataObjects::GroupingWorkspace_sptr &groupingWS)
Kernel::TimeROI getFilterROI(const API::MatrixWorkspace_sptr &wksp)
Create a TimeROI based on the filtering properties set in the algorithm.
API::MatrixWorkspace_sptr convertToTOF(API::MatrixWorkspace_sptr &wksp)
void exec() override
Execute the algorithm.
void initCalibrationConstants(API::MatrixWorkspace_sptr &wksp, const std::vector< double > &difc_focus)
static void loadEntryMetadata(const std::string &nexusfilename, T WS, const std::string &entry_name)
Load the run number and other meta data from the given bank.
std::vector< std::pair< int, std::pair< size_t, size_t > > > calculate_target_indices(const std::vector< DateAndTime > ×) const
Given a list of times, calculate the corresponding indices in the TimeSplitter.
Concrete workspace implementation.
Kernel/ArrayBoundedValidator.h.
Support for a property that holds an array of values.
BoundedValidator is a validator that requires the values to be between upper or lower bounds,...
A concrete property based on user options of a finite list of strings.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
Validator to check that a property is not left empty.
The concrete, templated class for properties.
Represents a time interval.
TimeROI : Object that holds information about when the time measurement was active.
std::vector< std::pair< size_t, size_t > > calculate_indices(const std::vector< Types::Core::DateAndTime > ×) const
void addROI(const std::string &startTime, const std::string &stopTime)
bool useAll() const
TimeROI selects all time to be used.
A specialised Property class for holding a series of time-value pairs.
std::set< std::string > allAddressesOfType(const std::string &type) const
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Mantid::Kernel::SingletonHolder< AnalysisDataServiceImpl > AnalysisDataService
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
const std::string GROUPING_WS("GroupingWorkspace")
const std::string FILTER_TIMESTART("FilterByTimeStart")
const std::string AZIMUTHALS("Azimuthal")
const std::string CAL_FILE("CalFileName")
const std::string FILTER_BAD_PULSES_LOWER_CUTOFF("BadPulsesLowerCutoff")
const std::string BANK_NUMBER("BankNumber")
const std::string ALLOW_LOGS("LogAllowList")
const std::string SPLITTER_RELATIVE("RelativeTime")
const std::string PROCESS_BANK_SPLIT_TASK("ProcessBankSplitTask")
const std::string OUTPUT_WKSP("OutputWorkspace")
const std::string CORRECTION_TO_SAMPLE("CorrectionToSample")
const std::string BIN_UNITS("BinningUnits")
const std::string FILTER_TIMESTOP("FilterByTimeStop")
const std::string L2("L2")
const std::string BLOCK_LOGS("LogBlockList")
const std::string X_DELTA("XDelta")
const std::string X_MIN("XMin")
const std::string FILENAME("Filename")
const std::string POLARS("Polar")
const std::string BINMODE("BinningMode")
const std::string SPLITTER_WS("SplitterWorkspace")
const std::string EVENTS_PER_THREAD("EventsPerThread")
const std::string FILTER_BAD_PULSES("FilterBadPulses")
const std::string X_MAX("XMax")
const std::string FULL_TIME("UseFullTime")
const std::string L1("L1")
const std::string READ_SIZE_FROM_DISK("ReadSizeFromDisk")
std::pair< size_t, size_t > PulseROI
const int64_t PULSETIME_OFFSET
constexpr double IGNORE_PIXEL
std::shared_ptr< SplittersWorkspace > SplittersWorkspace_sptr
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< GroupingWorkspace > GroupingWorkspace_sptr
shared pointer to the GroupingWorkspace class
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
constexpr double deg2rad
Defines units/enum for Crystal work.
MANTID_KERNEL_DLL std::string strmakef(char const *const fmt,...)
This is the constructor that std::string needed to have.
int MANTID_KERNEL_DLL createAxisFromRebinParams(const std::vector< double > ¶ms, std::vector< double > &xnew, const bool resize_xnew=true, const bool full_bins_only=false, const double xMinHint=std::nan(""), const double xMaxHint=std::nan(""), const bool useReverseLogarithmic=false, const double power=-1)
Creates a new output X array given a 'standard' set of rebinning parameters.
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
const std::string BINMODE("BinningMode")
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
int32_t detid_t
Typedef for a detector ID.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
std::string to_string(const wide_integer< Bits, Signed > &n)
std::vector< std::vector< std::atomic_uint32_t > > counts
std::vector< const std::vector< double > * > binedges
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.