/** Integrate the peaks of the workspace using parameters saved in the algorithm * class */ void CentroidPeaks::integrateEvent() { /// Peak workspace to centroid Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("InPeaksWorkspace"); /// Output peaks workspace, create if needed Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutPeaksWorkspace"); if (peakWS != inPeakWS) peakWS = inPeakWS->clone(); /// Radius to use around peaks int PeakRadius = getProperty("PeakRadius"); int MinPeaks = -1; int MaxPeaks = -1; size_t Numberwi = inWS->getNumberHistograms(); int NumberPeaks = peakWS->getNumberPeaks(); for (int i = 0; i < NumberPeaks; ++i) { auto &peak = peakWS->getPeak(i); int pixelID = peak.getDetectorID(); // Find the workspace index for this detector ID if (wi_to_detid_map.find(pixelID) != wi_to_detid_map.end()) { size_t wi = wi_to_detid_map[pixelID]; if (MinPeaks == -1 && peak.getRunNumber() == inWS->getRunNumber() && wi < Numberwi) MinPeaks = i; if (peak.getRunNumber() == inWS->getRunNumber() && wi < Numberwi) MaxPeaks = i; } } int Edge = getProperty("EdgePixels"); Progress prog(this, MinPeaks, 1.0, MaxPeaks); PARALLEL_FOR_IF(Kernel::threadSafe(*inWS, *peakWS)) for (int i = MinPeaks; i <= MaxPeaks; ++i) { PARALLEL_START_INTERUPT_REGION // Get a direct ref to that peak. auto &peak = peakWS->getPeak(i); int col = peak.getCol(); int row = peak.getRow(); double TOFPeakd = peak.getTOF(); std::string bankName = peak.getBankName(); int nCols = 0, nRows = 0; sizeBanks(bankName, nCols, nRows); double intensity = 0.0; double tofcentroid = 0.0; if (edgePixel(inst, bankName, col, row, Edge)) continue; double tofstart = TOFPeakd * std::pow(1.004, -PeakRadius); double tofend = TOFPeakd * std::pow(1.004, PeakRadius); double rowcentroid = 0.0; int rowstart = std::max(0, row - PeakRadius); int rowend = std::min(nRows - 1, row + PeakRadius); double colcentroid = 0.0; int colstart = std::max(0, col - PeakRadius); int colend = std::min(nCols - 1, col + PeakRadius); for (int irow = rowstart; irow <= rowend; ++irow) { for (int icol = colstart; icol <= colend; ++icol) { if (edgePixel(inst, bankName, icol, irow, Edge)) continue; auto it1 = wi_to_detid_map.find(findPixelID(bankName, icol, irow)); size_t workspaceIndex = (it1->second); EventList el = eventW->getSpectrum(workspaceIndex); el.switchTo(WEIGHTED_NOTIME); std::vector<WeightedEventNoTime> events = el.getWeightedEventsNoTime(); // Check for events in tof range for (const auto &event : events) { double tof = event.tof(); if (tof > tofstart && tof < tofend) { double weight = event.weight(); intensity += weight; rowcentroid += irow * weight; colcentroid += icol * weight; tofcentroid += tof * weight; } } } } // Set pixelID to change row and col row = int(rowcentroid / intensity); boost::algorithm::clamp(row, 0, nRows - 1); col = int(colcentroid / intensity); boost::algorithm::clamp(col, 0, nCols - 1); if (!edgePixel(inst, bankName, col, row, Edge)) { peak.setDetectorID(findPixelID(bankName, col, row)); // Set wavelength to change tof for peak object double tof = tofcentroid / intensity; Mantid::Kernel::Units::Wavelength wl; std::vector<double> timeflight; timeflight.push_back(tof); double scattering = peak.getScattering(); double L1 = peak.getL1(); double L2 = peak.getL2(); wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0); const double lambda = timeflight[0]; timeflight.clear(); peak.setWavelength(lambda); peak.setBinCount(intensity); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION removeEdgePeaks(*peakWS); // Save the output setProperty("OutPeaksWorkspace", peakWS); }
void AnvredCorrection::execEvent() { const int64_t numHists = static_cast<int64_t>(m_inputWS->getNumberHistograms()); std::string unitStr = m_inputWS->getAxis(0)->unit()->unitID(); //Create a new outputworkspace with not much in it DataObjects::EventWorkspace_sptr correctionFactors; correctionFactors = boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create("EventWorkspace",numHists,2,1) ); correctionFactors->sortAll(TOF_SORT, NULL); //Copy required stuff from it API::WorkspaceFactory::Instance().initializeFromParent(m_inputWS, correctionFactors, true); bool inPlace = (this->getPropertyValue("InputWorkspace") == this->getPropertyValue("OutputWorkspace")); if (inPlace) g_log.debug("Correcting EventWorkspace in-place."); // If sample not at origin, shift cached positions. const V3D samplePos = m_inputWS->getInstrument()->getSample()->getPos(); const V3D pos = m_inputWS->getInstrument()->getSource()->getPos()-samplePos; double L1 = pos.norm(); Progress prog(this,0.0,1.0,numHists); // Loop over the spectra PARALLEL_FOR2(eventW,correctionFactors) for (int64_t i = 0; i < int64_t(numHists); ++i) { PARALLEL_START_INTERUPT_REGION // Copy over bin boundaries const MantidVec& X = eventW->readX(i); correctionFactors->dataX(i) = X; // Get detector position IDetector_const_sptr det; try { det = eventW->getDetector(i); } catch (Exception::NotFoundError&) { // Catch if no detector. Next line tests whether this happened - test placed // outside here because Mac Intel compiler doesn't like 'continue' in a catch // in an openmp block. } // If no detector found, skip onto the next spectrum if ( !det ) continue; // This is the scattered beam direction Instrument_const_sptr inst = eventW->getInstrument(); V3D dir = det->getPos() - samplePos; double L2 = dir.norm(); // Two-theta = polar angle = scattering angle = between +Z vector and the scattered beam double scattering = dir.angle( V3D(0.0, 0.0, 1.0) ); EventList el = eventW->getEventList(i); el.switchTo(WEIGHTED_NOTIME); std::vector<WeightedEventNoTime> events = el.getWeightedEventsNoTime(); std::vector<WeightedEventNoTime>::iterator itev; std::vector<WeightedEventNoTime>::iterator itev_end = events.end(); Mantid::Kernel::Units::Wavelength wl; std::vector<double> timeflight; // multiplying an event list by a scalar value for (itev = events.begin(); itev != itev_end; itev++) { timeflight.push_back(itev->tof()); if (unitStr.compare("TOF") == 0) wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0); double value = this->getEventWeight(timeflight[0], scattering); timeflight.clear(); itev->m_errorSquared = static_cast<float>(itev->m_errorSquared * value*value); itev->m_weight *= static_cast<float>(value); } correctionFactors->getOrAddEventList(i) +=events; std::set<detid_t>& dets = eventW->getEventList(i).getDetectorIDs(); std::set<detid_t>::iterator j; for (j = dets.begin(); j != dets.end(); ++j) correctionFactors->getOrAddEventList(i).addDetectorID(*j); // When focussing in place, you can clear out old memory from the input one! if (inPlace) { eventW->getEventList(i).clear(); Mantid::API::MemoryManager::Instance().releaseFreeMemory(); } prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION correctionFactors->doneAddingEventLists(); setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(correctionFactors)); // Now do some cleaning-up since destructor may not be called immediately this->cleanup(); }