public override IEnumerable <string> Process(string fileName)
        {
            var result = new FileInfo(targetDir + "\\" + new FileInfo(fileName).Name + ".scancount").FullName;

            Dictionary <string, int> scanTypeCount = new Dictionary <string, int>();

            using (var reader = RawFileFactory.GetRawFileReader(fileName))
            {
                var firstScan = reader.GetFirstSpectrumNumber();
                var lastScan  = reader.GetLastSpectrumNumber();
                for (int scan = firstScan; scan <= lastScan; scan++)
                {
                    var msLevel  = reader.GetMsLevel(scan);
                    var scanMode = reader.GetScanMode(scan);
                    var key      = string.Format("MS{0}_{1}", msLevel, scanMode);
                    if (!scanTypeCount.ContainsKey(key))
                    {
                        scanTypeCount[key] = 1;
                    }
                    else
                    {
                        scanTypeCount[key] = scanTypeCount[key] + 1;
                    }
                }
            }

            ScanCountFormat.WriteToFile(result, scanTypeCount);

            return(new string[] { result });
        }
Beispiel #2
0
        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (rawFile.Exists)
            {
                if (reader != null)
                {
                    reader.Close();
                }
                reader   = RawFileFactory.GetRawFileReader(rawFile.FullName);
                lastScan = reader.GetLastSpectrumNumber();
            }

            if (ms3MatchedFile.Exists)
            {
                items = (from line in File.ReadAllLines(ms3MatchedFile.FullName).Skip(1)
                         let parts = line.Split('\t')
                                     let pm = int.Parse(parts[6])
                                              where pm > 0
                                              select new MS3MatchItem()
                {
                    Category = parts[0],
                    Sequence1 = parts[1],
                    Scan1 = int.Parse(parts[2]),
                    Sequence2 = parts[3],
                    Scan2 = int.Parse(parts[4]),
                    MinMz = parts[5].StringAfter(">=").Trim(),
                    PrecursorMatched = pm,
                    MS3Matched = int.Parse(parts[7])
                }).ToList();

                gvPeptides.DataSource = items;
            }
        }
