AlignAndFocusPowder.cpp 48.1 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
#include "MantidWorkflowAlgorithms/AlignAndFocusPowder.h"
8
#include "MantidAPI/AnalysisDataService.h"
9
#include "MantidAPI/FileFinder.h"
10
11
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
12
#include "MantidAPI/SpectrumInfo.h"
mantid-builder's avatar
mantid-builder committed
13
#include "MantidAPI/WorkspaceFactory.h"
14
15
16
#include "MantidDataObjects/GroupingWorkspace.h"
#include "MantidDataObjects/MaskWorkspace.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
17
#include "MantidDataObjects/TableWorkspace.h"
18
#include "MantidDataObjects/Workspace2D.h"
Lynch, Vickie's avatar
Lynch, Vickie committed
19
#include "MantidKernel/ArrayProperty.h"
Peterson, Peter's avatar
Peterson, Peter committed
20
#include "MantidKernel/BoundedValidator.h"
21
#include "MantidKernel/ConfigService.h"
Peterson, Peter's avatar
Peterson, Peter committed
22
#include "MantidKernel/DateTimeValidator.h"
23
#include "MantidKernel/EnabledWhenProperty.h"
24
#include "MantidKernel/InstrumentInfo.h"
25
#include "MantidKernel/PropertyManager.h"
26
#include "MantidKernel/PropertyManagerDataService.h"
27
28
29
30
31
32
33
#include "MantidKernel/System.h"

using Mantid::Geometry::Instrument_const_sptr;
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;

34
35
36
37
namespace Mantid {
namespace WorkflowAlgorithms {
using namespace Kernel;
using API::FileProperty;
LamarMoore's avatar
LamarMoore committed
38
39
40
using API::MatrixWorkspace;
using API::MatrixWorkspace_sptr;
using API::WorkspaceProperty;
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
namespace {
namespace PropertyNames {
const std::string INPUT_WKSP("InputWorkspace");
const std::string OUTPUT_WKSP("OutputWorkspace");
const std::string UNFOCUS_WKSP("UnfocussedWorkspace");
const std::string CAL_FILE("CalFileName");
const std::string GROUP_FILE("GroupFilename");
const std::string GROUP_WKSP("GroupingWorkspace");
const std::string CAL_WKSP("CalibrationWorkspace");
const std::string OFFSET_WKSP("OffsetsWorkspace");
const std::string MASK_WKSP("MaskWorkspace");
const std::string MASK_TABLE("MaskBinTable");
const std::string BINNING("Params");
const std::string RESAMPLEX("ResampleX");
const std::string BIN_IN_D("Dspacing");
const std::string D_MINS("DMin");
const std::string D_MAXS("DMax");
59
const std::string RAGGED_DELTA("DeltaRagged");
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const std::string TOF_MIN("TMin");
const std::string TOF_MAX("TMax");
const std::string WL_MIN("CropWavelengthMin");
const std::string WL_MAX("CropWavelengthMax");
const std::string PRESERVE_EVENTS("PreserveEvents");
const std::string REMOVE_PROMPT_PULSE("RemovePromptPulseWidth");
const std::string COMPRESS_TOF_TOL("CompressTolerance");
const std::string COMPRESS_WALL_TOL("CompressWallClockTolerance");
const std::string COMPRESS_WALL_START("CompressStartTime");
const std::string L1("PrimaryFlightPath");
const std::string SPEC_IDS("SpectrumIDs");
const std::string L2("L2");
const std::string POLAR("Polar");
const std::string AZIMUTHAL("Azimuthal");
const std::string PM_NAME("ReductionProperties");
75
const std::string LORENTZ("LorentzCorrection");
76
77
78
const std::string UNWRAP_REF("UnwrapRef");
const std::string LOWRES_REF("LowResRef");
const std::string LOWRES_SPEC_OFF("LowResSpectrumOffset");
mantid-builder's avatar
mantid-builder committed
79
80
} // namespace PropertyNames
} // namespace
81

82
83
84
85
86
87
88
// Register the class into the algorithm factory
DECLARE_ALGORITHM(AlignAndFocusPowder)

//----------------------------------------------------------------------------------------------
/** Initialisation method. Declares properties to be used in algorithm.
 */
void AlignAndFocusPowder::init() {
89
  declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(
90
                      PropertyNames::INPUT_WKSP, "", Direction::Input),
91
                  "The input workspace");
92
  declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>(
93
                      PropertyNames::OUTPUT_WKSP, "", Direction::Output),
94
                  "The result of diffraction focussing of InputWorkspace");
95
  declareProperty(
96
      std::make_unique<WorkspaceProperty<MatrixWorkspace>>(
97
98
          PropertyNames::UNFOCUS_WKSP, "", Direction::Output,
          PropertyMode::Optional),
99
100
      "Treated data in d-spacing before focussing (optional). This will likely "
      "need rebinning.");
101
102
103
104
105
  // declareProperty(
  //   new WorkspaceProperty<MatrixWorkspace>("LowResTOFWorkspace", "",
  //   Direction::Output, PropertyMode::Optional),
  //   "The name of the workspace containing the filtered low resolution TOF
  //   data.");
mantid-builder's avatar
mantid-builder committed
106
107
108
109
110
  declareProperty(std::make_unique<FileProperty>(
                      PropertyNames::CAL_FILE, "", FileProperty::OptionalLoad,
                      std::vector<std::string>{".h5", ".hd5", ".hdf", ".cal"}),
                  "The name of the calibration file with offset, masking, and "
                  "grouping data");
111
  declareProperty(std::make_unique<FileProperty>(
112
                      PropertyNames::GROUP_FILE, "", FileProperty::OptionalLoad,
mantid-builder's avatar
mantid-builder committed
113
                      std::vector<std::string>{".xml", ".cal"}),
Peterson, Peter's avatar
Peterson, Peter committed
114
                  "Overrides grouping from CalFileName");
115
116
117
118
  declareProperty(std::make_unique<WorkspaceProperty<GroupingWorkspace>>(
                      PropertyNames::GROUP_WKSP, "", Direction::InOut,
                      PropertyMode::Optional),
                  "Optional: A GroupingWorkspace giving the grouping info.");
119
120

