void UnwrapSNS::execEvent() { // set up the output workspace MatrixWorkspace_sptr matrixOutW = this->getProperty("OutputWorkspace"); if (matrixOutW != m_inputWS) { matrixOutW = m_inputWS->clone(); setProperty("OutputWorkspace", matrixOutW); } auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW); // set up the progress bar m_progress = new Progress(this, 0.0, 1.0, m_numberOfSpectra * 2); // algorithm assumes the data is sorted so it can jump out early outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress); this->getTofRangeData(true); // without the primary flight path the algorithm cannot work const auto &spectrumInfo = m_inputWS->spectrumInfo(); const double L1 = spectrumInfo.l1(); // do the actual work for (int workspaceIndex = 0; workspaceIndex < m_numberOfSpectra; workspaceIndex++) { std::size_t numEvents = outW->getSpectrum(workspaceIndex).getNumberEvents(); double Ld = -1.0; if (spectrumInfo.hasDetectors(workspaceIndex)) Ld = L1 + spectrumInfo.l2(workspaceIndex); std::vector<double> time_bins; if (outW->x(0).size() > 2) { this->unwrapX(m_inputWS->x(workspaceIndex), time_bins, Ld); outW->setBinEdges(workspaceIndex, std::move(time_bins)); } else { outW->setSharedX(workspaceIndex, m_inputWS->sharedX(workspaceIndex)); } if (numEvents > 0) { std::vector<double> times(numEvents); outW->getSpectrum(workspaceIndex).getTofs(times); double filterVal = m_Tmin * Ld / m_LRef; for (size_t j = 0; j < numEvents; j++) { if (times[j] < filterVal) times[j] += m_frameWidth; else break; // stop filtering } outW->getSpectrum(workspaceIndex).setTofs(times); } m_progress->report(); } outW->clearMRU(); this->runMaskDetectors(); }
void UnwrapSNS::execEvent() { // set up the output workspace MatrixWorkspace_sptr matrixOutW = this->getProperty("OutputWorkspace"); if (matrixOutW != m_inputWS) { matrixOutW = m_inputWS->clone(); setProperty("OutputWorkspace", matrixOutW); } auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW); // set up the progress bar m_progress = new Progress(this, 0.0, 1.0, m_numberOfSpectra * 2); // algorithm assumes the data is sorted so it can jump out early outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress); this->getTofRangeData(true); // do the actual work // PARALLEL_FOR2(m_inputWS, outW) for (int workspaceIndex = 0; workspaceIndex < m_numberOfSpectra; workspaceIndex++) { // PARALLEL_START_INTERUPT_REGION std::size_t numEvents = outW->getSpectrum(workspaceIndex).getNumberEvents(); bool isMonitor; double Ld = this->calculateFlightpath(workspaceIndex, isMonitor); MantidVec time_bins; if (outW->dataX(0).size() > 2) { this->unwrapX(m_inputWS->dataX(workspaceIndex), time_bins, Ld); outW->setX(workspaceIndex, time_bins); } else { outW->setX(workspaceIndex, m_inputWS->dataX(workspaceIndex)); } if (numEvents > 0) { MantidVec times(numEvents); outW->getSpectrum(workspaceIndex).getTofs(times); double filterVal = m_Tmin * Ld / m_LRef; for (size_t j = 0; j < numEvents; j++) { if (times[j] < filterVal) times[j] += m_frameWidth; else break; // stop filtering } outW->getSpectrum(workspaceIndex).setTofs(times); } m_progress->report(); // PARALLEL_END_INTERUPT_REGION } // PARALLEL_CHECK_INTERUPT_REGION outW->clearMRU(); this->runMaskDetectors(); }
/** Remove low resolution TOF from an EventWorkspace */ void RemoveLowResTOF::execEvent(const SpectrumInfo &spectrumInfo) { // set up the output workspace MatrixWorkspace_sptr matrixOutW = getProperty("OutputWorkspace"); auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW); MatrixWorkspace_sptr matrixLowResW = getProperty("LowResTOFWorkspace"); if (m_outputLowResTOF) { matrixLowResW = m_inputWS->clone(); setProperty("LowResTOFWorkspace", matrixLowResW); } auto lowW = boost::dynamic_pointer_cast<EventWorkspace>(matrixLowResW); g_log.debug() << "TOF range was " << m_inputEvWS->getTofMin() << " to " << m_inputEvWS->getTofMax() << " microseconds\n"; std::size_t numEventsOrig = outW->getNumberEvents(); // set up the progress bar m_progress = make_unique<Progress>(this, 0.0, 1.0, m_numberOfSpectra * 2); // algorithm assumes the data is sorted so it can jump out early outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress.get()); this->getTminData(true); size_t numClearedEventLists = 0; size_t numClearedEvents = 0; // do the actual work for (size_t workspaceIndex = 0; workspaceIndex < m_numberOfSpectra; workspaceIndex++) { if (outW->getSpectrum(workspaceIndex).getNumberEvents() > 0) { double tmin = this->calcTofMin(workspaceIndex, spectrumInfo); if (tmin != tmin) { // Problematic g_log.warning() << "tmin for workspaceIndex " << workspaceIndex << " is nan. Clearing out data. " << "There are " << outW->getSpectrum(workspaceIndex).getNumberEvents() << " of it. \n"; numClearedEventLists += 1; numClearedEvents += outW->getSpectrum(workspaceIndex).getNumberEvents(); outW->getSpectrum(workspaceIndex).clear(false); if (m_outputLowResTOF) lowW->getSpectrum(workspaceIndex).clear(false); } else if (tmin > 0.) { // there might be events between 0 and tmin (i.e., low resolution) outW->getSpectrum(workspaceIndex).maskTof(0., tmin); if (outW->getSpectrum(workspaceIndex).getNumberEvents() == 0) numClearedEventLists += 1; if (m_outputLowResTOF) { double tmax = lowW->getSpectrum(workspaceIndex).getTofMax(); if (tmax != tmax) { g_log.warning() << "tmax for workspaceIndex " << workspaceIndex << " is nan. Clearing out data. \n"; lowW->getSpectrum(workspaceIndex).clear(false); } else { // There is possibility that tmin calculated is larger than TOF-MAX // of the spectrum if (tmax + DBL_MIN > tmin) lowW->getSpectrum(workspaceIndex).maskTof(tmin, tmax + DBL_MIN); } } } else { // do nothing if tmin <= 0. for outW if (m_outputLowResTOF) { // tmin = 0. no event will be in low resolution lowW->getSpectrum(workspaceIndex).clear(false); } } // } } g_log.information() << "Went from " << numEventsOrig << " events to " << outW->getNumberEvents() << " events (" << (static_cast<double>(numEventsOrig - outW->getNumberEvents()) * 100. / static_cast<double>(numEventsOrig)) << "% removed)\n"; if (numClearedEventLists > 0) g_log.warning() << numClearedEventLists << " spectra of " << m_numberOfSpectra << " had all data removed. The number of removed events is " << numClearedEvents << ".\n"; g_log.debug() << "TOF range is now " << outW->getTofMin() << " to " << outW->getTofMax() << " microseconds\n"; outW->clearMRU(); }
void CorrectKiKf::execEvent() { g_log.information("Processing event workspace"); const MatrixWorkspace_const_sptr matrixInputWS = getProperty("InputWorkspace"); auto inputWS = boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS); // generate the output workspace pointer API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace"); if (matrixOutputWS != matrixInputWS) { matrixOutputWS = matrixInputWS->clone(); setProperty("OutputWorkspace", matrixOutputWS); } auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS); const std::string emodeStr = getProperty("EMode"); double efixedProp = getProperty("EFixed"), efixed; if (efixedProp == EMPTY_DBL()) { if (emodeStr == "Direct") { // Check if it has been store on the run object for this workspace if (inputWS->run().hasProperty("Ei")) { Kernel::Property *eiprop = inputWS->run().getProperty("Ei"); efixedProp = boost::lexical_cast<double>(eiprop->value()); g_log.debug() << "Using stored Ei value " << efixedProp << "\n"; } else { throw std::invalid_argument( "No Ei value has been set or stored within the run information."); } } else { // If not specified, will try to get Ef from the parameter file for // indirect geometry, // but it will be done for each spectrum separately, in case of different // analyzer crystals } } // Get the parameter map const ParameterMap &pmap = outputWS->constInstrumentParameters(); int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms()); API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms); PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS)) for (int64_t i = 0; i < numHistograms; ++i) { PARALLEL_START_INTERUPT_REGION double Efi = 0; // Now get the detector object for this histogram to check if monitor // or to get Ef for indirect geometry if (emodeStr == "Indirect") { if (efixedProp != EMPTY_DBL()) Efi = efixedProp; else try { IDetector_const_sptr det = inputWS->getDetector(i); if (!det->isMonitor()) { try { Parameter_sptr par = pmap.getRecursive(det.get(), "Efixed"); if (par) { Efi = par->value<double>(); g_log.debug() << "Detector: " << det->getID() << " EFixed: " << Efi << "\n"; } } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use single provided value */ } } } catch (std::runtime_error &) { g_log.information() << "Workspace Index " << i << ": cannot find detector" << "\n"; } } if (emodeStr == "Indirect") efixed = Efi; else efixed = efixedProp; // Do the correction auto &evlist = outputWS->getSpectrum(i); switch (evlist.getEventType()) { case TOF: // Switch to weights if needed. evlist.switchTo(WEIGHTED); /* no break */ // Fall through case WEIGHTED: correctKiKfEventHelper(evlist.getWeightedEvents(), efixed, emodeStr); break; case WEIGHTED_NOTIME: correctKiKfEventHelper(evlist.getWeightedEventsNoTime(), efixed, emodeStr); break; } prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->clearMRU(); if (inputWS->getNumberEvents() != outputWS->getNumberEvents()) { g_log.information() << "Ef <= 0 or Ei <= 0 for " << inputWS->getNumberEvents() - outputWS->getNumberEvents() << " events, out of " << inputWS->getNumberEvents() << '\n'; if (efixedProp == EMPTY_DBL()) g_log.information() << "Try to set fixed energy\n"; } }
void ModeratorTzero::execEvent(const std::string &emode) { g_log.information("Processing event workspace"); const MatrixWorkspace_const_sptr matrixInputWS = getProperty("InputWorkspace"); // generate the output workspace pointer API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace"); if (matrixOutputWS != matrixInputWS) { matrixOutputWS = matrixInputWS->clone(); setProperty("OutputWorkspace", matrixOutputWS); } auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS); // calculate tof shift once for all neutrons if emode==Direct double t0_direct(-1); if (emode == "Direct") { Kernel::Property *eiprop = outputWS->run().getProperty("Ei"); double Ei = boost::lexical_cast<double>(eiprop->value()); mu::Parser parser; parser.DefineVar("incidentEnergy", &Ei); // associate E1 to this parser parser.SetExpr(m_formula); t0_direct = parser.Eval(); } const auto &spectrumInfo = outputWS->spectrumInfo(); const double Lss = spectrumInfo.l1(); // Loop over the spectra const size_t numHists = static_cast<size_t>(outputWS->getNumberHistograms()); Progress prog(this, 0.0, 1.0, numHists); // report progress of algorithm PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS)) for (int i = 0; i < static_cast<int>(numHists); ++i) { PARALLEL_START_INTERUPT_REGION size_t wsIndex = static_cast<size_t>(i); EventList &evlist = outputWS->getSpectrum(wsIndex); if (evlist.getNumberEvents() > 0) // don't bother with empty lists { double L1(Lss); // distance from source to sample double L2(-1); // distance from sample to detector if (spectrumInfo.hasDetectors(i)) { if (spectrumInfo.isMonitor(i)) { // redefine the sample as the monitor L1 = Lss + spectrumInfo.l2(i); // L2 in SpectrumInfo defined negative L2 = 0; } else { L2 = spectrumInfo.l2(i); } } else { g_log.error() << "Unable to calculate distances to/from detector" << i << '\n'; } if (L2 >= 0) { // One parser for each parallel processor needed (except Edirect mode) double E1; mu::Parser parser; parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser parser.SetExpr(m_formula); // fast neutrons are shifted by min_t0_next, irrespective of tof double v1_max = L1 / m_t1min; E1 = m_convfactor * v1_max * v1_max; double min_t0_next = parser.Eval(); if (emode == "Indirect") { double t2(-1.0); // time from sample to detector. (-1) signals error if (spectrumInfo.isMonitor(i)) { t2 = 0.0; } else { static const double convFact = 1.0e-6 * sqrt(2 * PhysicalConstants::meV / PhysicalConstants::NeutronMass); std::vector<double> wsProp = spectrumInfo.detector(i).getNumberParameter("Efixed"); if (!wsProp.empty()) { double E2 = wsProp.at(0); //[E2]=meV double v2 = convFact * sqrt(E2); //[v2]=meter/microsec t2 = L2 / v2; } else { // t2 is kept to -1 if no Efixed is found g_log.debug() << "Efixed not found for detector " << i << '\n'; } } if (t2 >= 0) // t2 < 0 when no detector info is available { // fix the histogram bins auto &x = evlist.mutableX(); for (double &tof : x) { if (tof < m_t1min + t2) tof -= min_t0_next; else tof -= CalculateT0indirect(tof, L1, t2, E1, parser); } MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { if (tof < m_t1min + t2) tof -= min_t0_next; else tof -= CalculateT0indirect(tof, L1, t2, E1, parser); } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); } // end of if( t2>= 0) } // end of if(emode=="Indirect") else if (emode == "Elastic") { // Apply t0 correction to histogram bins auto &x = evlist.mutableX(); for (double &tof : x) { if (tof < m_t1min * (L1 + L2) / L1) tof -= min_t0_next; else tof -= CalculateT0elastic(tof, L1 + L2, E1, parser); } MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { // add a [-0.1,0.1] microsecond noise to avoid artifacts // resulting from original tof data if (tof < m_t1min * (L1 + L2) / L1) tof -= min_t0_next; else tof -= CalculateT0elastic(tof, L1 + L2, E1, parser); } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); } // end of else if(emode=="Elastic") else if (emode == "Direct") { // fix the histogram bins evlist.mutableX() -= t0_direct; MantidVec tofs = evlist.getTofs(); for (double &tof : tofs) { tof -= t0_direct; } evlist.setTofs(tofs); evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED); } // end of else if(emode=="Direct") } // end of if(L2 >= 0) } // end of if (evlist.getNumberEvents() > 0) prog.report(); PARALLEL_END_INTERUPT_REGION } // end of for (int i = 0; i < static_cast<int>(numHists); ++i) PARALLEL_CHECK_INTERUPT_REGION outputWS->clearMRU(); // Clears the Most Recent Used lists */ } // end of void ModeratorTzero::execEvent()