Пример #1
0
        /// <summary>
        /// Base-Constructor. Performs the initalizations common to all experiments.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The source from where to
        /// read the periods properties and data.</param>
        /// <param name="wiffPeriod">The <see cref="WiffPeriod"/> instance this experiment belongs to.</param>
        /// <param name="experimentIndex">The <b>zero-based</b> index of this experiment in the associated period.</param>
        public WiffExperiment(FMANWiffFileClass wiffFile, WiffPeriod wiffPeriod, int experimentIndex)
        {
            if (wiffFile == null)
            {
                throw new ArgumentNullException("wiffFile");
            }

            if (wiffPeriod == null)
            {
                throw new ArgumentNullException("wiffPeriod");
            }

            this.wiffPeriod = wiffPeriod;
            this.index      = experimentIndex;

            Initialize(wiffFile);
        }
Пример #2
0
        /// <summary>
        /// Constructor. Creates and initializes a WiffPeriod instance.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The source from where to
        /// read the periods properties and data.</param>
        /// <param name="wiffSample">The <see cref="WiffSample"/> instance this period belongs to.</param>
        /// <param name="periodIndex">The <b>zero-based</b> index of this period in the associated sample.</param>
        public WiffPeriod(FMANWiffFileClass wiffFile, WiffSample wiffSample, int periodIndex)
        {
            if (wiffSample == null)
            {
                throw new ArgumentNullException("wiffSample");
            }

            sample = wiffSample;

            if (periodIndex < 0)
            {
                throw new ArgumentOutOfRangeException("periodIndex");
            }

            index = periodIndex;

            Initialize(wiffFile);
        }
        /// <summary>
        /// Determines with what kind of experiment we're dealing with and instatiates
        /// an object of the accurate subclass derived from the abstract baseclass
        /// <see cref="WiffExperiment"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The source from where to
        /// read the experiments properties and data.</param>
        /// <param name="wiffPeriod">The <see cref="WiffPeriod"/> instance this the experiment belongs to.</param>
        /// <param name="experimentIndex">The <b>zero-based</b> index of the experiment in the associated period.</param>
        /// <returns>The newly created, <see cref="WiffExperiment"/> dirived object.</returns>
        public static WiffExperiment CreateWiffExperiment(FMANWiffFileClass wiffFile, WiffPeriod wiffPeriod, int experimentIndex)
        {
            Experiment experiment = (Experiment)wiffFile.GetExperimentObject(wiffPeriod.Sample.Index, wiffPeriod.Index, experimentIndex);
            // get scan type
            short          scanType      = experiment.ScanType;
            WiffExperiment theExperiment = null;

            switch (scanType)
            {
            case 0:     // Q1 scan
            {
                theExperiment = new Q1ScanExperiment(wiffFile, wiffPeriod, experimentIndex);
            }
            break;

            case 1:     // Q1 MI scan
            case 2:     // Q3 scan
            case 3:     // Q3 MI scan
                break;

            case 4:     // MRM scan
            {
                theExperiment = new MRMScanExperiment(wiffFile, wiffPeriod, experimentIndex);
            }
            break;

            case 5:     // precursor scan
            case 6:     // product ion scan
            case 7:     // neural loss scan
                break;

            default:
            {
                // TODO -- Check if this is really, really intended...
                theExperiment = new MRMScanExperiment(wiffFile, wiffPeriod, experimentIndex);
            }
            break;
            }

            return(theExperiment);
        }
Пример #4
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The data source.</param>
        private void Initialize(FMANWiffFileClass wiffFile)
        {
            //get the number of cycles
            cycles = wiffFile.GetActualNumberOfCycles(sample.Index, index);

            // get the period object
            Period period = (Period)wiffFile.GetPeriodObject(sample.Index, index);

            // get the cycle time
            cycleTime = period.CycleTime;

            // get number of experiments
            int nrExperiments = wiffFile.GetNumberOfExperiments(sample.Index, index);

            // loop through the experiments; the index of the experiments is zero based!!
            for (int actExperiment = 0; actExperiment < nrExperiments; actExperiment++)
            {
                WiffExperiment experiment = WiffExperimentFactory.CreateWiffExperiment(wiffFile, this, actExperiment);
                experiments.Add(experiment);
            }
        }
Пример #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The source from where to
        /// read the samples properties and data.</param>
        /// <param name="wiffFileContent">The <see cref="WiffFileContent"/> instance this sample belongs to.</param>
        /// <param name="sampleIndex">A <see cref="int"/> value specifying the <b>one-based</b>index of this sample in the <paramref name="wiffFile"/>.</param>
        /// <remarks>Please take note, that the the counting of samples in the wiff file start with 1( in contrary to most ather indexes).</remarks>
        public WiffSample(FMANWiffFileClass wiffFile, WiffFileContent wiffFileContent, int sampleIndex)
        {
            if (wiffFile == null)
            {
                throw new ArgumentNullException("wiffFile");
            }

            if (wiffFileContent == null)
            {
                throw new ArgumentNullException("wiffFileContent");
            }

            if (sampleIndex < 0)
            {
                throw new ArgumentOutOfRangeException("sampleIndex");
            }

            index = sampleIndex;
            this.wiffFileContent = wiffFileContent;

            Initialize(wiffFile);
        }
