92 const auto nHist = inputWS->getNumberHistograms();
94 const auto nBins = inputWS->blocksize();
104 if (entryName.empty()) {
105 entryName =
"mantid_workspace";
107 nxFile.makeGroup(entryName,
"NXentry",
true);
110 nxFile.writeData(
"definition",
"NXSPE");
111 nxFile.openData(
"definition");
116 nxFile.writeData(
"program_name",
"mantid");
117 nxFile.openData(
"program_name");
122 nxFile.makeGroup(
"NXSPE_info",
"NXcollection",
true);
127 if (!efixed_provided) {
130 auto eMode = inputWS->getEMode();
131 bool write_single_energy(
true);
132 if (!efixed_provided) {
139 if (detEfixed.size() == 1) {
141 }
else if (detEfixed.size() > 1) {
142 write_single_energy =
false;
143 nxFile.writeData(
"fixed_energy", detEfixed);
145 if (!write_single_energy || (detEfixed[0] > std::numeric_limits<float>::epsilon()))
163 const API::Run &run = inputWS->run();
171 if (write_single_energy)
172 nxFile.writeData(
"fixed_energy",
efixed);
174 nxFile.openData(
"fixed_energy");
175 nxFile.putAttr(
"units",
"meV");
181 nxFile.writeData(
"psi", psi);
182 nxFile.openData(
"psi");
183 nxFile.putAttr(
"units",
"degrees");
188 nxFile.writeData(
"ki_over_kf_scaling", 1);
190 nxFile.writeData(
"ki_over_kf_scaling", 0);
196 nxFile.makeGroup(
"instrument",
"NXinstrument",
true);
198 nxFile.writeData(
"name", inputWS->getInstrument()->getName());
200 nxFile.openData(
"name");
202 nxFile.putAttr(
"short_name", inputWS->getInstrument()->getName());
204 nxFile.writeData(
"run_number", inputWS->getRunNumber());
210 nxFile.makeGroup(
"fermi",
"NXfermi_chopper",
true);
211 nxFile.writeData(
"energy",
efixed);
220 nxFile.makeGroup(
"sample",
"NXsample",
true);
229 nxFile.makeGroup(
"data",
"NXdata",
true);
234 const auto &
X = inputWS->x(0);
235 nxFile.writeData(
"energy",
X.rawData());
236 nxFile.openData(
"energy");
237 nxFile.putAttr(
"units",
"meV");
242 Dimensions arrayDims{nHist, nBins};
247 nxFile.openData(
"data");
248 nxFile.putAttr(
"signal", 1);
249 nxFile.putAttr(
"axes",
"polar:energy");
255 Dimensions slabStart(2, 0), slabSize(2, 0);
256 auto chunkRows =
static_cast<Dimensions::value_type
>(
MAX_CHUNK_SIZE / 8 / nBins);
257 if (nHist < chunkRows) {
261 slabSize[0] = chunkRows;
265 using Buffer = boost::scoped_array<double>;
266 const size_t bufferSize(slabSize[0] * slabSize[1]);
267 Buffer signalBuffer(
new double[bufferSize]);
268 Buffer errorBuffer(
new double[bufferSize]);
272 uint64_t bufferCounter(0);
273 const auto &spectrumInfo = inputWS->spectrumInfo();
274 for (std::size_t i = 0; i < nHist; ++i) {
277 double *signalBufferStart = signalBuffer.get() + bufferCounter * nBins;
278 double *errorBufferStart = errorBuffer.get() + bufferCounter * nBins;
279 if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i)) {
281 if (!spectrumInfo.isMasked(i)) {
282 std::copy(inputWS->y(i).cbegin(), inputWS->y(i).cend(), signalBufferStart);
283 std::copy(inputWS->e(i).cbegin(), inputWS->e(i).cend(), errorBufferStart);
285 std::fill_n(signalBufferStart, nBins,
MASK_FLAG);
286 std::fill_n(errorBufferStart, nBins,
MASK_ERROR);
290 std::fill_n(signalBufferStart, nBins, 0.0);
291 std::fill_n(errorBufferStart, nBins, 0.0);
298 if (bufferCounter == chunkRows || i == nHist - 1) {
301 slabSize[0] = bufferCounter;
302 nxFile.openData(
"data");
303 nxFile.putSlab(signalBuffer.get(), slabStart, slabSize);
307 nxFile.openData(
"error");
308 nxFile.putSlab(errorBuffer.get(), slabStart, slabSize);
312 slabStart[0] += bufferCounter;
320 spCalcDetPar->initialize();
321 spCalcDetPar->setProperty(
"InputWorkspace", inputWS);
323 if (!(parFileName.empty() || parFileName ==
"not_used.par")) {
324 spCalcDetPar->setPropertyValue(
"ParFile", parFileName);
326 spCalcDetPar->execute();
329 auto const *pCalcDetPar =
dynamic_cast<FindDetectorsPar *
>(spCalcDetPar.get());
331 throw(std::bad_cast());
333 const std::vector<double> &azimuthal = pCalcDetPar->
getAzimuthal();
334 const std::vector<double> &polar = pCalcDetPar->getPolar();
335 const std::vector<double> &azimuthal_width = pCalcDetPar->getAzimWidth();
336 const std::vector<double> &polar_width = pCalcDetPar->getPolarWidth();
337 const std::vector<double> &secondary_flightpath = pCalcDetPar->getFlightPath();
340 nxFile.writeData(
"polar", polar);
343 nxFile.writeData(
"azimuthal", azimuthal);
346 nxFile.writeData(
"polar_width", polar_width);
347 nxFile.writeData(
"azimuthal_width", azimuthal_width);
350 nxFile.writeData(
"distance", secondary_flightpath);
368 const auto nHist =
static_cast<int64_t
>(inputWS->getNumberHistograms());
369 const auto &spectrumInfo = inputWS->spectrumInfo();
375 for (int64_t i = 0; i < nHist; ++i) {
376 if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i)) {
379 AllEnergies[nDet] =
pmap[UnitParams::efixed];
383 AllEnergies.resize(nDet);
387 if (std::all_of(AllEnergies.begin(), AllEnergies.end(), [&AllEnergies](
double energy) {
388 return std::abs(energy - AllEnergies[0]) < std::numeric_limits<float>::epsilon();
391 AllEnergies.resize(1);