double MahalanobisDistance::operator()(const Peak& A, const Peak& B, double drt, double dmz, double dz=0., double dint=0.) { if(drt <= 0 || dmz <= 0){ MSPP_LOG(logERROR) << "MahalanobisDistance::operator(): drt and dmz have to be positive." << std::endl; } mspp_precondition(drt > 0. && dmz > 0. , "MahalanobisDistance::operator(): drt and dmz have to be positive."); if(A.getAbundance() < dint || B.getAbundance() < dint){ // low abundance peak --> high distance return DBL_MAX; } if(dz == 0.){ // only calculate distance if peaks have same charge if(A.getCharge() != B.getCharge()){ // charge differs and dz == 0: max. distance return DBL_MAX; }else{ // charge equal: normal distance double rt = (A.getRt()-B.getRt()); double mz = (A.getMz()-B.getMz()); return sqrt(rt*rt/(drt*drt) + mz*mz/(dmz*dmz)); } }else{ // return normal distance double rt = (A.getRt()-B.getRt()); double mz = (A.getMz()-B.getMz()); double z = A.getCharge() - B.getCharge(); return sqrt(rt*rt/(drt*drt) + mz*mz/(dmz*dmz) + z*z/(dz*dz)); } }
/** * Returns selected information for a "peak" at QLabFrame. * * @param qFrame An arbitrary position in Q-space. This does not have to *be the * position of a peak. * @param labCoords Set true if the position is in the lab coordinate system, *false if * it is in the sample coordinate system. * @return a vector whose elements contain different information about the *"peak" at that position. * each element is a pair of description of information and the string *form for the corresponding * value. */ int PeaksWorkspace::peakInfoNumber(Kernel::V3D qFrame, bool labCoords) const { std::vector<std::pair<std::string, std::string>> Result; std::ostringstream oss; oss << std::setw(12) << std::fixed << std::setprecision(3) << (qFrame.norm()); std::pair<std::string, std::string> QMag("|Q|", oss.str()); Result.push_back(QMag); oss.str(""); oss.clear(); oss << std::setw(12) << std::fixed << std::setprecision(3) << (2.0 * M_PI / qFrame.norm()); std::pair<std::string, std::string> dspc("d-spacing", oss.str()); oss.str(""); oss.clear(); Result.push_back(dspc); int seqNum = -1; double minDist = 10000000; for (int i = 0; i < getNumberPeaks(); i++) { Peak pk = getPeak(i); V3D Q = pk.getQLabFrame(); if (!labCoords) Q = pk.getQSampleFrame(); double D = qFrame.distance(Q); if (D < minDist) { minDist = D; seqNum = i + 1; } } return seqNum; }
TEST(Peak, Peak2D) { vector<vector<int> > A = { {10, 8, 10, 10}, {14, 13, 12, 11}, {15, 9, 11, 21}, {16, 17, 19, 20} }; Peak peak; pair<int, int> p = peak.find2d(A); int dr[] = {-1, 0, 1, 0}; int dc[] = {0, 1, 0, -1}; int n = A.size(); int m = A[0].size(); bool test = true; for (int i = 0; i < 4; i++) { int r = p.first + dr[i]; int c = p.second + dc[i]; if (r >= 0 && r < n && c >= 0 && c < m) { test &= A[p.first][p.second] >= A[r][c]; } } EXPECT_TRUE(test); }
TEST(Peak, Peak1D) { vector<int> A = {1, 2, 3, 5, 0, 3, 1, 3, 8, 9}; Peak peak; int n = A.size(); int i = peak.find1d(A); EXPECT_TRUE((i == 0 && A[i] >= A[1]) || (i == n - 1 && A[i-1] <= A[i]) || (A[i-1] <= A[i] && A[i] >= A[i+1])); }
int LuaPeak::setLabel(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const char* str = ""; if( lua_gettop(L) > 1 ) str = luaL_checkstring( L, 2 ); obj->getOwner()->setTag( obj, str ); return 0; }
int LuaPeak::getAssig(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const Peak::Assig& a = obj->getAssig(); { for( int i = 0; i < obj->getDimCount(); i++ ) lua_pushnumber( L, a[ i ] ); } return obj->getDimCount(); }
int LuaPeak::getAmp(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); Spectrum* spec = 0; if( lua_gettop( L ) > 1 ) { spec = RefBinding<Spectrum>::cast( L, 2 ); } lua_pushnumber(L, obj->getAmp( spec ) ); return 1; }
int LuaPeak::setAssig(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const int n = lua_gettop(L); /* number of arguments */ if( n != ( obj->getDimCount() + 1 ) ) luaL_error( L, "Expecting %d arguments", int( obj->getDimCount() + 1 ) ); Peak::Assig a; for( int i = 2; i <= n; i++ ) a[ i-1 ] = luaL_checknumber( L, i ); // TEST obj->getOwner()->setAssig( obj, a ); return 0; }
int LuaPeak::getPos(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); Spectrum* spec = 0; if( lua_gettop( L ) > 1 ) { spec = RefBinding<Spectrum>::cast( L, 2 ); } const PeakPos& a = obj->getPos( spec ); for( int i = 0; i < obj->getDimCount(); i++ ) lua_pushnumber( L, a[ i ] ); return obj->getDimCount(); }
int LuaPeak::getModel(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); int n = lua_gettop(L); /* number of arguments */ Spectrum* spec = 0; if( n > 1 ) { spec = RefBinding<Spectrum>::cast( L, 2 ); } PeakModel* m = obj->getModel( spec ); RefBinding<PeakModel>::create( L, m ); return 1; }
int LuaPeak::setModel(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const int n = lua_gettop(L); /* number of arguments */ int id = 0; if( n > 1 ) id = luaL_checknumber( L, 2 ); Spectrum* spec = 0; if( n > 2 ) { spec = RefBinding<Spectrum>::cast( L, 3 ); } obj->getOwner()->setModel( obj, id, spec ); return 0; }
int LuaPeak::setAmp(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); int n = lua_gettop(L); /* number of arguments */ Amplitude a = 0; if( n > 1 ) a = luaL_checknumber( L, 2 ); Spectrum* spec = 0; if( n > 2 ) { spec = RefBinding<Spectrum>::cast( L, 3 ); } obj->getOwner()->setAmp( obj, a, spec ); return 0; }
int LuaPeak::getGuesses(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const Peak::GuessMap& sm = obj->getGuesses(); Peak::GuessMap::const_iterator i; lua_newtable( L ); int t = lua_gettop( L ); for( i = sm.begin(); i != sm.end(); ++i ) { lua_pushnumber( L, (*i).first ); RefBinding<Peak::Guess>::create( L, (*i).second.deref() ); lua_rawset( L, t ); } return 1; }
int LuaPeak::setPos(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); const int n = lua_gettop(L); /* number of arguments */ const int dim = obj->getDimCount(); if( n < dim + 1 ) luaL_error( L, "Expecting at least %d arguments", dim ); PpmPoint a; for( int i = 1; i <= dim; i++ ) a.push_back( luaL_checknumber( L, i + 1 ) ); Spectrum* spec = 0; if( n > ( dim + 1 ) ) { spec = RefBinding<Spectrum>::cast( L, n ); } obj->getOwner()->setPos( obj, a, spec ); return 0; }
void loop_start(float * newSpec) { memcpy(this_spectrum, newSpec, sizeof(float) * FREQUENCY_LENGTH); current = NO_PEAK; for (int i = 0; i < FREQUENCY_LENGTH; ++i) { current.update(i, this_spectrum[i]); } this_attr.sum = sum_over(Range::around(current)); this_attr.sdev = sdev_over(); this_attr.sdratio = sdev_except( FULL_RANGE, Range::around(current)) / this_attr.sdev; }
int LuaPeak::setGuess(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); int n = lua_gettop(L); /* number of arguments */ Peak::Guess* g = RefBinding<Peak::Guess>::check( L, 2 ); float f = 0.0; Peak::Assig a; if( n > 2 ) { f = luaL_checknumber( L, 3 ); if( f < 0.0 || f > 1.0 ) luaL_error( L, "Invalid probability value" ); const int off = 4; for( int i = off; i <= n; i++ ) { if( i - off >= Peak::Assig::MAX_DIM ) luaL_error( L, "Invalid number of dimensions" ); a[ i - off ] = luaL_checknumber( L, i ); } } obj->getOwner()->setGuess( obj, g->getId(), a, f ); return 0; }
/** Compare two peaks using the stored criteria */ inline bool operator()(const Peak& a, const Peak& b) { for (size_t i = 0; i < criteria.size(); i++) { std::string & col = criteria[i].first; bool ascending = criteria[i].second; bool lessThan = false; if (col == "BankName") { // If this criterion is equal, move on to the next one std::string valA = a.getBankName(); std::string valB = b.getBankName(); // Move on to lesser criterion if equal if (valA == valB) continue; lessThan = (valA < valB); } else { // General double comparison double valA = a.getValueByColName(col); double valB = b.getValueByColName(col); // Move on to lesser criterion if equal if (valA == valB) continue; lessThan = (valA < valB); } // Flip the sign of comparison if descending. if (ascending) return lessThan; else return !lessThan; } // If you reach here, all criteria were ==; so not <, so return false return false; }
bool FindUBUsingIndexedPeaks::isPeakIndexed(Peak &peak) { V3D hkl(peak.getIntHKL()); // ##### KEEP V3D mnp(peak.getIntMNP()); return (IndexingUtils::ValidIndex(hkl, 1.0) || IndexingUtils::ValidIndex(mnp, 1.0)); }
void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws) { if (nd < 3) throw std::invalid_argument("Workspace must have at least 3 dimensions."); progress(0.01, "Refreshing Centroids"); // TODO: This might be slow, progress report? // Make sure all centroids are fresh ws->getBox()->refreshCentroid(); typedef IMDBox<MDE,nd>* boxPtr; if (ws->getNumExperimentInfo() == 0) throw std::runtime_error("No instrument was found in the MDEventWorkspace. Cannot find peaks."); // TODO: Do we need to pick a different instrument info? ExperimentInfo_sptr ei = ws->getExperimentInfo(0); // Instrument associated with workspace Geometry::Instrument_const_sptr inst = ei->getInstrument(); // Find the run number int runNumber = ei->getRunNumber(); // Check that the workspace dimensions are in Q-sample-frame or Q-lab-frame. eDimensionType dimType; std::string dim0 = ws->getDimension(0)->getName(); if (dim0 == "H") { dimType = HKL; throw std::runtime_error("Cannot find peaks in a workspace that is already in HKL space."); } else if (dim0 == "Q_lab_x") { dimType = QLAB; } else if (dim0 == "Q_sample_x") dimType = QSAMPLE; else throw std::runtime_error("Unexpected dimensions: need either Q_lab_x or Q_sample_x."); // Find the goniometer rotation matrix Mantid::Kernel::Matrix<double> goniometer(3,3, true); // Default IDENTITY matrix try { goniometer = ei->mutableRun().getGoniometerMatrix(); } catch (std::exception & e) { g_log.warning() << "Error finding goniometer matrix. It will not be set in the peaks found." << std::endl; g_log.warning() << e.what() << std::endl; } /// Arbitrary scaling factor for density to make more manageable numbers, especially for older file formats. signal_t densityScalingFactor = 1e-6; // Calculate a threshold below which a box is too diffuse to be considered a peak. signal_t thresholdDensity = 0.0; thresholdDensity = ws->getBox()->getSignalNormalized() * DensityThresholdFactor * densityScalingFactor; g_log.notice() << "Threshold signal density: " << thresholdDensity << std::endl; // We will fill this vector with pointers to all the boxes (up to a given depth) typename std::vector<boxPtr> boxes; // Get all the MDboxes progress(0.10, "Getting Boxes"); ws->getBox()->getBoxes(boxes, 1000, true); // TODO: Here keep only the boxes > e.g. 3 * mean. typedef std::pair<double, boxPtr> dens_box; // Map that will sort the boxes by increasing density. The key = density; value = box *. typename std::multimap<double, boxPtr> sortedBoxes; progress(0.20, "Sorting Boxes by Density"); typename std::vector<boxPtr>::iterator it1; typename std::vector<boxPtr>::iterator it1_end = boxes.end(); for (it1 = boxes.begin(); it1 != it1_end; it1++) { boxPtr box = *it1; double density = box->getSignalNormalized() * densityScalingFactor; // Skip any boxes with too small a signal density. if (density > thresholdDensity) sortedBoxes.insert(dens_box(density,box)); } // List of chosen possible peak boxes. std::vector<boxPtr> peakBoxes; prog = new Progress(this, 0.30, 0.95, MaxPeaks); int64_t numBoxesFound = 0; // Now we go (backwards) through the map // e.g. from highest density down to lowest density. typename std::multimap<double, boxPtr>::reverse_iterator it2; typename std::multimap<double, boxPtr>::reverse_iterator it2_end = sortedBoxes.rend(); for (it2 = sortedBoxes.rbegin(); it2 != it2_end; it2++) { signal_t density = it2->first; boxPtr box = it2->second; #ifndef MDBOX_TRACK_CENTROID coord_t boxCenter[nd]; box->calculateCentroid(boxCenter); #else const coord_t * boxCenter = box->getCentroid(); #endif // Compare to all boxes already picked. bool badBox = false; for (typename std::vector<boxPtr>::iterator it3=peakBoxes.begin(); it3 != peakBoxes.end(); it3++) { #ifndef MDBOX_TRACK_CENTROID coord_t otherCenter[nd]; (*it3)->calculateCentroid(otherCenter); #else const coord_t * otherCenter = (*it3)->getCentroid(); #endif // Distance between this box and a box we already put in. coord_t distSquared = 0.0; for (size_t d=0; d<nd; d++) { coord_t dist = otherCenter[d] - boxCenter[d]; distSquared += (dist * dist); } // Reject this box if it is too close to another previously found box. if (distSquared < peakRadiusSquared) { badBox = true; break; } } // The box was not rejected for another reason. if (!badBox) { if (numBoxesFound++ >= MaxPeaks) { g_log.notice() << "Number of peaks found exceeded the limit of " << MaxPeaks << ". Stopping peak finding." << std::endl; break; } peakBoxes.push_back(box); g_log.information() << "Found box at "; for (size_t d=0; d<nd; d++) g_log.information() << (d>0?",":"") << boxCenter[d]; g_log.information() << "; Density = " << density << std::endl; // Report progres for each box found. prog->report("Finding Peaks"); } } prog->resetNumSteps(numBoxesFound, 0.95, 1.0); // Copy the instrument, sample, run to the peaks workspace. peakWS->copyExperimentInfoFrom(ei.get()); // --- Convert the "boxes" to peaks ---- for (typename std::vector<boxPtr>::iterator it3=peakBoxes.begin(); it3 != peakBoxes.end(); it3++) { // The center of the box = Q in the lab frame boxPtr box = *it3; #ifndef MDBOX_TRACK_CENTROID coord_t boxCenter[nd]; box->calculateCentroid(boxCenter); #else const coord_t * boxCenter = box->getCentroid(); #endif V3D Q(boxCenter[0], boxCenter[1], boxCenter[2]); // Create a peak and add it // Empty starting peak. Peak p; try { if (dimType == QLAB) { // Build using the Q-lab-frame constructor p = Peak(inst, Q); // Save gonio matrix for later p.setGoniometerMatrix(goniometer); } else if (dimType == QSAMPLE) { // Build using the Q-sample-frame constructor p = Peak(inst, Q, goniometer); } } catch (std::exception &e) { g_log.notice() << "Error creating peak at " << Q << " because of '" << e.what() << "'. Peak will be skipped." << std::endl; continue; } try { // Look for a detector p.findDetector(); } catch (...) { /* Ignore errors in ray-tracer TODO: Handle for WISH data later */ } // The "bin count" used will be the box density. p.setBinCount( box->getSignalNormalized() * densityScalingFactor); // Save the run number found before. p.setRunNumber(runNumber); peakWS->addPeak(p); // Report progres for each box found. prog->report("Adding Peaks"); } // for each box found }
int LuaPeak::setColor(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); obj->getOwner()->setColor( obj, luaL_checknumber( L, 2 ) ); return 0; }
/** * Calculates the h,k, and l offsets from an integer for (some of )the peaks, *given the parameter values. * * @param out For each peak there are 3 consecutive elements in this array. The *first is for the h offset from an * integer, the second is the k offset and the 3rd is the l offset * @param xValues xValues give the index in the PeaksWorkspace for the peak. *For each peak considered there are * three consecutive entries all with the same index * @param nData The size of the xValues and out arrays */ void PeakHKLErrors::function1D(double *out, const double *xValues, const size_t nData) const { PeaksWorkspace_sptr Peaks = AnalysisDataService::Instance().retrieveWS<PeaksWorkspace>( PeakWorkspaceName); boost::shared_ptr<Geometry::Instrument> instNew = getNewInstrument(Peaks); if (!Peaks) throw std::invalid_argument("Peaks not stored under the name " + PeakWorkspaceName); std::map<int, Mantid::Kernel::Matrix<double>> RunNum2GonMatrixMap; getRun2MatMap(Peaks, OptRuns, RunNum2GonMatrixMap); const DblMatrix &UBx = Peaks->sample().getOrientedLattice().getUB(); DblMatrix UBinv(UBx); UBinv.Invert(); UBinv /= (2 * M_PI); double GonRotx = getParameter("GonRotx"); double GonRoty = getParameter("GonRoty"); double GonRotz = getParameter("GonRotz"); Matrix<double> GonRot = RotationMatrixAboutRegAxis(GonRotx, 'x') * RotationMatrixAboutRegAxis(GonRoty, 'y') * RotationMatrixAboutRegAxis(GonRotz, 'z'); double ChiSqTot = 0.0; for (size_t i = 0; i < nData; i += 3) { int peakNum = boost::math::iround(xValues[i]); IPeak &peak_old = Peaks->getPeak(peakNum); int runNum = peak_old.getRunNumber(); std::string runNumStr = std::to_string(runNum); Peak peak = createNewPeak(peak_old, instNew, 0, peak_old.getL1()); size_t N = OptRuns.find("/" + runNumStr + "/"); if (N < OptRuns.size()) { peak.setGoniometerMatrix(GonRot * RunNum2GonMatrixMap[runNum]); } else { peak.setGoniometerMatrix(GonRot * peak.getGoniometerMatrix()); } V3D sampOffsets(getParameter("SampleXOffset"), getParameter("SampleYOffset"), getParameter("SampleZOffset")); peak.setSamplePos(peak.getSamplePos() + sampOffsets); V3D hkl = UBinv * peak.getQSampleFrame(); for (int k = 0; k < 3; k++) { double d1 = hkl[k] - floor(hkl[k]); if (d1 > .5) d1 = d1 - 1; if (d1 < -.5) d1 = d1 + 1; out[i + k] = d1; ChiSqTot += d1 * d1; } } g_log.debug() << "------------------------Function---------------------------" "--------------------\n"; for (size_t p = 0; p < nParams(); p++) { g_log.debug() << parameterName(p) << "(" << getParameter(p) << "),"; if ((p + 1) % 6 == 0) g_log.debug() << '\n'; } g_log.debug() << '\n'; g_log.debug() << "Off constraints="; for (size_t p = 0; p < nParams(); p++) { IConstraint *constr = getConstraint(p); if (constr) if ((constr->check() > 0)) g_log.debug() << "(" << parameterName(p) << "=" << constr->check() << ");"; } g_log.debug() << '\n'; g_log.debug() << " Chi**2 = " << ChiSqTot << " nData = " << nData << '\n'; }
int LuaPeak::getLabel(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); lua_pushstring(L, obj->getTag().data() ); return 1; }
void PeakHKLErrors::functionDeriv1D(Jacobian *out, const double *xValues, const size_t nData) { PeaksWorkspace_sptr Peaks = AnalysisDataService::Instance().retrieveWS<PeaksWorkspace>( PeakWorkspaceName); boost::shared_ptr<Geometry::Instrument> instNew = getNewInstrument(Peaks); const DblMatrix &UB = Peaks->sample().getOrientedLattice().getUB(); DblMatrix UBinv(UB); UBinv.Invert(); UBinv /= 2 * M_PI; double GonRotx = getParameter("GonRotx"); double GonRoty = getParameter("GonRoty"); double GonRotz = getParameter("GonRotz"); Matrix<double> InvGonRotxMat = RotationMatrixAboutRegAxis(GonRotx, 'x'); Matrix<double> InvGonRotyMat = RotationMatrixAboutRegAxis(GonRoty, 'y'); Matrix<double> InvGonRotzMat = RotationMatrixAboutRegAxis(GonRotz, 'z'); Matrix<double> GonRot = InvGonRotxMat * InvGonRotyMat * InvGonRotzMat; InvGonRotxMat.Invert(); InvGonRotyMat.Invert(); InvGonRotzMat.Invert(); std::map<int, Kernel::Matrix<double>> RunNums2GonMatrix; getRun2MatMap(Peaks, OptRuns, RunNums2GonMatrix); g_log.debug() << "----------------------------Derivative------------------------\n"; V3D samplePosition = instNew->getSample()->getPos(); IPeak &ppeak = Peaks->getPeak(0); double L0 = ppeak.getL1(); double velocity = (L0 + ppeak.getL2()) / ppeak.getTOF(); double K = 2 * M_PI / ppeak.getWavelength() / velocity; // 2pi/lambda = K* velocity V3D beamDir = instNew->getBeamDirection(); size_t paramNums[] = {parameterIndex(std::string("SampleXOffset")), parameterIndex(std::string("SampleYOffset")), parameterIndex(std::string("SampleZOffset"))}; for (size_t i = 0; i < nData; i += 3) { int peakNum = boost::math::iround(xValues[i]); IPeak &peak_old = Peaks->getPeak(peakNum); Peak peak = createNewPeak(peak_old, instNew, 0, peak_old.getL1()); int runNum = peak_old.getRunNumber(); std::string runNumStr = std::to_string(runNum); for (int kk = 0; kk < static_cast<int>(nParams()); kk++) { out->set(i, kk, 0.0); out->set(i + 1, kk, 0.0); out->set(i + 2, kk, 0.0); } double chi, phi, omega; size_t chiParamNum, phiParamNum, omegaParamNum; size_t N = OptRuns.find("/" + runNumStr); if (N < OptRuns.size()) { chi = getParameter("chi" + (runNumStr)); phi = getParameter("phi" + (runNumStr)); omega = getParameter("omega" + (runNumStr)); peak.setGoniometerMatrix(GonRot * RunNums2GonMatrix[runNum]); chiParamNum = parameterIndex("chi" + (runNumStr)); phiParamNum = parameterIndex("phi" + (runNumStr)); omegaParamNum = parameterIndex("omega" + (runNumStr)); } else { Geometry::Goniometer Gon(peak.getGoniometerMatrix()); std::vector<double> phichiOmega = Gon.getEulerAngles("YZY"); chi = phichiOmega[1]; phi = phichiOmega[2]; omega = phichiOmega[0]; // peak.setGoniometerMatrix( GonRot*Gon.getR()); chiParamNum = phiParamNum = omegaParamNum = nParams() + 10; peak.setGoniometerMatrix(GonRot * peak.getGoniometerMatrix()); } V3D sampOffsets(getParameter("SampleXOffset"), getParameter("SampleYOffset"), getParameter("SampleZOffset")); peak.setSamplePos(peak.getSamplePos() + sampOffsets); // NOTE:Use getQLabFrame except for below. // For parameters the getGoniometerMatrix should remove GonRot, for derivs // wrt GonRot*, wrt chi*,phi*,etc. // Deriv wrt chi phi and omega if (phiParamNum < nParams()) { Matrix<double> chiMatrix = RotationMatrixAboutRegAxis(chi, 'z'); Matrix<double> phiMatrix = RotationMatrixAboutRegAxis(phi, 'y'); Matrix<double> omegaMatrix = RotationMatrixAboutRegAxis(omega, 'y'); Matrix<double> dchiMatrix = DerivRotationMatrixAboutRegAxis(chi, 'z'); Matrix<double> dphiMatrix = DerivRotationMatrixAboutRegAxis(phi, 'y'); Matrix<double> domegaMatrix = DerivRotationMatrixAboutRegAxis(omega, 'y'); Matrix<double> InvG = omegaMatrix * chiMatrix * phiMatrix; InvG.Invert(); // Calculate Derivatives wrt chi(phi,omega) in degrees Matrix<double> R = omegaMatrix * chiMatrix * dphiMatrix; Matrix<double> InvR = InvG * R * InvG * -1; V3D lab = peak.getQLabFrame(); V3D Dhkl0 = UBinv * InvR * lab; R = omegaMatrix * dchiMatrix * phiMatrix; InvR = InvG * R * InvG * -1; V3D Dhkl1 = UBinv * InvR * peak.getQLabFrame(); R = domegaMatrix * chiMatrix * phiMatrix; InvR = InvG * R * InvG * -1; V3D Dhkl2 = UBinv * InvR * peak.getQLabFrame(); // R.transpose should be R inverse out->set(i, chiParamNum, Dhkl1[0]); out->set(i + 1, chiParamNum, Dhkl1[1]); out->set(i + 2, chiParamNum, Dhkl1[2]); out->set(i, phiParamNum, Dhkl0[0]); out->set(i + 1, phiParamNum, Dhkl0[1]); out->set(i + 2, phiParamNum, Dhkl0[2]); out->set(i, omegaParamNum, Dhkl2[0]); out->set(i + 1, omegaParamNum, Dhkl2[1]); out->set(i + 2, omegaParamNum, Dhkl2[2]); } // if optimize for chi phi and omega on this peak //------------------------Goniometer Rotation Derivatives //----------------------- Matrix<double> InvGonRot(GonRot); InvGonRot.Invert(); Matrix<double> InvGon = InvGonRot * peak.getGoniometerMatrix(); InvGon.Invert(); V3D DGonx = (UBinv * InvGon * InvGonRotzMat * InvGonRotyMat * DerivRotationMatrixAboutRegAxis( -GonRotx, 'x') * // - gives inverse of GonRot peak.getQLabFrame()) * -1; V3D DGony = (UBinv * InvGon * InvGonRotzMat * DerivRotationMatrixAboutRegAxis(-GonRoty, 'y') * InvGonRotxMat * peak.getQLabFrame()) * -1; V3D DGonz = (UBinv * InvGon * DerivRotationMatrixAboutRegAxis(-GonRotz, 'z') * InvGonRotyMat * InvGonRotxMat * peak.getQLabFrame()) * -1; size_t paramnum = parameterIndex("GonRotx"); out->set(i, paramnum, DGonx[0]); out->set(i + 1, paramnum, DGonx[1]); out->set(i + 2, paramnum, DGonx[2]); out->set(i, parameterIndex("GonRoty"), DGony[0]); out->set(i + 1, parameterIndex("GonRoty"), DGony[1]); out->set(i + 2, parameterIndex("GonRoty"), DGony[2]); out->set(i, parameterIndex("GonRotz"), DGonz[0]); out->set(i + 1, parameterIndex("GonRotz"), DGonz[1]); out->set(i + 2, parameterIndex("GonRotz"), DGonz[2]); //-------------------- Sample Orientation derivatives //---------------------------------- // Qlab = -KV + k|V|*beamdir // D = pos-sampPos //|V|= vmag=(L0 + D )/tof // t1= tof - L0/|V| {time from sample to pixel} // V = D/t1 V3D D = peak.getDetPos() - samplePosition; double vmag = (L0 + D.norm()) / peak.getTOF(); double t1 = peak.getTOF() - L0 / vmag; // Derivs wrt sample x, y, z // Ddsx =( - 1, 0, 0), d|D|^2/dsx -> 2|D|d|D|/dsx =d(tranp(D)* D)/dsx =2 // Ddsx* tranp(D) //|D| also called Dmag V3D Dmagdsxsysz(D); Dmagdsxsysz *= (-1 / D.norm()); V3D vmagdsxsysz = Dmagdsxsysz / peak.getTOF(); V3D t1dsxsysz = vmagdsxsysz * (L0 / vmag / vmag); Matrix<double> Gon = peak.getGoniometerMatrix(); Gon.Invert(); // x=0 is deriv wrt SampleXoffset, x=1 is deriv wrt SampleYoffset, etc. for (int x = 0; x < 3; x++) { V3D pp; pp[x] = 1; V3D dQlab1 = pp / -t1 - D * (t1dsxsysz[x] / t1 / t1); V3D dQlab2 = beamDir * vmagdsxsysz[x]; V3D dQlab = dQlab2 - dQlab1; dQlab *= K; V3D dQSamp = Gon * dQlab; V3D dhkl = UBinv * dQSamp; out->set(i, paramNums[x], dhkl[0]); out->set(i + 1, paramNums[x], dhkl[1]); out->set(i + 2, paramNums[x], dhkl[2]); } } }
void PeaksWorkspace::saveNexus(::NeXus::File * file) const { //Number of Peaks const size_t np(peaks.size()); // Column vectors for peaks table std::vector<int> detectorID(np); std::vector<double> H(np); std::vector<double> K(np); std::vector<double> L(np); std::vector<double> intensity(np); std::vector<double> sigmaIntensity(np); std::vector<double> binCount(np); std::vector<double> initialEnergy(np); std::vector<double> finalEnergy(np); std::vector<double> waveLength(np); std::vector<double> scattering(np); std::vector<double> dSpacing(np); std::vector<double> TOF(np); std::vector<int> runNumber(np); std::vector<double> goniometerMatrix(9 * np); // Populate column vectors from Peak Workspace for (size_t i = 0; i < np; i++) { Peak p = peaks[i]; detectorID[i] = p.getDetectorID(); H[i] = p.getH(); K[i] = p.getK(); L[i] = p.getL(); intensity[i] = p.getIntensity(); sigmaIntensity[i] = p.getSigmaIntensity(); binCount[i] = p.getBinCount(); initialEnergy[i] = p.getInitialEnergy(); finalEnergy[i] = p.getFinalEnergy(); waveLength[i] = p.getWavelength(); scattering[i] = p.getScattering(); dSpacing[i] = p.getDSpacing(); TOF[i] = p.getTOF(); runNumber[i] = p.getRunNumber(); { Matrix<double> gm = p.getGoniometerMatrix(); goniometerMatrix[9 * i] = gm[0][0]; goniometerMatrix[9 * i + 1] = gm[1][0]; goniometerMatrix[9 * i + 2] = gm[2][0]; goniometerMatrix[9 * i + 3] = gm[0][1]; goniometerMatrix[9 * i + 4] = gm[1][1]; goniometerMatrix[9 * i + 5] = gm[2][1]; goniometerMatrix[9 * i + 6] = gm[0][2]; goniometerMatrix[9 * i + 7] = gm[1][2]; goniometerMatrix[9 * i + 8] = gm[1][2]; } // etc. } // Start Peaks Workspace in Nexus File std::string specifyInteger = "An integer"; std::string specifyDouble = "A double"; file->makeGroup("peaks_workspace", "NXentry", true); // For when peaksWorkspace can be loaded // Detectors column file->writeData("column_1", detectorID); file->openData("column_1"); file->putAttr("name", "Dectector ID"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); file->closeData(); // H column file->writeData("column_2", H); file->openData("column_2"); file->putAttr("name", "H"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // K column file->writeData("column_3", K); file->openData("column_3"); file->putAttr("name", "K"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // L column file->writeData("column_4", L); file->openData("column_4"); file->putAttr("name", "L"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Intensity column file->writeData("column_5", intensity); file->openData("column_5"); file->putAttr("name", "Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Sigma Intensity column file->writeData("column_6", sigmaIntensity); file->openData("column_6"); file->putAttr("name", "Sigma Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Bin Count column file->writeData("column_7", binCount); file->openData("column_7"); file->putAttr("name", "Bin Count"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Initial Energy column file->writeData("column_8", initialEnergy); file->openData("column_8"); file->putAttr("name", "Initial Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Final Energy column file->writeData("column_9", finalEnergy); file->openData("column_9"); file->putAttr("name", "Final Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Wave Length Column file->writeData("column_10", waveLength); file->openData("column_10"); file->putAttr("name", "Wave Length"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Scattering Column file->writeData("column_11", scattering); file->openData("column_11"); file->putAttr("name", "Scattering"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // D Spacing Column file->writeData("column_12", dSpacing); file->openData("column_12"); file->putAttr("name", "D Spacing"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // TOF Column file->writeData("column_13", TOF); file->openData("column_13"); file->putAttr("name", "TOF"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); //Run Number column file->writeData("column_14", runNumber); file->openData("column_14"); file->putAttr("name", "Run Number"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Goniometer Matrix Column std::vector<int> array_dims; array_dims.push_back(static_cast<int>(peaks.size())); array_dims.push_back(9); file->writeData("column_15", goniometerMatrix, array_dims); file->openData("column_15"); file->putAttr("name", "Goniometer Matrix"); file->putAttr("interpret_as", "A matrix of 3x3 doubles"); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // QLab & QSample are calculated and do not need to be saved file->closeGroup(); // end of peaks workpace }
void PeaksWorkspace::saveNexus(::NeXus::File *file) const { // Number of Peaks const size_t np(peaks.size()); // Column vectors for peaks table std::vector<int> detectorID(np); std::vector<double> H(np); std::vector<double> K(np); std::vector<double> L(np); std::vector<double> intensity(np); std::vector<double> sigmaIntensity(np); std::vector<double> binCount(np); std::vector<double> initialEnergy(np); std::vector<double> finalEnergy(np); std::vector<double> waveLength(np); std::vector<double> scattering(np); std::vector<double> dSpacing(np); std::vector<double> TOF(np); std::vector<int> runNumber(np); std::vector<double> goniometerMatrix(9 * np); std::vector<std::string> shapes(np); // Populate column vectors from Peak Workspace size_t maxShapeJSONLength = 0; for (size_t i = 0; i < np; i++) { Peak p = peaks[i]; detectorID[i] = p.getDetectorID(); H[i] = p.getH(); K[i] = p.getK(); L[i] = p.getL(); intensity[i] = p.getIntensity(); sigmaIntensity[i] = p.getSigmaIntensity(); binCount[i] = p.getBinCount(); initialEnergy[i] = p.getInitialEnergy(); finalEnergy[i] = p.getFinalEnergy(); waveLength[i] = p.getWavelength(); scattering[i] = p.getScattering(); dSpacing[i] = p.getDSpacing(); TOF[i] = p.getTOF(); runNumber[i] = p.getRunNumber(); { Matrix<double> gm = p.getGoniometerMatrix(); goniometerMatrix[9 * i] = gm[0][0]; goniometerMatrix[9 * i + 1] = gm[1][0]; goniometerMatrix[9 * i + 2] = gm[2][0]; goniometerMatrix[9 * i + 3] = gm[0][1]; goniometerMatrix[9 * i + 4] = gm[1][1]; goniometerMatrix[9 * i + 5] = gm[2][1]; goniometerMatrix[9 * i + 6] = gm[0][2]; goniometerMatrix[9 * i + 7] = gm[1][2]; goniometerMatrix[9 * i + 8] = gm[2][2]; } const std::string shapeJSON = p.getPeakShape().toJSON(); shapes[i] = shapeJSON; if (shapeJSON.size() > maxShapeJSONLength) { maxShapeJSONLength = shapeJSON.size(); } } // Start Peaks Workspace in Nexus File const std::string specifyInteger = "An integer"; const std::string specifyDouble = "A double"; const std::string specifyString = "A string"; file->makeGroup("peaks_workspace", "NXentry", true); // For when peaksWorkspace can be loaded // Coordinate system file->writeData("coordinate_system", static_cast<uint32_t>(m_coordSystem)); // Write out the Qconvention // ki-kf for Inelastic convention; kf-ki for Crystallography convention std::string m_QConvention = this->getConvention(); file->putAttr("QConvention", m_QConvention); // Detectors column file->writeData("column_1", detectorID); file->openData("column_1"); file->putAttr("name", "Detector ID"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); file->closeData(); // H column file->writeData("column_2", H); file->openData("column_2"); file->putAttr("name", "H"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // K column file->writeData("column_3", K); file->openData("column_3"); file->putAttr("name", "K"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // L column file->writeData("column_4", L); file->openData("column_4"); file->putAttr("name", "L"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Intensity column file->writeData("column_5", intensity); file->openData("column_5"); file->putAttr("name", "Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Sigma Intensity column file->writeData("column_6", sigmaIntensity); file->openData("column_6"); file->putAttr("name", "Sigma Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Bin Count column file->writeData("column_7", binCount); file->openData("column_7"); file->putAttr("name", "Bin Count"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Initial Energy column file->writeData("column_8", initialEnergy); file->openData("column_8"); file->putAttr("name", "Initial Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Final Energy column file->writeData("column_9", finalEnergy); file->openData("column_9"); file->putAttr("name", "Final Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Wave Length Column file->writeData("column_10", waveLength); file->openData("column_10"); file->putAttr("name", "Wave Length"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Scattering Column file->writeData("column_11", scattering); file->openData("column_11"); file->putAttr("name", "Scattering"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // D Spacing Column file->writeData("column_12", dSpacing); file->openData("column_12"); file->putAttr("name", "D Spacing"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // TOF Column file->writeData("column_13", TOF); file->openData("column_13"); file->putAttr("name", "TOF"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Run Number column file->writeData("column_14", runNumber); file->openData("column_14"); file->putAttr("name", "Run Number"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Goniometer Matrix Column std::vector<int> array_dims; array_dims.push_back(static_cast<int>(peaks.size())); array_dims.push_back(9); file->writeData("column_15", goniometerMatrix, array_dims); file->openData("column_15"); file->putAttr("name", "Goniometer Matrix"); file->putAttr("interpret_as", "A matrix of 3x3 doubles"); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Shape std::vector<int64_t> dims; dims.push_back(np); dims.push_back(static_cast<int>(maxShapeJSONLength)); const std::string name = "column_16"; file->makeData(name, NeXus::CHAR, dims, false); file->openData(name); auto toNexus = new char[maxShapeJSONLength * np]; for (size_t ii = 0; ii < np; ii++) { std::string rowStr = shapes[ii]; for (size_t ic = 0; ic < rowStr.size(); ic++) toNexus[ii * maxShapeJSONLength + ic] = rowStr[ic]; for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxShapeJSONLength); ic++) toNexus[ii * maxShapeJSONLength + ic] = ' '; } file->putData((void *)(toNexus)); delete[] toNexus; file->putAttr("units", "Not known"); // Units may need changing when known file->putAttr("name", "Shape"); file->putAttr("interpret_as", specifyString); file->closeData(); // QLab & QSample are calculated and do not need to be saved file->closeGroup(); // end of peaks workpace }
int LuaPeak::getId(lua_State *L) { Peak* obj = RefBinding<Peak>::check( L, 1); lua_pushnumber(L, obj->getId() ); return 1; }
/** Append the peaks from a .peaks file into the workspace * @param outWS :: the workspace in which to place the information * @param filename :: path to the .peaks file */ void LoadIsawPeaks::appendFile( PeaksWorkspace_sptr outWS, std::string filename ) { // Open the file std::ifstream in( filename.c_str() ); // Read the header, load the instrument double T0; std::string s = readHeader( outWS, in , T0); // set T0 in the run parameters API::Run & m_run = outWS->mutableRun(); m_run.addProperty<double>("T0", T0, true); if( !in.good() || s.length() < 1 ) throw std::runtime_error( "End of Peaks file before peaks" ); if( s.compare( std::string( "0" ) ) != 0 ) throw std::logic_error( "No header for Peak segments" ); readToEndOfLine( in , true ); s = getWord( in , false ); int run, bankNum; double chi , phi , omega , monCount; // Build the universal goniometer that will build the rotation matrix. Mantid::Geometry::Goniometer uniGonio; uniGonio.makeUniversalGoniometer(); // TODO: Can we find the number of peaks to get better progress reporting? Progress prog(this, 0.0, 1.0, 100); while( in.good() ) { // Read the header if necessary s = readPeakBlockHeader( s , in , run , bankNum , chi , phi , omega , monCount ); // Build the Rotation matrix using phi,chi,omega uniGonio.setRotationAngle("phi", phi); uniGonio.setRotationAngle("chi", chi); uniGonio.setRotationAngle("omega", omega); //Put goniometer into peaks workspace outWS->mutableRun().setGoniometer(uniGonio, false); std::ostringstream oss; std::string bankString = "bank"; if (outWS->getInstrument()->getName() == "WISH") bankString = "WISHpanel0"; oss << bankString << bankNum; std::string bankName = oss.str(); int seqNum = -1; try { // Read the peak Peak peak = readPeak(outWS, s, in, seqNum, bankName); // Get the calculated goniometer matrix Matrix<double> gonMat = uniGonio.getR(); peak.setGoniometerMatrix(gonMat); peak.setRunNumber(run); peak.setMonitorCount( monCount ); double tof = peak.getTOF(); Kernel::Units::Wavelength wl; wl.initialize(peak.getL1(), peak.getL2(), peak.getScattering(), 0, peak.getInitialEnergy(), 0.0); peak.setWavelength(wl.singleFromTOF( tof)); // Add the peak to workspace outWS->addPeak(peak); } catch (std::runtime_error & e) { g_log.warning() << "Error reading peak SEQN " << seqNum << " : " << e.what() << std::endl; } prog.report(); } }
//Merge Peaklists merge_lower and merge_upper void PeakListCollection::mergePeakLists_(unsigned int merge_lower, unsigned int merge_upper, std::vector<PeakList>& c, double drt, double dmz, double dz, double dint = 0.) { PeakList newPeakList; //Peaklists will be merged into newPeakList std::vector<map_item> newCorrespondenceMapColumn; //correspondenceMap information will be merged in here //get assignments via StableMarriage StableMarriage sm(c[merge_lower], c[merge_upper], drt, dmz, dz, dint); //set limit: do not assign Peaks with distance larger than 1. Note: normalization constants //drt and dmz must be adjusted properly. sm.setLimit(1.); StableMarriage::Assignment assign = sm.getAssignment(); //process peaks with a partner for(unsigned int i = 0; i < assign.ass12.size(); i++){ if(assign.ass12[i] > -1){ //write matched Peaks into newPeaklist //calculate average Rt, Mz and Intensity values //Peak1: PL: merge_lower ; Item: i ; plContent: correspondenceMap_[merge_lower][i].size() //Peak2: PL: merge_upper ; Item: assign.ass12[i] ; plContent: correspondenceMap_[merge_upper][assign.ass12[i]].size() //Number of peaks merged into single peak = size of originInformation vector double plc_lower = correspondenceMap_[merge_lower][i].size(); double plc_upper = correspondenceMap_[merge_upper][assign.ass12[i]].size(); double avRt = (c[merge_lower][i].getRt()*plc_lower + c[merge_upper][assign.ass12[i]].getRt()*plc_upper) / (plc_lower + plc_upper); double avMz = (c[merge_lower][i].getMz()*plc_lower + c[merge_upper][assign.ass12[i]].getMz()*plc_upper) / (plc_lower + plc_upper); double avInt = (c[merge_lower][i].getAbundance()*plc_lower + c[merge_upper][assign.ass12[i]].getAbundance()*plc_upper) / (plc_lower + plc_upper); //create temporary peak and fill with averaged values Peak temp; temp.setCharge(c[merge_lower][i].getCharge()); //charge is assumed to be equal temp.setRt(avRt); temp.setMz(avMz); temp.setAbundance(avInt); //add temporary peak to peaklist newPeakList.push_back(temp); //write origin information of matched peaks map_item tempItem; //copy all origin information from merge_lower for(unsigned int j = 0; j < correspondenceMap_[merge_lower][i].size(); j++){ tempItem.push_back(correspondenceMap_[merge_lower][i][j]); } //copy all origin information from merge_upper for(unsigned int j = 0; j < correspondenceMap_[merge_upper][assign.ass12[i]].size(); j++){ tempItem.push_back(correspondenceMap_[merge_upper][assign.ass12[i]][j]); } //add item to column newCorrespondenceMapColumn.push_back(tempItem); } } //process PeakList merge_lower for(unsigned int i = 0; i < assign.ass12.size(); i++){ if(assign.ass12[i] == -1){ newPeakList.push_back(c[merge_lower][i]); map_item tempItem; //copy all origin information for(unsigned int j = 0; j < correspondenceMap_[merge_lower][i].size(); j++){ tempItem.push_back(correspondenceMap_[merge_lower][i][j]); } newCorrespondenceMapColumn.push_back(tempItem); } } //process PeakList merge_upper for(unsigned int i = 0; i < assign.ass21.size(); i++){ if(assign.ass21[i] == -1){ newPeakList.push_back(c[merge_upper][i]); map_item tempItem; //copy all origin information for(unsigned int j = 0; j < correspondenceMap_[merge_upper][i].size(); j++){ tempItem.push_back(correspondenceMap_[merge_upper][i][j]); } newCorrespondenceMapColumn.push_back(tempItem); } } //refresh correspondence map //erase merged columns correspondenceMap_.erase(correspondenceMap_.begin()+merge_upper); correspondenceMap_.erase(correspondenceMap_.begin()+merge_lower); //add new column correspondenceMap_.push_back(newCorrespondenceMapColumn); //refresh peaklist collection c //erase merged peaklists c.erase(c.begin()+merge_upper); c.erase(c.begin()+merge_lower); //add new peaklist c.push_back(newPeakList); //update plContent_ plContent_.push_back(plContent_[merge_lower] + plContent_[merge_upper]); plContent_.erase(plContent_.begin()+merge_upper); plContent_.erase(plContent_.begin()+merge_lower); return; }
int PeakProcessor::DiscoverPeaks (std::vector<double> *vect_mz, std::vector<double> *vect_intensity, double start_mz, double stop_mz) { if(vect_intensity->size() < 1) return 0 ; mobj_peak_data->Clear() ; int num_data_pts = (int) (*vect_intensity).size() ; int ilow ; int ihigh ; Peak peak ; int start_index = mobj_pk_index.GetNearestBinary(*vect_mz, start_mz, 0, num_data_pts-1) ; int stop_index = mobj_pk_index.GetNearestBinary(*vect_mz, stop_mz, start_index, num_data_pts-1) ; if (start_index <= 0) start_index = 1 ; if (stop_index >= (int)vect_mz->size() -2) stop_index = (int)vect_mz->size() - 2 ; for (int index = start_index ; index <= stop_index ; index++) { double FWHM = -1 ; double current_intensity = (*vect_intensity)[index] ; double last_intensity = (*vect_intensity)[index-1] ; double next_intensity = (*vect_intensity)[index+1] ; double current_mz = (*vect_mz)[index] ; if (menm_profile_type == CENTROIDED) { if (current_intensity >= mdbl_peak_intensity_threshold) { double mass_ = (*vect_mz)[index] ; double SN = current_intensity / mdbl_peak_intensity_threshold ; double FWHM = 0.6 ; peak.Set(mass_, current_intensity, SN, mobj_peak_data->GetNumPeaks(), index, FWHM) ; mobj_peak_data->AddPeak(peak) ; } } else if (menm_profile_type == PROFILE) { if(current_intensity >= last_intensity && current_intensity >= next_intensity && current_intensity >= this->mdbl_peak_intensity_threshold) { //See if the peak meets the conditions. //The peak data will be found at _transformData->begin()+i+1. double SN = 0 ; if (!mbln_thresholded_data) SN = this->mobj_peak_statistician.FindSignalToNoise(current_intensity, (*vect_intensity), index); else SN = current_intensity / mdbl_background_intensity ; // Run Full-Width Half-Max algorithm to try and squeak out a higher SN if(SN < this->mdbl_signal_2_noise_threshold) { double mass_ = (*vect_mz)[index] ; FWHM = this->mobj_peak_statistician.FindFWHM((*vect_mz), (*vect_intensity), index, SN); if(FWHM > 0 && FWHM < 0.5) { ilow = mobj_pk_index.GetNearestBinary((*vect_mz), current_mz - FWHM, 0, index); ihigh = mobj_pk_index.GetNearestBinary((*vect_mz), current_mz + FWHM, index, stop_index); double low_intensity = (*vect_intensity)[ilow] ; double high_intensity = (*vect_intensity)[ihigh] ; double sum_intensity = low_intensity + high_intensity ; if(sum_intensity) SN = (2.0 * current_intensity) / sum_intensity ; else SN = 10; } } // Found a peak, make sure it is in the attention list, if there is one. if(SN >= this->mdbl_signal_2_noise_threshold && ( !this->mbln_chk_attention_list || this->IsInAttentionList(current_mz))) { // Find a more accurate m/z location of the peak. double fittedPeak = mobj_peak_fit.Fit(index, (*vect_mz), (*vect_intensity)); if (FWHM == -1) { FWHM = this->mobj_peak_statistician.FindFWHM((*vect_mz), (*vect_intensity), index, SN); } if (FWHM > 0) { peak.Set(fittedPeak, current_intensity, SN, mobj_peak_data->GetNumPeaks(), index, FWHM) ; mobj_peak_data->AddPeak(peak) ; } // move beyond peaks have the same intensity. bool incremented = false ; while( index < num_data_pts && (*vect_intensity)[index] == current_intensity) { incremented = true ; index++ ; } if(index > 0 && index < num_data_pts && incremented) index-- ; } } } } mobj_peak_data->mptr_vect_mzs = vect_mz ; mobj_peak_data->mptr_vect_intensities = vect_intensity ; return mobj_peak_data->GetNumPeaks() ; }