Beispiel #3
0
        public override IEnumerable <string> Process(string targetDirectory)
        {
            var targetDir = new DirectoryInfo(targetDirectory);

            if (!targetDir.Exists)
            {
                targetDir.Create();
            }

            var result = new List <string>();

            for (int i = 0; i < rawFiles.Count; i++)
            {
                if (Progress.IsCancellationPending())
                {
                    throw new UserTerminatedException();
                }

                string rootMsg = MyConvert.Format("{0} / {1} : {2}", i + 1, rawFiles.Count,
                                                  rawFiles[i]);

                Progress.SetMessage(1, rootMsg);
                using (var rawFile = RawFileFactory.GetRawFileReader(rawFiles[i]))
                {
                    var processor = new Raw2MgfProcessor(rawFile, this.writer, this.retentionTimeTolerance, this.ppmPrecursorTolerance,
                                                         this.ppmPeakTolerance, this.pklProcessor, targetDir, groupByMode);
                    processor.Progress = Progress;

                    result.AddRange(processor.Process(rawFiles[i]));
                }
            }

            return(result);
        }
        protected override IEnumerable <string> DoProcess(string fileName, List <int> ignoreScans, int lastScan, bool bContinue)
        {
            var result = new List <string>();

            bool bReadAgain = false;

            using (var rawReader = RawFileFactory.GetRawFileReader(fileName))
            {
                try
                {
                    DoInitialize(rawReader, fileName);

                    string experimental = rawReader.GetFileNameWithoutExtension(fileName);

                    SetMessage("Processing " + fileName + " ...");

                    int firstSpectrumNumber = rawReader.GetFirstSpectrumNumber();
                    int lastSpectrumNumber  = rawReader.GetLastSpectrumNumber();
                    //          int lastSpectrumNumber = 5000;

                    SetRange(firstSpectrumNumber, lastSpectrumNumber);

                    for (int scan = firstSpectrumNumber; scan <= lastSpectrumNumber;)
                    {
                        if (Progress.IsCancellationPending())
                        {
                            throw new UserTerminatedException();
                        }

                        if (IsLoopStopped)
                        {
                            return(result);
                        }

                        scan = DoWritePeakList(rawReader, scan, fileName, result, experimental, lastSpectrumNumber, ignoreScans, ref bReadAgain);
                        if (bReadAgain)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    DoFinalize(bReadAgain, rawReader, fileName, result);
                }
            }

            if (bReadAgain)
            {
                return(DoProcess(fileName, ignoreScans, 0, false));
            }
            else
            {
                return(result);
            }
        }
        protected override void DoRealGo()
        {
            if (_reader != null)
            {
                _reader.Close();
            }

            _reader = RawFileFactory.GetRawFileReader(GetOriginFile());

            _firstScan = _reader.GetFirstSpectrumNumber();
            _lastScan  = _reader.GetLastSpectrumNumber();

            txtScan.Text = _firstScan.ToString();
            DisplayScan(0);
        }
Beispiel #6
0
        public virtual List <OffsetEntry> GetOffsets(string fileName)
        {
            var result = new List <OffsetEntry>();

            foreach (var ion in monitorIons)
            {
                ion.PrecursorPPM = this.maxShiftPPM;
                ion.OffsetPPM    = 0;
            }

            using (var reader = RawFileFactory.GetRawFileReader(fileName))
            {
                DoGetOffsets(result, reader, "Calculating mass shift from " + fileName + "...");
            }

            return(result);
        }
        public override IEnumerable <string> Process(string rawFilename)
        {
            if (null == rawReader)
            {
                rawReader = RawFileFactory.GetRawFileReader(rawFilename);
            }

            var rawFile = new FileInfo(rawFilename);

            if (!rawFile.Exists)
            {
                throw new ArgumentException("Raw file not exists : " + rawFilename);
            }

            Progress.SetMessage("Reading peak list from " + rawFilename + " ...");
            List <PeakList <Peak> > pklList = ReadTandemMassFromRaw(rawFile);

            List <PeakList <Peak> > mergedPklList;

            bool mergeScans = this.retentionTimeTolerance > 0;

            if (mergeScans)
            {
                Progress.SetMessage("Merging peak list, total " + pklList.Count + " ...");
                mergedPklList = MergePeakList(pklList);

                Progress.SetMessage("Merging peak list finished, " + mergedPklList.Count + " kept.");
            }
            else
            {
                mergedPklList = pklList;
            }

            var result = new HashSet <string>();

            if (mergedPklList.Count > 0)
            {
                result.Union(WritePeakLists(rawFile, mergedPklList));
            }

            Progress.SetMessage("Succeed!");

            return(new List <string>(result));
        }
Beispiel #8
0
        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (rawFile.Exists)
            {
                if (reader != null)
                {
                    reader.Close();
                }
                reader   = RawFileFactory.GetRawFileReader(rawFile.FullName);
                lastScan = reader.GetLastSpectrumNumber();
            }

            if (ms3xcorrFile.Exists)
            {
                items = (from line in File.ReadAllLines(ms3xcorrFile.FullName).Skip(1)
                         let parts = line.Split('\t')
                                     select new MS3XcorrItem()
                {
                    Category = parts[0],
                    Sequence1 = parts[1],
                    MS2Scan1 = int.Parse(parts[2]),
                    MS2Precursor1 = double.Parse(parts[3]),
                    MS3Scan1 = int.Parse(parts[4]),
                    MS3Precursor1 = double.Parse(parts[5]),
                    Sequence2 = parts[6],
                    MS2Scan2 = int.Parse(parts[7]),
                    MS2Precursor2 = double.Parse(parts[8]),
                    MS3Scan2 = int.Parse(parts[9]),
                    MS3Precursor2 = double.Parse(parts[10]),
                    Xcorr = double.Parse(parts[11])
                }).ToList();

                items.RemoveAll(m => m.MS3Precursor1 < 250);
                items = items.OrderBy(m => m.Category).ThenBy(m => m.Sequence1).ThenBy(m => m.MS3Precursor1).ToList();
                gvPeptides.DataSource = items;
            }
        }
        public override IEnumerable <string> Process()
        {
            var boundaryInput = Path.ChangeExtension(options.OutputFile, ".chros.tsv");

            if (!File.Exists(boundaryInput) || options.Overwrite)
            {
                var format           = GetPeptideReader();
                var spectra          = format.ReadFromFile(options.InputFile);
                var peptideMap       = spectra.ToGroupDictionary(m => m.Query.FileScan.Experimental.ToLower());
                var rawfiles         = options.RawFiles.ToDictionary(m => RawFileFactory.GetExperimental(m).ToLower());
                var rententionWindow = options.MaximumRetentionTimeWindow;

                var missed = peptideMap.Keys.Except(rawfiles.Keys).ToArray();
                if (missed.Length > 0)
                {
                    throw new Exception(string.Format("Cannot find raw file of {0} in file list", missed.Merge("/")));
                }

                var optionThreadCount = options.ThreadCount == 0 ? Environment.ProcessorCount : options.ThreadCount;
                var option            = new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Math.Min(optionThreadCount, peptideMap.Count),
                };

                var chroMap = new List <Tuple <string, List <ChromatographProfile> > >();
                foreach (var raw in peptideMap)
                {
                    var peptides = raw.Value;

                    var waitingPeaks = new List <ChromatographProfile>();
                    foreach (var peptide in peptides)
                    {
                        var chro = new ChromatographProfile()
                        {
                            Experimental            = peptide.Query.FileScan.Experimental,
                            IdentifiedScan          = peptide.Query.FileScan.FirstScan,
                            IdentifiedRetentionTime = peptide.Query.FileScan.RetentionTime,
                            ObservedMz    = peptide.GetPrecursorMz(),
                            TheoreticalMz = peptide.GetTheoreticalMz(),
                            Charge        = peptide.Query.Charge,
                            Sequence      = peptide.Peptide.PureSequence,
                            FileName      = GetTargetFile(peptide),
                            SubFileName   = GetTargetSubFile(peptide)
                        };
                        chro.InitializeIsotopicIons(options.MzTolerancePPM, options.MinimumIsotopicPercentage);
                        waitingPeaks.Add(chro);
                    }

                    chroMap.Add(new Tuple <string, List <ChromatographProfile> >(raw.Key, waitingPeaks));
                }

                ConcurrentBag <ChromatographProfile> detected = new ConcurrentBag <ChromatographProfile>();

                Parallel.ForEach(chroMap, option, raw =>
                {
                    var rawFileName  = raw.Item1;
                    var waitingPeaks = raw.Item2;

                    Dictionary <string, List <ChromatographProfile> > resultMap = new Dictionary <string, List <ChromatographProfile> >();

                    List <FullMS> fullMSList = new List <FullMS>();
                    Progress.SetMessage("Reading full ms list from " + rawfiles[rawFileName] + "...");
                    using (var rawReader = new CacheRawFile(RawFileFactory.GetRawFileReader(rawfiles[rawFileName])))
                    {
                        var firstScan = rawReader.GetFirstSpectrumNumber();
                        var lastScan  = rawReader.GetLastSpectrumNumber();
                        for (int scan = firstScan; scan <= lastScan; scan++)
                        {
                            var mslevel = rawReader.GetMsLevel(scan);
                            if (mslevel == 1)
                            {
                                fullMSList.Add(new FullMS()
                                {
                                    Scan          = scan,
                                    RetentionTime = rawReader.ScanToRetentionTime(scan),
                                    Peaks         = null
                                });
                            }
                        }

                        foreach (var chro in waitingPeaks)
                        {
                            if (chro.IdentifiedScan == 0 && chro.IdentifiedRetentionTime > 0)
                            {
                                for (int i = 1; i < fullMSList.Count; i++)
                                {
                                    if (chro.IdentifiedRetentionTime < fullMSList[i].RetentionTime)
                                    {
                                        break;
                                    }
                                    chro.IdentifiedScan = fullMSList[i].Scan + 1;
                                }
                            }
                        }

                        var chroGroups = waitingPeaks.GroupBy(chro => chro.GetPeptideId());
                        foreach (var chroGroup in chroGroups)
                        {
                            List <ChromatographProfile> profileChros = new List <ChromatographProfile>();
                            foreach (var chro in chroGroup.OrderBy(m => m.IdentifiedScan))
                            {
                                var masterScanIndex = 0;
                                for (int i = 1; i < fullMSList.Count; i++)
                                {
                                    if (chro.IdentifiedScan < fullMSList[i].Scan)
                                    {
                                        break;
                                    }
                                    masterScanIndex = i;
                                }
                                var masterScan          = fullMSList[masterScanIndex].Scan;
                                var masterRetentionTime = fullMSList[masterScanIndex].RetentionTime;

                                bool bExist = false;
                                foreach (var profileChro in profileChros)
                                {
                                    foreach (var pkl in profileChro.Profiles)
                                    {
                                        if (pkl.Scan == fullMSList[masterScanIndex].Scan)
                                        {
                                            pkl.Identified = true;
                                            bExist         = true;
                                            break;
                                        }
                                    }

                                    if (bExist)
                                    {
                                        break;
                                    }
                                }

                                if (bExist)
                                {
                                    continue;
                                }

                                //Progress.SetMessage("Processing {0} : {1:0.#####} : {2} : {3}", chro.Sequence, chro.ObservedMz, chro.IdentifiedScan, Path.GetFileName(chro.FileName));

                                //allow one missed scan
                                int naCount = 2;
                                for (int scanIndex = masterScanIndex; scanIndex >= 0; scanIndex--)
                                {
                                    if (Progress.IsCancellationPending())
                                    {
                                        throw new UserTerminatedException();
                                    }

                                    var curRetentionTime = fullMSList[scanIndex].RetentionTime;
                                    if (masterRetentionTime - curRetentionTime > rententionWindow)
                                    {
                                        break;
                                    }

                                    if (!AddEnvelope(chro, rawReader, fullMSList, scanIndex))
                                    {
                                        naCount--;
                                        if (naCount == 0)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }

                                    if (scanIndex == masterScanIndex)
                                    {
                                        chro.Profiles.Last().Identified = true;
                                    }
                                }
                                chro.Profiles.Reverse();

                                naCount = 2;
                                for (int scanIndex = masterScanIndex + 1; scanIndex < fullMSList.Count; scanIndex++)
                                {
                                    if (Progress.IsCancellationPending())
                                    {
                                        throw new UserTerminatedException();
                                    }

                                    var curRetentionTime = fullMSList[scanIndex].RetentionTime;
                                    if (curRetentionTime - masterRetentionTime > rententionWindow)
                                    {
                                        break;
                                    }

                                    if (!AddEnvelope(chro, rawReader, fullMSList, scanIndex))
                                    {
                                        naCount--;
                                        if (naCount == 0)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }
                                }

                                profileChros.Add(chro);
                            }

                            profileChros.RemoveAll(l => l.Profiles.Count < options.MinimumScanCount);
                            profileChros.Sort((m1, m2) => m2.Profiles.Count.CompareTo(m1.Profiles.Count));

                            bool bMain = true;
                            foreach (var chro in profileChros)
                            {
                                var filename = bMain ? chro.FileName : chro.SubFileName;
                                if (bMain)
                                {
                                    detected.Add(chro);
                                }

                                bMain = false;

                                new ChromatographProfileTextWriter().WriteToFile(filename, chro);
                                new ChromatographProfileXmlFormat().WriteToFile(filename + ".xml", chro);
                            }
                        }
                    }
                }
                                 );

                var chroList = new List <ChromatographProfile>(detected);
                chroList.Sort((m1, m2) => m1.FileName.CompareTo(m2.FileName));

                if (chroList.Count == 0)
                {
                    throw new Exception("Cannot find chromotograph!");
                }

                using (var sw = new StreamWriter(boundaryInput))
                {
                    sw.WriteLine("ChroDirectory\tChroFile\tSample\tPeptideId\tTheoreticalMz\tCharge\tIdentifiedScan");
                    foreach (var chro in chroList)
                    {
                        sw.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}",
                                     Path.GetDirectoryName(chro.FileName).Replace("\\", "/"),
                                     Path.GetFileNameWithoutExtension(chro.FileName),
                                     chro.Experimental,
                                     chro.GetPeptideId(),
                                     chro.TheoreticalMz,
                                     chro.Charge,
                                     chro.IdentifiedScan);
                    }
                }
            }

            if (!File.Exists(options.OutputFile) || options.Overwrite)
            {
                Progress.SetMessage("Finding boundaries ...");
                var boundaryOptions = new RTemplateProcessorOptions()
                {
                    InputFile      = boundaryInput,
                    OutputFile     = options.OutputFile,
                    RTemplate      = BoundaryR,
                    RExecute       = ExternalProgramConfig.GetExternalProgram("R"),
                    CreateNoWindow = true
                };
                boundaryOptions.Parameters.Add("outputImage<-" + (options.DrawImage ? "1" : "0"));
                boundaryOptions.Parameters.Add("maximumProfileDistance<-" + options.MaximumProfileDistance.ToString());
                new RTemplateProcessor(boundaryOptions)
                {
                    Progress = this.Progress
                }.Process();
            }

            //if (options.DrawImage)
            //{
            //  Progress.SetMessage("Drawing images ...");

            //  var imageOptions = new RTemplateProcessorOptions()
            //  {
            //    InputFile = options.OutputFile,
            //    OutputFile = Path.ChangeExtension(options.OutputFile, ".image"),
            //    RTemplate = ImageR,
            //    RExecute = SystemUtils.GetRExecuteLocation(),
            //    CreateNoWindow = true,
            //    NoResultFile = true
            //  };
            //  new RTemplateProcessor(imageOptions) { Progress = this.Progress }.Process();
            //}

            return(new string[] { options.OutputFile });
        }
        public override IEnumerable <string> Process(string targetDir)
        {
            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            var option = new ParallelOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount,
                CancellationToken      = token
            };

            foreach (var entry in this.spectra)
            {
                if (!this.rawFiles.ContainsKey(entry.Key))
                {
                    throw new Exception(string.Format("Cannot find raw file for {0}", entry.Key));
                }
            }

            SimplePeakChroPngWriter writer = new SimplePeakChroPngWriter();

            Parallel.ForEach(spectra, option, raw =>
            {
                var peptides     = raw.ToList();
                var waitingPeaks = new List <IIdentifiedSpectrum>();

                foreach (var peak in peptides)
                {
                    string file = GetTargetFile(targetDir, peak);
                    if (force || !File.Exists(file))
                    {
                        waitingPeaks.Add(peak);
                    }
                }

                if (waitingPeaks.Count == 0)
                {
                    return;
                }

                using (var rawReader = new CacheRawFile(RawFileFactory.GetRawFileReader(this.rawFiles[raw.Key.ToLower()])))
                {
                    int firstScan = rawReader.GetFirstSpectrumNumber();
                    int lastScan  = rawReader.GetLastSpectrumNumber();

                    foreach (var peak in waitingPeaks)
                    {
                        //if (peak.Query.FileScan.FirstScan != 7628)
                        //{
                        //  continue;
                        //}

                        var chro         = new SimplePeakChro();
                        chro.Mz          = peak.ObservedMz;
                        chro.Charge      = peak.Query.Charge;
                        chro.MzTolerance = PrecursorUtils.ppm2mz(chro.Mz, this.ppmTolerance);
                        chro.Sequence    = peak.Sequence;

                        bool bFirst = true;

                        for (int scan = peak.Query.FileScan.FirstScan - 1; scan >= firstScan; scan--)
                        {
                            if (Progress.IsCancellationPending())
                            {
                                return;
                            }

                            if (rawReader.GetMsLevel(scan) == 1)
                            {
                                if (!AddPeaks(rawReader, scan, chro, bFirst))
                                {
                                    break;
                                }

                                bFirst = false;
                            }
                        }

                        chro.Peaks.Reverse();

                        for (int scan = peak.Query.FileScan.FirstScan + 1; scan <= lastScan; scan++)
                        {
                            if (Progress.IsCancellationPending())
                            {
                                return;
                            }

                            if (rawReader.GetMsLevel(scan) == 1)
                            {
                                if (!AddPeaks(rawReader, scan, chro, false))
                                {
                                    break;
                                }
                            }
                        }

                        string file = GetTargetFile(targetDir, peak);

                        new SimplePeakChroXmlFormat().WriteToFile(file, chro);

                        var pngFile = GetTargetImageFile(targetDir, peak);
                        writer.WriteToFile(pngFile, chro);
                    }
                }
            });

            return(new string[] { targetDir });
        }