  declareProperty(
121
      std::make_unique<WorkspaceProperty<ITableWorkspace>>(
122
123
          PropertyNames::CAL_WKSP, "", Direction::InOut,
          PropertyMode::Optional),
124
125
      "Optional: A Workspace containing the calibration information. Either "
      "this or CalibrationFile needs to be specified.");
126
  declareProperty(
127
      std::make_unique<WorkspaceProperty<OffsetsWorkspace>>(
128
129
          PropertyNames::OFFSET_WKSP, "", Direction::Input,
          PropertyMode::Optional),
130
      "Optional: An OffsetsWorkspace giving the detector calibration values.");
131
132
133
134
  declareProperty(std::make_unique<WorkspaceProperty<MaskWorkspace>>(
                      PropertyNames::MASK_WKSP, "", Direction::InOut,
                      PropertyMode::Optional),
                  "Optional: A workspace giving which detectors are masked.");
135
  declareProperty(
136
      std::make_unique<WorkspaceProperty<TableWorkspace>>(
137
138
          "MaskBinTable", "", Direction::Input, PropertyMode::Optional),
      "Optional: A workspace giving pixels and bins to mask.");
139
140
  declareProperty( // intentionally not using the RebinParamsValidator
      std::make_unique<ArrayProperty<double>>(PropertyNames::BINNING),
141
142
143
144
145
      "A comma separated list of first bin boundary, width, last bin boundary. "
      "Optionally\n"
      "this can be followed by a comma and more widths and last boundary "
      "pairs.\n"
      "Negative width values indicate logarithmic binning.");
146
  declareProperty(PropertyNames::RESAMPLEX, 0,
LamarMoore's avatar
LamarMoore committed
147
148
149
                  "Number of bins in x-axis. Non-zero value "
                  "overrides \"Params\" property. Negative "
                  "value means logarithmic binning.");
150
151
152
153
  setPropertySettings(PropertyNames::BINNING,
                      std::make_unique<EnabledWhenProperty>(
                          PropertyNames::RESAMPLEX, IS_DEFAULT));
  declareProperty(PropertyNames::BIN_IN_D, true,
154
                  "Bin in Dspace. (True is Dspace; False is TOF)");
155
156
157
158
159
160
161
162
  declareProperty(
      std::make_unique<ArrayProperty<double>>(PropertyNames::D_MINS),
      "Minimum for Dspace axis. (Default 0.) ");
  mapPropertyName(PropertyNames::D_MINS, "d_min");
  declareProperty(
      std::make_unique<ArrayProperty<double>>(PropertyNames::D_MAXS),
      "Maximum for Dspace axis. (Default 0.) ");
  mapPropertyName(PropertyNames::D_MAXS, "d_max");
163
164
165
166
  declareProperty(
      std::make_unique<ArrayProperty<double>>(PropertyNames::RAGGED_DELTA),
      "Step parameter for rebin");
  mapPropertyName(PropertyNames::RAGGED_DELTA, "delta");
167
168
169
170
  declareProperty(PropertyNames::TOF_MIN, EMPTY_DBL(),
                  "Minimum for TOF axis. Defaults to 0. ");
  mapPropertyName(PropertyNames::TOF_MIN, "tof_min");
  declareProperty(PropertyNames::TOF_MAX, EMPTY_DBL(),
171
                  "Maximum for TOF or dspace axis. Defaults to 0. ");
172
173
  mapPropertyName(PropertyNames::TOF_MAX, "tof_max");
  declareProperty(PropertyNames::PRESERVE_EVENTS, true,
LamarMoore's avatar
LamarMoore committed
174
175
176
177
                  "If the InputWorkspace is an "
                  "EventWorkspace, this will preserve "
                  "the full event list (warning: this "
                  "will use much more memory!).");
178
  declareProperty(PropertyNames::REMOVE_PROMPT_PULSE, 0.,
LamarMoore's avatar
LamarMoore committed
179
180
181
                  "Width of events (in "
                  "microseconds) near the prompt "
                  "pulse to remove. 0 disables");
182
  auto mustBePositive = std::make_shared<BoundedValidator<double>>();
Peterson, Peter's avatar
Peterson, Peter committed
183
  mustBePositive->setLower(0.0);
184
185
186
187
188
189
  declareProperty(std::make_unique<PropertyWithValue<double>>(
                      PropertyNames::COMPRESS_TOF_TOL, 1e-5, mustBePositive,
                      Direction::Input),
                  "Compress events (in "
                  "microseconds) within this "
                  "tolerance. (Default 1e-5)");
Sam Jenkins's avatar
Sam Jenkins committed
190
191
  declareProperty(
      std::make_unique<PropertyWithValue<double>>(
192
193
          PropertyNames::COMPRESS_WALL_TOL, EMPTY_DBL(), mustBePositive,
          Direction::Input),
Peterson, Peter's avatar
Peterson, Peter committed
194
195
196
197
      "The tolerance (in seconds) on the wall-clock time for comparison. Unset "
      "means compressing all wall-clock times together disabling pulsetime "
      "resolution.");

198
  auto dateValidator = std::make_shared<DateTimeValidator>();
Peterson, Peter's avatar
Peterson, Peter committed
199
200
  dateValidator->allowEmpty(true);
  declareProperty(
201
      PropertyNames::COMPRESS_WALL_START, "", dateValidator,
Peterson, Peter's avatar
Peterson, Peter committed
202
203
204
205
      "An ISO formatted date/time string specifying the timestamp for "
      "starting filtering. Ignored if WallClockTolerance is not specified. "
      "Default is start of run",
      Direction::Input);
mantid-builder's avatar
mantid-builder committed
206
207
208
209
  declareProperty(PropertyNames::LORENTZ, false,
                  "Multiply each spectrum by "
                  "sin(theta) where theta is "
                  "half of the Bragg angle");
210
  declareProperty(PropertyNames::UNWRAP_REF, 0.,
LamarMoore's avatar
LamarMoore committed
211
212
                  "Reference total flight path for frame "
                  "unwrapping. Zero skips the correction");
213
  declareProperty(
214
      PropertyNames::LOWRES_REF, 0.,
215
216
217
218
      "Reference DIFC for resolution removal. Zero skips the correction");
  declareProperty(
      "CropWavelengthMin", 0.,
      "Crop the data at this minimum wavelength. Overrides LowResRef.");
219
  mapPropertyName(PropertyNames::WL_MIN, "wavelength_min");
220
221
222
  declareProperty("CropWavelengthMax", EMPTY_DBL(),
                  "Crop the data at this maximum wavelength. Forces use of "
                  "CropWavelengthMin.");
223
224
  mapPropertyName(PropertyNames::WL_MAX, "wavelength_max");
  declareProperty(PropertyNames::L1, -1.0,
225
                  "If positive, focus positions are changed.  (Default -1) ");
226
227
228
229
230
  declareProperty(
      std::make_unique<ArrayProperty<int32_t>>(PropertyNames::SPEC_IDS),
      "Optional: Spectrum Nos (note that it is not detector ID or "
      "workspace indices).");
  declareProperty(std::make_unique<ArrayProperty<double>>(PropertyNames::L2),
231
                  "Optional: Secondary flight (L2) paths for each detector");
mantid-builder's avatar
mantid-builder committed
232
233
  declareProperty(std::make_unique<ArrayProperty<double>>(PropertyNames::POLAR),
                  "Optional: Polar angles (two thetas) for detectors");
234
235
236
  declareProperty(
      std::make_unique<ArrayProperty<double>>(PropertyNames::AZIMUTHAL),
      "Azimuthal angles (out-of-plain) for detectors");
237

238
  declareProperty(PropertyNames::LOWRES_SPEC_OFF, -1,
239
                  "Offset on spectrum No of low resolution spectra from high "
240
241
242
243
244
                  "resolution one. "
                  "If negative, then all the low resolution TOF will not be "
                  "processed.  Otherwise, low resolution TOF "
                  "will be stored in an additional set of spectra. "
                  "If offset is equal to 0, then the low resolution will have "
245
                  "same spectrum Nos as the normal ones.  "
246
247
                  "Otherwise, the low resolution spectra will have spectrum "
                  "IDs offset from normal ones. ");
248
  declareProperty(PropertyNames::PM_NAME, "__powdereduction", Direction::Input);
249
250
}

