size_t ConvToMDEventsWS::convertEventList(size_t workspaceIndex) { const Mantid::DataObjects::EventList &el = m_EventWS->getSpectrum(workspaceIndex); size_t numEvents = el.getNumberEvents(); if (numEvents == 0) return 0; // create local unit conversion class UnitsConversionHelper localUnitConv(m_UnitConversion); uint32_t detID = m_detID[workspaceIndex]; uint16_t runIndexLoc = m_RunIndex; std::vector<coord_t> locCoord(m_Coord); // set up unit conversion and calculate up all coordinates, which depend on // spectra index only if (!m_QConverter->calcYDepCoordinates(locCoord, workspaceIndex)) return 0; // skip if any y outsize of the range of interest; localUnitConv.updateConversion(workspaceIndex); // // allocate temporary buffers for MD Events data // MD events coordinates buffer std::vector<coord_t> allCoord; std::vector<float> sig_err; // array for signal and error. std::vector<uint16_t> run_index; // Buffer for run index for each event std::vector<uint32_t> det_ids; // Buffer of det Id-s for each event allCoord.reserve(this->m_NDims * numEvents); sig_err.reserve(2 * numEvents); run_index.reserve(numEvents); det_ids.reserve(numEvents); // This little dance makes the getting vector of events more general (since // you can't overload by return type). typename std::vector<T> const *events_ptr; getEventsFrom(el, events_ptr); const typename std::vector<T> &events = *events_ptr; // Iterators to start/end for (auto it = events.cbegin(); it != events.cend(); it++) { double val = localUnitConv.convertUnits(it->tof()); double signal = it->weight(); double errorSq = it->errorSquared(); if (!m_QConverter->calcMatrixCoord(val, locCoord, signal, errorSq)) continue; // skip ND outside the range sig_err.push_back(static_cast<float>(signal)); sig_err.push_back(static_cast<float>(errorSq)); run_index.push_back(runIndexLoc); det_ids.push_back(detID); allCoord.insert(allCoord.end(), locCoord.begin(), locCoord.end()); } // Add them to the MDEW size_t n_added_events = run_index.size(); m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, n_added_events); return n_added_events; }
/** convert range of spectra starting from initial spectra startSpectra into MD *events *@param startSpectra -- initial spectra number to begin conversion from * * @returns -- number of events added to the workspace. */ size_t ConvToMDHistoWS::conversionChunk(size_t startSpectra) { size_t nAddedEvents(0), nBufEvents(0); // cache global variable locally bool ignoreZeros(m_ignoreZeros); const size_t specSize = this->m_InWS2D->blocksize(); // preprocessed detectors associate each spectra with a detector (position) size_t nValidSpectra = m_NSpectra; // create local unit conversion class UnitsConversionHelper localUnitConv(m_UnitConversion); // local coordinatres initiated by the global coordinates which do not depend // on detector std::vector<coord_t> locCoord(m_Coord); // allocate temporary buffer for MD Events data std::vector<float> sig_err(2 * m_bufferSize); // array for signal and error. std::vector<uint16_t> run_index( m_bufferSize); // Buffer run index for each event std::vector<uint32_t> det_ids( m_bufferSize); // Buffer of det Id-s for each event std::vector<coord_t> allCoord(m_NDims * m_bufferSize); // MD events coordinates buffer size_t n_coordinates = 0; size_t nSpectraToProcess = startSpectra + m_spectraChunk; if (nSpectraToProcess > nValidSpectra) nSpectraToProcess = nValidSpectra; // External loop over the spectra: for (size_t i = startSpectra; i < nSpectraToProcess; ++i) { size_t iSpctr = m_detIDMap[i]; int32_t det_id = m_detID[i]; const MantidVec &X = m_InWS2D->readX(iSpctr); const MantidVec &Signal = m_InWS2D->readY(iSpctr); const MantidVec &Error = m_InWS2D->readE(iSpctr); // calculate the coordinates which depend on detector posision if (!m_QConverter->calcYDepCoordinates(locCoord, i)) continue; // skip y outside of the range; bool histogram(true); if (X.size() == Signal.size()) histogram = false; // convert units localUnitConv.updateConversion(i); std::vector<double> XtargetUnits; XtargetUnits.resize(X.size()); if (histogram) { double xm1 = localUnitConv.convertUnits(X[0]); for (size_t j = 1; j < XtargetUnits.size(); j++) { double xm = localUnitConv.convertUnits(X[j]); XtargetUnits[j - 1] = 0.5 * (xm + xm1); xm1 = xm; } XtargetUnits[XtargetUnits.size() - 1] = xm1; // just in case, should not be used } else for (size_t j = 0; j < XtargetUnits.size(); j++) XtargetUnits[j] = localUnitConv.convertUnits(X[j]); //=> START INTERNAL LOOP OVER THE "TIME" for (size_t j = 0; j < specSize; ++j) { double signal = Signal[j]; // drop NaN events if (isNaN(signal)) continue; // drop 0 -value signals if necessary. if (ignoreZeros && (signal == 0.)) continue; double errorSq = Error[j] * Error[j]; if (!m_QConverter->calcMatrixCoord(XtargetUnits[j], locCoord, signal, errorSq)) continue; // skip ND outside the range // ADD RESULTING EVENTS TO THE BUFFER // coppy all data into data buffer for future transformation into events; sig_err[2 * nBufEvents + 0] = float(signal); sig_err[2 * nBufEvents + 1] = float(errorSq); run_index[nBufEvents] = m_RunIndex; det_ids[nBufEvents] = det_id; for (size_t ii = 0; ii < m_NDims; ii++) allCoord[n_coordinates++] = locCoord[ii]; // calculate number of events nBufEvents++; if (nBufEvents >= m_bufferSize) { m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, nBufEvents); nAddedEvents += nBufEvents; // reset buffer counts n_coordinates = 0; nBufEvents = 0; } } // end spectra loop } // end detectors loop; if (nBufEvents > 0) { m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord, nBufEvents); nAddedEvents += nBufEvents; nBufEvents = 0; } return nAddedEvents; }