/// <summary> /// Reads a single trace header from the file /// </summary> /// <param name="traceIndex">The trace index as it appears in squence in the file</param> /// <returns>The segy trace header</returns> public SegyTraceHeader ReadTraceHeader(long traceIndex) { CodeContract.Requires(traceIndex < (long)TraceCount, "Trace index to read must be less than the number of traces in the file."); CodeContract.Requires(traceIndex >= 0, "Trace index must be greater than or equal to 0"); var isLilEndian = IsLittleEndian; _stream.Seek(0, SeekOrigin.Begin); var textFileHeadersCount = FileTextualHeaders.Length; var binaryHeader = FileBinaryHeader; var dataStartIndex = TextHeaderBytesCount + BinaryHeaderBytesCount + TextHeaderBytesCount * (textFileHeadersCount - 1); var sampleFormat = (FormatCode)binaryHeader.DataSampleFormatCode; var sampleSz = SizeFrom(sampleFormat); var initStreamPosition = dataStartIndex + traceIndex * (TraceHeaderBytesCount + sampleSz * binaryHeader.SamplesPerTraceOfFile); // as per rev 1, all data values are assumed big endian CodeContract.Assume(initStreamPosition <= _stream.Length, "initial trace index exceeds file length."); _stream.Seek(initStreamPosition, SeekOrigin.Begin); var traceHeaderByteArr = _reader.ReadBytes(TraceHeaderBytesCount); return(SegyTraceHeader.From(traceHeaderByteArr, isLilEndian)); }
/// <summary> /// Reads a single trace from the file. /// </summary> /// <param name="traceIndex">The trace index as it appears in squence in the file</param> /// <returns>The segy trace</returns> public SegyTrace ReadTrace(long traceIndex) { CodeContract.Requires(traceIndex < TraceCount, "Trace index to read must be less than the number of traces in the file."); CodeContract.Requires(traceIndex >= 0, "Trace index must be greater than or equal to 0"); var islilEndian = IsLittleEndian; _stream.Seek(0, SeekOrigin.Begin); var textFileHeadersCount = FileTextualHeaders.Length; var binaryHeader = FileBinaryHeader; var dataStartIndex = TextHeaderBytesCount + BinaryHeaderBytesCount + TextHeaderBytesCount * (textFileHeadersCount - 1); var sampleFormat = (FormatCode)binaryHeader.DataSampleFormatCode; int sampleSz = SizeFrom(sampleFormat); // as per rev 1, all data values are assumed big endian var ns = binaryHeader.SamplesPerTraceOfFile; var initStreamPosition = dataStartIndex + (240 + ns * sampleSz) * traceIndex; CodeContract.Assume(initStreamPosition <= _stream.Length, "initial trace index exceeds file length."); _stream.Seek(initStreamPosition, SeekOrigin.Begin); var traceHeaderByteArr = _reader.ReadBytes(TraceHeaderBytesCount); var trHeader = SegyTraceHeader.From(traceHeaderByteArr, islilEndian); var traceDataBytesSz = trHeader.SampleCount * sampleSz; var traceDataBytes = _reader.ReadBytes(traceDataBytesSz); var traceData = GetData(traceDataBytes, sampleFormat, trHeader.SampleCount); var seismicTrace = new SegyTrace { ComponentAxis = 0, Data = traceData, Header = trHeader }; return(seismicTrace); }
/// <summary> /// Ctor /// </summary> /// <param name="traceHeader">The trace header to use for this trace</param> /// <param name="data">Trace data for this trace</param> /// <param name="componentAxis">The cartesian coordinate direction in which this trace exists</param> public SegyTrace(SegyTraceHeader traceHeader, float[] data, int componentAxis = 0) { Header = traceHeader; Data = data; ComponentAxis = componentAxis; CodeContract.Assume(data.Length <= ushort.MaxValue, "The length of the data array for this trace must not exceed ushort.MaxValue due to type definitions of the sample count property in the trace header."); Header.SampleCount = (ushort)data.Length; }
/// <summary> /// Reads a set of segy traceheaders in the file within a defined range /// <remarks> /// if startTrace and endTrace are default for this method, all traces in the file will be read</remarks> /// </summary> /// <param name="progress">A progress handler</param> /// <param name="ct">A cancellation token</param> /// <param name="startTrace">The 0 based starting trace index to read</param> /// <param name="endTrace">The 0 based ending trace index to read</param> /// <returns>A collection of segy trace headers</returns> public IEnumerable <SegyTraceHeader> ReadTraceHeaders(IProgress <int> progress = null, CancellationToken ct = default(CancellationToken), long startTrace = 0, long nTraces = Int64.MaxValue) { var lastTraceToReadIndex = startTrace + nTraces; if (lastTraceToReadIndex > TraceCount) { lastTraceToReadIndex = TraceCount; } if (lastTraceToReadIndex != Int64.MaxValue) { CodeContract.Requires(lastTraceToReadIndex <= TraceCount, "Ending trace index must be less than the number of traces in the file."); } CodeContract.Requires(startTrace >= 0, "Cannot read a negative number of traces."); CodeContract.Requires(startTrace >= 0, "Starting trace index must be greater than 0."); var islilEndian = IsLittleEndian; var dataStartIndex = 3600 + (3200 * (FileTextualHeaders.Length - 1)); var sampleFormat = (FormatCode)FileBinaryHeader.DataSampleFormatCode; int sampleSz = SizeFrom(sampleFormat); // as per rev 1, all data values are assumed big endian //BigList<SgyTraceHeader> trHdrs; BigArray <SegyTraceHeader> trHArr; if (nTraces == long.MaxValue) { trHArr = new BigArray <SegyTraceHeader>(TraceCount - startTrace); } else { trHArr = new BigArray <SegyTraceHeader>(nTraces); } var streamLen = _stream.Length; var streamPos = dataStartIndex + startTrace * (240 + sampleSz * FileBinaryHeader.SamplesPerTraceOfFile); CodeContract.Assume(streamPos <= _stream.Length, "initial trace index exceeds file length."); _stream.Seek(streamPos, SeekOrigin.Begin); int ns = FileBinaryHeader.SamplesPerTraceOfFile; // Assume that the binary header has num samples per trace. dont trust trace headers var traceDataBytesSz = ns * sampleSz; int progPercent = 0; for (long i = startTrace; (i < lastTraceToReadIndex) && (streamPos < streamLen); i++) { var traceHeaderByteArr = _reader.ReadBytes(TraceHeaderBytesCount); var trHdr = SegyTraceHeader.From(traceHeaderByteArr, islilEndian); trHArr[i - startTrace] = trHdr; _stream.Seek(traceDataBytesSz, SeekOrigin.Current); streamPos += 240 + traceDataBytesSz; if (ct.IsCancellationRequested) { break; } if (progress == null) { continue; } var percent = (int)(100 * (double)_stream.Position / _stream.Length); if (progPercent == percent) { continue; } progress.Report(percent); progPercent = percent; } return(trHArr); }
/// <summary> /// Ctor /// </summary> public SegyTrace() { Header = new SegyTraceHeader(); }