251
252
253
std::map<std::string, std::string> AlignAndFocusPowder::validateInputs() {
  std::map<std::string, std::string> result;

254
255
256
257
258
259
260
  if (!isDefault(PropertyNames::UNFOCUS_WKSP)) {
    if (getPropertyValue(PropertyNames::OUTPUT_WKSP) ==
        getPropertyValue(PropertyNames::UNFOCUS_WKSP)) {
      result[PropertyNames::OUTPUT_WKSP] =
          "Cannot be the same as UnfocussedWorkspace";
      result[PropertyNames::UNFOCUS_WKSP] =
          "Cannot be the same as OutputWorkspace";
261
262
263
    }
  }

264
  m_inputW = getProperty(PropertyNames::INPUT_WKSP);
265
  m_inputEW = std::dynamic_pointer_cast<EventWorkspace>(m_inputW);
266
  if (m_inputEW && m_inputEW->getNumberEvents() <= 0)
Zhang, Chen's avatar
Zhang, Chen committed
267
    result[PropertyNames::INPUT_WKSP] =
268
269
270
        "Empty workspace encounter, possibly due to beam down."
        "Please plot the pCharge-time to identify suitable range for "
        "re-time-slicing";
271

272
273
274
  return result;
}

Tom Perkins's avatar
Tom Perkins committed
275
template <typename NumT> struct RegLowVectorPair {
276
277
278
279
  std::vector<NumT> reg;
  std::vector<NumT> low;
};

280
template <typename NumT>
281
282
283
284
RegLowVectorPair<NumT> splitVectors(const std::vector<NumT> &orig,
                                    const size_t numVal,
                                    const std::string &label) {
  RegLowVectorPair<NumT> out;
285
286

  // check that there is work to do
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  if (!orig.empty()) {
    // do the spliting
    if (orig.size() == numVal) {
      out.reg.assign(orig.begin(), orig.end());
      out.low.assign(orig.begin(), orig.end());
    } else if (orig.size() == 2 * numVal) {
      out.reg.assign(orig.begin(), orig.begin() + numVal);
      out.low.assign(orig.begin() + numVal, orig.begin());
    } else {
      std::stringstream msg;
      msg << "Input number of " << label << " ids is not equal to "
          << "the number of histograms or empty (" << orig.size() << " != 0 or "
          << numVal << " or " << (2 * numVal) << ")";
      throw std::runtime_error(msg.str());
    }
302
  }
303
  return out;
304
305
306
307
308
309
310
311
312
}

//----------------------------------------------------------------------------------------------
/**
 * Function to get a vector property either from a PropertyManager or the
 * algorithm
 * properties. If both PM and algorithm properties are specified, the algorithm
 * one wins.
 * The return value is the first element in the vector if it is not empty.
313
 * @param name : The algorithm property to retrieve.
314
315
316
 * @param avec : The vector to hold the property value.
 * @return : The default value of the requested property.
 */
317
318
319
double
AlignAndFocusPowder::getVecPropertyFromPmOrSelf(const std::string &name,
                                                std::vector<double> &avec) {
320
  avec = getProperty(name);
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  if (!avec.empty()) {
    return avec[0];
  }
  // No overrides provided.
  return 0.0;
}

//----------------------------------------------------------------------------------------------
/** Executes the algorithm
 *  @throw Exception::FileError If the grouping file cannot be opened or read
 * successfully
 *  @throw runtime_error If unable to run one of the Child Algorithms
 * successfully
 */