Beispiel #11
0
        public virtual List <IsobaricScan> ReadFromFile(string fileName)
        {
            var result = new List <IsobaricScan>();

            var askedScanMode = GetScanMode();
            var lowerScanMode = new HashSet <string>(from a in askedScanMode
                                                     select a.ToLower());

            using (var rawReader = RawFileFactory.GetRawFileReader(fileName, this.IsTandemMS3))
            {
                FirstScan = rawReader.GetFirstSpectrumNumber();
                EndScan   = rawReader.GetLastSpectrumNumber();

                DoAfterFileOpen(rawReader);

                var firstIsolationWidth = 0.0;

                var icount = 0;
                for (int scan = FirstScan; scan <= EndScan; scan++)
                {
                    if (!rawReader.IsScanValid(scan))
                    {
                        continue;
                    }

                    if (this.MsLevel == rawReader.GetMsLevel(scan))
                    {
                        firstIsolationWidth = rawReader.GetIsolationWidth(scan);
                        if (firstIsolationWidth > 0 && firstIsolationWidth < 5)
                        {
                            break;
                        }
                        icount++;
                        if (icount > 10)
                        {
                            break;
                        }
                    }
                }

                if (firstIsolationWidth == 0.0)
                {
                    firstIsolationWidth = defaultIsolationWidth;
                }

                Progress.SetMessage("Reading channel information ...");
                Progress.SetRange(FirstScan, EndScan);

                for (int scan = FirstScan; scan <= EndScan; scan++)
                {
                    if (Progress.IsCancellationPending())
                    {
                        throw new UserTerminatedException();
                    }

                    if (!rawReader.IsScanValid(scan))
                    {
                        continue;
                    }

                    Progress.SetPosition(scan);

                    if (this.MsLevel == rawReader.GetMsLevel(scan))
                    {
                        //Console.WriteLine("Scan : {0}", scan);

                        string scanMode = rawReader.GetScanMode(scan).ToLower();
                        if (string.IsNullOrEmpty(scanMode))
                        {
                            AppendScan(rawReader, result, scan, "UNKNOWN", firstIsolationWidth);
                        }
                        else if (lowerScanMode.Count == 0 || lowerScanMode.Contains(scanMode))
                        {
                            AppendScan(rawReader, result, scan, scanMode.ToUpper(), firstIsolationWidth);
                        }
                        else
                        {
                            Console.WriteLine("Scan {0} is skipped with mode {1}", scan, scanMode);
                        }
                    }
                }
            }

            return(result);
        }
        public override IEnumerable <string> Process(string fileName)
        {
            var result = new List <string>();

            QueryItemListFormat format = new QueryItemListFormat();

            FileInfo rawFile = new FileInfo(rawFileName);

            Progress.SetMessage("Reading query product ion from " + fileName);
            var queryItems = format.ReadFromFile(fileName);

            using (IRawFile reader = RawFileFactory.GetRawFileReader(rawFileName))
            {
                reader.Open(rawFileName);

                int firstSpectrumNumber = reader.GetFirstSpectrumNumber();

                LipidPrecursorQuery queryFunc = new LipidPrecursorQuery(reader);
                queryFunc.Progress = this.Progress;

                char[] chars = new char[] { '\t' };

                int curIndex = 0;
                foreach (var query in queryItems)
                {
                    Progress.SetMessage(MyConvert.Format("{0}/{1} - Querying precursor ions for product ion {2} ...", ++curIndex, queryItems.Count, query.ProductIonMz));

                    string savedQueryFile = GetQueryFileName(rawFileName, query.ProductIonMz, productIonPPM, precursorPPM);

                    PrecursorItemListXmlFormat pilFormat = new PrecursorItemListXmlFormat();
                    List <PrecursorItem>       precursors;
                    if (!File.Exists(savedQueryFile))
                    {
                        precursors = queryFunc.QueryPrecursorFromProductIon(query, productIonPPM, precursorPPM);
                        pilFormat.WriteToFile(savedQueryFile, precursors);
                    }
                    else
                    {
                        precursors = pilFormat.ReadFromFile(savedQueryFile);
                    }

                    result.Add(savedQueryFile);


                    var precursorMzs = (from item in precursors
                                        group item by item.PrecursorMZ into mzGroup
                                        let count = mzGroup.Where(m => m.PrecursorIntensity > 0).Count()
                                                    orderby count descending
                                                    select new PrecursorArea {
                        PrecursorMz = mzGroup.Key, ScanCount = count, Area = 0.0
                    }).ToList();

                    //去掉冗余的precursor
                    for (int i = precursorMzs.Count - 1; i >= 0; i--)
                    {
                        if (precursorMzs[i].ScanCount >= 5)
                        {
                            break;
                        }

                        for (int j = 0; j < i; j++)
                        {
                            if (precursorMzs[j].ScanCount < 5)
                            {
                                break;
                            }

                            double ppm = PrecursorUtils.mz2ppm(precursorMzs[i].PrecursorMz, Math.Abs(precursorMzs[i].PrecursorMz - precursorMzs[j].PrecursorMz));
                            if (ppm < precursorPPM)
                            {
                                precursorMzs.RemoveAt(i);
                                break;
                            }
                        }
                    }

                    string savedDetailDir = FileUtils.ChangeExtension(savedQueryFile, "");
                    if (!Directory.Exists(savedDetailDir))
                    {
                        Directory.CreateDirectory(savedDetailDir);
                    }

                    for (int i = 0; i < precursorMzs.Count; i++)
                    {
                        Progress.SetMessage(MyConvert.Format("{0}/{1} {2} - {3}/{4} Get chromotograph for precursor {5} ...", curIndex, queryItems.Count, query.ProductIonMz, i + 1, precursorMzs.Count, precursorMzs[i].PrecursorMz));

                        string targetFile = savedDetailDir + "\\" + GetDetailFileName(rawFileName, precursorMzs[i].PrecursorMz);

                        var itemFormat = new LabelFreeSummaryItemXmlFormat();

                        LabelFreeSummaryItem item;
                        if (File.Exists(targetFile))
                        {
                            item = itemFormat.ReadFromFile(targetFile);
                        }
                        else
                        {
                            var ions = queryFunc.QueryChromotograph(precursorMzs[i].PrecursorMz, precursorPPM);

                            int continueCount = 0;
                            int firstIndex    = -1;
                            for (int j = 0; j < ions.Count; j++)
                            {
                                if (ions[j].Intensity > 0)
                                {
                                    if (firstIndex == -1)
                                    {
                                        firstIndex    = j;
                                        continueCount = 1;
                                    }
                                    else
                                    {
                                        continueCount++;
                                        if (continueCount >= 5)
                                        {
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    firstIndex    = -1;
                                    continueCount = 0;
                                }
                            }

                            if (continueCount >= 5)
                            {
                                ions.RemoveRange(0, firstIndex);
                            }

                            continueCount = 0;
                            int lastIndex = -1;
                            for (int j = ions.Count - 1; j >= 0; j--)
                            {
                                if (ions[j].Intensity > 0)
                                {
                                    if (lastIndex == -1)
                                    {
                                        lastIndex     = j;
                                        continueCount = 1;
                                    }
                                    else
                                    {
                                        continueCount++;
                                        if (continueCount >= 5)
                                        {
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    lastIndex     = -1;
                                    continueCount = 0;
                                }
                            }

                            if (continueCount >= 5)
                            {
                                ions.RemoveRange(lastIndex + 1, ions.Count - lastIndex - 1);
                            }

                            //get full ms corresponding to identified ms/ms
                            var identified = new HashSet <int>();
                            foreach (var p in precursors)
                            {
                                if (p.PrecursorMZ == precursorMzs[i].PrecursorMz)
                                {
                                    for (int j = p.Scan - 1; j >= firstSpectrumNumber; j--)
                                    {
                                        if (reader.GetMsLevel(j) == 1)
                                        {
                                            identified.Add(j);
                                            break;
                                        }
                                    }
                                }
                            }

                            ions.ForEach(m =>
                            {
                                m.Identified = identified.Contains(m.Scan);
                                m.Enabled    = true;
                            });

                            Debug.Assert(ions.FindAll(m => m.Identified == true).Count == identified.Count);

                            item = new LabelFreeSummaryItem()
                            {
                                RawFilename = rawFileName,
                                Sequence    = MyConvert.Format("{0:0.0000}; {1:0.00}", query.ProductIonMz, query.MinRelativeIntensity)
                            };
                            item.AddRange(ions);
                            item.CalculatePPM(precursorMzs[i].PrecursorMz);

                            new LabelFreeSummaryItemXmlFormat().WriteToFile(targetFile, item);
                        }

                        precursorMzs[i].Area = item.GetArea();
                        string savedAreaFile = GetAreaFileName(rawFileName, query.ProductIonMz, productIonPPM, precursorPPM);
                        new PrecursorAreaListTextFormat().WriteToFile(savedAreaFile, precursorMzs);
                    }
                }

                return(result);
            }
        }
        public override List <IsobaricScan> ReadFromFile(string fileName)
        {
            var result = new List <IsobaricScan>();

            using (var rawReader = RawFileFactory.GetRawFileReader(fileName))
            {
                int startScan = rawReader.GetFirstSpectrumNumber();
                int endScan   = rawReader.GetLastSpectrumNumber();

                Progress.SetRange(startScan, endScan);

                for (int scan = startScan; scan <= endScan; scan++)
                {
                    if (Progress.IsCancellationPending())
                    {
                        throw new UserTerminatedException();
                    }

                    Progress.SetPosition(scan);

                    if (2 == rawReader.GetMsLevel(scan))
                    {
                        string scanMode = rawReader.GetScanMode(scan);
                        if (string.IsNullOrEmpty(scanMode))
                        {
                            AppendScan(rawReader, result, scan, "UNKNOWN");
                            continue;
                        }

                        scanMode = scanMode.ToLower();
                        if (scanMode.Equals("pqd"))
                        {
                            AppendScan(rawReader, result, scan, "PQD");
                        }
                        else if (scanMode.Equals("cid"))
                        {
                            //如果上一个scan是pqd,那么,现在这个cid的结果从该pqd读取。
                            if (result.Count > 0 && result[result.Count - 1].RawPeaks.ScanTimes[0].Scan == scan - 1 && result[result.Count - 1].RawPeaks.ScanMode == "PQD")
                            {
                                var lastItem = result[result.Count - 1];

                                var item = new IsobaricScan(lastItem);
                                item.Scan     = rawReader.GetScanTime(scan);
                                item.ScanMode = "CID";

                                result.Add(item);
                            }
                            else//否则,从自己的peaklist中读取。
                            {
                                AppendScan(rawReader, result, scan, "CID");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Scan {0} is skipped with mode {1}", scan, scanMode);
                        }
                    }
                }
            }

            return(result);
        }
        public override IEnumerable <string> Process(string fileName)
        {
            var result = new List <string>();

            Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > > mode_maps     = new Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > >();
            Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > > mode_compmaps = new Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > >();
            Dictionary <int, int> scanCounts = new Dictionary <int, int>();

            using (var reader = RawFileFactory.GetRawFileReader(fileName))
            {
                var firstScan = reader.GetFirstSpectrumNumber();
                var lastScan  = reader.GetLastSpectrumNumber();
                //var firstScan = 17047;
                //var lastScan = 17047;

                for (int i = firstScan; i <= lastScan; i++)
                {
                    Peak precursor;
                    if (reader.GetMsLevel(i) == 1)
                    {
                        precursor = new Peak(0.0, 0.0, FULLMS_CHARGE);
                    }
                    else
                    {
                        precursor = reader.GetPrecursorPeak(i);
                    }

                    if (!scanCounts.ContainsKey(precursor.Charge))
                    {
                        scanCounts[precursor.Charge] = 1;
                    }
                    else
                    {
                        scanCounts[precursor.Charge] = scanCounts[precursor.Charge] + 1;
                    }

                    var pkl = reader.GetPeakList(i);
                    if (pkl.Count == 0)
                    {
                        continue;
                    }

                    pkl.ScanMode = reader.GetScanMode(i);

                    Dictionary <int, Dictionary <int, List <PeakEntry> > > maps;
                    Dictionary <int, Dictionary <int, List <PeakEntry> > > compmaps;
                    if (!mode_maps.TryGetValue(pkl.ScanMode, out maps))
                    {
                        maps = new Dictionary <int, Dictionary <int, List <PeakEntry> > >();
                        mode_maps[pkl.ScanMode] = maps;
                    }

                    if (!mode_compmaps.TryGetValue(pkl.ScanMode, out compmaps))
                    {
                        compmaps = new Dictionary <int, Dictionary <int, List <PeakEntry> > >();
                        mode_compmaps[pkl.ScanMode] = compmaps;
                    }

                    //if (i == 17047)
                    //{
                    //  pkl.ForEach(m => Console.WriteLine("{0}\t{1}", m.Mz, m.Intensity));
                    //  return null;
                    //}

                    if (Progress.IsCancellationPending() || IsLoopStopped)
                    {
                        return(null);
                    }

                    if (!maps.ContainsKey(precursor.Charge))
                    {
                        maps[precursor.Charge]     = new Dictionary <int, List <PeakEntry> >();
                        compmaps[precursor.Charge] = new Dictionary <int, List <PeakEntry> >();
                    }

                    var map     = maps[precursor.Charge];
                    var compmap = compmaps[precursor.Charge];

                    var maxPeak      = pkl.FindMaxIntensityPeak();
                    var minIntensity = maxPeak.Intensity * options.MinRelativeIntensity;

                    double precursorMass = precursor.Charge > 0 ? PrecursorUtils.MzToMH(precursor.Mz, precursor.Charge, true) : 0.0;
                    foreach (var peak in pkl)
                    {
                        if (peak.Intensity > minIntensity)
                        {
                            AddPeak(map, maxPeak.Intensity, i, peak);

                            if (precursor.Charge > 0)
                            {
                                var peakMass = peak.Charge == 0 ? peak.Mz : PrecursorUtils.MzToMH(peak.Mz, peak.Charge, true);
                                peakMass = precursorMass - peakMass;
                                AddPeak(compmap, maxPeak.Intensity, i, new Peak(peakMass, peak.Intensity, peak.Charge));
                            }
                        }
                    }
                }
            }

            foreach (var mode in mode_maps.Keys)
            {
                var maps     = mode_maps[mode];
                var compmaps = mode_compmaps[mode];

                var keys = (from charge in maps.Keys
                            orderby charge
                            select charge).ToList();

                var resultFile1 = new FileInfo(string.Format("{0}/{1}.{2}.forward.ionfrequency",
                                                             options.TargetDirectory,
                                                             new FileInfo(fileName).Name,
                                                             mode)).FullName;

                WriteMap(scanCounts, keys, resultFile1, maps, true);

                result.Add(resultFile1);

                var resultFile2 = new FileInfo(string.Format("{0}/{1}.{2}.backward.ionfrequency",
                                                             options.TargetDirectory,
                                                             new FileInfo(fileName).Name,
                                                             mode)).FullName;

                WriteMap(scanCounts, keys, resultFile2, compmaps, false);

                result.Add(resultFile2);
            }

            return(result);
        }
        public override IEnumerable <string> Process(string targetFileName)
        {
            this.reader.Progress = this.Progress;

            List <string>       resultFile = new List <string>();
            List <IsobaricItem> result     = new List <IsobaricItem>();

            ITraqResultXmlFormatFast format = new ITraqResultXmlFormatFast();

            XmlTextWriter sw = null;

            if (!individual)
            {
                sw = XmlUtils.CreateWriter(targetFileName, Encoding.ASCII);
                ITraqResultXmlFormatFast.StartWriteDocument(sw, reader.ToString());
            }

            try
            {
                for (int i = 0; i < rawFiles.Count(); i++)
                {
                    if (Progress.IsCancellationPending())
                    {
                        throw new UserTerminatedException();
                    }

                    Progress.SetMessage(1, MyConvert.Format("Processing {0}/{1} ...", i + 1, rawFiles.Count()));
                    using (var rawreader = RawFileFactory.GetRawFileReader(rawFiles[i]))
                    {
                        reader.RawReader = rawreader;

                        ITraqResultFileDistiller distiller = new ITraqResultFileDistiller(reader, minPeakCount, plexType, isotopeImpurityCorrectionTableFileName, precursorPPMTolearnce)
                        {
                            Progress             = this.Progress,
                            NormalizationBuilder = this.builder
                        };

                        if (individual)
                        {
                            string itraqFile = distiller.Process(rawFiles[i]).First();
                            resultFile.Add(itraqFile);
                        }
                        else
                        {
                            var curResult = distiller.GetTraqResult(rawFiles[i]);

                            foreach (var item in curResult)
                            {
                                ITraqResultXmlFormatFast.WriteIsobaricItem(sw, item);
                            }

                            curResult = null;
                        }

                        GC.Collect();
                        GC.WaitForFullGCComplete();
                    }
                }

                Progress.SetMessage(0, "");
            }
            finally
            {
                if (!individual)
                {
                    sw.Close();
                }
            }

            if (!individual)
            {
                var indexBuilder = new ITraqResultXmlIndexBuilder(true)
                {
                    Progress = this.Progress
                };
                indexBuilder.Process(targetFileName);
                resultFile.Add(targetFileName);
            }

            Progress.SetMessage(1, "Finished!");

            return(resultFile);
        }
Beispiel #16
0
        public override IEnumerable <string> Process(string targetPrefix)
        {
            var result = new List <string>();

            Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > > mode_maps     = new Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > >();
            Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > > mode_compmaps = new Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > >();
            Dictionary <int, int> scanCounts = new Dictionary <int, int>();

            foreach (var fileName in sourceFiles)
            {
                //var fileName = fileNames.Skip(2).First();
                Console.WriteLine(fileName);
                var name = Path.GetFileNameWithoutExtension(fileName);

                using (var reader = RawFileFactory.GetRawFileReader(fileName))
                {
                    var firstScan = reader.GetFirstSpectrumNumber();
                    var lastScan  = reader.GetLastSpectrumNumber();

                    for (int i = firstScan; i <= lastScan; i++)
                    {
                        Peak   precursor;
                        string mode;
                        if (reader.GetMsLevel(i) == 1)
                        {
                            precursor = new Peak(0.0, 0.0, FULLMS_CHARGE);
                            mode      = "hcd";
                        }
                        else
                        {
                            precursor = reader.GetPrecursorPeak(i);
                            mode      = reader.GetScanMode(i);
                        }

                        if (!scanCounts.ContainsKey(precursor.Charge))
                        {
                            scanCounts[precursor.Charge] = 1;
                        }
                        else
                        {
                            scanCounts[precursor.Charge] = scanCounts[precursor.Charge] + 1;
                        }

                        var pkl = reader.GetPeakList(i);
                        if (pkl.Count == 0)
                        {
                            continue;
                        }

                        pkl.ScanMode = mode;

                        Dictionary <int, Dictionary <int, List <PeakEntry> > > maps;
                        Dictionary <int, Dictionary <int, List <PeakEntry> > > compmaps;
                        if (!mode_maps.TryGetValue(pkl.ScanMode, out maps))
                        {
                            maps = new Dictionary <int, Dictionary <int, List <PeakEntry> > >();
                            mode_maps[pkl.ScanMode] = maps;
                        }

                        if (!mode_compmaps.TryGetValue(pkl.ScanMode, out compmaps))
                        {
                            compmaps = new Dictionary <int, Dictionary <int, List <PeakEntry> > >();
                            mode_compmaps[pkl.ScanMode] = compmaps;
                        }

                        if (!maps.ContainsKey(precursor.Charge))
                        {
                            maps[precursor.Charge]     = new Dictionary <int, List <PeakEntry> >();
                            compmaps[precursor.Charge] = new Dictionary <int, List <PeakEntry> >();
                        }

                        var map     = maps[precursor.Charge];
                        var compmap = compmaps[precursor.Charge];

                        var maxPeak      = pkl.FindMaxIntensityPeak();
                        var minIntensity = maxPeak.Intensity * options.MinRelativeIntensity;

                        double precursorMass = precursor.Charge > 0 ? PrecursorUtils.MzToMH(precursor.Mz, precursor.Charge, true) : 0.0;
                        var    filescan      = string.Format("{0}_{1}", name, i);
                        foreach (var peak in pkl)
                        {
                            if (peak.Intensity > minIntensity)
                            {
                                AddPeak(map, maxPeak.Intensity, filescan, peak);

                                if (precursor.Charge > 0)
                                {
                                    var peakMass = peak.Charge == 0 ? peak.Mz : PrecursorUtils.MzToMH(peak.Mz, peak.Charge, true);
                                    peakMass = precursorMass - peakMass;
                                    AddPeak(compmap, maxPeak.Intensity, filescan, new Peak(peakMass, peak.Intensity, peak.Charge));
                                }
                            }
                        }
                    }
                }
                //break;
            }

            targetPrefix = Path.GetFileName(targetPrefix);

            foreach (var mode in mode_maps.Keys)
            {
                var maps     = mode_maps[mode];
                var compmaps = mode_compmaps[mode];

                var keys = (from charge in maps.Keys
                            orderby charge
                            select charge).ToList();

                var resultFile1 = new FileInfo(string.Format("{0}/{1}.{2}.forward.ionfrequency",
                                                             options.TargetDirectory,
                                                             targetPrefix,
                                                             mode)).FullName;

                WriteMap(scanCounts, keys, resultFile1, maps, true);

                result.Add(resultFile1);

                var resultFile2 = new FileInfo(string.Format("{0}/{1}.{2}.backward.ionfrequency",
                                                             options.TargetDirectory,
                                                             targetPrefix,
                                                             mode)).FullName;

                WriteMap(scanCounts, keys, resultFile2, compmaps, false);

                result.Add(resultFile2);
            }

            return(result);
        }
        public override IEnumerable <string> Process()
        {
            var format           = new MascotPeptideTextFormat();
            var spectra          = format.ReadFromFile(options.InputFile);
            var peptideMap       = spectra.ToGroupDictionary(m => m.Query.FileScan.Experimental.ToLower());
            var rawfiles         = Directory.GetFiles(options.RawDirectory, "*.raw", SearchOption.AllDirectories).ToDictionary(m => Path.GetFileNameWithoutExtension(m).ToLower());
            var rententionWindow = options.RetentionTimeWindow;

            var missed = peptideMap.Keys.Except(rawfiles.Keys).ToArray();

            if (missed.Length > 0)
            {
                throw new Exception(string.Format("Cannot find raw file of {0} in directory {1}", missed.Merge("/"), options.RawDirectory));
            }

            var option = new ParallelOptions()
            {
                //MaxDegreeOfParallelism = Math.Min(1, peptideMap.Count),
                MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, peptideMap.Count),
            };

            Parallel.ForEach(peptideMap, option, raw =>
            {
                //foreach (var raw in peptideMap)
                //{
                var peptides = raw.Value;

                Progress.SetMessage("Preparing isotopic for " + raw.Key + " ...");
                var waitingPeaks = new List <ChromatographProfile>();
                foreach (var peptide in peptides)
                {
                    string file = GetTargetFile(peptide);
                    var chro    = new ChromatographProfile()
                    {
                        Experimental   = peptide.Query.FileScan.Experimental,
                        IdentifiedScan = peptide.Query.FileScan.FirstScan,
                        ObservedMz     = peptide.GetPrecursorMz(),
                        TheoreticalMz  = peptide.GetTheoreticalMz(),
                        Charge         = peptide.Query.Charge,
                        Sequence       = peptide.Peptide.PureSequence,
                        FileName       = Path.GetFileName(file)
                    };
                    chro.InitializeIsotopicIons(options.MzTolerancePPM);
                    waitingPeaks.Add(chro);
                }

                if (waitingPeaks.Count == 0)
                {
                    //continue;
                    return;
                }

                Dictionary <string, List <ChromatographProfile> > resultMap = new Dictionary <string, List <ChromatographProfile> >();

                List <FullMS> fullMSList = new List <FullMS>();
                Progress.SetMessage("Reading full ms list from " + rawfiles[raw.Key] + "...");
                using (var rawReader = new CacheRawFile(RawFileFactory.GetRawFileReader(rawfiles[raw.Key])))
                {
                    var firstScan = rawReader.GetFirstSpectrumNumber();
                    var lastScan  = rawReader.GetLastSpectrumNumber();
                    for (int scan = firstScan; scan <= lastScan; scan++)
                    {
                        var mslevel = rawReader.GetMsLevel(scan);
                        if (mslevel == 1)
                        {
                            fullMSList.Add(new FullMS()
                            {
                                Scan          = scan,
                                RetentionTime = rawReader.ScanToRetentionTime(scan),
                                Peaks         = null
                            });
                        }
                    }

                    var chroGroups = waitingPeaks.GroupBy(chro => string.Format("{0}_{1:0.0000}", chro.Sequence, chro.TheoreticalMz));
                    foreach (var chroGroup in chroGroups)
                    {
                        List <ChromatographProfile> profileChros = new List <ChromatographProfile>();
                        foreach (var chro in chroGroup.OrderBy(m => m.IdentifiedScan))
                        {
                            var masterScanIndex = 0;
                            for (int i = 1; i < fullMSList.Count; i++)
                            {
                                if (chro.IdentifiedScan < fullMSList[i].Scan)
                                {
                                    break;
                                }
                                masterScanIndex = i;
                            }
                            var masterScan          = fullMSList[masterScanIndex].Scan;
                            var masterRetentionTime = fullMSList[masterScanIndex].RetentionTime;

                            bool bExist = false;
                            foreach (var profileChro in profileChros)
                            {
                                foreach (var pkl in profileChro.Profiles)
                                {
                                    if (pkl.Scan == fullMSList[masterScanIndex].Scan)
                                    {
                                        pkl.Identified = true;
                                        bExist         = true;
                                        break;
                                    }
                                }

                                if (bExist)
                                {
                                    break;
                                }
                            }

                            if (bExist)
                            {
                                continue;
                            }

                            Progress.SetMessage("Processing {0} : {1:0.#####} : {2} : {3}", chro.Sequence, chro.ObservedMz, chro.IdentifiedScan, Path.GetFileName(chro.FileName));

                            for (int scanIndex = masterScanIndex; scanIndex >= 0; scanIndex--)
                            {
                                if (Progress.IsCancellationPending())
                                {
                                    throw new UserTerminatedException();
                                }

                                var curRetentionTime = fullMSList[scanIndex].RetentionTime;
                                if (masterRetentionTime - curRetentionTime > rententionWindow)
                                {
                                    break;
                                }

                                if (!AddEnvelope(chro, rawReader, fullMSList, scanIndex))
                                {
                                    break;
                                }

                                if (scanIndex == masterScanIndex)
                                {
                                    chro.Profiles.Last().Identified = true;
                                }
                            }
                            chro.Profiles.Reverse();

                            for (int scanIndex = masterScanIndex + 1; scanIndex < fullMSList.Count; scanIndex++)
                            {
                                if (Progress.IsCancellationPending())
                                {
                                    throw new UserTerminatedException();
                                }

                                var curRetentionTime = fullMSList[scanIndex].RetentionTime;
                                if (curRetentionTime - masterRetentionTime > rententionWindow)
                                {
                                    break;
                                }

                                if (!AddEnvelope(chro, rawReader, fullMSList, scanIndex))
                                {
                                    break;
                                }
                            }

                            profileChros.Add(chro);
                        }

                        profileChros.RemoveAll(l => l.Profiles.Count < options.MinimumScanCount);
                        profileChros.Sort((m1, m2) => m2.Profiles.Count.CompareTo(m1.Profiles.Count));

                        bool bMain = true;
                        foreach (var chro in profileChros)
                        {
                            string filename;
                            if (bMain)
                            {
                                filename = Path.Combine(GetTargetDirectory(chro.Experimental), chro.FileName);
                            }
                            else
                            {
                                filename = Path.Combine(GetTargetSubDirectory(chro.Experimental), Path.ChangeExtension(chro.FileName, ".sub" + Path.GetExtension(chro.FileName)));
                            }
                            bMain = false;

                            new ChromatographProfileTextWriter().WriteToFile(filename, chro);
                            new ChromatographProfileXmlFormat().WriteToFile(filename + ".xml", chro);
                        }
                    }
                }
            }
                             );

            Progress.SetMessage("Finding boundaries ...");
            var boundaryOptions = new RTemplateProcessorOptions()
            {
                InputFile      = targetDir,
                OutputFile     = options.OutputFile,
                RTemplate      = BoundaryR,
                RExecute       = SystemUtils.GetRExecuteLocation(),
                CreateNoWindow = true
            };

            new RTemplateProcessor(boundaryOptions)
            {
                Progress = this.Progress
            }.Process();

            return(new string[] { options.OutputFile });
        }
        public override IEnumerable <string> Process(string fileName)
        {
            var result = new List <string>();

            Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > > mode_maps = new Dictionary <string, Dictionary <int, Dictionary <int, List <PeakEntry> > > >();
            Dictionary <int, int> scanCounts = new Dictionary <int, int>();

            using (var reader = RawFileFactory.GetRawFileReader(fileName))
            {
                var firstScan = reader.GetFirstSpectrumNumber();
                var lastScan  = reader.GetLastSpectrumNumber();

                for (int i = firstScan; i <= lastScan; i++)
                {
                    if (reader.GetMsLevel(i) != 2)
                    {
                        continue;
                    }

                    var precursor = reader.GetPrecursorPeak(i);

                    if (!scanCounts.ContainsKey(precursor.Charge))
                    {
                        scanCounts[precursor.Charge] = 1;
                    }
                    else
                    {
                        scanCounts[precursor.Charge] = scanCounts[precursor.Charge] + 1;
                    }

                    var pkl = reader.GetPeakList(i);
                    if (pkl.Count == 0)
                    {
                        continue;
                    }

                    pkl.ScanMode = reader.GetScanMode(i);

                    Dictionary <int, Dictionary <int, List <PeakEntry> > > maps;
                    if (!mode_maps.TryGetValue(pkl.ScanMode, out maps))
                    {
                        maps = new Dictionary <int, Dictionary <int, List <PeakEntry> > >();
                        mode_maps[pkl.ScanMode] = maps;
                    }

                    if (Progress.IsCancellationPending() || IsLoopStopped)
                    {
                        return(null);
                    }

                    if (!maps.ContainsKey(precursor.Charge))
                    {
                        maps[precursor.Charge] = new Dictionary <int, List <PeakEntry> >();
                    }

                    var map = maps[precursor.Charge];

                    var maxPeak      = pkl.FindMaxIntensityPeak();
                    var minIntensity = maxPeak.Intensity * options.MinRelativeIntensity;

                    foreach (var peak in pkl)
                    {
                        if (peak.Intensity > minIntensity)
                        {
                            var peakMass    = peak.Mz - precursor.Mz;
                            var mztolerance = PrecursorUtils.ppm2mz(peak.Mz, options.ProductIonPPM);
                            AddPeak(map, maxPeak.Intensity, i, new Peak(peakMass, peak.Intensity, peak.Charge), mztolerance);
                        }
                    }
                }
            }

            foreach (var mode in mode_maps.Keys)
            {
                var maps = mode_maps[mode];

                var keys = (from charge in maps.Keys
                            orderby charge
                            select charge).ToList();

                var resultFile1 = new FileInfo(string.Format("{0}/{1}.{2}.precursor_delta.ionfrequency",
                                                             options.TargetDirectory,
                                                             new FileInfo(fileName).Name,
                                                             mode)).FullName;

                WriteMap(scanCounts, keys, resultFile1, maps, true);

                result.Add(resultFile1);
            }

            return(result);
        }
Beispiel #19
0
        public override List <OffsetEntry> GetOffsets(string fileName)
        {
            var result = new List <OffsetEntry>();

            foreach (var ion in monitorIons)
            {
                ion.PrecursorPPM = this.maxShiftPPM;
                ion.OffsetPPM    = 0;
            }

            using (var reader = new CacheRawFile(RawFileFactory.GetRawFileReader(fileName)))
            {
                DoGetOffsets(result, reader, "Processing " + fileName + ", first round ...");

                var firstScan = reader.GetFirstSpectrumNumber();
                var lastScan  = reader.GetLastSpectrumNumber();

                var dic = result.ToDictionary(m => m.Scan);

                SetMessage("Processing " + fileName + ", second round ...");
                SetRange(firstScan, lastScan);
                for (int scan = firstScan; scan <= lastScan; scan++)
                {
                    if (reader.GetMsLevel(scan) == 1)
                    {
                        SetPosition(scan);

                        if (IsLoopStopped)
                        {
                            return(null);
                        }

                        if (Progress.IsCancellationPending())
                        {
                            throw new UserTerminatedException();
                        }

                        var pkl = reader.GetPeakList(scan);
                        var rt  = reader.ScanToRetentionTime(scan);

                        var offsetEntry = dic[scan];
                        foreach (var ion in monitorIons)
                        {
                            ion.PrecursorPPM = this.precursorPPM;
                            ion.OffsetPPM    = offsetEntry.InitValue.MedianInWindow;
                        }

                        var offsetValues = GetOffsetsFromPeakList(pkl);

                        if (offsetValues.Count > 0)
                        {
                            offsetEntry.RefineValue.IonOffset = GetWeightedPPM(offsetValues);
                            offsetEntry.RefineValue.Count     = offsetValues.Count;
                        }
                        else
                        {
                            offsetEntry.RefineValue.IonOffset = 0.0;
                            offsetEntry.RefineValue.Count     = 0;
                        }
                    }
                }

                CalculateOffset(result, m => m.RefineValue);
            }

            return(result);
        }
        protected virtual IEnumerable <string> DoProcess(string fileName, List <int> ignoreScans, int lastScan, bool bContinue)
        {
            var result = new List <string>();

            bool bReadAgain = false;

            using (var rawReader = RawFileFactory.GetRawFileReader(fileName))
            {
                try
                {
                    if (!bContinue)
                    {
                        DoInitialize(rawReader, fileName);
                    }

                    string experimental = rawReader.GetFileNameWithoutExtension(fileName);

                    SetMessage("Processing " + fileName + " ...");

                    int firstSpectrumNumber = rawReader.GetFirstSpectrumNumber();
                    int lastSpectrumNumber  = rawReader.GetLastSpectrumNumber();
                    //int firstSpectrumNumber = 79800;

                    SetRange(firstSpectrumNumber, lastSpectrumNumber);

                    lastScan = Math.Max(lastScan, firstSpectrumNumber);
                    for (int scan = lastScan; scan <= lastSpectrumNumber; scan++)
                    {
                        lastScan = scan;

                        if (Progress.IsCancellationPending())
                        {
                            throw new UserTerminatedException();
                        }

                        if (IsLoopStopped)
                        {
                            return(result);
                        }

                        if (ignoreScans.Contains(scan))
                        {
                            continue;
                        }

                        SetPosition(scan);

                        int msLevel = rawReader.GetMsLevel(scan);

                        if (!DoAcceptMsLevel(msLevel))
                        {
                            continue;
                        }

                        //Console.WriteLine("Reading scan {0}", scan);

                        PeakList <Peak> pkl;
                        try
                        {
                            PrecursorPeak precursor = null;
                            if (msLevel > 1)
                            {
                                precursor = new PrecursorPeak(rawReader.GetPrecursorPeak(scan));
                            }

                            pkl              = rawReader.GetPeakList(scan);
                            pkl.MsLevel      = msLevel;
                            pkl.Experimental = experimental;
                            pkl.ScanMode     = rawReader.GetScanMode(scan);
                            pkl.Precursor    = precursor;

                            if (msLevel > 1 && precursor.Charge == 0)
                            {
                                precursor.Charge = PrecursorUtils.GuessPrecursorCharge(pkl, pkl.PrecursorMZ);
                            }
                        }
                        catch
                        {
                            Console.WriteLine("Scan {0} ignored.", scan);
                            ignoreScans.Add(scan);
                            File.WriteAllLines(GetIgnoreScanFile(fileName), (from i in ignoreScans
                                                                             let s = i.ToString()
                                                                                     select s).ToArray());
                            bReadAgain = true;
                            break;
                        }

                        PeakList <Peak> pklProcessed;
                        if (msLevel > 1)
                        {
                            if (null == this.PeakListProcessor || (options.ExtractRawMS3 && pkl.MsLevel >= 3))
                            {
                                pklProcessed = pkl;
                            }
                            else
                            {
                                pklProcessed = this.PeakListProcessor.Process(pkl);
                            }
                        }
                        else
                        {
                            pklProcessed = pkl;
                        }

                        if (null != pklProcessed && pklProcessed.Count > 0)
                        {
                            DoWritePeakList(rawReader, pklProcessed, fileName, result);
                        }
                    }
                }
                finally
                {
                    if (!bReadAgain)
                    {
                        DoFinalize(bReadAgain, rawReader, fileName, result);
                    }
                }
            }

            if (bReadAgain)
            {
                return(DoProcess(fileName, ignoreScans, lastScan, true));
            }
            else
            {
                return(result);
            }
        }
Beispiel #21
0
        private List <SrmScan> GetMRMScans(string directory)
        {
            var fileName = GetPeakFileName(directory);

            if (File.Exists(fileName))
            {
                SetProgressMessage("Reading scan from " + fileName + " ...");
                return(new SrmScanFileFormat().ReadFromFile(fileName));
            }
            else
            {
                List <PeakList <Peak> > pkls = new List <PeakList <Peak> >();

                SetProgressMessage("Reading scan from " + directory + " ...");
                IRawFile reader = RawFileFactory.GetRawFileReader(directory);
                try
                {
                    var firstCount = reader.GetFirstSpectrumNumber();
                    var lastCount  = reader.GetLastSpectrumNumber();

                    Progress.SetRange(firstCount, lastCount);
                    Progress.SetPosition(firstCount);
                    for (int i = firstCount; i <= lastCount; i++)
                    {
                        if (reader.GetMsLevel(i) != 2)
                        {
                            continue;
                        }

                        if (Progress.IsCancellationPending())
                        {
                            throw new UserTerminatedException();
                        }

                        Progress.Increment(1);

                        var pkl       = reader.GetPeakList(i);
                        var precursor = reader.GetPrecursorPeak(i);
                        if (precursor != null)
                        {
                            pkl.PrecursorMZ     = precursor.Mz;
                            pkl.PrecursorCharge = precursor.Charge;
                        }
                        pkl.ScanTimes.Add(new ScanTime(i, reader.ScanToRetentionTime(i)));

                        pkls.Add(pkl);
                    }

                    List <SrmScan> result = new List <SrmScan>();

                    pkls.ForEach(m => m.ForEach(n => result.Add(new SrmScan(m.PrecursorMZ, n.Mz, m.ScanTimes[0].RetentionTime, n.Intensity, true))));

                    new SrmScanFileFormat().WriteToFile(fileName, result);

                    SetProgressMessage("finished.");

                    return(result);
                }
                finally
                {
                    reader.Close();
                }
            }
        }
Beispiel #22
0
        public override IEnumerable <string> Process(string fileName)
        {
            Dictionary <int, List <PeakEntry> > maps     = new Dictionary <int, List <PeakEntry> >();
            Dictionary <int, List <PeakEntry> > compmaps = new Dictionary <int, List <PeakEntry> >();
            Dictionary <int, int> scanCounts             = new Dictionary <int, int>();

            using (var reader = RawFileFactory.GetRawFileReader(fileName))
            {
                //var firstScan = 17047;
                //var lastScan = 17047;
                var firstScan = reader.GetFirstSpectrumNumber();
                var lastScan  = reader.GetLastSpectrumNumber();

                for (int i = firstScan; i <= lastScan; i++)
                {
                    Peak precursor;
                    if (reader.GetMsLevel(i) == 1)
                    {
                        precursor = new Peak(0.0, 0.0, FULLMS_CHARGE);
                    }
                    else
                    {
                        precursor = reader.GetPrecursorPeak(i);
                    }

                    if (!scanCounts.ContainsKey(precursor.Charge))
                    {
                        scanCounts[precursor.Charge] = 1;
                    }
                    else
                    {
                        scanCounts[precursor.Charge] = scanCounts[precursor.Charge] + 1;
                    }

                    var pkl = reader.GetPeakList(i);
                    if (pkl.Count == 0)
                    {
                        continue;
                    }

                    if (Progress.IsCancellationPending() || IsLoopStopped)
                    {
                        return(null);
                    }

                    if (!maps.ContainsKey(precursor.Charge))
                    {
                        maps[precursor.Charge]     = new List <PeakEntry>();
                        compmaps[precursor.Charge] = new List <PeakEntry>();
                    }

                    var ions     = maps[precursor.Charge];
                    var compIons = compmaps[precursor.Charge];

                    var maxPeak      = pkl.FindMaxIntensityPeak();
                    var minIntensity = maxPeak.Intensity * this.minRelativeIntensity;

                    double precursorMass = precursor.Charge > 0 ? PrecursorUtils.MzToMass(precursor.Mz, precursor.Charge, true) : 0.0;
                    foreach (var peak in pkl)
                    {
                        if (peak.Intensity > minIntensity)
                        {
                            AddPeak(ions, maxPeak.Intensity, i, peak);

                            if (precursor.Charge > 0)
                            {
                                var peakMass = peak.Charge == 0 ? peak.Mz : PrecursorUtils.MzToMass(peak.Mz, peak.Charge, true);
                                peakMass = precursorMass - peakMass;
                                AddPeak(compIons, maxPeak.Intensity, i, new Peak(peakMass, peak.Intensity, peak.Charge));
                            }
                        }
                    }
                    pkl.Clear();
                }
            }

            var keys = (from charge in maps.Keys
                        orderby charge
                        select charge).ToList();

            var resultFile1 = new FileInfo(targetDir + "//" + new FileInfo(fileName).Name + ".forward.ionfrequency").FullName;

            WriteMap(scanCounts, keys, resultFile1, maps, true);

            var resultFile2 = new FileInfo(targetDir + "//" + new FileInfo(fileName).Name + ".backward.ionfrequency").FullName;

            WriteMap(scanCounts, keys, resultFile2, compmaps, false);

            return(new string[] { resultFile1, resultFile2 });
        }
Beispiel #23
0
        public override IEnumerable <string> Process()
        {
            var format         = new MascotPeptideTextFormat();
            var expPeptidesMap = format.ReadFromFile(options.PeptideFile).GroupBy(m => m.Query.FileScan.Experimental).ToDictionary(m => m.Key, m => m.ToList());
            var expRawfileMap  = options.RawFiles.ToDictionary(m => Path.GetFileNameWithoutExtension(m));

            foreach (var exp in expPeptidesMap.Keys)
            {
                if (!expRawfileMap.ContainsKey(exp))
                {
                    throw new Exception(string.Format("Raw file of {0} is not assigned in RawFiles.", exp));
                }
            }

            var ms2list = new List <MS2Item>();

            foreach (var exp in expPeptidesMap.Keys)
            {
                var rawfile  = expRawfileMap[exp];
                var peptides = expPeptidesMap[exp];

                using (var reader = RawFileFactory.GetRawFileReader(rawfile, false))
                {
                    var firstScan = reader.GetFirstSpectrumNumber();
                    var lastScan  = reader.GetLastSpectrumNumber();

                    Progress.SetRange(0, peptides.Count);
                    Progress.SetMessage("Extracting MS2/MS3 information ...");
                    int count = 0;
                    foreach (var peptide in peptides)
                    {
                        count++;
                        Progress.SetPosition(count);

                        var ms2 = new MS2Item()
                        {
                            Peptide      = peptide.Peptide.Sequence,
                            Precursor    = peptide.GetPrecursorMz(),
                            Charge       = peptide.Query.Charge,
                            Modification = peptide.Modifications,
                            FileScans    = new SequestFilename[] { peptide.Query.FileScan }.ToList(),
                            Score       = peptide.Score,
                            ExpectValue = peptide.ExpectValue,
                            Proteins    = peptide.GetProteins("/")
                        };

                        for (int ms3scan = peptide.Query.FileScan.FirstScan + 1; ms3scan < lastScan; ms3scan++)
                        {
                            var mslevel = reader.GetMsLevel(ms3scan);
                            if (mslevel != 3)
                            {
                                break;
                            }
                            var pkl = reader.GetPeakList(ms3scan);
                            if (pkl.Count == 0)
                            {
                                continue;
                            }
                            var precursor = reader.GetPrecursorPeak(ms3scan);
                            pkl.PrecursorMZ = precursor.Mz;
                            ms2.MS3Spectra.Add(new MS3Item(pkl));
                        }

                        if (ms2.MS3Spectra.Count > 0)
                        {
                            ms2list.Add(ms2);
                        }
                    }
                }
            }

            Progress.SetMessage("Merging MS2 by peptide and charge ...");

            var ms2group   = ms2list.GroupBy(m => string.Format("{0}:{1}", m.Peptide, m.Charge)).ToList();
            var ms2library = new List <MS2Item>();

            foreach (var g in ms2group)
            {
                if (g.Count() < options.MinIdentifiedSpectraPerPeptide)
                {
                    continue;
                }

                var gitem = g.First();
                gitem.CombinedCount = g.Count();
                gitem.Precursor     = g.Average(m => m.Precursor);
                gitem.Score         = g.Max(m => m.Score);
                gitem.ExpectValue   = g.Min(m => m.ExpectValue);
                gitem.FileScans     = (from gg in g from fs in gg.FileScans select fs).ToList();
                foreach (var ms2 in g.Skip(1))
                {
                    gitem.MS3Spectra.AddRange(ms2.MS3Spectra);
                }

                ms2library.Add(gitem);
            }

            ms2library.Sort((m1, m2) =>
            {
                var res = m1.Peptide.CompareTo(m2.Peptide);
                if (res == 0)
                {
                    res = m1.Charge.CompareTo(m2.Charge);
                }
                return(res);
            });

            new MS2ItemXmlFormat().WriteToFile(options.OutputUncombinedFile, ms2library);

            Progress.SetMessage("Combing MS3 by precursor ...");

            var builder = new BestSpectrumTopSharedPeaksBuilder(options.FragmentPPMTolerance, options.MaxFragmentPeakCount);

            ms2library.ForEach(m => m.CombineMS3Spectra(builder, options.PrecursorPPMTolerance));

            Progress.SetMessage("Initialize terminal loss ...");
            var aas = options.GetAminoacids();

            ms2library.ForEach(l => l.InitTerminalLoss(aas, options.MaxTerminalLossLength, options.MinSequenceLength));

            new MS2ItemXmlFormat().WriteToFile(options.OutputFile, ms2library);

            Progress.End();

            return(new[] { options.OutputFile, options.OutputUncombinedFile });
        }
        private List <MS2Item> GetCandidateMs2ItemList(Dictionary <string, string> expRawfileMap, Dictionary <string, HashSet <int> > expScanMap)
        {
            var result = new List <MS2Item>();

            foreach (var exp in expRawfileMap.Keys)
            {
                var rawfile = expRawfileMap[exp];
                var scans   = expScanMap.ContainsKey(exp) ? expScanMap[exp] : new HashSet <int>();

                Progress.SetMessage("Reading MS2/MS3 from {0} ...", rawfile);
                using (var reader = RawFileFactory.GetRawFileReader(rawfile, false))
                {
                    var firstScan = reader.GetFirstSpectrumNumber();
                    var lastScan  = reader.GetLastSpectrumNumber();

                    Progress.SetRange(firstScan, lastScan);
                    for (int scan = firstScan; scan < lastScan; scan++)
                    {
                        var msLevel = reader.GetMsLevel(scan);
                        if (msLevel != 2)
                        {
                            continue;
                        }

                        if (scans.Contains(scan))
                        {
                            continue;
                        }

                        if (Progress.IsCancellationPending())
                        {
                            throw new UserTerminatedException();
                        }

                        Progress.SetPosition(scan);

                        var ms2precursor = reader.GetPrecursorPeak(scan);
                        var ms2          = new MS2Item()
                        {
                            Precursor = ms2precursor.Mz,
                            Charge    = ms2precursor.Charge,
                            FileScans = new SequestFilename[] { new SequestFilename(exp, scan, scan, ms2precursor.Charge, string.Empty) }.ToList()
                        };

                        for (int ms3scan = scan + 1; ms3scan < lastScan; ms3scan++)
                        {
                            var mslevel = reader.GetMsLevel(ms3scan);
                            if (mslevel != 3)
                            {
                                scan = ms3scan - 1;
                                break;
                            }
                            var pkl = reader.GetPeakList(ms3scan);
                            if (pkl.Count == 0)
                            {
                                continue;
                            }

                            var ms3precursor = reader.GetPrecursorPeak(ms3scan);
                            pkl.PrecursorMZ = ms3precursor.Mz;
                            ms2.MS3Spectra.Add(new MS3Item(pkl));
                        }

                        if (ms2.MS3Spectra.Count > 0)
                        {
                            result.Add(ms2);
                        }
                    }
                }
            }

            return(result);
        }
        public override void Update(object sender, UpdateQuantificationItemEventArgs e)
        {
            var summary = e.Item as O18QuantificationSummaryItem;

            if (summary == null)
            {
                throw new ArgumentNullException("UpdateQuantificationItemEventArgs.Item cannot be null");
            }

            panel.InitGraphPane(this.title, "m/z", "Intensity", true, 0.0);

            ZedGraphicExtension.ClearData(zgcGraph, false);
            try
            {
                var envelope = summary.ObservedEnvelopes.Find(m => m.IsSelected);
                if (envelope == null)
                {
                    return;
                }

                panel.InitGraphPane(this.title + ", Scan=" + envelope.Scan.ToString(), "m/z", "Intensity", true, 0.0);

                double minMz = envelope[0].Mz - 1.0;
                double maxMz = envelope[envelope.Count - 1].Mz + 1.0;

                zgcGraph.GraphPane.XAxis.Scale.Min = minMz;
                zgcGraph.GraphPane.XAxis.Scale.Max = maxMz;

                var ppl = new PointPairList();
                envelope.ForEach(p => { if (p.Intensity > 0)
                                        {
                                            ppl.Add(p.Mz, p.Intensity);
                                        }
                                 });
                panel.AddIndividualLine("Isotopic Envelope", ppl, Color.Red);
                panel.AddTextUp(ppl, 5, (m => m.X.ToString("0.0000")));

                var halfMax = (from env in envelope
                               select env.Intensity).Max() / 2;
                ppl.Clear();
                envelope.ForEach(p => { if (p.Intensity == 0)
                                        {
                                            ppl.Add(p.Mz, halfMax);
                                        }
                                 });
                panel.AddIndividualLine("", ppl, defaultColor: Color.Red, dStyle: DashStyle.Dash);
                panel.AddTextUp(ppl, 5, (m => m.X.ToString("0.0000")));

                if (File.Exists(summary.RawFilename))
                {
                    if (rawFile == null)
                    {
                        rawFile = RawFileFactory.GetRawFileReader(summary.RawFilename);
                    }
                    else if (!rawFile.FileName.Equals(summary.RawFilename))
                    {
                        rawFile.Close();
                        rawFile = RawFileFactory.GetRawFileReader(summary.RawFilename);
                    }

                    PeakList <Peak> pkl    = rawFile.GetPeakList(envelope.ScanTimes[0].Scan);
                    var             pplRaw = new PointPairList();
                    for (int i = 0; i < pkl.Count; i++)
                    {
                        if (pkl[i].Mz < minMz)
                        {
                            continue;
                        }
                        else if (pkl[i].Mz > maxMz)
                        {
                            break;
                        }
                        pplRaw.Add(pkl[i].Mz, -pkl[i].Intensity);
                    }

                    panel.AddIndividualLine("PeakList From RawFile", pplRaw, Color.Blue);
                    panel.AddTextDown(pplRaw, 5, (m => m.X.ToString("0.0000")));

                    /*
                     * foreach (var p in ppl)
                     * {
                     * if (p.Y == 0)
                     * {
                     *  double ppm = double.MaxValue;
                     *  double ppmAbs = Math.Abs(ppm);
                     *  foreach (var pp in pplRaw)
                     *  {
                     *    double ppmCur = PrecursorUtils.mz2ppm(pp.X, pp.X - p.X);
                     *    double ppmCurAbs = Math.Abs(ppmCur);
                     *    if (Math.Abs(ppmCur) < ppmAbs)
                     *    {
                     *      ppm = ppmCur;
                     *      ppmAbs = ppmCurAbs;
                     *    }
                     *
                     *    if (pp.X > p.X)
                     *    {
                     *      break;
                     *    }
                     *  }
                     *
                     *  p.Z = ppm;
                     * }
                     * }
                     */
                }
            }
            finally
            {
                ZedGraphicExtension.UpdateGraph(zgcGraph);
            }
        }