Пример #6
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The data source.</param>
        protected override void Initialize(FMANWiffFileClass wiffFile)
        {
            // get experiment object and the experiment parameters
            ITripleQuadMALDI experimentParams = (ITripleQuadMALDI)wiffFile.GetExperimentObject(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);
            Experiment       experiment       = (Experiment)wiffFile.GetExperimentObject(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);

            MassRange massRange = (MassRange)experiment.GetMassRange(0);

            minMass      = massRange.QstartMass; // anaSpec.GetStartMass();
            maxMass      = massRange.QstopMass;  // anaSpec.GetStopMass();
            massStepSize = massRange.QstepMass;  //anaSpec.StepSize;

            // get the number of MS data points
            massSpecDataPoints = (int)((maxMass - minMass) / massStepSize + 1);

            // select 1. data points
            FMANChromData chrom = new FMANChromData();

            chrom.WiffFileName = wiffFile.GetWiffFileName();
            chrom.SetToTIC(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);

            // dimension the data arrray
            nrDataPoints = chrom.GetNumberOfDataPoints();
            rawData      = new float[nrDataPoints];
            timeData     = new float[nrDataPoints];

            //loop through the mass ranges
            massRangeName = "TIC " + minMass.ToString() + " - " + maxMass.ToString();

            double xValue = chrom.GetDataPointXValue(1);
            double yValue = chrom.GetDataPointYValue(1);

            massRangeMax = double.MinValue;
            massRangeMin = double.MaxValue;
            timeOffset   = xValue * 1000;
            // helper for mean and median
            double       meanSum         = 0;
            List <float> valuesForMedian = new List <float>();

            // read the data...
            for (int actDataPoint = 1; actDataPoint <= nrDataPoints; actDataPoint++)
            {
                // get the actual value...
                xValue = chrom.GetDataPointXValue(actDataPoint);
                yValue = chrom.GetDataPointYValue(actDataPoint);
                // and copy it to our local data structur
                rawData[actDataPoint - 1]  = (float)yValue;
                timeData[actDataPoint - 1] = (float)xValue * 60;

                // keep track of the extrema
                if (yValue < massRangeMin)
                {
                    massRangeMin = yValue;
                }
                if (yValue > massRangeMax)
                {
                    massRangeMax = yValue;
                }

                // mean and median calculation...
                // sum up the value to calculate the mean
                meanSum += yValue;
                // fill an extra array to calculate the median
                valuesForMedian.Add((float)yValue);
            }
            // calculate the mean
            meanValue = (float)(meanSum / nrDataPoints);
            // calculate the median
            valuesForMedian.Sort();
            medianValue = ((valuesForMedian.Count % 2) == 0) ? (float)(valuesForMedian[(valuesForMedian.Count / 2) - 1] + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f : valuesForMedian[valuesForMedian.Count / 2];


#if (false) // analyze the timing values in timeData
            List <float> timeSpans = new List <float>();
            for (int i = 1; i < timeData.Length; i++)
            {
                timeSpans.Add(timeData[i] - timeData[i - 1]);
            }
            float tMean   = 0;
            float tMedian = 0;
            timeSpans.Sort();
            foreach (float ts in timeSpans)
            {
                tMean += ts;
            }
            tMean   = tMean / timeSpans.Count;
            tMedian = ((timeSpans.Count % 2) == 0) ? (float)(timeSpans[(timeSpans.Count / 2) - 1] + timeSpans[timeSpans.Count / 2]) / 2.0f : timeSpans[timeSpans.Count / 2];
#endif

            // fetch the x1, x2, y1, y2, width and height from the WiffSample instance this experiment belongs to.
            double x1     = WiffPeriod.Sample.P1.X;
            double y1     = WiffPeriod.Sample.P1.Y;
            double x2     = WiffPeriod.Sample.P2.X;
            double y2     = WiffPeriod.Sample.P2.Y;
            double width  = WiffPeriod.Sample.Width;
            double height = WiffPeriod.Sample.Height;

            //get MALDI parmas and assign variables
            string strMALDIParams = experimentParams.TripleQuadMALDIParameters;

            // x speed in mm/s
            xSpeed = float.Parse(strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None)[6]);

            //line distance in mm
            yDist = float.Parse(strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None)[8]) / 1000;

            //time per point in s
            xTime = (float)((chrom.GetDataPointXValue(nrDataPoints) - chrom.GetDataPointXValue(2)) * 60 / (nrDataPoints - 2));
            xDist = (float)(int)(xSpeed * xTime * 1000) / 1000;

            //number of poins in x
            xPoints = (int)((width) / xSpeed / xTime);

            // fetch the position data from the WiffSample instance this experiment belongs to.
            uint[,] posData = WiffPeriod.Sample.PositionData;
            long posDataLength = WiffPeriod.Sample.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;
                    // ok, we're done...
                    break;
                }
            }

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

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

            // y2 from the wiff file is not the actual y2 from the stage - replace with value from path file...
            y2 = (double)Math.Round((decimal)posData[lastNonZeroTimeInPos, 2] / 1000, 2);

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


            double timeSpanPos = posData[lastNonZeroTimeInPos, 0] / 1000.0 - posData[firstNonZeroTimeInPos, 0] / 1000.0;

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

            lineBreak = lineBreak / xTime;

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

            lineOffset = (5 - (timeData[5] - timeOffset) / xTime) + 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("formating image data...");

            // prepare the data structure
            float[][] dataTIC;
            try
            {
                dataTIC = new float[xPoints][];
                for (int i = 0; i < dataTIC.Length; i++)
                {
                    dataTIC[i] = new float[yPoints];
                }

                // copy the data from wiff file datastream to the rectangular array. Take account of the line offset and
                // the line break timings.
                for (int y = 0; y < yPoints; y++)
                {
                    int currentPoint;
                    // currentLine is the offset to the start of the current line in the linear datastream (rawData)
                    int currentLine = (int)Math.Floor(Math.Abs(lineOffset + ((x2 - x1) / xSpeed / xTime + lineBreak) * y));
                    for (int x = 0; x < xPoints; x++)
                    {
                        if (y % 2 == 0)
                        {
                            // even y: scan direction: -->
                            currentPoint = (int)(currentLine + x);
                        }
                        else
                        {
                            // odd y:  scan direction: <--
                            currentPoint = (int)(currentLine + xPoints - 1 - x);
                        }
                        if (currentPoint < nrDataPoints)
                        {
                            dataTIC[x][y] = rawData[currentPoint];
                        }
                        else
                        {
                            dataTIC[x][y] = 0;
                        }
                    }
                    AppContext.ProgressSetValue(100.0 * y / yPoints);
                }
            }
            finally
            {
                AppContext.ProgressClear();
            }

            // create the appropriate dataset and add it to the WiffFileContent object...
            string   imgName = WiffPeriod.Sample.Name + " : " + massRangeName;
            Document doc     = WiffPeriod.Sample.WiffFileContent.Document;
            //create the meta information data structure and populate with relevant information...
            ImageMetaData metaData = new ImageMetaData();
            try
            {
                metaData.Add("Sample Name", typeof(string), WiffPeriod.Sample.Name, false);
                metaData.Add("Mass Range", typeof(string), massRangeName, false);
                string[] splitted = strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None);
                metaData.Add("Laser Frequency (Hz)", typeof(string), splitted[1], false);
                metaData.Add("Laser Power (%)", typeof(string), splitted[2], false);
                metaData.Add("Ablation Mode", typeof(string), splitted[3], false);
                metaData.Add("Skimmer Voltage (V)", typeof(string), splitted[4], false);
                metaData.Add("Source Gas", typeof(string), splitted[5], false);
                metaData.Add("Raster Speed (mm/s)", typeof(string), splitted[6], false);
                metaData.Add("Raster Pitch", typeof(string), splitted[8], false);
            }
            catch (Exception e) { Util.ReportException(e); }

            ImageData imageTIC = new ImageData(doc, dataTIC, imgName, metaData, (float)massRangeMin, (float)massRangeMax,
                                               (float)meanValue, (float)medianValue, (float)xDist, (float)yDist, (float)minMass, (float)maxMass);


            ///////////////////////////////////////////////////////////////////////////////////////////////////////
            // Q1 spectrum scan...
            FMANSpecData spec = new FMANSpecData();
            spec.WiffFileName = wiffFile.GetWiffFileName();

            // prepare the data structure
            List <float[][]> dataList;
            List <ImageData> imageDataList;
            AppContext.ProgressStart("formating spectrum data...");
            try
            {
                dataList = new List <float[][]>();
                for (int i = 0; i < massSpecDataPoints; i++)
                {
                    float[][] data = new float[xPoints][];
                    for (int j = 0; j < xPoints; j++)
                    {
                        data[j] = new float[yPoints];
                    }
                    dataList.Add(data);
                }


                for (int y = 0; y < yPoints; y++)
                {
                    int currentPoint;
                    // currentLine is the offset to the start of the current line in the linear datastream (rawData)
                    int currentLine = (int)Math.Floor(Math.Abs(lineOffset + ((x2 - x1) / xSpeed / xTime + lineBreak) * y));
                    for (int x = 0; x < xPoints; x++)
                    {
                        if (y % 2 == 0)
                        {
                            // even y: scan direction: -->
                            currentPoint = (int)(currentLine + x);
                        }
                        else
                        {
                            // odd y:  scan direction: <--
                            currentPoint = (int)(currentLine + xPoints - 1 - x);
                        }
                        if (currentPoint >= nrDataPoints)
                        {
                            continue;
                        }

                        float currentTime = (float)chrom.GetXValueInSec(currentPoint + 1);
                        spec.SetSpectrum(WiffPeriod.Sample.Index, WiffPeriod.Index, Index, currentTime, currentTime);
                        int specDataPoints = spec.GetNumberOfDataPoints();

                        for (int k = 1; k <= specDataPoints; k++)
                        {
                            int specIndex = (int)((spec.GetDataPointXValue(k) - minMass) / massStepSize + 0.4);
                            dataList[specIndex][x][y] = (float)spec.GetDataPointYValue(k);
                        }
                    }
                    AppContext.ProgressSetValue(100.0 * y / yPoints);
                }

                // create the list of imageData objects passed to the imageSpectrumData object on it's creation later on...
                imageDataList = new List <ImageData>();
                for (int k = 0; k < massSpecDataPoints; k++)
                {
                    float[][] specData = dataList[k];
                    float     mass     = (float)(minMass + (massStepSize * k));
                    imgName = WiffPeriod.Sample.Name + " : " + mass.ToString();

                    // 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;
                    float mean   = 0;
                    float median = 0;
                    // helper for mean and median
                    meanSum = 0;
                    valuesForMedian.Clear();
                    {
                        for (int x = 0; x < xPoints; x++)
                        {
                            for (int y = 0; y < yPoints; 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
                    mean = (float)(meanSum / (xPoints * yPoints));
                    // calculate the median
                    valuesForMedian.Sort();
                    median = ((valuesForMedian.Count % 2) == 0) ? (float)(valuesForMedian[(valuesForMedian.Count / 2) - 1] + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f : valuesForMedian[valuesForMedian.Count / 2];

                    // ok, now create the imageData and add to list...
                    ImageData imageData = new ImageData(doc, specData, imgName, new ImageMetaData(), minInt, maxInt, mean, median, (float)xDist, (float)yDist, (float)0.0f, (float)mass);
                    imageDataList.Add(imageData);
                }
            }
            finally
            {
                AppContext.ProgressClear();
            }


            // now everything should be set to create the ImageSpectrumData object...
            imgName = WiffPeriod.Sample.Name + " SPECT " + minMass.ToString() + " - " + maxMass.ToString();
            ImageSpectrumData imageSpectrum = new ImageSpectrumData(doc, imgName, new ImageMetaData(), imageDataList, (float)minMass, (float)maxMass, (float)massStepSize);
            imageSpectrum.ImageTIC = imageTIC;
            WiffPeriod.Sample.WiffFileContent.Add(imageSpectrum);


#if (false)
            // TODO -- find out what to do with the 'globalMassMax' value
            float anaTime = (float)chrom.GetXValueInSec(nrDataPoints - 1);
            chrom.SetToBPC(WiffPeriod.Sample.Index, WiffPeriod.Index, Index, 0, anaTime, minMass, maxMass, 2 * massStepSize);
            double tempMass;
            chrom.GetYValueRange(out tempMass, out globalMassMax);

            chrom.SetToTIC(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);
#endif

            chrom.WiffFileName = "";
            chrom             = null;
            spec.WiffFileName = "";
            spec = null;
        }
Пример #7
0
 /// <summary>
 /// Constructor. Creates and initializes a Q1ScanExperiment instance.
 /// </summary>
 /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The source from where to
 /// read the periods properties and data.</param>
 /// <param name="wiffPeriod">The <see cref="WiffPeriod"/> instance this experiment belongs to.</param>
 /// <param name="experimentIndex">The <b>zero-based</b> index of this experiment in the associated period.</param>
 public Q1ScanExperiment(FMANWiffFileClass wiffFile, WiffPeriod wiffPeriod, int experimentIndex)
     : base(wiffFile, wiffPeriod, experimentIndex)
 {
 }
Пример #8
0
        // Private Methods (1) 

        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The data source.</param>
        private void Initialize(FMANWiffFileClass wiffFile)
        {
            // retrieve this sample's name
            name = wiffFile.GetSampleName(index);

            // 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
            {
                string     pathFile       = wiffFileContent.FileName + " (" + index.ToString() + ").path";
                FileStream positionStream = new FileStream(@pathFile, FileMode.Open, FileAccess.Read);

                // calculate the count of position entries
                positionDataLength = positionStream.Length / 12; // 12 Byte per position entry

                // the array to hold the position information
                positionData = new uint[positionDataLength, 3];
                BinaryReader positionReader = new BinaryReader(positionStream);
                for (long i = 0; i < positionDataLength; i++)
                {
                    positionData[i, 0] = positionReader.ReadUInt32();
                    positionData[i, 1] = positionReader.ReadUInt32();
                    positionData[i, 2] = positionReader.ReadUInt32();
                    if ((i % (positionDataLength / 100.0)) == 0) // hundred progress ticks
                    {
                        AppContext.ProgressSetValue(100.0 * i / positionDataLength);
                    }
                }

                positionReader.Close();
                positionStream.Close();
            }
            finally
            {
                AppContext.ProgressClear();
            }

#if (false)
            string csvPosFile = wiffFileContent.FileName + " (" + index.ToString() + ").path" + ".csv";
            using (FileStream csvPosStream = new FileStream(@csvPosFile, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(csvPosStream))
                {
                    for (long i = 0; i < positionDataLength; i++)
                    {
                        sw.Write(positionData[i, 0]);
                        sw.Write(',');
                        sw.Write(positionData[i, 1]);
                        sw.Write(',');
                        sw.Write(positionData[i, 2]);
                        sw.WriteLine();
                    }
                }
            }
#endif


            // get user data of the selected sample
            string userData = wiffFile.GetUserData(index);

            if (!string.IsNullOrEmpty(userData))
            {
                //width in mm
                x2    = float.Parse(userData.Split(',')[2]);
                x1    = float.Parse(userData.Split(',')[0]);
                width = x2 - x1;

                //height in mm
                y2     = float.Parse(userData.Split(',')[3]);
                y1     = float.Parse(userData.Split(',')[1]);
                height = y2 - y1;
            }


            // get the number of periods
            int nrPeriods = wiffFile.GetActualNumberOfPeriods(index);

            // loop through the periods; the index of the periods is zero based!!
            for (int actPeriod = 0; actPeriod < nrPeriods; actPeriod++)
            {
                WiffPeriod period = new WiffPeriod(wiffFile, this, actPeriod);
                periods.Add(period);
            }
        }
Пример #9
0
 /// <summary>
 /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
 /// </summary>
 /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The data source.</param>
 protected abstract void Initialize(FMANWiffFileClass wiffFile);
Пример #10
0
        /// <summary>
        /// Load the wiff file's content.
        /// </summary>
        /// <returns>A <see cref="bool"/> value indicating the success of the loading.</returns>
        public bool LoadContent()
        {
#if (COPY_LOCAL)
            string tempFile = "";
#endif

            bool result = false;
            FMANWiffFileControlClass wiffFileControl = null;
            FMANWiffFileClass        wiffFile        = null;

            try
            {
                string fileToOpen = fileName;
#if (COPY_LOCAL)
                // if file is not local, copy it to the users tempdir
                string uncName = Util.PathToUnc(fileName);
                if (!string.IsNullOrEmpty(uncName))
                {
                    string tempDir = Path.GetTempPath();
                    string file    = Path.GetFileName(uncName);
                    tempFile   = Path.Combine(tempDir, file);
                    fileToOpen = tempFile;
                    File.Copy(fileName, fileToOpen, true);
                    // and the scan file
                    if (File.Exists(fileName + ".scan"))
                    {
                        File.Copy(fileName + ".scan", fileToOpen + ".scan", true);
                    }
                }
#endif

                wiffFileControl = new FMANWiffFileControlClass();
                // get wiff file object from given file
                wiffFile = (FMANWiffFileClass)wiffFileControl.GetWiffFileObject(fileToOpen, 1);

                // get number of samples
                int nrSamples = wiffFile.GetActualNumberOfSamples();

#if (false) // let the user select one sample to be processed
                string[] sampleNames = new string[nrSamples];
                // the index for the samples in the wiff file is based 1 !!
                int actSample;
                for (actSample = 1; actSample <= nrSamples; actSample++)
                {
                    sampleNames[actSample - 1] = wiffFile.GetSampleName(actSample);
                }

                if (nrSamples > 1)
                {
                    // get the sample which is actually to be used...
                    SelectSampleDlg selectSample = new SelectSampleDlg(sampleNames);
                    selectSample.Owner = AppContext.MainWindow;
                    selectSample.ShowDialog();
                    if (selectSample.DialogResult == true)
                    {
                        actSample = selectSample.SelectedSampleIndex;
                    }
                    else if (selectSample.DialogResult == false)
                    {
                        return(false);
                    }
                }
                else
                {
                    // just one sample in wiff file
                    actSample = 1;
                }

                // create and add the singular sample to this objects list of samples...
                WiffSample sample = new WiffSample(wiffFile, actSample);
                samples.Add(sample);
#else      // create sample objects for all the samples present in the wiff file
                // the index for the samples in the wiff file is based 1 !!
                for (int actSample = 1; actSample <= nrSamples; actSample++)
                {
                    // create and add the sample to this objects list of samples...
                    WiffSample sample = new WiffSample(wiffFile, this, actSample);
                    samples.Add(sample);
                }
#endif
                result = true;
            }
            catch (Exception e)
            {
                Util.ReportException(e);
                result = false;
            }
            finally
            {
                try
                {
                    if (wiffFile != null)
                    {
                        wiffFile.CloseWiffFile();
                        wiffFile = null;
                    }

                    wiffFileControl = null;
#if (COPY_LOCAL)
                    if (!string.IsNullOrEmpty(tempFile) && File.Exists(tempFile))
                    {
                        File.Delete(tempFile);
                        if (File.Exists(tempFile + ".scan"))
                        {
                            File.Delete(tempFile + ".scan");
                        }
                    }
#endif
                }
                catch (Exception) { }
            }

            return(result);
        }
Пример #11
0
        /// <summary>
        /// Fills this instance data members with the information read from <paramref name="wiffFile"/>.
        /// </summary>
        /// <param name="wiffFile">A <see cref="FMANWiffFileClass"/> instance. The data source.</param>
        protected override void Initialize(FMANWiffFileClass wiffFile)
        {
            // set the status information
            AppContext.StatusInfo = "Getting wiff-data";

            // get the experiment parameters and the experiment object
            ITripleQuadMALDI experimentParams = (ITripleQuadMALDI)wiffFile.GetExperimentObject(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);
            Experiment       experiment       = (Experiment)wiffFile.GetExperimentObject(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);

            // get the number of mass MRM transitions
            massRanges = experiment.MassRangesCount;

            // select 1. MRM trace
            FMANChromData anaChrom = new FMANChromData();

            anaChrom.WiffFileName = wiffFile.GetWiffFileName();
            anaChrom.SetToXICZeroWidth(WiffPeriod.Sample.Index, WiffPeriod.Index, Index, 0);

            // dimension the data arrray, the number "data points"
            nrDataPoints = anaChrom.GetNumberOfDataPoints();

            rawData       = new float[massRanges, nrDataPoints];
            timeData      = new float[nrDataPoints];
            dwellTime     = new double[massRanges];
            massRangeName = new string[massRanges];
            massRangeMax  = new double[massRanges];
            massRangeMin  = new double[massRanges];
            meanValues    = new float[massRanges];
            medianValues  = new float[massRanges];

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


            // loop through the mass ranges
            double[] startMass = new double[massRanges];
            double[] stopMass  = new double[massRanges];
            double[] stepMass  = new double[massRanges];
            for (int actMassRange = 0; actMassRange < massRanges; actMassRange++)
            {
                // get mass range object
                MassRange anaMassRange = (MassRange)experiment.GetMassRange(actMassRange);
                startMass[actMassRange] = anaMassRange.QstartMass;
                stopMass[actMassRange]  = anaMassRange.QstopMass;
                stepMass[actMassRange]  = anaMassRange.QstepMass;

                massRangeName[actMassRange] = Math.Round(startMass[actMassRange], 2).ToString() + " > " + Math.Round(stepMass[actMassRange], 2).ToString();

                dwellTime[actMassRange] = anaMassRange.DwellTime;

                // select MRM trace
                anaChrom.SetToXICZeroWidth(WiffPeriod.Sample.Index, WiffPeriod.Index, Index, (short)actMassRange);

                // loop throug the spectrum
                massRangeMax[actMassRange] = double.MinValue;
                massRangeMin[actMassRange] = double.MaxValue;
                meanSum = 0.0;
                valuesForMedian.Clear();
                for (int actDataPoint = 1; actDataPoint <= nrDataPoints; actDataPoint++)
                {
                    // get the actual value
                    double anaXValue = anaChrom.GetDataPointXValue(actDataPoint);
                    double anaYValue = anaChrom.GetDataPointYValue(actDataPoint);
                    if (anaYValue < massRangeMin[actMassRange])
                    {
                        massRangeMin[actMassRange] = anaYValue;
                    }
                    if (anaYValue > massRangeMax[actMassRange])
                    {
                        massRangeMax[actMassRange] = anaYValue;
                    }

                    // now get the actual data
                    rawData[actMassRange, actDataPoint - 1] = (float)anaYValue;
                    timeData[actDataPoint - 1] = (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
                meanValues[actMassRange] = (float)(meanSum / nrDataPoints);
                // calculate the median
                valuesForMedian.Sort();
                medianValues[actMassRange] = ((valuesForMedian.Count % 2) == 0) ? (float)(valuesForMedian[(valuesForMedian.Count / 2) - 1] + valuesForMedian[valuesForMedian.Count / 2]) / 2.0f : valuesForMedian[valuesForMedian.Count / 2];
            }

            // get MALDI parmas and assign variables
            string strMALDIParams = experimentParams.TripleQuadMALDIParameters;

            // x speed in mm/s
            xSpeed = float.Parse(strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None)[6]);

            //line distance in mm
            yDist = float.Parse(strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None)[8]) / 1000;

            //time per point in s
            xTime = (float)((anaChrom.GetDataPointXValue(nrDataPoints) - anaChrom.GetDataPointXValue(2)) * 60 / (nrDataPoints - 2));
            xDist = (float)(int)(xSpeed * xTime * 1000) / 1000;

            anaChrom.SetToTIC(WiffPeriod.Sample.Index, WiffPeriod.Index, Index);

            // fetch the x1, x2, y1, y2, width and height from the WiffSample instance this experiment belongs to.
            double x1     = WiffPeriod.Sample.P1.X;
            double y1     = WiffPeriod.Sample.P1.Y;
            double x2     = WiffPeriod.Sample.P2.X;
            double y2     = WiffPeriod.Sample.P2.Y;
            double width  = WiffPeriod.Sample.Width;
            double height = WiffPeriod.Sample.Height;

            //number of poins in x
            xPoints = (int)((width) / xSpeed / xTime);

            //number of points in y
            yPoints = (int)((height) / yDist + 0.5) + 1;

            // lineOffset = 1;

            // fetch the position data from the WiffSample instance this experiment belongs to.
            uint[,] posData = WiffPeriod.Sample.PositionData;
            long posDataLength = WiffPeriod.Sample.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;
                    // ok, we're done...
                    break;
                }
            }

            long lastNonZeroTimeInPos = -1;

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

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

            // y2 from the wiff file is not the actual y2 from the stage - replace with value from path file...
            y2 = (double)Math.Round((decimal)posData[lastNonZeroTimeInPos, 2] / 1000, 2);

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

#if (false)  // experimental method to format the ms-data to the x,y suitable for an image representation
             // fet two time stamps from the start and end of chrom file
            double tFirstMSDataPoint = anaChrom.GetDataPointXValue(10) * 60 * 1000;
            double tLastMSDataPoint  = anaChrom.GetDataPointXValue(nrDataPoints - 10) * 60 * 1000;
            int    positionMarker    = 1;

            // get the corresponding position from the path file
            for (int i = 0; posData[i, 0] < tFirstMSDataPoint; i++)
            {
                positionMarker = i;
            }

            double xFirstMSDataPoint =
                ((tFirstMSDataPoint - posData[positionMarker, 0]) / (posData[positionMarker + 1, 0] - posData[positionMarker, 0])
                 * (int)(posData[positionMarker + 1, 1] - posData[positionMarker, 1])
                 + posData[positionMarker, 1]) / 1000;
            double yFirstMSDataPoint = (double)Math.Round((decimal)posData[positionMarker, 2] / 1000, 2);

            for (int i = 0; posData[i, 0] < tLastMSDataPoint; i++)
            {
                positionMarker = i;
            }
            double xLastMSDataPoint =
                ((tLastMSDataPoint - posData[positionMarker, 0]) / (posData[positionMarker + 1, 0] - posData[positionMarker, 0])
                 * (int)(posData[positionMarker + 1, 1] - posData[positionMarker, 1])
                 + posData[positionMarker, 1]) / 1000;
            double yLastMSDataPoint = (double)Math.Round((decimal)posData[positionMarker, 2] / 1000, 2);

            lineOffset = 10 - (xFirstMSDataPoint - x1) / xDist;

            if (yPoints % 2 == 0)
            {
                // even number of scanlines
                lineBreak = (((nrDataPoints - 10 - 10)
                              - (x2 - (float)xFirstMSDataPoint) / xDist
                              - (yPoints - 2) * (x2 - x1) / xDist
                              - (x2 - (float)xLastMSDataPoint) / xDist))
                            / (yPoints - 1);
            }
            else
            {
                // odd number of scanlines
                lineBreak = (((nrDataPoints - 10 - 10)
                              - (x2 - (float)xFirstMSDataPoint) / xDist
                              - (yPoints - 2) * (x2 - x1) / xDist
                              - ((float)xLastMSDataPoint - x1) / xDist))
                            / (yPoints - 1);
            }


            //timeOffset = (float)posData[5, 0] / 1000 - (((float)posData[5, 1] / 1000 - x1) / xSpeed);


            for (int actMassRange = 0; actMassRange < massRanges; actMassRange++)
            {
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                // format the data into a rectangular, 2 dimensional array of floats that will represent the image data
                //

                // prepare the data structure
                float[][] imageData = new float[xPoints][];
                for (int i = 0; i < imageData.Length; i++)
                {
                    imageData[i] = new float[yPoints];
                }

                // copy the data from wiff file datastream to the rectangular array. Take account of the line offset and
                // the line break timings.
                for (int y = 0; y < yPoints; y++)

                {
                    int currentPoint;
                    // currentLine is the offset to the start of the current line in the linear datastream (rawData)
                    int currentLine = (int)Math.Floor(lineOffset + ((x2 - x1) / xDist + lineBreak) * y);
                    for (int x = 0; x < xPoints; x++)
                    {
                        if (y % 2 == 0)
                        {
                            // even y: scan direction: -->
                            currentPoint = (int)(currentLine + x);
                        }
                        else
                        {
                            // odd y:  scan direction: <--
                            currentPoint = (int)(currentLine + xPoints - 1 - x);
                        }
                        if (currentPoint < nrDataPoints)
                        {
                            imageData[x][y] = rawData[actMassRange, currentPoint];
                        }
                        else
                        {
                            imageData[x][y] = 0;
                        }
                    }
                }
                lineOffset += ((double)dwellTime[actMassRange] + 5) / 1000 * xSpeed / xDist;
#endif

            double timeSpanPos = posData[lastNonZeroTimeInPos, 0] / 1000.0 - posData[firstNonZeroTimeInPos, 0] / 1000.0;


            double syncTime1 = (float)posData[firstNonZeroTimeInPos, 0] / 1000;
            double syncTime2 = (float)posData[lastNonZeroTimeInPos, 0] / 1000;
            if (yPoints % 2 == 0)
            {
                // even number of scanlines
                lineBreak = ((syncTime2 - syncTime1)
                             - (x2 - (float)posData[firstNonZeroTimeInPos, 1] / 1000) / xSpeed
                             - (yPoints - 2) * (x2 - x1) / xSpeed
                             - (x2 - (float)posData[lastNonZeroTimeInPos, 1] / 1000) / xSpeed)
                            / (yPoints - 1);
                //timeOffset = (float)posData[posDataLength - 1, 0] / 1000 + (((float)posData[posDataLength - 1, 1] / 1000 - x1) / xSpeed) - (float)timeData[nrDataPoints - 1] + (float)timeData[0] - 2*xTime; //testing new method
            }
            else
            {
                // odd number of scanlines
                lineBreak = ((syncTime2 - syncTime1)
                             - (x2 - (float)posData[firstNonZeroTimeInPos, 1] / 1000) / xSpeed
                             - (yPoints - 2) * (x2 - x1) / xSpeed
                             - ((float)posData[lastNonZeroTimeInPos, 1] / 1000 - x1) / xSpeed)
                            / (yPoints - 1);
                //timeOffset = (float)posData[posDataLength - 1, 0] / 1000 + ((x2 - (float)posData[posDataLength - 1, 1] / 1000) / xSpeed) - (float)timeData[nrDataPoints - 1] + (float)timeData[0] - xTime;//testing new method
            }
            // MSt lineBreak = lineBreak / xTime;


            timeOffset = (float)posData[firstNonZeroTimeInPos, 0] / 1000 - (((float)posData[firstNonZeroTimeInPos, 1] / 1000 - x1) / xSpeed); // original method of calculation
            //MSt lineOffset = (timeData[0]-timeOffset) * xSpeed / xDist + .5;

            double dwellTimeSum = 0;

            // reset the status information
            AppContext.StatusInfo = "";

            for (int actMassRange = 0; actMassRange < massRanges; actMassRange++)
            {
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                // format the data into a rectangular, 2 dimensional array of floats that will represent the image data
                //

                // prepare the data structure
                float[][] imageData = new float[xPoints][];
                for (int i = 0; i < imageData.Length; i++)
                {
                    imageData[i] = new float[yPoints];
                }

                dwellTimeSum -= (dwellTime[actMassRange] / 1000 / 2);


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

                FormatImageFuzzy(imageData, actMassRange, (x2 - x1), dwellTimeSum, optLineBreak, optTimeOffset);

                dwellTimeSum -= (dwellTime[actMassRange] / 1000 / 2);


                // create the appropriate dataset and add it to the WiffFileContent object...
                string   imgName = WiffPeriod.Sample.Name + " : " + massRangeName[actMassRange];
                Document doc     = WiffPeriod.Sample.WiffFileContent.Document;
                //create the meta information data structure and populate with relevant information...
                ImageMetaData metaData = new ImageMetaData();
                try
                {
                    metaData.Add("Sample Name", typeof(string), WiffPeriod.Sample.Name, false);
                    metaData.Add("Mass Range", typeof(string), massRangeName[actMassRange], false);
                    metaData.Add("X1 (mm)", typeof(string), x1.ToString(), false);
                    metaData.Add("X2 (mm)", typeof(string), x2.ToString(), false);
                    metaData.Add("Y1 (mm)", typeof(string), y1.ToString(), false);
                    metaData.Add("Y2 (mm)", typeof(string), y2.ToString(), false);
                    metaData.Add("Data Points in X", typeof(string), xPoints.ToString(), false);
                    metaData.Add("Data Points in Y", typeof(string), yPoints.ToString(), false);
                    metaData.Add("Point Width (mm)", typeof(string), xDist.ToString(), false);
                    metaData.Add("Point Height (mm)", typeof(string), yDist.ToString(), false);
                    string[] splitted = strMALDIParams.Split(sepMALDIParams, System.StringSplitOptions.None);
                    metaData.Add("Laser Frequency (Hz)", typeof(string), splitted[1], false);
                    metaData.Add("Laser Power (%)", typeof(string), splitted[2], false);
                    metaData.Add("Ablation Mode", typeof(string), splitted[3], false);
                    metaData.Add("Skimmer Voltage (V)", typeof(string), splitted[4], false);
                    metaData.Add("Source Gas", typeof(string), splitted[5], false);
                    metaData.Add("Raster Speed (mm/s)", typeof(string), splitted[6], false);
                    metaData.Add("Line Distance (µm)", typeof(string), splitted[8], false);
                }
                catch (Exception e) { Util.ReportException(e); }

                WiffPeriod.Sample.WiffFileContent.Add(new ImageData(doc, imageData, imgName, metaData, (float)massRangeMin[actMassRange], (float)massRangeMax[actMassRange],
                                                                    (float)meanValues[actMassRange], (float)medianValues[actMassRange], (float)xDist, (float)yDist, (float)startMass[actMassRange], (float)stepMass[actMassRange]));
            }

            anaChrom.WiffFileName = "";
            anaChrom = null;
        }