void AlignAndFocusPowder::exec() {
  // retrieve the properties
337
  m_inputW = getProperty(PropertyNames::INPUT_WKSP);
338
  m_inputEW = std::dynamic_pointer_cast<EventWorkspace>(m_inputW);
339
  m_instName = m_inputW->getInstrument()->getName();
340
341
342
343
344
345
  try {
    m_instName =
        Kernel::ConfigService::Instance().getInstrument(m_instName).shortName();
  } catch (Exception::NotFoundError &) {
    ; // not noteworthy
  }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  std::string calFilename = getPropertyValue(PropertyNames::CAL_FILE);
  std::string groupFilename = getPropertyValue(PropertyNames::GROUP_FILE);
  m_calibrationWS = getProperty(PropertyNames::CAL_WKSP);
  m_maskWS = getProperty(PropertyNames::MASK_WKSP);
  m_groupWS = getProperty(PropertyNames::GROUP_WKSP);
  DataObjects::TableWorkspace_sptr maskBinTableWS =
      getProperty(PropertyNames::MASK_TABLE);
  m_l1 = getProperty(PropertyNames::L1);
  specids = getProperty(PropertyNames::SPEC_IDS);
  l2s = getProperty(PropertyNames::L2);
  tths = getProperty(PropertyNames::POLAR);
  phis = getProperty(PropertyNames::AZIMUTHAL);
  m_params = getProperty(PropertyNames::BINNING);
  dspace = getProperty(PropertyNames::BIN_IN_D);
  auto dmin = getVecPropertyFromPmOrSelf(PropertyNames::D_MINS, m_dmins);
  auto dmax = getVecPropertyFromPmOrSelf(PropertyNames::D_MAXS, m_dmaxs);
362
  this->getVecPropertyFromPmOrSelf(PropertyNames::RAGGED_DELTA, m_delta_ragged);
363
364
  LRef = getProperty(PropertyNames::UNWRAP_REF);
  DIFCref = getProperty(PropertyNames::LOWRES_REF);
365
  const bool applyLorentz = getProperty(PropertyNames::LORENTZ);
366
367
  minwl = getProperty(PropertyNames::WL_MIN);
  maxwl = getProperty(PropertyNames::WL_MAX);
368
369
  if (maxwl == 0.)
    maxwl = EMPTY_DBL(); // python can only specify 0 for unused
370
371
372
373
374
375
376
377
  tmin = getProperty(PropertyNames::TOF_MIN);
  tmax = getProperty(PropertyNames::TOF_MAX);
  m_preserveEvents = getProperty(PropertyNames::PRESERVE_EVENTS);
  m_resampleX = getProperty(PropertyNames::RESAMPLEX);
  const double compressEventsTolerance =
      getProperty(PropertyNames::COMPRESS_TOF_TOL);
  const double wallClockTolerance =
      getProperty(PropertyNames::COMPRESS_WALL_TOL);
378
379
  // determine some bits about d-space and binning
  if (m_resampleX != 0) {
380
381
382
383
384
385
    // ignore the normal rebin parameters
    m_params.clear();
  } else if (m_params.size() == 1 && m_delta_ragged.empty()) {
    // if there is 1 binning parameter and not in ragged rebinning mode
    // ignore what people asked for
    dspace = bool(dmax > 0.);
386
387
  }
  if (dspace) {
388
389
390
391
    if (m_params.size() == 1 && (!isEmpty(dmin)) && (!isEmpty(dmax))) {
      if (dmin > 0. && dmax > dmin) {
        double step = m_params[0];
        m_params.clear();
392
393
394
        m_params.emplace_back(dmin);
        m_params.emplace_back(step);
        m_params.emplace_back(dmax);
LamarMoore's avatar
LamarMoore committed
395
396
397
        g_log.information()
            << "d-Spacing binning updated: " << m_params[0] << "  "
            << m_params[1] << "  " << m_params[2] << "\n";
398
399
400
401
      } else {
        g_log.warning() << "something is wrong with dmin (" << dmin
                        << ") and dmax (" << dmax
                        << "). They are being ignored.\n";
Zhou, Wenduo's avatar
Zhou, Wenduo committed
402
      }
403
    }
404
  } else {
405
406
407
    if (m_params.size() == 1 && (!isEmpty(tmin)) && (!isEmpty(tmax))) {
      if (tmin > 0. && tmax > tmin) {
        double step = m_params[0];
408
        m_params[0] = tmin;
409
410
        m_params.emplace_back(step);
        m_params.emplace_back(tmax);
411
        g_log.information() << "TOF binning updated: " << m_params[0] << "  "
412
                            << m_params[1] << "  " << m_params[2] << "\n";
413
414
415
416
      } else {
        g_log.warning() << "something is wrong with tmin (" << tmin
                        << ") and tmax (" << tmax
                        << "). They are being ignored.\n";
Zhou, Wenduo's avatar
Zhou, Wenduo committed
417
      }
418
    }
419
  }
420
421
  xmin = 0.;
  xmax = 0.;
422
423
424
425
426
427
428
429
430
431
  if (tmin > 0.) {
    xmin = tmin;
  }
  if (tmax > 0.) {
    xmax = tmax;
  }
  if (!dspace && m_params.size() == 3) {
    xmin = m_params[0];
    xmax = m_params[2];
  }
Lynch, Vickie's avatar
Lynch, Vickie committed
432

433
  // Low resolution
434
  int lowresoffset = getProperty(PropertyNames::LOWRES_SPEC_OFF);
435
436
437
438
439
440
  if (lowresoffset < 0) {
    m_processLowResTOF = false;
  } else {
    m_processLowResTOF = true;
    m_lowResSpecOffset = static_cast<size_t>(lowresoffset);
  }
Lynch, Vickie's avatar
Lynch, Vickie committed
441

Peterson, Peter's avatar
Peterson, Peter committed
442
  loadCalFile(calFilename, groupFilename);
443
444

  // Now setup the output workspace
445
  m_outputW = getProperty(PropertyNames::OUTPUT_WKSP);
446
  if (m_inputEW) {
Zhou, Wenduo's avatar
Zhou, Wenduo committed
447
    // event workspace
448
    if (m_outputW != m_inputW) {
Zhou, Wenduo's avatar
Zhou, Wenduo committed
449
      // out-of-place: clone the input EventWorkspace
450
      m_outputEW = m_inputEW->clone();
451
      m_outputW = std::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW);
452
    } else {
453
      // in-place
454
      m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
455
456
    }
  } else {
Zhou, Wenduo's avatar
Zhou, Wenduo committed
457
    // workspace2D
458
    if (m_outputW != m_inputW) {
459
      m_outputW = m_inputW->clone();
Zhou, Wenduo's avatar
Zhou, Wenduo committed
460
    }
461
  }
Lynch, Vickie's avatar
Lynch, Vickie committed
462

