/** 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 CentroidPeaksMD::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { if (nd != 3) throw std::invalid_argument("For now, we expect the input MDEventWorkspace " "to have 3 dimensions only."); /// Peak workspace to centroid Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace"); /// Output peaks workspace, create if needed Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace"); if (peakWS != inPeakWS) peakWS.reset(inPeakWS->clone().release()); std::string CoordinatesToUseStr = getPropertyValue("CoordinatesToUse"); int CoordinatesToUse = ws->getSpecialCoordinateSystem(); if (CoordinatesToUse == 1 && CoordinatesToUseStr != "Q (lab frame)") g_log.warning() << "Warning: used Q (lab frame) coordinates for MD " "workspace, not CoordinatesToUse from input " << std::endl; else if (CoordinatesToUse == 2 && CoordinatesToUseStr != "Q (sample frame)") g_log.warning() << "Warning: used Q (sample frame) coordinates for MD " "workspace, not CoordinatesToUse from input " << std::endl; else if (CoordinatesToUse == 3 && CoordinatesToUseStr != "HKL") g_log.warning() << "Warning: used HKL coordinates for MD workspace, not " "CoordinatesToUse from input " << std::endl; /// Radius to use around peaks double PeakRadius = getProperty("PeakRadius"); // cppcheck-suppress syntaxError PRAGMA_OMP(parallel for schedule(dynamic, 10) ) for (int i = 0; i < int(peakWS->getNumberPeaks()); ++i) { // Get a direct ref to that peak. IPeak &p = peakWS->getPeak(i); double detectorDistance = p.getL2(); // Get the peak center as a position in the dimensions of the workspace V3D pos; if (CoordinatesToUse == 1) //"Q (lab frame)" pos = p.getQLabFrame(); else if (CoordinatesToUse == 2) //"Q (sample frame)" pos = p.getQSampleFrame(); else if (CoordinatesToUse == 3) //"HKL" pos = p.getHKL(); // Build the sphere transformation bool dimensionsUsed[nd]; coord_t center[nd]; for (size_t d = 0; d < nd; ++d) { dimensionsUsed[d] = true; // Use all dimensions center[d] = static_cast<coord_t>(pos[d]); } CoordTransformDistance sphere(nd, center, dimensionsUsed); // Initialize the centroid to 0.0 signal_t signal = 0; coord_t centroid[nd]; for (size_t d = 0; d < nd; d++) centroid[d] = 0.0; // Perform centroid ws->getBox()->centroidSphere( sphere, static_cast<coord_t>(PeakRadius * PeakRadius), centroid, signal); // Normalize by signal if (signal != 0.0) { for (size_t d = 0; d < nd; d++) centroid[d] /= static_cast<coord_t>(signal); V3D vecCentroid(centroid[0], centroid[1], centroid[2]); // Save it back in the peak object, in the dimension specified. if (CoordinatesToUse == 1) //"Q (lab frame)" { p.setQLabFrame(vecCentroid, detectorDistance); p.findDetector(); } else if (CoordinatesToUse == 2) //"Q (sample frame)" { p.setQSampleFrame(vecCentroid, detectorDistance); p.findDetector(); } else if (CoordinatesToUse == 3) //"HKL" { p.setHKL(vecCentroid); } g_log.information() << "Peak " << i << " at " << pos << ": signal " << signal << ", centroid " << vecCentroid << " in " << CoordinatesToUse << std::endl; } else { g_log.information() << "Peak " << i << " at " << pos << " had no signal, and could not be centroided." << std::endl; } } // Save the output setProperty("OutputWorkspace", peakWS); }
void CentroidPeaksMD::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { if (nd != 3) throw std::invalid_argument("For now, we expect the input MDEventWorkspace to have 3 dimensions only."); /// Peak workspace to centroid Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("PeaksWorkspace"); /// Output peaks workspace, create if needed Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace"); if (peakWS != inPeakWS) peakWS = inPeakWS->clone(); /// Value of the CoordinatesToUse property. std::string CoordinatesToUse = getPropertyValue("CoordinatesToUse"); // TODO: Confirm that the coordinates requested match those in the MDEventWorkspace /// Radius to use around peaks double PeakRadius = getProperty("PeakRadius"); PRAGMA_OMP(parallel for schedule(dynamic, 10) ) for (int i=0; i < int(peakWS->getNumberPeaks()); ++i) { // Get a direct ref to that peak. IPeak & p = peakWS->getPeak(i); double detectorDistance = p.getL2(); // Get the peak center as a position in the dimensions of the workspace V3D pos; if (CoordinatesToUse == "Q (lab frame)") pos = p.getQLabFrame(); else if (CoordinatesToUse == "Q (sample frame)") pos = p.getQSampleFrame(); else if (CoordinatesToUse == "HKL") pos = p.getHKL(); // Build the sphere transformation bool dimensionsUsed[nd]; coord_t center[nd]; for (size_t d=0; d<nd; ++d) { dimensionsUsed[d] = true; // Use all dimensions center[d] = pos[d]; } CoordTransformDistance sphere(nd, center, dimensionsUsed); // Initialize the centroid to 0.0 signal_t signal = 0; coord_t centroid[nd]; for (size_t d=0; d<nd; d++) centroid[d] = 0.0; // Perform centroid ws->getBox()->centroidSphere(sphere, PeakRadius*PeakRadius, centroid, signal); // Normalize by signal if (signal != 0.0) { for (size_t d=0; d<nd; d++) centroid[d] /= signal; V3D vecCentroid(centroid[0], centroid[1], centroid[2]); // Save it back in the peak object, in the dimension specified. if (CoordinatesToUse == "Q (lab frame)") { p.setQLabFrame( vecCentroid, detectorDistance); p.findDetector(); } else if (CoordinatesToUse == "Q (sample frame)") { p.setQSampleFrame( vecCentroid, detectorDistance); p.findDetector(); } else if (CoordinatesToUse == "HKL") { p.setHKL( vecCentroid ); } g_log.information() << "Peak " << i << " at " << pos << ": signal " << signal << ", centroid " << vecCentroid << " in " << CoordinatesToUse << std::endl; } else { g_log.information() << "Peak " << i << " at " << pos << " had no signal, and could not be centroided." << std::endl; } } // Save the output setProperty("OutputWorkspace", peakWS); }