/** * put the pointers into an array sorted by mass * * @param Peptol the precursor mass tolerance * @param Zdep should the tolerance be charge dependent? * @return maximum m/z value */ int CMSPeakSet::SortPeaks(int Peptol, int Zdep, int Numisotopes, bool Pepppm, int ChargeSign) { int iCharges; CMSPeak* Peaks; TPeakSet::iterator iPeakSet; int CalcMass; // the calculated mass TMassPeak *temp; int ptol; // charge corrected mass tolerance int MaxMZ(0); MassIntervals.Clear(); // first sort for(iPeakSet = GetPeaks().begin(); iPeakSet != GetPeaks().end(); iPeakSet++ ) { Peaks = *iPeakSet; // skip empty spectra if(Peaks->GetError() == eMSHitError_notenuffpeaks) continue; // loop thru possible charges for(iCharges = 0; iCharges < Peaks->GetNumCharges(); iCharges++) { // correction for incorrect charge determination. // see 12/13/02 notebook, pg. 135 if(Pepppm) { ptol = (Zdep * (Peaks->GetCharges()[iCharges] - 1) + 1); ptol *= Peptol; ptol *= MSSCALE2DBL(Peaks->GetPrecursormz()) / 1000000.0; } else ptol = (Zdep * (Peaks->GetCharges()[iCharges] - 1) + 1) * Peptol; int iIsotopes; for(iIsotopes = 0; iIsotopes <= Numisotopes; ++iIsotopes) { temp = new TMassPeak; CalcMass = Peaks->GetPrecursormz() * Peaks->GetCharges()[iCharges] - MSSCALE2INT(Peaks->GetCharges()[iCharges]*kProton) * ChargeSign; temp->ExpMass = CalcMass; CalcMass = CalcMass - MSSCALE2INT(iIsotopes*kNeutron); // correction for c-13 temp->Mass = CalcMass; temp->Peptol = ptol; temp->Charge = Peaks->GetCharges()[iCharges]; temp->Peak = Peaks; // save the TMassPeak info const CRange<ncbi::TSignedSeqPos> myrange(temp->Mass - temp->Peptol, temp->Mass + temp->Peptol); const ncbi::CConstRef<ncbi::CObject> myobject(static_cast <CObject *> (temp)); MassIntervals.Insert(myrange, myobject); // keep track of maximum m/z if(temp->Mass + temp->Peptol > MaxMZ) MaxMZ = temp->Mass + temp->Peptol; } } } return MaxMZ; }
void Clonality::AddClonalPenalty(std::vector<float> const& signalInFlow, std::vector<int> const& keyLen, int const fnum, std::vector<int>& flowCount, std::vector<float>& penalty) { // adds the penalty for every bead in this flow // characterize the flow using signal across beads std::vector<double> peaks; GetPeaks(signalInFlow, peaks); scprint( this, "adjusted_peaks=%d;\n", (int)peaks.size()); // debug_peaks.assign(peaks.begin(), peaks.end()); size_t npeaks = peaks.size(); if (npeaks < 2) { // this flow needs to have at least 2 peaks to be used return; } // if signal is too low a bead will rejected float too_low = peaks[0] -(peaks[1] - peaks[0])*.8; scprint( this,"too_low = peaks[0] = %f - (peaks[1]=%f -peaks[0])*.8 = %f\n", peaks[0], peaks[1], too_low); // beads with signals near the 5th peak are 4-mers, ignore higher float missing = (npeaks < 5) ? 5 - npeaks : 0; float too_high = peaks[npeaks-1] + (missing + .5)*(peaks[1]-peaks[0]); scprint( this,"too_high = peaks[%d] = %f + (missing +.5 = %f) * (peaks[1] = %f - peaks[0] = %f) = %f\n", (int)npeaks-1, peaks[npeaks-1], (missing+.5), peaks[1], peaks[0], too_high); // given the flow characteristics, add the flow penalty to the overall penalty // for each bead. If a penalty is applied, also increment flowCount for the bead for (int ibd=0; ibd < (int)signalInFlow.size(); ibd++){ // key flows don't get penalized if (fnum < keyLen[ibd]) continue; // maximum penalty already applied #if __cplusplus >= 201103L if ( std::isinf(penalty[ibd]) ) #else if ( isinf(penalty[ibd]) ) #endif continue; // reject any bead where signal is not present by using maximum penalty if ( isnan( signalInFlow[ibd] )) { penalty[ibd] = numeric_limits<float>::infinity(); continue; } // reject any beads with signals that are too low using maximum penalty if (signalInFlow[ibd] < too_low) { // fprintf(stdout, "signalInFlow[%d]=%f < %f\n", (int)ibd, signalInFlow[ibd], too_low); penalty[ibd] = numeric_limits<float>::infinity(); continue; } // find the nearest peak and calculate the penalty bool found = false; for (size_t i=0; i < npeaks-1; i++) { if ( (signalInFlow[ibd] >= peaks[i]*1.5 -peaks[i+1]*.5) && (signalInFlow[ibd] < (peaks[i]+peaks[i+1])*.5) ) { float w = 1.0f/(i+1); // weight some peaks more heavily? penalty[ibd] += (signalInFlow[ibd]-peaks[i])*(signalInFlow[ibd]-peaks[i])*w; flowCount[ibd]++; found = true; break; } } if (found) continue; if ( (signalInFlow[ibd] >= (peaks[npeaks-2]+peaks[npeaks-1])*.5 ) && (signalInFlow[ibd] < (peaks[npeaks-1]*1.5 - peaks[npeaks-1]*.5) ) ) { float w = 1.0f/npeaks; penalty[ibd] += (signalInFlow[ibd]-peaks[npeaks-1])*(signalInFlow[ibd]-peaks[npeaks-1])*w; flowCount[ibd]++; continue; } // do not increase the penalty if signal is higher than known peaks // but not too high. Do not penalize the bead in this flow if ( (signalInFlow[ibd] >= (peaks[npeaks-1]*1.5 - peaks[npeaks-2]*.5) ) && (signalInFlow[ibd] < too_high)) { continue; } // reject any beads with signals that are too high if (signalInFlow[ibd] >= too_high){ // fprintf(stdout, "signalInFlow[%d]=%f > %f\n", (int)ibd, signalInFlow[ibd], too_high); penalty[ibd] = numeric_limits<float>::infinity(); continue; } } }