463
464
465
466
467
468
  if (m_processLowResTOF) {
    if (!m_inputEW) {
      throw std::runtime_error(
          "Input workspace is not EventWorkspace.  It is not supported now.");
    } else {
      // Make a brand new EventWorkspace
469
      m_lowResEW = std::dynamic_pointer_cast<EventWorkspace>(
470
471
          WorkspaceFactory::Instance().create(
              "EventWorkspace", m_inputEW->getNumberHistograms(), 2, 1));
Zhou, Wenduo's avatar
Zhou, Wenduo committed
472

473
      // Cast to the matrixOutputWS and save it
474
      m_lowResW = std::dynamic_pointer_cast<MatrixWorkspace>(m_lowResEW);
475
      // m_lowResW->setName(lowreswsname);
476
    }
477
  }
478

479
  // set up a progress bar with the "correct" number of steps
480
  m_progress = std::make_unique<Progress>(this, 0., 1., 21);
481
482

  if (m_inputEW) {
483
484
485
    if (compressEventsTolerance > 0.) {
      g_log.information() << "running CompressEvents(Tolerance="
                          << compressEventsTolerance;
Peterson, Peter's avatar
Peterson, Peter committed
486
487
488
      if (!isEmpty(wallClockTolerance))
        g_log.information() << " and WallClockTolerance=" << wallClockTolerance;
      g_log.information() << ") started at "
489
                          << Types::Core::DateAndTime::getCurrentTime() << "\n";
490
491
492
493
      API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents");
      compressAlg->setProperty("InputWorkspace", m_outputEW);
      compressAlg->setProperty("OutputWorkspace", m_outputEW);
      compressAlg->setProperty("OutputWorkspace", m_outputEW);
494
      compressAlg->setProperty("Tolerance", compressEventsTolerance);
Peterson, Peter's avatar
Peterson, Peter committed
495
496
      if (!isEmpty(wallClockTolerance)) {
        compressAlg->setProperty("WallClockTolerance", wallClockTolerance);
497
498
        compressAlg->setPropertyValue(
            "StartTime", getPropertyValue(PropertyNames::COMPRESS_WALL_START));
Peterson, Peter's avatar
Peterson, Peter committed
499
      }
500
501
      compressAlg->executeAsChildAlg();
      m_outputEW = compressAlg->getProperty("OutputWorkspace");
502
      m_outputW = std::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW);
503
504
505
    } else {
      g_log.information() << "Not compressing event list\n";
      doSortEvents(m_outputW); // still sort to help some thing out
506
    }
507
  }
508
  m_progress->report();
Zhou, Wenduo's avatar
Zhou, Wenduo committed
509

510
  if (xmin > 0. || xmax > 0.) {
511
512
513
514
515
    double tempmin;
    double tempmax;
    m_outputW->getXMinMax(tempmin, tempmax);

    g_log.information() << "running CropWorkspace(TOFmin=" << xmin
516
                        << ", TOFmax=" << xmax << ") started at "
517
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
518
519
520
521
522
523
524
525
526
    API::IAlgorithm_sptr cropAlg = createChildAlgorithm("CropWorkspace");
    cropAlg->setProperty("InputWorkspace", m_outputW);
    cropAlg->setProperty("OutputWorkspace", m_outputW);
    if ((xmin > 0.) && (xmin > tempmin))
      cropAlg->setProperty("Xmin", xmin);
    if ((xmax > 0.) && (xmax < tempmax))
      cropAlg->setProperty("Xmax", xmax);
    cropAlg->executeAsChildAlg();
    m_outputW = cropAlg->getProperty("OutputWorkspace");
527
    m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
528
529
530
  }
  m_progress->report();

531
  // filter the input events if appropriate
532
533
  double removePromptPulseWidth =
      getProperty(PropertyNames::REMOVE_PROMPT_PULSE);
534
  if (removePromptPulseWidth > 0.) {
535
    m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
536
537
    if (m_outputEW->getNumberEvents() > 0) {
      g_log.information() << "running RemovePromptPulse(Width="
538
                          << removePromptPulseWidth << ") started at "
539
                          << Types::Core::DateAndTime::getCurrentTime() << "\n";
Peterson, Peter's avatar
Peterson, Peter committed
540
541
      API::IAlgorithm_sptr filterPAlg =
          createChildAlgorithm("RemovePromptPulse");
542
543
544
545
546
      filterPAlg->setProperty("InputWorkspace", m_outputW);
      filterPAlg->setProperty("OutputWorkspace", m_outputW);
      filterPAlg->setProperty("Width", removePromptPulseWidth);
      filterPAlg->executeAsChildAlg();
      m_outputW = filterPAlg->getProperty("OutputWorkspace");
547
      m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
548
549
550
    } else {
      g_log.information("skipping RemovePromptPulse on empty EventWorkspace");
    }
551
552
553
  }
  m_progress->report();

554
  if (maskBinTableWS) {
555
    g_log.information() << "running MaskBinsFromTable started at "
556
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
557
558
559
560
561
562
    API::IAlgorithm_sptr alg = createChildAlgorithm("MaskBinsFromTable");
    alg->setProperty("InputWorkspace", m_outputW);
    alg->setProperty("OutputWorkspace", m_outputW);
    alg->setProperty("MaskingInformation", maskBinTableWS);
    alg->executeAsChildAlg();
    m_outputW = alg->getProperty("OutputWorkspace");
563
    m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
564
565
566
567
  }
  m_progress->report();

  if (m_maskWS) {
568
    g_log.information() << "running MaskDetectors started at "
569
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
570
571
572
573
574
575
576
    const auto &maskedDetectors = m_maskWS->getMaskedDetectors();
    API::IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskInstrument");
    maskAlg->setProperty("InputWorkspace", m_outputW);
    maskAlg->setProperty("OutputWorkspace", m_outputW);
    maskAlg->setProperty(
        "DetectorIDs",
        std::vector<detid_t>(maskedDetectors.begin(), maskedDetectors.end()));
577
    maskAlg->executeAsChildAlg();
Nick Draper's avatar
Nick Draper committed
578
    m_outputW = maskAlg->getProperty("OutputWorkspace");
579
    m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
580
581
  }
  m_progress->report();
Lynch, Vickie's avatar
Lynch, Vickie committed
582

583
584
585
586
  if (!dspace)
    m_outputW = rebin(m_outputW);
  m_progress->report();

