예제 #1
0
        public Peak1DArray ReadSpectrumPeaks(string spectrumID)
        {
            RaiseDisposed();

            try
            {
                int sampleIndex, experimentIndex, scanIndex;
                Parse(spectrumID, out sampleIndex, out experimentIndex, out scanIndex);

                using (MassSpectrometerSample sample = batch.GetSample(sampleIndex).MassSpectrometerSample)
                    using (MSExperiment msExp = sample.GetMSExperiment(experimentIndex))
                    {
                        Clearcore2.Data.MassSpectrum ms = msExp.GetMassSpectrum(scanIndex);
                        Peak1DArray pa = new Peak1DArray(
                            BinaryDataCompressionType.NoCompression,
                            BinaryDataType.Float32,
                            BinaryDataType.Float32);

                        //Peak1D[] peaks = new Peak1D[ms.NumDataPoints];

                        //for (int i = 0; i < ms.NumDataPoints; i++)
                        //    peaks[i] = new Peak1D(ms.GetYValue(i), ms.GetXValue(i));

                        //pa.Peaks = MzLiteArray.ToMzLiteArray(peaks);

                        pa.Peaks = new WiffPeaksArray(ms);

                        return(pa);
                    }
            }
            catch (Exception ex)
            {
                throw new MzLiteIOException(ex.Message, ex);
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WiffExperiment"/> class
        /// Base-Constructor. Performs the initalizations common to all experiments.
        /// </summary>
        /// <param name="msexperiment">Mass Spec Experiment</param>
        /// <param name="wiffsample">Wiff Sample</param>
        protected WiffExperiment(MSExperiment msexperiment, WiffSample wiffsample)
        {
            if (msexperiment == null)
            {
                throw new ArgumentNullException("msexperiment");
            }

            this.Init(msexperiment, wiffsample);
        }
예제 #3
0
 private static IEnumerable <MzLite.Model.MassSpectrum> Yield(Batch batch, int sampleIndex)
 {
     using (MassSpectrometerSample sample = batch.GetSample(sampleIndex).MassSpectrometerSample)
     {
         for (int experimentIndex = 0; experimentIndex < sample.ExperimentCount; experimentIndex++)
         {
             using (MSExperiment msExp = sample.GetMSExperiment(experimentIndex))
             {
                 for (int scanIndex = 0; scanIndex < msExp.Details.NumberOfScans; scanIndex++)
                 {
                     yield return(GetSpectrum(batch, sample, msExp, sampleIndex, experimentIndex, scanIndex));
                 }
             }
         }
     }
 }
예제 #4
0
        /// <summary>
        /// Determines with what kind of experiment we're dealing with and instatiates an object of the accurate
        /// subclass derived from the abstract baseclass read the experiments properties and data.
        /// WiffScanTypeEnumeration: Q1, MRM, SimQ1, Q3, SimQ3, Undefined, PrecursorIon, ProductIon, NeutralLoss, TofMS,
        /// TofProductIon, TofPrecursorIon, EnhancedProductIon, EnhancedResolution, MS3, TimeDelayFragmentation, EnhancedMS, EnhancedMulticharge,
        /// </summary>
        /// <param name="msexperiment"> The msexperiment. </param>
        /// <param name="wiffsample"> The wiffsample. </param>
        /// <returns> The newly created, <see cref="WiffExperiment"/> dirived object. </returns>
        public static WiffExperiment CreateWiffExperiment(MSExperiment msexperiment, WiffSample wiffsample)
        {
            ExperimentType expType = msexperiment.Details.ExperimentType;

            WiffExperiment theExperiment;

            switch (expType)
            {
            case ExperimentType.MRM:
            {
                theExperiment = new MrmScanExperiment(msexperiment, wiffsample);
            }

            break;

            case ExperimentType.MS:
            {
                theExperiment = new MsScanExperiment(msexperiment, wiffsample);
            }

            break;

            case ExperimentType.Precursor:
            case ExperimentType.NeutralGainOrLoss:
            case ExperimentType.Product:
            case ExperimentType.SIM:
            {
                theExperiment = new MsScanExperiment(msexperiment, wiffsample);
            }

            break;

            default:
            {
                // TODO -- Check if this is really, really intended...??
                theExperiment = new MrmScanExperiment(msexperiment, wiffsample);
            }

            break;
            }

            return(theExperiment);
        }
예제 #5
0
        private static bool GetIsolationWindow(
            MSExperiment exp,
            out double isoWidth,
            out double targetMz)
        {
            FragmentBasedScanMassRange mri = null;

            MassRange[] mr = exp.Details.MassRangeInfo;
            isoWidth = 0d;
            targetMz = 0d;

            if (mr.Length > 0)
            {
                mri      = mr[0] as FragmentBasedScanMassRange;
                isoWidth = mri.IsolationWindow * 0.5d;
                targetMz = mri.FixedMasses[0];
            }

            return(mri != null);
        }
예제 #6
0
        public MzLite.Model.MassSpectrum ReadMassSpectrum(string spectrumID)
        {
            RaiseDisposed();

            try
            {
                int sampleIndex, experimentIndex, scanIndex;
                Parse(spectrumID, out sampleIndex, out experimentIndex, out scanIndex);

                using (MassSpectrometerSample sample = batch.GetSample(sampleIndex).MassSpectrometerSample)
                    using (MSExperiment msExp = sample.GetMSExperiment(experimentIndex))
                    {
                        return(GetSpectrum(batch, sample, msExp, sampleIndex, experimentIndex, scanIndex));
                    }
            }
            catch (Exception ex)
            {
                throw new MzLiteIOException(ex.Message, ex);
            }
        }
예제 #7
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="inputMsExperiment"/>.
        /// </summary>
        /// <param name="inputMsExperiment">instance, the data source</param>
        /// <param name="wiffsample"> Wiff Sample</param>
        protected override void Initialize(MSExperiment inputMsExperiment, WiffSample wiffsample)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                // set the status information
                AppContext.StatusInfo = "Getting wiff-data";

                // (1) Get Maldi Parameters
                string strMaldiParams = wiffsample.MaldiParametersString;

                // (2) get the number of mass MRM transitions
                this.massRanges = inputMsExperiment.Details.MassRangeInfo.Length;

                // (3) select 1. MRM trace
                XYData tic = inputMsExperiment.GetTotalIonChromatogram();

                // (4) Dimension the data arrray, the number "data points"
                this.numDataPoint = tic.NumDataPoints;

                // (5) Set up arrays for info
                this.rawData       = new float[this.massRanges, this.numDataPoint];
                this.timeData      = new float[this.numDataPoint];
                this.dwellTime     = new double[this.massRanges];
                this.massRangeName = new string[this.massRanges];
                this.massRangeMax  = new double[this.massRanges];
                this.massRangeMin  = new double[this.massRanges];
                this.meanValues    = new float[this.massRanges];
                this.medianValues  = new float[this.massRanges];

                // helper for mean and median
                var valuesForMedian = new List <float>();

                // (6) loop through the mass ranges
                for (int actMassRange = 0; actMassRange < this.massRanges; actMassRange++)
                {
                    // get mass range object
                    this.massRangeName[actMassRange] = inputMsExperiment.Details.MassRangeInfo[actMassRange].Name;

                    this.dwellTime[actMassRange] = inputMsExperiment.Details.MassRangeInfo[actMassRange].DwellTime;

                    // loop through the spectrum
                    this.massRangeMax[actMassRange] = double.MinValue;
                    this.massRangeMin[actMassRange] = double.MaxValue;
                    double meanSum = 0.0;
                    valuesForMedian.Clear();

                    // Extract xic Full Scan
                    var option = new ExtractedIonChromatogramSettings(actMassRange);
                    ExtractedIonChromatogram xic = inputMsExperiment.GetExtractedIonChromatogram(option);

                    // JP 23/11 I think there might be a better way to do this.
                    for (int actDataPoint = 0; actDataPoint < this.numDataPoint; actDataPoint++)
                    {
                        // get the actual value
                        double anaXValue = xic.GetActualXValues()[actDataPoint];
                        double anaYValue = xic.GetActualYValues()[actDataPoint];

                        if (anaYValue < this.massRangeMin[actMassRange])
                        {
                            this.massRangeMin[actMassRange] = anaYValue;
                        }

                        if (anaYValue > this.massRangeMax[actMassRange])
                        {
                            this.massRangeMax[actMassRange] = anaYValue;
                        }

                        // now get the actual data
                        this.rawData[actMassRange, actDataPoint] = (float)anaYValue;
                        this.timeData[actDataPoint] = (float)anaXValue * 60;

                        // mean and median calculation...sum up the value to calculate the mean
                        meanSum += anaYValue;

                        // fill an extra array to calculate the median
                        valuesForMedian.Add((float)anaYValue);
                    }

                    // calculate the mean
                    this.meanValues[actMassRange] = (float)(meanSum / this.numDataPoint);

                    // calculate the median
                    valuesForMedian.Sort();
                    this.medianValues[actMassRange] = ((valuesForMedian.Count % 2) == 0) ? (valuesForMedian[(valuesForMedian.Count / 2) - 1] + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f : valuesForMedian[valuesForMedian.Count / 2];
                }

                // (7) time per point in sec
                this.timeinXDirection = (float)((tic.GetActualXValues()[this.numDataPoint - 1] - tic.GetActualXValues()[1]) * 60 / (this.numDataPoint - 2));

                // (8) Calculate distInXDirection: fetch the x1, x2, y1, y2, width and height from the WiffSample instance this experiment belongs to.
                double x1    = wiffsample.P1.X;
                double y2    = 82 - wiffsample.P1.Y;
                double x2    = wiffsample.P2.X;
                double width = wiffsample.Width;

                // (9) fetch the position data from the WiffSample instance this experiment belongs to.
                uint[,] posData = wiffsample.PositionData;
                long posDataLength = wiffsample.PositionDataLength;

                // try and find the first and last valid indices in the posData, where valid means a nonzero time value...
                long firstNonZeroTimeInPos = -1;
                for (long t = 0; t < posDataLength - 1; t++)
                {
                    if (posData[t, 0] > 0)
                    {
                        firstNonZeroTimeInPos = t + 1;
                        break; // ok, we're done...
                    }
                }

                long lastNonZeroTimeInPos = -1;
                for (long t = posDataLength - 1; t >= 0; t++)
                {
                    if (posData[t, 0] > 0)
                    {
                        lastNonZeroTimeInPos = t - 1;
                        break; // ok, we're done...
                    }
                }

                // (10) Make sure we have found valid values, bail out if not
                if (firstNonZeroTimeInPos < 0 || lastNonZeroTimeInPos < 0)
                {
                    // haven't found a valid posData triplet. All time values are zero or less...bail out
                    return;
                }

                // (11) Calculate distInYDirection
                this.distInYDirection = 0;
                for (long t = firstNonZeroTimeInPos; t < lastNonZeroTimeInPos; t++)
                {
                    if ((posData[t, 1] > ((x2 + x1) * 500)) & Equals(this.distInYDirection, 0.0))
                    {
                        this.distInYDirection = posData[t, 2];
                    }

                    if ((posData[t, 1] < ((x2 + x1) * 500)) & (this.distInYDirection > 0))
                    {
                        this.distInYDirection = (float)Math.Round((decimal)(posData[t, 2] - this.distInYDirection) / 500, (int)(1 - Math.Log10((posData[t, 2] - this.distInYDirection) / 500))) / 2;
                        break;
                    }
                }

                // (12) Calculate speed in x direction
                this.speedinXDirection = (float)Math.Round((posData[firstNonZeroTimeInPos + 2, 1] - posData[firstNonZeroTimeInPos + 1, 1]) / (decimal)(posData[firstNonZeroTimeInPos + 2, 0] - posData[firstNonZeroTimeInPos + 1, 0]) * 2, 0) / 2;

                // (13) distInXDirection
                this.distInXDirection = (float)(int)(this.speedinXDirection * this.timeinXDirection * 1000) / 1000;

                // (14) number of points in x
                this.numPointsOnXAxis = (int)(width / this.speedinXDirection / this.timeinXDirection);

                // (15) number of points in y
                // y2 from the wiff file is not the actual y2 from the stage - replace with value from path file...
                // JP added "82 -" so what we convert wiff format to analyse co-ordinate system
                var y1 = 82 - (double)Math.Round((decimal)posData[lastNonZeroTimeInPos, 2] / 1000, 2);

                // ...and this has an effect of the numPointsOnYAxis
                this.numPointsOnYAxis = (int)Math.Round((decimal)((y2 - y1) / this.distInYDirection) + 1);

                // (16) Calc Lines Breaks
                double syncTime1 = (float)posData[firstNonZeroTimeInPos, 0] / 1000;
                double syncTime2 = (float)posData[lastNonZeroTimeInPos, 0] / 1000;

                if (this.numPointsOnYAxis % 2 == 0)
                {
                    // even number of scanlines
                    this.lineBreak = ((syncTime2 - syncTime1)
                                      - ((x2 - ((float)posData[firstNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection)
                                      - (((this.numPointsOnYAxis - 2) * (x2 - x1)) / this.speedinXDirection)
                                      - ((x2 - ((float)posData[lastNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection))
                                     / (this.numPointsOnYAxis - 1);
                }
                else
                {
                    // odd number of scanlines
                    this.lineBreak = ((syncTime2 - syncTime1)
                                      - ((x2 - ((float)posData[firstNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection)
                                      - (((this.numPointsOnYAxis - 2) * (x2 - x1)) / this.speedinXDirection)
                                      - ((((float)posData[lastNonZeroTimeInPos, 1] / 1000) - x1) / this.speedinXDirection))
                                     / (this.numPointsOnYAxis - 1);
                }

                // (17) time offset
                this.timeOffset = ((float)posData[firstNonZeroTimeInPos, 0] / 1000) - ((((float)posData[firstNonZeroTimeInPos, 1] / 1000) - x1) / this.speedinXDirection);

                double dwellTimeSum = 0;

                AppContext.StatusInfo = string.Empty;

                // (18) Format Data
                for (int actMassRange = 0; actMassRange < this.massRanges; actMassRange++)
                {
                    // format the data into a rectangular, 2 dimensional array of floats that will represent the image data
                    var imageData = new float[this.numPointsOnXAxis][];
                    for (int i = 0; i < imageData.Length; i++)
                    {
                        imageData[i] = new float[this.numPointsOnYAxis];
                    }

                    dwellTimeSum -= this.dwellTime[actMassRange] / 1000 / 2;

                    double optTimeOffset = this.timeOffset;
                    double optLineBreak  = this.lineBreak;
                    if (AppContext.UseApproximation)
                    {
                        // Perform the optimization...
                        this.HeuristicOptimization(imageData, actMassRange, x2 - x1, dwellTimeSum, ref optLineBreak, ref optTimeOffset);
                    }

                    this.FormatImageSharp(imageData, actMassRange, x2 - x1, dwellTimeSum, optLineBreak, optTimeOffset);

                    dwellTimeSum -= this.dwellTime[actMassRange] / 1000 / 2;

                    // create the appropriate dataset and add it to the WiffFileContent object...
                    string   imgName = wiffsample.Name + " : " + this.massRangeName[actMassRange];
                    Document doc     = wiffsample.WiffFileContent.Document;

                    // create the meta information data structure and populate with relevant information...
                    var metaData = new ImageMetaData();
                    try
                    {
                        const float Epsilon = (float)1E-10;
                        metaData.Add("Sample Name", typeof(string), wiffsample.Name, false);
                        metaData.Add("Mass Range", typeof(string), this.massRangeName[actMassRange], false);
                        metaData.Add("X1 (mm)", typeof(string), (Math.Abs(x1 - (int)x1) < Epsilon) ? x1.ToString("0.0") : x1.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Y1 (mm)", typeof(string), (Math.Abs(y1 - (int)y1) < Epsilon) ? y1.ToString("0.0") : y1.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("X2 (mm)", typeof(string), (Math.Abs(x2 - (int)x2) < Epsilon) ? x2.ToString("0.0") : x2.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Y2 (mm)", typeof(string), (Math.Abs(y2 - (int)y2) < Epsilon) ? y2.ToString("0.0") : y2.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Data Points in X", typeof(string), this.numPointsOnXAxis.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Data Points in Y", typeof(string), this.numPointsOnYAxis.ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Point Width (mm)", typeof(string), Math.Round(this.distInXDirection, 2).ToString(CultureInfo.InvariantCulture), false);
                        metaData.Add("Point Height (mm)", typeof(string), Math.Round(this.distInYDirection, 2).ToString(CultureInfo.InvariantCulture), false);

                        // Add Maldi Parameters
                        string[] splitstring = strMaldiParams.Split(SepMaldiParams, StringSplitOptions.None);
                        metaData.Add("Laser Frequency (Hz)", typeof(string), splitstring[1], false);
                        metaData.Add("Laser Power (%)", typeof(string), splitstring[2], false);
                        metaData.Add("Ablation Mode", typeof(string), splitstring[3], false);
                        metaData.Add("Skimmer Voltage (V)", typeof(string), splitstring[4], false);
                        metaData.Add("Source Gas", typeof(string), splitstring[5], false);
                        metaData.Add("Raster Speed (mm/s)", typeof(string), splitstring[6], false);
                        metaData.Add("Line Direction", typeof(string), splitstring[7], false);
                        metaData.Add("Rastor Pitch ", typeof(string), splitstring[8], false);
                    }
                    catch (Exception e)
                    {
                        Util.ReportException(e);
                    }

                    // (19) Create new ImageData and add WiffContent to Wiffsample
                    wiffsample.WiffFileContent.Add(new ImageData(
                                                       doc,
                                                       imageData,
                                                       imgName,
                                                       metaData,
                                                       (float)this.massRangeMin[actMassRange],
                                                       (float)this.massRangeMax[actMassRange],
                                                       this.meanValues[actMassRange],
                                                       this.medianValues[actMassRange],
                                                       (float)this.distInXDirection,
                                                       (float)this.distInYDirection,
                                                       null,
                                                       Core.ExperimentType.MRM));
                }
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MrmScanExperiment"/> class
 /// </summary>
 /// <param name="msexperiment">Mass Spec Experiment</param>
 /// <param name="wiffsample">wiff sample</param>
 public MrmScanExperiment(MSExperiment msexperiment, WiffSample wiffsample)
     : base(msexperiment, wiffsample)
 {
 }
예제 #9
0
 /// <summary>
 /// Calls the virtual Initialize method
 /// </summary>
 /// <param name="msexperiment">Mass Spec Experiment</param>
 /// <param name="wiffsample">Wiff Sample</param>
 private void Init(MSExperiment msexperiment, WiffSample wiffsample)
 {
     this.Initialize(msexperiment, wiffsample);
 }
예제 #10
0
 /// <summary>
 /// Fills this instance data members with the information read from <paramref name="inputMsExperiment"/>
 /// </summary>
 /// <param name="inputMsExperiment">Mass Spec Experiment</param>
 /// <param name="wiffsample">Wiff Sample</param>
 protected abstract void Initialize(MSExperiment inputMsExperiment, WiffSample wiffsample);
예제 #11
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="inputMsExperiment"/>
        /// </summary>
        /// <param name="inputMsExperiment">Mass Spec Experiment</param>
        /// <param name="wiffsample">Wiff Sample</param>
        protected override void Initialize(MSExperiment inputMsExperiment, WiffSample wiffsample)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                // (1) Get Maldi Parameters
                string strMaldiParams = wiffsample.MaldiParametersString;

                this.msexperiment = inputMsExperiment;

                // (2) Get the number of mass transitions - For MS experiments by default we will look at the first scan ([0])
                MassRange massRange         = this.msexperiment.Details.MassRangeInfo[0];
                var       fullScanMassRange = massRange as FullScanMassRange;

                if (fullScanMassRange != null)
                {
                    this.minMass      = fullScanMassRange.StartMass;
                    this.maxMass      = fullScanMassRange.EndMass;
                    this.massStepSize = fullScanMassRange.StepSize;
                }

                this.massSpecDataPoints = (int)(((this.maxMass - this.minMass) / this.massStepSize) + 1);

                // (3) Populate masscal
                this.masscal = new float[this.massSpecDataPoints];

                for (int i = 0; i < this.massSpecDataPoints; i++)
                {
                    this.masscal[i] = (float)(this.minMass + (i * this.massStepSize));
                }

                // (4) Select 1 trace
                XYData tic = this.msexperiment.GetTotalIonChromatogram();

                // (5) Dimension the data array, the number "data points"
                this.numDataPoints = tic.NumDataPoints;

                this.rawData  = new float[this.numDataPoints];
                this.timeData = new float[this.numDataPoints];

                // (6) mass range info
                this.massRangeName = "TIC " + this.msexperiment.Details.MassRangeInfo[0].Name;

                double actualXValue = tic.GetActualXValues()[0];
                this.massRangeMax = double.MinValue;
                this.massRangeMin = double.MaxValue;
                this.timeOffset   = actualXValue * 1000;

                // helper for mean and median
                double meanSum         = 0;
                var    valuesForMedian = new List <float>();

                // (7) read the data...
                for (int actDataPoint = 0; actDataPoint < this.numDataPoints; actDataPoint++)
                {
                    // get the actual value...
                    actualXValue = tic.GetActualXValues()[actDataPoint];
                    double actualYValue = tic.GetActualYValues()[actDataPoint];

                    // and copy it to our local data structure
                    this.rawData[actDataPoint]  = (float)actualYValue;
                    this.timeData[actDataPoint] = (float)actualXValue * 60;

                    // keep track of the extrema
                    if (actualYValue < this.massRangeMin)
                    {
                        this.massRangeMin = actualYValue;
                    }

                    if (actualYValue > this.massRangeMax)
                    {
                        this.massRangeMax = actualYValue;
                    }

                    // mean and median calculation... sum up the value to calculate the mean
                    meanSum += actualYValue;

                    // fill an extra array to calculate the median
                    valuesForMedian.Add((float)actualYValue);
                }

                // (8) Calculate the mean
                this.meanValue = (float)(meanSum / this.numDataPoints);

                // (9) Calculate the median
                valuesForMedian.Sort();
                this.medianValue = ((valuesForMedian.Count % 2) == 0) ? (valuesForMedian[(valuesForMedian.Count / 2) - 1] + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f : valuesForMedian[valuesForMedian.Count / 2];

                // (10) fetch the x1, x2, y1, y2, width and height from the WiffSample instance this experiment belongs to.
                this.x1    = wiffsample.P1.X;
                this.y2    = 82 - wiffsample.P1.Y;
                this.x2    = wiffsample.P2.X;
                this.width = wiffsample.Width;

                // (11) time per point in s
                this.timeinXDirection = (float)((tic.GetActualXValues()[this.numDataPoints - 1] - tic.GetActualXValues()[1]) * 60 / (this.numDataPoints - 2));

                // (12) fetch the position data from the WiffSample instance this experiment belongs to.
                uint[,] posData = wiffsample.PositionData;
                long posDataLength = wiffsample.PositionDataLength;

                // try and find the first and last valid indices in the posData, where valid means a nonzero time value...
                long firstNonZeroTimeInPos = -1;
                for (long t = 0; t < posDataLength - 1; t++)
                {
                    if (posData[t, 0] > 0)
                    {
                        firstNonZeroTimeInPos = t;

                        break;
                    }
                }

                long lastNonZeroTimeInPos = -1;
                for (long t = posDataLength - 1; t >= 0; t++)
                {
                    if (posData[t, 0] > 0)
                    {
                        lastNonZeroTimeInPos = t;

                        break;
                    }
                }

                if (firstNonZeroTimeInPos < 0 || lastNonZeroTimeInPos < 0)
                {
                    // haven't found a valid posData triplet. All time values are zero or less... bail out (Put in an Error Message here?)
                    return;
                }

                // (13) Distance in Y direction
                this.distInYDirection = 0;
                for (long t = firstNonZeroTimeInPos; t < lastNonZeroTimeInPos; t++)
                {
                    if ((posData[t, 1] > ((this.x2 + this.x1) * 500)) & Equals(this.distInYDirection, 0.0))
                    {
                        this.distInYDirection = posData[t, 2];
                    }

                    if ((posData[t, 1] < ((this.x2 + this.x1) * 500)) & (this.distInYDirection > 0))
                    {
                        this.distInYDirection = (float)Math.Round((decimal)(posData[t, 2] - this.distInYDirection) / 500, (int)(1 - Math.Log10((posData[t, 2] - this.distInYDirection) / 500))) / 2;
                        break;
                    }
                }

                // (14) calculate speed in x direction
                this.speedinXDirection = (float)Math.Round(((posData[firstNonZeroTimeInPos + 2, 1] - posData[firstNonZeroTimeInPos + 1, 1]) / (decimal)(posData[firstNonZeroTimeInPos + 2, 0] - posData[firstNonZeroTimeInPos + 1, 0]) * 2), 0) / 2;

                // (15) distInXDirection
                this.distInXDirection = (float)(int)(this.speedinXDirection * this.timeinXDirection * 1000) / 1000;

                // (16) number of points in x
                this.numPointsOnXAxis = (int)(this.width / this.speedinXDirection / this.timeinXDirection);

                // (17) number of points in y
                // y1 from the wiff file is not the actual y1 from the stage - replace with value from path file...
                this.y1 = 82 - (double)Math.Round(((decimal)posData[lastNonZeroTimeInPos, 2] / 1000), 2);

                // ...and this has an effect of the ypoints
                this.numPointsOnYAxis = (int)Math.Round((decimal)((this.y2 - this.y1) / this.distInYDirection) + 1);

                // (18) calculate the line breaks
                var timeSpanPos = (posData[lastNonZeroTimeInPos, 0] / 1000.0)
                                  - (posData[firstNonZeroTimeInPos, 0] / 1000.0);

                if (this.numPointsOnYAxis % 2 == 0)
                {
                    // even number of scanlines
                    this.lineBreak = (timeSpanPos - ((this.x2 - ((float)posData[firstNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection)
                                      - (((this.numPointsOnYAxis - 2) * this.width) / this.speedinXDirection)
                                      - ((this.x2 - ((float)posData[lastNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection)) / (this.numPointsOnYAxis - 1);
                }
                else
                {
                    // odd number of scanlines
                    this.lineBreak = (timeSpanPos - ((this.x2 - ((float)posData[firstNonZeroTimeInPos, 1] / 1000)) / this.speedinXDirection)
                                      - (((this.numPointsOnYAxis - 2) * this.width) / this.speedinXDirection)
                                      - ((((float)posData[lastNonZeroTimeInPos, 1] / 1000) - this.x1) / this.speedinXDirection)) / (this.numPointsOnYAxis - 1);
                }

                this.lineBreak = this.lineBreak / this.timeinXDirection;

                this.timeOffset = ((float)posData[firstNonZeroTimeInPos, 0] / 1000)
                                  - ((((float)posData[firstNonZeroTimeInPos, 1] / 1000) - this.x1) / this.speedinXDirection);

                this.lineOffset = (5 - ((this.timeData[5] - this.timeOffset) / this.timeinXDirection)) + 1;

                // TIC throughout the total massrange...
                // format the data into a rectangular, 2 dimensional array of floats that will represent the image data
                AppContext.ProgressStart("formatting image data...");

                // (19) copy the data from wiff file datastream to the rectangular array. Take account of the line offset and the line break timings
                float[][] dataTic;

                try
                {
                    dataTic            = new float[this.numPointsOnXAxis][];
                    this.sampleDataPos = new int[this.numPointsOnXAxis][];

                    for (int i = 0; i < dataTic.Length; i++)
                    {
                        dataTic[i]            = new float[this.numPointsOnYAxis];
                        this.sampleDataPos[i] = new int[this.numPointsOnYAxis];
                    }

                    for (int pointOnYAxis = 0; pointOnYAxis < this.numPointsOnYAxis; pointOnYAxis++)
                    {
                        // currentLine is the offset to the start of the current line in the linear datastream (rawData)
                        var currentLine = (int)Math.Floor(Math.Abs(this.lineOffset
                                                                   + (((((this.x2 - this.x1) / this.speedinXDirection) / this.timeinXDirection)
                                                                       + this.lineBreak) * pointOnYAxis)));
                        for (int pointOnXAxis = 0; pointOnXAxis < this.numPointsOnXAxis; pointOnXAxis++)
                        {
                            int currentPoint;
                            if (pointOnYAxis % 2 == 0)
                            {
                                // even y: scan direction: -->
                                currentPoint = currentLine + pointOnXAxis;
                            }
                            else
                            {
                                // odd y:  scan direction: <--
                                currentPoint = currentLine + this.numPointsOnXAxis - 1 - pointOnXAxis;
                            }

                            if (currentPoint < this.numDataPoints)
                            {
                                dataTic[pointOnXAxis][this.numPointsOnYAxis - 1 - pointOnYAxis] = this.rawData[currentPoint];

                                // Add in a new array to save these dataPos. We can use them to get the scan number
                                // Scan number is the current point
                                this.sampleDataPos[pointOnXAxis][this.numPointsOnYAxis - 1 - pointOnYAxis] = currentPoint;
                            }
                            else
                            {
                                dataTic[pointOnXAxis][this.numPointsOnYAxis - 1 - pointOnYAxis]            = 0;
                                this.sampleDataPos[pointOnXAxis][this.numPointsOnYAxis - 1 - pointOnYAxis] = 0;
                            }
                        }

                        AppContext.ProgressSetValue((100.0 * pointOnYAxis) / this.numPointsOnYAxis);
                    }
                }
                finally
                {
                    AppContext.ProgressClear();
                }

                // (20) create the appropriate dataset and add it to the WiffFileContent object...
                string   imgName = wiffsample.Name + " : " + this.massRangeName;
                Document doc     = wiffsample.WiffFileContent.Document;

                // (21) Calculate Bin Points
                // Set a default bin size of 1 - Important it is set to 1 and not zero
                this.binsize = 1;
                this.GetBinSize(wiffsample.ScanFileSize, this.numPointsOnXAxis, this.numPointsOnYAxis);

                // By default we set this to massSpecDataPoints
                this.binnedmassSpecDataPoints = this.massSpecDataPoints;

                if (this.binsize > 1)
                {
                    this.binnedmassSpecDataPoints = this.massSpecDataPoints / this.binsize;
                }

                // create the meta information data structure and populate with relevant information...
                var metaData = new ImageMetaData();
                try
                {
                    const float Epsilon = (float)1E-10;
                    metaData.Add("Sample Name", typeof(string), wiffsample.Name, false);
                    metaData.Add("Mass Range", typeof(string), this.massRangeName, false);
                    metaData.Add("Mass Step Size", typeof(string), this.massStepSize, false);
                    metaData.Add("X1 (mm)", typeof(string), (Math.Abs(this.x1 - (int)this.x1) < Epsilon) ? this.x1.ToString("0.0") : this.x1.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Y1 (mm)", typeof(string), (Math.Abs(this.y1 - (int)this.y1) < Epsilon) ? this.y1.ToString("0.0") : this.y1.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("X2 (mm)", typeof(string), (Math.Abs(this.x2 - (int)this.x2) < Epsilon) ? this.x2.ToString("0.0") : this.x2.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Y2 (mm)", typeof(string), (Math.Abs(this.y2 - (int)this.y2) < Epsilon) ? this.y2.ToString("0.0") : this.y2.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Data Points in X", typeof(string), this.numPointsOnXAxis.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Data Points in Y", typeof(string), this.numPointsOnYAxis.ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Point Width (mm)", typeof(string), Math.Round(this.distInXDirection, 2).ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Point Height (mm)", typeof(string), Math.Round(this.distInYDirection, 2).ToString(CultureInfo.InvariantCulture), false);
                    metaData.Add("Bin Size", typeof(string), this.binsize.ToString(CultureInfo.InvariantCulture), false);

                    // Add Maldi Parameters
                    string[] splitstring = strMaldiParams.Split(SepMaldiParams, StringSplitOptions.None);
                    metaData.Add("Laser Frequency (Hz)", typeof(string), splitstring[1], false);
                    metaData.Add("Laser Power (%)", typeof(string), splitstring[2], false);
                    metaData.Add("Ablation Mode", typeof(string), splitstring[3], false);
                    metaData.Add("Skimmer Voltage (V)", typeof(string), splitstring[4], false);
                    metaData.Add("Source Gas", typeof(string), splitstring[5], false);
                    metaData.Add("Raster Speed (mm/s)", typeof(string), splitstring[6], false);
                    metaData.Add("Line Direction", typeof(string), splitstring[7], false);
                    metaData.Add("Rastor Pitch ", typeof(string), splitstring[8], false);
                }
                catch (Exception e)
                {
                    Util.ReportException(e);
                }

                // (22) Create the ImageData
                var imageTic = new ImageData(
                    doc,
                    dataTic,
                    imgName,
                    metaData,
                    (float)this.massRangeMin,
                    (float)this.massRangeMax,
                    this.meanValue,
                    this.medianValue,
                    (float)this.distInXDirection,
                    (float)this.distInYDirection,
                    this.masscal,
                    Core.ExperimentType.MS);

                // (23) Collate the Spectrum Data
                List <ImageData> imageDataList = null;

                try
                {
                    // (24) Create a list of array's to hold the mass spec images (in effect a 3x3 array or a list of 2x2 array)
                    this.dataList = new List <float[][]>();
                    for (int numMassSpecDataPts = 0; numMassSpecDataPts < this.binnedmassSpecDataPoints; numMassSpecDataPts++)
                    {
                        var data = new float[this.numPointsOnXAxis][];
                        for (int pointOnXAxis = 0; pointOnXAxis < this.numPointsOnXAxis; pointOnXAxis++)
                        {
                            data[pointOnXAxis] = new float[this.numPointsOnYAxis];
                        }

                        this.dataList.Add(data);
                    }

                    // (25) Populate dataList. We can populate this by Scan (PopulateListByScan()) Or MassSpec (PopulateListByMass())
                    // For now we will use by Scan as it is more effcient
                    this.PopulateListByScan();

                    // (26) Create the list of imageData objects passed to the imageSpectrumData object on it's creation later on...
                    imageDataList = new List <ImageData>();

                    for (int massSpecDataPt = 0; massSpecDataPt < this.binnedmassSpecDataPoints; massSpecDataPt++)
                    {
                        float[][] specData = this.dataList[massSpecDataPt];

                        imgName = wiffsample.Name + " : " + this.massRangeName;

                        // TODO -- rethink if one should really calculate the mean, median, min, max etc. if the images aren't used for imaging but for export...
                        float minInt = float.MaxValue;
                        float maxInt = float.MinValue;

                        // helper for mean and median
                        meanSum = 0;
                        valuesForMedian.Clear();
                        {
                            for (int x = 0; x < this.numPointsOnXAxis; x++)
                            {
                                for (int y = 0; y < this.numPointsOnYAxis; y++)
                                {
                                    float value = specData[x][y];

                                    // keep track of the extrema
                                    if (value < minInt)
                                    {
                                        minInt = value;
                                    }

                                    if (value > maxInt)
                                    {
                                        maxInt = value;
                                    }

                                    // mean and median calculation...
                                    // sum up the value to calculate the mean
                                    meanSum += value;

                                    // fill an extra array to calculate the median
                                    valuesForMedian.Add(value);
                                }
                            }
                        }

                        // calculate the mean
                        var mean = (float)(meanSum / (this.numPointsOnXAxis * this.numPointsOnYAxis));

                        // calculate the median
                        valuesForMedian.Sort();
                        float median = ((valuesForMedian.Count % 2) == 0)
                                           ? (valuesForMedian[(valuesForMedian.Count / 2) - 1]
                                              + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f
                                           : valuesForMedian[valuesForMedian.Count / 2];

                        // ok, now create the imageData and add to list...
                        var imageData = new ImageData(
                            doc,
                            specData,
                            imgName,
                            metaData,
                            minInt,
                            maxInt,
                            mean,
                            median,
                            (float)this.distInXDirection,
                            (float)this.distInYDirection,
                            this.masscal,
                            Core.ExperimentType.MS);
                        imageDataList.Add(imageData);
                    }
                }
                catch (Exception e)
                {
                    Util.ReportException(e);
                }

                // (27) Now everything should be set to create the ImageSpectrumData object...
                imgName = wiffsample.Name + " SPECT " + this.massRangeMin.ToString(CultureInfo.InvariantCulture) + " - " + this.massRangeMax.ToString(CultureInfo.InvariantCulture);

                var imageSpectrum = new ImageSpectrumData(
                    doc,
                    imgName,
                    metaData,
                    this.masscal,
                    imageDataList,
                    Core.ExperimentType.MS)
                {
                    ImageTic = imageTic
                };

                wiffsample.WiffFileContent.Add(imageSpectrum);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
예제 #12
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="Batch"/> instance. The data source.</param>
        private void Initialize(Batch wiffFile)
        {
            Sample sample = wiffFile.GetSample(this.index);

            // retrieve this sample's name
            this.name = sample.Details.SampleName;

            // get the position information for the selected sample the position data exists
            // in a seperate file ( one per sample ) and is read from that file 'manually'
            AppContext.ProgressStart("reading path file");
            try
            {
                // 1) Set the various WiffSample Parameters
                string pathFile = this.wiffFileContent.FileName + " (" + (this.index + 1).ToString(CultureInfo.InvariantCulture) + ").path";

                // Make sure the path file exists
                if (!File.Exists(pathFile))
                {
                    MessageBox.Show(pathFile + " is missing", "Missing File");
                    return;
                }

                var positionStream = new FileStream(@pathFile, FileMode.Open, FileAccess.Read);

                // calculate the count of position entries (12 bytes per position entry)
                this.positionDataLength = positionStream.Length / 12;

                this.x1 = 1e10;
                this.x2 = 0.0;
                this.y1 = 1e10;
                this.y2 = 0.0;

                // the array to hold the position information
                this.positionData = new uint[this.positionDataLength, 3];
                var positionReader = new BinaryReader(positionStream);
                for (long posindex = 0; posindex < this.positionDataLength; posindex++)
                {
                    this.positionData[posindex, 0] = positionReader.ReadUInt32();
                    this.positionData[posindex, 1] = positionReader.ReadUInt32();
                    this.positionData[posindex, 2] = positionReader.ReadUInt32();

                    // hundred progress ticks
                    if (Equals(posindex % (this.positionDataLength / 100.0), 0.0))
                    {
                        AppContext.ProgressSetValue(100.0 * posindex / this.positionDataLength);
                    }

                    if (this.positionData[posindex, 1] < this.x1)
                    {
                        this.x1 = this.positionData[posindex, 1];
                    }

                    if (this.positionData[posindex, 1] > this.x2)
                    {
                        this.x2 = this.positionData[posindex, 1];
                    }

                    if (this.positionData[posindex, 2] < this.y1)
                    {
                        this.y1 = this.positionData[posindex, 2];
                    }

                    if (this.positionData[posindex, 2] > this.y2)
                    {
                        this.y2 = this.positionData[posindex, 2];
                    }
                }

                positionReader.Close();
                positionStream.Close();

                this.x1 /= 1000;
                this.x2 /= 1000;
                this.y1 /= 1000;
                this.y2 /= 1000;

                this.width  = this.x2 - this.x1;
                this.height = this.y2 - this.y1;
            }
            finally
            {
                AppContext.ProgressClear();
            }

            // 2) Get the size of the scan file  set scanfilesize
            string scanpathFile = this.wiffFileContent.FileName + ".scan";
            var    fileinfo     = new FileInfo(scanpathFile);

            this.scanfilesize = fileinfo.Length;

            MassSpectrometerSample massSpecSample = sample.MassSpectrometerSample;
            int numberOfExperiments = massSpecSample.ExperimentCount;

            // 3) Get number of experiments and create WiffExperiments for each
            // loop through the experiments; the index of the experiments is zero based!!
            for (int actExperiment = 0; actExperiment < numberOfExperiments; actExperiment++)
            {
                MSExperiment msexperiment = massSpecSample.GetMSExperiment(actExperiment);

                WiffExperiment experiment = WiffExperimentFactory.CreateWiffExperiment(msexperiment, this);

                this.experiments.Add(experiment);
            }
        }
예제 #13
0
 public void SetActiveSample(int sampleIndex)
 {
     _activeSample       = _wiffFile.GetSample(sampleIndex);
     _activeMSExperiment = _activeSample.MassSpectrometerSample.GetMSExperiment(0);
 }
예제 #14
0
        private static MzLite.Model.MassSpectrum GetSpectrum(
            Batch batch,
            MassSpectrometerSample sample,
            MSExperiment msExp,
            int sampleIndex,
            int experimentIndex,
            int scanIndex)
        {
            MassSpectrumInfo wiffSpectrum = msExp.GetMassSpectrumInfo(scanIndex);

            MzLite.Model.MassSpectrum mzLiteSpectrum = new Model.MassSpectrum(ToSpectrumID(sampleIndex, experimentIndex, scanIndex));

            // spectrum

            mzLiteSpectrum.SetMsLevel(wiffSpectrum.MSLevel);

            if (wiffSpectrum.CentroidMode)
            {
                mzLiteSpectrum.SetCentroidSpectrum();
            }
            else
            {
                mzLiteSpectrum.SetProfileSpectrum();
            }

            // scan

            Scan scan = new Scan();

            scan.SetScanStartTime(wiffSpectrum.StartRT)
            .UO_Minute();

            mzLiteSpectrum.Scans.Add(scan);

            // precursor

            if (wiffSpectrum.IsProductSpectrum)
            {
                Precursor precursor = new Precursor();

                double isoWidth;
                double targetMz;

                if (GetIsolationWindow(wiffSpectrum.Experiment, out isoWidth, out targetMz))
                {
                    precursor.IsolationWindow
                    .SetIsolationWindowTargetMz(targetMz)
                    .SetIsolationWindowUpperOffset(isoWidth)
                    .SetIsolationWindowLowerOffset(isoWidth);
                }

                SelectedIon selectedIon = new SelectedIon();

                selectedIon.SetSelectedIonMz(wiffSpectrum.ParentMZ)
                .SetChargeState(wiffSpectrum.ParentChargeState);

                precursor.SelectedIons.Add(selectedIon);

                precursor.Activation
                .SetCollisionEnergy(wiffSpectrum.CollisionEnergy);

                mzLiteSpectrum.Precursors.Add(precursor);
            }

            return(mzLiteSpectrum);
        }
예제 #15
0
 // 从sample中得到一个MSExperiment
 public void GetMSExperiment(int experiment)
 {
     m_msExperiment = m_sample.MassSpectrometerSample.GetMSExperiment(experiment - 1);
 }
예제 #16
0
 public void SetActiveSample(int sampleIndex)
 {
     _activeSample = _wiffFile.GetSample(sampleIndex);
     _activeMSExperiment = _activeSample.MassSpectrometerSample.GetMSExperiment(0);
 }