示例#1
0
 private static short AddMassError(ICollection <short> massErrors10X, double massError)
 {
     if (massErrors10X != null)
     {
         short massError10X = ChromPeak.To10x(massError);
         massErrors10X.Add(massError10X);
         return(massError10X);
     }
     return(0);
 }
示例#2
0
 private static void WriteMassErrors(Stream stream, IList <float> values)
 {
     PrimitiveArrays.Write(stream, values.Select(value => ChromPeak.To10x(value)).ToArray());
 }
示例#3
0
        public TimeIntensities Interpolate(IList <float> timesNew, bool inferZeros)
        {
            if (timesNew.Count == 0)
            {
                return(this);
            }
            double intervalDelta = 0;

            if (timesNew.Count > 1)
            {
                intervalDelta = (timesNew[timesNew.Count - 1] - timesNew[0]) / (timesNew.Count - 1);
            }

            var           timesMeasured      = Times;
            var           intensMeasured     = Intensities;
            IList <float> massErrorsMeasured = MassErrors;

            var intensNew     = new List <float>();
            var massErrorsNew = massErrorsMeasured != null ? new List <float>() : null;

            int    iTime         = 0;
            double timeLast      = timesNew[0];
            double intenLast     = 0;
            double massErrorLast = 0;

            if (!inferZeros && intensMeasured.Count != 0)
            {
                intenLast = intensMeasured[0];
                if (massErrorsMeasured != null)
                {
                    massErrorLast = massErrorsMeasured[0];
                }
            }
            for (int i = 0; i < timesMeasured.Count && iTime < timesNew.Count; i++)
            {
                double intenNext;
                float  time       = timesMeasured[i];
                float  inten      = intensMeasured[i];
                double totalInten = inten;
                double massError  = 0;
                if (massErrorsMeasured != null)
                {
                    massError = massErrorsMeasured[i];
                }

                // Continue enumerating points until one is encountered
                // that has a greater time value than the point being assigned.
                while (i < timesMeasured.Count - 1 && time < timesNew[iTime])
                {
                    i++;
                    time  = timesMeasured[i];
                    inten = intensMeasured[i];

                    if (massErrorsMeasured != null)
                    {
                        // Average the mass error in these points weigthed by intensity
                        // into the next mass error value
                        totalInten += inten;
                        // TODO: Figure out whether this is an appropriate estimation method
                        massError += (massErrorsMeasured[i] - massError) * inten / totalInten;
                    }
                }

                if (i >= timesMeasured.Count)
                {
                    break;
                }

                // If the next measured intensity is more than the new delta
                // away from the intensity being assigned, then interpolate
                // the next point toward zero, and set the last intensity to
                // zero.
                if (inferZeros && intenLast > 0 && timesNew[iTime] + intervalDelta < time)
                {
                    intenNext = intenLast +
                                (timesNew[iTime] - timeLast) * (0 - intenLast) /
                                (timesNew[iTime] + intervalDelta - timeLast);
                    intensNew.Add((float)intenNext);
                    AddMassError(massErrorsNew, massError);
                    timeLast  = timesNew[iTime++];
                    intenLast = 0;
                }

                if (inferZeros)
                {
                    // If the last intensity was zero, and the next measured time
                    // is more than a delta away, assign zeros until within a
                    // delta of the measured intensity.
                    while (intenLast == 0 && iTime < timesNew.Count && timesNew[iTime] + intervalDelta < time)
                    {
                        intensNew.Add(0);
                        AddMassError(massErrorsNew, massError);
                        timeLast = timesNew[iTime++];
                    }
                }
                else
                {
                    // Up to just before the current point, project the line from the
                    // last point to the current point at each interval.
                    while (iTime < timesNew.Count && timesNew[iTime] + intervalDelta < time)
                    {
                        intenNext = intenLast + (timesNew[iTime] - timeLast) * (inten - intenLast) / (time - timeLast);
                        intensNew.Add((float)intenNext);
                        AddMassError(massErrorsNew, massError);
                        iTime++;
                    }
                }

                if (iTime >= timesNew.Count)
                {
                    break;
                }

                // Interpolate from the last intensity toward the measured
                // intenisty now within a delta of the point being assigned.
                if (time == timeLast)
                {
                    intenNext = intenLast;
                }
                else
                {
                    intenNext = intenLast + (timesNew[iTime] - timeLast) * (inten - intenLast) / (time - timeLast);
                }
                intensNew.Add((float)intenNext);
                massErrorLast = AddMassError(massErrorsNew, massError);
                iTime++;
                intenLast = inten;
                timeLast  = time;
            }

            // Fill any unassigned intensities with zeros.
            while (intensNew.Count < timesNew.Count)
            {
                intensNew.Add(0);
                AddMassError(massErrorsNew, massErrorLast);
            }
            int[] scanIndexesNew = null;
            // Replicate scan ids to match new times.
            if (ScanIds != null)
            {
                scanIndexesNew = new int[timesNew.Count];
                int rawIndex = 0;
                for (int i = 0; i < timesNew.Count; i++)
                {
                    // Choose the RawScanId corresponding to the closest RawTime to the new time.
                    float newTime = timesNew[i];
                    while (rawIndex < Times.Count && Times[rawIndex] <= newTime)
                    {
                        rawIndex++;
                    }
                    if (rawIndex >= Times.Count)
                    {
                        rawIndex--;
                    }
                    if (rawIndex > 0 && newTime - Times[rawIndex - 1] < Times[rawIndex] - newTime)
                    {
                        rawIndex--;
                    }
                    scanIndexesNew[i] = ScanIds[rawIndex];
                }
            }

            IEnumerable <float> massErrorsNewTruncated = null;

            if (massErrorsNew != null)
            {
                // Round off all the mass errors, since that is what will be persisted in the .skyd file
                massErrorsNewTruncated = massErrorsNew.Select(error => ChromPeak.To10x(error) / 10f);
            }
            return(new TimeIntensities(timesNew, intensNew, massErrorsNewTruncated, scanIndexesNew));
        }