587
  if (m_calibrationWS) {
588
    g_log.information() << "running AlignDetectors started at "
589
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
590
591
592
    API::IAlgorithm_sptr alignAlg = createChildAlgorithm("AlignDetectors");
    alignAlg->setProperty("InputWorkspace", m_outputW);
    alignAlg->setProperty("OutputWorkspace", m_outputW);
593
    alignAlg->setProperty("CalibrationWorkspace", m_calibrationWS);
594
595
596
597
598
599
    alignAlg->executeAsChildAlg();
    m_outputW = alignAlg->getProperty("OutputWorkspace");
  } else {
    m_outputW = convertUnits(m_outputW, "dSpacing");
  }
  m_progress->report();
Lynch, Vickie's avatar
Lynch, Vickie committed
600

601
602
603
604
605
  // ----------------- WACKY LORENTZ THING HERE
  // TODO should call LorentzCorrection as a sub-algorithm
  if (applyLorentz) {
    g_log.information() << "Applying Lorentz correction started at "
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
606
607
608
609
610
611
612

    API::IAlgorithm_sptr alg = createChildAlgorithm("LorentzCorrection");
    alg->setProperty("InputWorkspace", m_outputW);
    alg->setProperty("OutputWorkspace", m_outputW);
    alg->setPropertyValue("Type", "PowderTOF");
    alg->executeAsChildAlg();
    m_outputW = alg->getProperty("OutputWorkspace");
613
    m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
614
615
  }

616
  if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) {
617
618
619
620
621
622
623
    m_outputW = convertUnits(m_outputW, "TOF");
  }
  m_progress->report();

  // Beyond this point, low resolution TOF workspace is considered.
  if (LRef > 0.) {
    g_log.information() << "running UnwrapSNS(LRef=" << LRef << ",Tmin=" << tmin
624
                        << ",Tmax=" << tmax << ") started at "
625
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
626
627
628
629
630
631
632
633
634
635
636
637
    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("UnwrapSNS");
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
    removeAlg->setProperty("LRef", LRef);
    if (tmin > 0.)
      removeAlg->setProperty("Tmin", tmin);
    if (tmax > tmin)
      removeAlg->setProperty("Tmax", tmax);
    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
  }
  m_progress->report();
Zhou, Wenduo's avatar
Zhou, Wenduo committed
638

639
640
641
642
  if (minwl > 0. || (!isEmpty(maxwl))) { // just crop the worksapce
    // turn off the low res stuff
    m_processLowResTOF = false;

643
    EventWorkspace_sptr ews =
644
        std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
Zhou, Wenduo's avatar
Zhou, Wenduo committed
645
    if (ews)
646
647
648
649
      g_log.information() << "Number of events = " << ews->getNumberEvents()
                          << ". ";
    g_log.information("\n");

650
651
    m_outputW = convertUnits(m_outputW, "Wavelength");

Peterson, Peter's avatar
Peterson, Peter committed
652
653
654
    g_log.information() << "running CropWorkspace(WavelengthMin=" << minwl;
    if (!isEmpty(maxwl))
      g_log.information() << ", WavelengthMax=" << maxwl;
655
    g_log.information() << ") started at "
656
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
Peterson, Peter's avatar
Peterson, Peter committed
657

658
    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("CropWorkspace");
659
660
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
661
662
    removeAlg->setProperty("XMin", minwl);
    removeAlg->setProperty("XMax", maxwl);
663
664
    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
Peterson, Peter's avatar
Peterson, Peter committed
665
666
    if (ews)
      g_log.information() << "Number of events = " << ews->getNumberEvents()
667
                          << ".\n";
668
669
  } else if (DIFCref > 0.) {
    g_log.information() << "running RemoveLowResTof(RefDIFC=" << DIFCref
670
                        << ",K=3.22) started at "
671
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
672
    EventWorkspace_sptr ews =
673
        std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
674
675
676
677
678
679
680
681
682
683
684
685
    if (ews)
      g_log.information() << "Number of events = " << ews->getNumberEvents()
                          << ". ";
    g_log.information("\n");

    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("RemoveLowResTOF");
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
    removeAlg->setProperty("ReferenceDIFC", DIFCref);
    removeAlg->setProperty("K", 3.22);
    if (tmin > 0.)
      removeAlg->setProperty("Tmin", tmin);
686
    if (m_processLowResTOF)
687
      removeAlg->setProperty("LowResTOFWorkspace", m_lowResW);
688

689
690
    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
Zhou, Wenduo's avatar
Zhou, Wenduo committed
691
    if (m_processLowResTOF)
692
693
694
695
696
      m_lowResW = removeAlg->getProperty("LowResTOFWorkspace");
  }
  m_progress->report();

  EventWorkspace_sptr ews =
697
      std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
698
699
700
701
  if (ews) {
    size_t numhighevents = ews->getNumberEvents();
    if (m_processLowResTOF) {
      EventWorkspace_sptr lowes =
702
          std::dynamic_pointer_cast<EventWorkspace>(m_lowResW);
703
704
705
706
707
      size_t numlowevents = lowes->getNumberEvents();
      g_log.information() << "Number of high TOF events = " << numhighevents
                          << "; "
                          << "Number of low TOF events = " << numlowevents
                          << ".\n";
708
    }
709
710
  }
  m_progress->report();
711

712
  // Convert units
713
  if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) {
714
715
716
717
718
    m_outputW = convertUnits(m_outputW, "dSpacing");
    if (m_processLowResTOF)
      m_lowResW = convertUnits(m_lowResW, "dSpacing");
  }
  m_progress->report();
Zhou, Wenduo's avatar
Zhou, Wenduo committed
719

720
  if (dspace) {
721
    m_outputW = rebin(m_outputW);
722
723
    if (m_processLowResTOF)
      m_lowResW = rebin(m_lowResW);
724
  }
725
726
727
728
729
730
731
  m_progress->report();

  doSortEvents(m_outputW);
  if (m_processLowResTOF)
    doSortEvents(m_lowResW);
  m_progress->report();

732
733
734
735
736
737
738
  // copy the output workspace just before `DiffractionFocusing`
  // this probably should be binned by callers before inspecting
  if (!isDefault("UnfocussedWorkspace")) {
    auto wkspCopy = m_outputW->clone();
    setProperty("UnfocussedWorkspace", std::move(wkspCopy));
  }

