/** Carries out the binary operation IN-PLACE on a single EventList, * with another EventList as the right-hand operand. * * @param lhs :: Reference to the EventList that will be modified in place. * @param rhs :: Const reference to the EventList on the right hand side. */ void Divide::performEventBinaryOperation(DataObjects::EventList &lhs, const DataObjects::EventList &rhs) { // We must histogram the rhs event list to divide. MantidVec rhsY, rhsE; rhs.generateHistogram(rhs.constDataX(), rhsY, rhsE); lhs.divide(rhs.constDataX(), rhsY, rhsE); }
/** Carries out the binary operation IN-PLACE on a single EventList, * with another EventList as the right-hand operand. * * @param lhs :: Reference to the EventList that will be modified in place. * @param rhs :: Const reference to the EventList on the right hand side. */ void Multiply::performEventBinaryOperation(DataObjects::EventList &lhs, const DataObjects::EventList &rhs) { // We must histogram the rhs event list to multiply. MantidVec rhsY, rhsE; rhs.generateHistogram(rhs.x().rawData(), rhsY, rhsE); lhs.multiply(rhs.x().rawData(), rhsY, rhsE); }
/** Convert events to "fake" events as counts in outWS */ void CountEventsInPulses::convertEvents(DataObjects::EventWorkspace_sptr outWS, bool sumspectra) { // 1. Get run_start time std::string runstartstr = inpWS->run().getProperty("run_start")->value(); Kernel::DateAndTime runstart(runstartstr); int64_t runstarttime = runstart.totalNanoseconds(); // 2. Convert TOF and add to new event workspace double margin_sec = mPulseLength * 0.01; g_log.information() << "Pulse length = " << mPulseLength << " (sec). Margine = " << margin_sec << " For safe binning. " << std::endl; PARALLEL_FOR2(inpWS, outWS) for (int wsindex = 0; wsindex < static_cast<int>(inpWS->getNumberHistograms()); wsindex++) { DataObjects::EventList realevents = inpWS->getEventList(wsindex); DataObjects::EventList *fakeevents; if (sumspectra) { fakeevents = outWS->getEventListPtr(0); } else { fakeevents = outWS->getEventListPtr(wsindex); } size_t numevents = realevents.getNumberEvents(); for (size_t ie = 0; ie < numevents; ie++) { DataObjects::WeightedEvent event = realevents.getEvent(ie); // Swap TOF and pulse time and add to new event list // a) TOF (ms) -> Pulse Time double oldtof = event.tof(); int64_t oldtofns = int64_t(oldtof * 1000); Kernel::DateAndTime newpulsetime(oldtofns); // b) Pulse Time (ns) -> TOF (ms) -> second int64_t oldpulsetime = event.pulseTime().totalNanoseconds() - runstarttime; double newtofinsecond = double(oldpulsetime) * 1.0E-9 + margin_sec; DataObjects::TofEvent fakeevent(newtofinsecond, newpulsetime); fakeevents->addEventQuickly(fakeevent); } // ENDFOR events } // END FOR: Per Spectrum g_log.debug() << "DBx505 Input Events = " << inpWS->getNumberEvents() << "; Output Events = " << outWS->getNumberEvents() << std::endl; return; }
/** Carries out the binary operation IN-PLACE on a single EventList, * with another (histogrammed) spectrum as the right-hand operand. * * @param lhs :: Reference to the EventList that will be modified in place. * @param rhsX :: The vector of rhs X bin boundaries * @param rhsY :: The vector of rhs data values * @param rhsE :: The vector of rhs error values */ void Divide::performEventBinaryOperation(DataObjects::EventList &lhs, const MantidVec &rhsX, const MantidVec &rhsY, const MantidVec &rhsE) { // Divide is implemented at the EventList level. lhs.divide(rhsX, rhsY, rhsE); }
/** Carries out the binary operation IN-PLACE on a single EventList, * with another (histogrammed) spectrum as the right-hand operand. * * @param lhs :: Reference to the EventList that will be modified in place. * @param rhsX :: The vector of rhs X bin boundaries * @param rhsY :: The vector of rhs data values * @param rhsE :: The vector of rhs error values */ void Multiply::performEventBinaryOperation(DataObjects::EventList &lhs, const MantidVec &rhsX, const MantidVec &rhsY, const MantidVec &rhsE) { // Multiply is implemented at the EventList level. lhs.multiply(rhsX, rhsY, rhsE); }
/** Carries out the binary operation IN-PLACE on a single EventList, * with a single (double) value as the right-hand operand. * Performs the multiplication by a scalar (with error) * * @param lhs :: Reference to the EventList that will be modified in place. * @param rhsY :: The rhs data value * @param rhsE :: The rhs error value */ void Divide::performEventBinaryOperation(DataObjects::EventList &lhs, const double &rhsY, const double &rhsE) { // Multiply is implemented at the EventList level. lhs.divide(rhsY, rhsE); }
/** Set up corrections with customized TOF correction input * The first column must be either DetectorID or Spectrum (from 0... as * workspace index) * The second column must be Correction or CorrectFactor, a number between 0 * and 1, i.e, [0, 1] * The third column is optional as shift in unit of second */ void FilterEvents::setupCustomizedTOFCorrection() { // Check input workspace vector<string> colnames = m_detCorrectWorkspace->getColumnNames(); bool hasshift = false; if (colnames.size() < 2) throw runtime_error("Input table workspace is not valide."); else if (colnames.size() >= 3) hasshift = true; bool usedetid; if (colnames[0].compare("DetectorID") == 0) usedetid = true; else if (colnames[0].compare("Spectrum") == 0) usedetid = false; else { usedetid = false; stringstream errss; errss << "First column must be either DetectorID or Spectrum. " << colnames[0] << " is not supported. "; throw runtime_error(errss.str()); } // Parse detector and its TOF correction (i.e., offset factor and tof shift) // to a map map<detid_t, double> toffactormap; map<detid_t, double> tofshiftmap; size_t numrows = m_detCorrectWorkspace->rowCount(); for (size_t i = 0; i < numrows; ++i) { TableRow row = m_detCorrectWorkspace->getRow(i); // Parse to map detid_t detid; double offset_factor; row >> detid >> offset_factor; if (offset_factor >= 0 && offset_factor <= 1) { // Valid offset (factor value) toffactormap.emplace(detid, offset_factor); } else { // Error, throw! stringstream errss; errss << "Correction (i.e., offset) equal to " << offset_factor << " of row " << "is out of range [0, 1]."; throw runtime_error(errss.str()); } // Shift if (hasshift) { double shift; row >> shift; tofshiftmap.emplace(detid, shift); } } // ENDFOR(row i) // Check size of TOF correction map size_t numhist = m_eventWS->getNumberHistograms(); if (toffactormap.size() > numhist) { g_log.warning() << "Input correction table workspace has more detectors (" << toffactormap.size() << ") than input workspace " << m_eventWS->name() << "'s spectra number (" << numhist << ".\n"; } else if (toffactormap.size() < numhist) { stringstream errss; errss << "Input correction table workspace has more detectors (" << toffactormap.size() << ") than input workspace " << m_eventWS->name() << "'s spectra number (" << numhist << ".\n"; throw runtime_error(errss.str()); } // Apply to m_detTofOffsets and m_detTofShifts if (usedetid) { // Get vector IDs vector<detid_t> vecDetIDs(numhist, 0); // Set up the detector IDs to vecDetIDs and set up the initial value for (size_t i = 0; i < numhist; ++i) { // It is assumed that there is one detector per spectra. // If there are more than 1 spectrum, it is very likely to have problem // with correction factor const DataObjects::EventList events = m_eventWS->getEventList(i); auto detids = events.getDetectorIDs(); if (detids.size() != 1) { // Check whether there are more than 1 detector per spectra. stringstream errss; errss << "The assumption is that one spectrum has one and only one " "detector. " << "Error is found at spectrum " << i << ". It has " << detids.size() << " detectors."; throw runtime_error(errss.str()); } vecDetIDs[i] = *detids.begin(); } // Map correction map to list map<detid_t, double>::iterator fiter; for (size_t i = 0; i < numhist; ++i) { detid_t detid = vecDetIDs[i]; // correction (factor) map fiter = toffactormap.find(detid); if (fiter != toffactormap.end()) m_detTofFactors[i] = fiter->second; else { stringstream errss; errss << "Detector " << "w/ ID << " << detid << " of spectrum " << i << " in Eventworkspace " << m_eventWS->name() << " cannot be found in input TOF calibration workspace. "; throw runtime_error(errss.str()); } // correction shift map fiter = tofshiftmap.find(detid); if (fiter != tofshiftmap.end()) m_detTofOffsets[i] = fiter->second; } // ENDFOR (each spectrum i) } else { // It is spectrum Number already map<detid_t, double>::iterator fiter; // correction factor for (fiter = toffactormap.begin(); fiter != toffactormap.end(); ++fiter) { size_t wsindex = static_cast<size_t>(fiter->first); if (wsindex < numhist) m_detTofFactors[wsindex] = fiter->second; else { stringstream errss; errss << "Workspace index " << wsindex << " is out of range."; throw runtime_error(errss.str()); } } // correction shift for (fiter = tofshiftmap.begin(); fiter != tofshiftmap.end(); ++fiter) { size_t wsindex = static_cast<size_t>(fiter->first); if (wsindex < numhist) m_detTofOffsets[wsindex] = fiter->second; else { stringstream errss; errss << "Workspace index " << wsindex << " is out of range."; throw runtime_error(errss.str()); } } } return; }
/** Write out an event list into an already-opened group * @param el :: reference to the EventList to write. * @param group_name :: group_name to create. * */ int NexusFileIO::writeEventList( const DataObjects::EventList & el, std::string group_name) const { //write data entry NXstatus status=NXmakegroup(fileID, group_name.c_str(), "NXdata"); if(status==NX_ERROR) return(2); NXopengroup(fileID, group_name.c_str(), "NXdata"); // Copy the detector IDs to an array. const std::set<detid_t>& dets = el.getDetectorIDs(); // Write out the detector IDs if (!dets.empty()) { std::vector<detid_t> detectorIDs(dets.begin(),dets.end()); int dims_array[1]; NXwritedata("detector_IDs", NX_INT64, 1, dims_array, (void*)(detectorIDs.data()), false ); } std::string eventType("UNKNOWN"); size_t num = el.getNumberEvents(); switch (el.getEventType()) { case TOF: eventType = "TOF"; writeEventListData( el.getEvents(), true, true, false, false ); break; case WEIGHTED: eventType = "WEIGHTED"; writeEventListData( el.getWeightedEvents(), true, true, true, true ); break; case WEIGHTED_NOTIME: eventType = "WEIGHTED_NOTIME"; writeEventListData( el.getWeightedEventsNoTime(), true, false, true, true ); break; } // --- Save the type of sorting ----- std::string sortType; switch (el.getSortType()) { case TOF_SORT: sortType = "TOF_SORT"; break; case PULSETIME_SORT: sortType = "PULSETIME_SORT"; break; case UNSORTED: default: sortType = "UNSORTED"; break; } NXputattr (fileID, "sort_type", reinterpret_cast<void*>(const_cast<char*>(sortType.c_str())), static_cast<int>(sortType.size()), NX_CHAR); // Save an attribute with the type of each event. NXputattr (fileID, "event_type", reinterpret_cast<void*>(const_cast<char*>(eventType.c_str())), static_cast<int>(eventType.size()), NX_CHAR); // Save an attribute with the number of events NXputattr (fileID, "num_events", (void*)(&num), 1, NX_INT64); // Close it up! status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }