private SpectrumPeaksInfo.MI[] ReadSpectrum(BiblioSpectrumInfo info) { const int lenPair = sizeof(float) + sizeof(float); byte[] peaks = new byte[info.NumPeaks * lenPair]; lock (ReadStream) { try { Stream fs = ReadStream.Stream; // Seek to stored location fs.Seek(info.Location, SeekOrigin.Begin); // Single read to get all the peaks if (fs.Read(peaks, 0, peaks.Length) < peaks.Length) { throw new IOException(Resources.BiblioSpecLibrary_ReadSpectrum_Failure_trying_to_read_peaks); } } catch (Exception) { // If an exception is thrown, close the stream in case the failure is something // like a network failure that can be remedied by re-opening the stream. ReadStream.CloseStream(); throw; } } // Build the list var arrayMI = new SpectrumPeaksInfo.MI[info.NumPeaks]; for (int i = 0, iNext = 0; i < peaks.Length; i += lenPair) { arrayMI[iNext].Intensity = BitConverter.ToSingle(peaks, i + sizeof(Single)); arrayMI[iNext++].Mz = BitConverter.ToSingle(peaks, i); } return(arrayMI); }
// ReSharper restore UnusedMember.Local private bool Load(ILoadMonitor loader) { ProgressStatus status = new ProgressStatus(string.Format(Resources.BiblioSpecLibrary_Load_Loading__0__library, Path.GetFileName(FilePath))); loader.UpdateProgress(status); long lenRead = 0; // AdlerChecksum checksum = new AdlerChecksum(); try { // Use a buffered stream for initial read BufferedStream stream = new BufferedStream(CreateStream(loader), 32 * 1024); int countHeader = (int)LibHeaders.count * 4; byte[] libHeader = new byte[countHeader]; if (stream.Read(libHeader, 0, countHeader) != countHeader) { throw new InvalidDataException(Resources.BiblioSpecLibrary_Load_Data_truncation_in_library_header_File_may_be_corrupted); } lenRead += countHeader; // Check the first byte of the primary version number to determine // whether the format is little- or big-endian. Little-endian will // have the version number in this byte, while big-endian will have zero. if (libHeader[(int)LibHeaders.version1 * 4] == 0) { _bigEndian = true; } int numSpectra = GetInt32(libHeader, (int)LibHeaders.num_spectra); var dictLibrary = new Dictionary <LibKey, BiblioSpectrumInfo>(numSpectra); var setSequences = new HashSet <LibSeqKey>(); string revStr = string.Format("{0}.{1}", // Not L10N GetInt32(libHeader, (int)LibHeaders.version1), GetInt32(libHeader, (int)LibHeaders.version2)); Revision = float.Parse(revStr, CultureInfo.InvariantCulture); // checksum.MakeForBuff(libHeader, AdlerChecksum.ADLER_START); countHeader = (int)SpectrumHeaders.count * 4; byte[] specHeader = new byte[1024]; byte[] specSequence = new byte[1024]; for (int i = 0; i < numSpectra; i++) { int percent = i * 100 / numSpectra; if (status.PercentComplete != percent) { // Check for cancellation after each integer change in percent loaded. if (loader.IsCanceled) { loader.UpdateProgress(status.Cancel()); return(false); } // If not cancelled, update progress. loader.UpdateProgress(status = status.ChangePercentComplete(percent)); } // Read spectrum header int bytesRead = stream.Read(specHeader, 0, countHeader); if (bytesRead != countHeader) { throw new InvalidDataException(Resources.BiblioSpecLibrary_Load_Data_truncation_in_spectrum_header_File_may_be_corrupted); } // If this is the first header, and the sequence length is zero, // then this is a Linux format library. Switch to linux format, // and start over. if (i == 0 && GetInt32(specHeader, (int)SpectrumHeaders.seq_len) == 0) { _linuxFormat = true; stream.Seek(lenRead, SeekOrigin.Begin); // Re-ead spectrum header countHeader = (int)SpectrumHeadersLinux.count * 4; bytesRead = stream.Read(specHeader, 0, countHeader); if (bytesRead != countHeader) { throw new InvalidDataException(Resources.BiblioSpecLibrary_Load_Data_truncation_in_spectrum_header_File_may_be_corrupted); } } lenRead += bytesRead; // checksum.MakeForBuff(specHeader, checksum.ChecksumValue); int charge = GetInt32(specHeader, (int)SpectrumHeaders.charge); if (charge > TransitionGroup.MAX_PRECURSOR_CHARGE) { throw new InvalidDataException(Resources.BiblioSpecLibrary_Load_Invalid_precursor_charge_found_File_may_be_corrupted); } int numPeaks = GetInt32(specHeader, (int)SpectrumHeaders.num_peaks); int seqLength = GetInt32(specHeader, (_linuxFormat ? (int)SpectrumHeadersLinux.seq_len : (int)SpectrumHeaders.seq_len)); int copies = GetInt32(specHeader, (_linuxFormat ? (int)SpectrumHeadersLinux.copies : (int)SpectrumHeaders.copies)); // Read sequence information int countSeq = (seqLength + 1) * 2; if (stream.Read(specSequence, 0, countSeq) != countSeq) { throw new InvalidDataException(Resources.BiblioSpecLibrary_Load_Data_truncation_in_spectrum_sequence_File_may_be_corrupted); } lenRead += countSeq; // checksum.MakeForBuff(specSequence, checksum.ChecksumValue); // Store in dictionary if (IsUnmodified(specSequence, seqLength + 1, seqLength)) { // These libraries should not have duplicates, but just in case. // CONSIDER: Emit error about redundancy? // These legacy libraries assume [+57.0] modified Cysteine LibKey key = new LibKey(GetCModified(specSequence, ref seqLength), 0, seqLength, charge); if (!dictLibrary.ContainsKey(key)) { dictLibrary.Add(key, new BiblioSpectrumInfo((short)copies, (short)numPeaks, lenRead)); } setSequences.Add(new LibSeqKey(key)); } // Read over peaks int countPeaks = 2 * sizeof(Single) * numPeaks; stream.Seek(countPeaks, SeekOrigin.Current); // Skip spectrum lenRead += countPeaks; // checksum.MakeForBuff(specPeaks, checksum.ChecksumValue); } // Checksum = checksum.ChecksumValue; _dictLibrary = dictLibrary; _setSequences = setSequences; loader.UpdateProgress(status.Complete()); return(true); } catch (InvalidDataException x) { loader.UpdateProgress(status.ChangeErrorException(x)); return(false); } catch (IOException x) { loader.UpdateProgress(status.ChangeErrorException(x)); return(false); } catch (Exception x) { x = new Exception(string.Format(Resources.BiblioSpecLibrary_Load_Failed_loading_library__0__, FilePath), x); loader.UpdateProgress(status.ChangeErrorException(x)); return(false); } finally { if (ReadStream != null) { // Close the read stream to ensure we never leak it. // This only costs on extra open, the first time the // active document tries to read. try { ReadStream.CloseStream(); } catch (IOException) {} } } }