739
740
741
742
743
744
745
746
747
748
749
750
751
  // Diffraction focus
  m_outputW = diffractionFocus(m_outputW);
  if (m_processLowResTOF)
    m_lowResW = diffractionFocus(m_lowResW);
  m_progress->report();

  doSortEvents(m_outputW);
  if (m_processLowResTOF)
    doSortEvents(m_lowResW);
  m_progress->report();

  // this next call should probably be in for rebin as well
  // but it changes the system tests
752
  if (dspace && m_resampleX != 0.) {
753
    if (m_delta_ragged.empty()) {
754
755
      m_outputW = rebin(m_outputW);
    } else {
756
      m_outputW = rebinRagged(m_outputW, true);
757
758
    }
    if (m_processLowResTOF) {
759
      if (m_delta_ragged.empty()) {
760
761
        m_lowResW = rebin(m_lowResW);
      } else {
762
        m_lowResW = rebinRagged(m_lowResW, true);
763
764
      }
    }
765
766
767
768
769
770
771
772
  }
  m_progress->report();

  // edit the instrument geometry
  if (m_groupWS &&
      (m_l1 > 0 || !tths.empty() || !l2s.empty() || !phis.empty())) {
    size_t numreg = m_outputW->getNumberHistograms();

Peterson, Peter's avatar
Peterson, Peter committed
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
    try {
      // set up the vectors for doing everything
      auto specidsSplit = splitVectors(specids, numreg, "specids");
      auto tthsSplit = splitVectors(tths, numreg, "two-theta");
      auto l2sSplit = splitVectors(l2s, numreg, "L2");
      auto phisSplit = splitVectors(phis, numreg, "phi");

      // Edit instrument
      m_outputW = editInstrument(m_outputW, tthsSplit.reg, specidsSplit.reg,
                                 l2sSplit.reg, phisSplit.reg);

      if (m_processLowResTOF) {
        m_lowResW = editInstrument(m_lowResW, tthsSplit.low, specidsSplit.low,
                                   l2sSplit.low, phisSplit.low);
      }
    } catch (std::runtime_error &e) {
      g_log.warning("Not editing instrument geometry:");
      g_log.warning(e.what());
791
792
793
    }
  }
  m_progress->report();
Zhou, Wenduo's avatar
Zhou, Wenduo committed
794

795
796
797
798
799
800
801
802
803
804
  // Conjoin 2 workspaces if there is low resolution
  if (m_processLowResTOF) {
    m_outputW = conjoinWorkspaces(m_outputW, m_lowResW, m_lowResSpecOffset);
  }
  m_progress->report();

  // Convert units to TOF
  m_outputW = convertUnits(m_outputW, "TOF");
  m_progress->report();

805
  if (!dspace && !m_delta_ragged.empty()) {
806
    m_outputW = rebinRagged(m_outputW, false);
807
808
  }

809
  // compress again if appropriate
810
  m_outputEW = std::dynamic_pointer_cast<EventWorkspace>(m_outputW);
811
812
813
  if ((m_outputEW) && (compressEventsTolerance > 0.)) {
    g_log.information() << "running CompressEvents(Tolerance="
                        << compressEventsTolerance;
Peterson, Peter's avatar
Peterson, Peter committed
814
815
816
    if (!isEmpty(wallClockTolerance))
      g_log.information() << " and WallClockTolerance=" << wallClockTolerance;
    g_log.information() << ") started at "
817
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
818
819
820
    API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents");
    compressAlg->setProperty("InputWorkspace", m_outputEW);
    compressAlg->setProperty("OutputWorkspace", m_outputEW);
821
    compressAlg->setProperty("Tolerance", compressEventsTolerance);
Peterson, Peter's avatar
Peterson, Peter committed
822
823
824
825
826
    if (!isEmpty(wallClockTolerance)) {
      compressAlg->setProperty("WallClockTolerance", wallClockTolerance);
      compressAlg->setPropertyValue("StartTime",
                                    getPropertyValue("CompressStartTime"));
    }
827
828
    compressAlg->executeAsChildAlg();
    m_outputEW = compressAlg->getProperty("OutputWorkspace");
829
    m_outputW = std::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW);
830
831
  }
  m_progress->report();
832

833
834
835
  // return the output workspace
  setProperty("OutputWorkspace", m_outputW);
}
Zhou, Wenduo's avatar
Zhou, Wenduo committed
836

837
838
//----------------------------------------------------------------------------------------------
/** Call edit instrument geometry
LamarMoore's avatar
LamarMoore committed
839
 */
840
API::MatrixWorkspace_sptr AlignAndFocusPowder::editInstrument(
David Fairbrother's avatar
David Fairbrother committed
841
842
843
    API::MatrixWorkspace_sptr ws, const std::vector<double> &polars,
    const std::vector<specnum_t> &specids, const std::vector<double> &l2s,
    const std::vector<double> &phis) {
844
  g_log.information() << "running EditInstrumentGeometry started at "
845
                      << Types::Core::DateAndTime::getCurrentTime() << "\n";
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

  API::IAlgorithm_sptr editAlg = createChildAlgorithm("EditInstrumentGeometry");
  editAlg->setProperty("Workspace", ws);
  if (m_l1 > 0.)
    editAlg->setProperty("PrimaryFlightPath", m_l1);
  if (!polars.empty())
    editAlg->setProperty("Polar", polars);
  if (!specids.empty())
    editAlg->setProperty("SpectrumIDs", specids);
  if (!l2s.empty())
    editAlg->setProperty("L2", l2s);
  if (!phis.empty())
    editAlg->setProperty("Azimuthal", phis);
  editAlg->executeAsChildAlg();

  ws = editAlg->getProperty("Workspace");

  return ws;
}

//----------------------------------------------------------------------------------------------
/** Call diffraction focus to a matrix workspace.
LamarMoore's avatar
LamarMoore committed
868
 */
