예제 #1
0
        /// <summary>
        /// Appends a set of traces to the end of the file or trace series.
        /// </summary>
        /// <param name="traces">Traces to write</param>
        /// <param name="progress">A progress handler</param>
        /// <param name="ct">Cancellation token</param>
        public void Write(IEnumerable <SegyTrace> traces, IProgress <int> progress = null, CancellationToken ct = default(CancellationToken))
        {
            CodeContract.Requires <NullReferenceException>(traces != null, "Traces cannot be null.");

            if (ct.IsCancellationRequested)
            {
                return;
            }

            BigArray <SegyTrace> segyTraces = traces as BigArray <SegyTrace> ?? traces.ToBigArray();

            CodeContract.Assume(segyTraces.Any(), "There must be at least one trace to write.");

            // get "traces" statistics.
            var distinctTraceSampleCounts = traces.Select(tr => tr.Data.Length).Distinct();
            int numTraceLengths           = distinctTraceSampleCounts.Count();

            // assume number of trace lengths is 1.
            CodeContract.Assume(numTraceLengths == 1, "There are traces to write with inconsistent lengths.  All traces must have the same length");
            _stream.Seek(0, SeekOrigin.End);

            if (TraceSampleCount == 0)
            {
                TraceSampleCount = distinctTraceSampleCounts.FirstOrDefault();
            }
            else
            {
                CodeContract.Assume(TraceSampleCount == distinctTraceSampleCounts.FirstOrDefault(), "Trace lengths to write is not consistent with the rest of the trace lengths in this file.");
            }

            var  currProgress = 0;
            long traceCount   = segyTraces.LongCount();
            long ctr          = 0;

            foreach (var sgyTrace in traces)
            {
                _writer.Write(sgyTrace.GetBytes());
                ctr++;

                // report progress and cancel if requested
                if (ct.IsCancellationRequested)
                {
                    break;
                }
                if (progress == null)
                {
                    continue;
                }
                var progPercent = (int)(100 * (double)ctr / traceCount);
                if (currProgress == progPercent)
                {
                    continue;
                }

                progress?.Report(progPercent);
                currProgress++;
            }
        }