869
870
871
872
API::MatrixWorkspace_sptr
AlignAndFocusPowder::diffractionFocus(API::MatrixWorkspace_sptr ws) {
  if (!m_groupWS) {
    g_log.information() << "not focussing data\n";
Zhou, Wenduo's avatar
Zhou, Wenduo committed
873
874
875
    return ws;
  }

876
877
878
879
880
881
882
  if (m_maskWS) {
    API::IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors");
    maskAlg->setProperty("Workspace", m_groupWS);
    maskAlg->setProperty("MaskedWorkspace", m_maskWS);
    maskAlg->executeAsChildAlg();
  }

883
  g_log.information() << "running DiffractionFocussing started at "
884
                      << Types::Core::DateAndTime::getCurrentTime() << "\n";
Zhou, Wenduo's avatar
Zhou, Wenduo committed
885

886
887
888
889
890
891
892
  API::IAlgorithm_sptr focusAlg = createChildAlgorithm("DiffractionFocussing");
  focusAlg->setProperty("InputWorkspace", ws);
  focusAlg->setProperty("OutputWorkspace", ws);
  focusAlg->setProperty("GroupingWorkspace", m_groupWS);
  focusAlg->setProperty("PreserveEvents", m_preserveEvents);
  focusAlg->executeAsChildAlg();
  ws = focusAlg->getProperty("OutputWorkspace");
Zhou, Wenduo's avatar
Zhou, Wenduo committed
893

894
895
  return ws;
}
Zhou, Wenduo's avatar
Zhou, Wenduo committed
896

897
898
//----------------------------------------------------------------------------------------------
/** Convert units
LamarMoore's avatar
LamarMoore committed
899
 */
900
901
API::MatrixWorkspace_sptr
AlignAndFocusPowder::convertUnits(API::MatrixWorkspace_sptr matrixws,
David Fairbrother's avatar
David Fairbrother committed
902
                                  const std::string &target) {
903
904
  g_log.information() << "running ConvertUnits(Target=" << target
                      << ") started at "
905
                      << Types::Core::DateAndTime::getCurrentTime() << "\n";
906
907
908
909
910
911
912
913
914
915
916
917
918
919

  API::IAlgorithm_sptr convert2Alg = createChildAlgorithm("ConvertUnits");
  convert2Alg->setProperty("InputWorkspace", matrixws);
  convert2Alg->setProperty("OutputWorkspace", matrixws);
  convert2Alg->setProperty("Target", target);
  convert2Alg->executeAsChildAlg();

  matrixws = convert2Alg->getProperty("OutputWorkspace");

  return matrixws;
}

//----------------------------------------------------------------------------------------------
/** Rebin
LamarMoore's avatar
LamarMoore committed
920
 */
921
922
API::MatrixWorkspace_sptr
AlignAndFocusPowder::rebin(API::MatrixWorkspace_sptr matrixws) {
923
  if (!m_delta_ragged.empty()) {
924
925
    return matrixws;
  } else if (m_resampleX != 0) {
926
927
928
929
    // ResampleX
    g_log.information() << "running ResampleX(NumberBins=" << abs(m_resampleX)
                        << ", LogBinning=" << (m_resampleX < 0) << ", dMin("
                        << m_dmins.size() << "), dmax(" << m_dmaxs.size()
930
                        << ")) started at "
931
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
932
933
934
935
936
937
938
939
940
941
942
943
    API::IAlgorithm_sptr alg = createChildAlgorithm("ResampleX");
    alg->setProperty("InputWorkspace", matrixws);
    alg->setProperty("OutputWorkspace", matrixws);
    if ((!m_dmins.empty()) && (!m_dmaxs.empty())) {
      size_t numHist = m_outputW->getNumberHistograms();
      if ((numHist == m_dmins.size()) && (numHist == m_dmaxs.size())) {
        alg->setProperty("XMin", m_dmins);
        alg->setProperty("XMax", m_dmaxs);
      } else {
        g_log.information()
            << "Number of dmin and dmax values don't match the "
            << "number of workspace indices. Ignoring the parameters.\n";
944
945
      }
    }
946
947
948
949
950
951
952
    alg->setProperty("NumberBins", abs(m_resampleX));
    alg->setProperty("LogBinning", (m_resampleX < 0));
    alg->executeAsChildAlg();
    matrixws = alg->getProperty("OutputWorkspace");
    return matrixws;
  } else {
    g_log.information() << "running Rebin( ";
Hahn, Steven's avatar
Hahn, Steven committed
953
954
    for (double param : m_params)
      g_log.information() << param << " ";
955
    g_log.information() << ") started at "
956
                        << Types::Core::DateAndTime::getCurrentTime() << "\n";
957
958
959
960
    for (double param : m_params)
      if (isEmpty(param))
        g_log.warning("encountered empty binning parameter");

961
962
963
964
965
966
967
    API::IAlgorithm_sptr rebin3Alg = createChildAlgorithm("Rebin");
    rebin3Alg->setProperty("InputWorkspace", matrixws);
    rebin3Alg->setProperty("OutputWorkspace", matrixws);
    rebin3Alg->setProperty("Params", m_params);
    rebin3Alg->executeAsChildAlg();
    matrixws = rebin3Alg->getProperty("OutputWorkspace");
    return matrixws;
968
  }
969
}
Zhou, Wenduo's avatar
Zhou, Wenduo committed
970

971
//----------------------------------------------------------------------------------------------
972
/** RebinRagged this should only be done on the final focussed workspace
973
974
 */
API::MatrixWorkspace_sptr
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
AlignAndFocusPowder::rebinRagged(API::MatrixWorkspace_sptr matrixws, const bool inDspace) {
  // local variables to control whether or not to log individual values
  bool print_xmin = false;
  bool print_xmax = false;

  // configure RebinRagged
  API::IAlgorithm_sptr alg = createChildAlgorithm("RebinRagged");
  if (inDspace) {
      if (!m_dmins.empty()) {
          print_xmin = true;
          alg->setProperty("XMin", m_dmins);
      }
      if (!m_dmaxs.empty()) {
          print_xmax = true;
        alg->setProperty("XMax", m_dmaxs);
      }
  } else { // assume time-of-flight
      if (tmin > 0.) {
          print_xmin = true;
          // wacky syntax to set a single value to an ArrayProperty
          alg->setProperty("XMin", std::vector<double>(1, tmin));
      }
      if (tmax > 0. && tmax > tmin) {
          print_xmax = true;
          // wacky syntax to set a single value to an ArrayProperty
          alg->setProperty("XMax", std::vector<double>(1, tmax));
For faster browsing, not all history is shown. View entire blame