Skip to main content

giga_segy_core/
enums.rs

1//! This contains all the enums that are used in the trace and binary headers.
2//!
3//! The SEG-Y format uses binary and trace headers (technically both headers are binary), which contain
4//! general metadata and other data which convey how the trace data is to be interpreted. In a lot of cases
5//! this information may only have certain values, which lends itself well to being represented by enums.
6//! (More information on this can be found in the
7//! [SEG-Y_r2.0 document](<https://seg.org/Portals/0/SEG/News%20and%20Resources/Technical%20Standards/seg_y_rev2_0-mar2017.pdf>)
8//! (January 2017) tables 2 and 3).
9//!
10//! As a general rule, enums that are found only in the binary header have fixed numerical values
11//! and return an error when an invalid value is found. Enums from the trace header can also
12//! return an undefined `Invalid` variant. This is needed because custom byte indices can be set for
13//! some values in the header, which would mean that the placement of others is unknown. Hence there
14//! is a need to be able to return a "non value" without crashing (but also ideally without too many)
15//! layers of complexity.
16use num::FromPrimitive;
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20use crate::errors::*;
21
22/// Choose which of the header lines to count traces by.
23#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
24#[repr(C)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub enum OrderTraceBy {
27    Default = 1,
28    TraceSequenceOnLine = 2,
29    TraceSequenceInFile = 3,
30    FieldRecordNo = 4,
31    TraceNo = 5,
32    TraceNoInEnsemble = 6,
33}
34
35/// From bytes 3225-3226  (25-26) of the binary header.
36#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
37#[repr(C)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39pub enum SampleFormatCode {
40    IbmFloat32 = 1,
41    Int32 = 2,
42    Int16 = 3,
43    FixPoint32 = 4, //Obsolete.
44    Float32 = 5,
45    Float64 = 6,
46    Int24 = 7,
47    Int8 = 8,
48    Int64 = 9,
49    UInt32 = 10,
50    UInt16 = 11,
51    UInt64 = 12,
52    UInt24 = 15,
53    UInt8 = 16,
54}
55
56impl std::fmt::Display for SampleFormatCode {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
58        write!(f, "{:?}", self)
59    }
60}
61
62impl SampleFormatCode {
63    /// NB: We give a result here to make life simpler for ourselves down the line.
64    pub fn new(source: u16) -> Result<Self, RsgError> {
65        SampleFormatCode::from_u16(source).ok_or_else(|| RsgError::ParseEnum {
66            f: "SampleFormatCode".to_string(),
67            code: source,
68        })
69    }
70
71    /// The byte length of a datum is important when guestimating the length of a trace.
72    pub fn datum_byte_length(self) -> usize {
73        match self {
74            Self::IbmFloat32 => 4,
75            Self::Int32 => 4,
76            Self::Int16 => 2,
77            Self::FixPoint32 => 4, //Obsolete.
78            Self::Float32 => 4,
79            Self::Float64 => 8,
80            Self::Int24 => 3,
81            Self::Int8 => 1,
82            Self::Int64 => 8,
83            Self::UInt32 => 4,
84            Self::UInt16 => 2,
85            Self::UInt64 => 8,
86            Self::UInt24 => 3,
87            Self::UInt8 => 1,
88        }
89    }
90}
91
92/// From bytes 3229-3230 (29-30) of the binary header.
93#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
94#[repr(C)]
95#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
96pub enum TraceSortingCode {
97    Other = -1,
98    Unknown = 0,
99    AsRec = 1,
100    CDPEnsemble = 2,
101    SingleFoldContinuous = 3,
102    HorizontalStack = 4,
103    CommonSourcePoint = 5,
104    CommonReceiverPoint = 6,
105    CommonOffsetPoint = 7,
106    CommonMidPoint = 8,
107    CommonConversionPoint = 9,
108    Invalid,
109}
110
111impl TraceSortingCode {
112    /// NB: We give a result here to make life simpler for ourselves down the line.
113    pub fn new(source: i16) -> Self {
114        Self::from_i16(source).unwrap_or(Self::Invalid)
115    }
116}
117
118/// From bytes 3239-3240 (39-40) of the binary header.
119#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
120#[repr(C)]
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
122pub enum SweepTypeCode {
123    Unspecified = 0,
124    Linear = 1,
125    Parabolic = 2,
126    Exponential = 3,
127    Other = 4,
128    Invalid,
129}
130
131impl SweepTypeCode {
132    /// NB: We give a result here to make life simpler for ourselves down the line.
133    pub fn new(source: u16) -> Self {
134        Self::from_u16(source).unwrap_or(Self::Invalid)
135    }
136}
137
138/// From bytes 3247-3248 (47-48) of the binary header.
139/// Also in bytes 139-140 of the standard trace header.
140#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
141#[repr(C)]
142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
143pub enum TaperType {
144    Unspecified = 0,
145    Linear = 1,
146    Cosine2 = 2,
147    Other = 3,
148    Invalid,
149}
150
151impl TaperType {
152    /// NB: We give a result here to make life simpler for ourselves down the line.
153    pub fn new(source: u16) -> Self {
154        Self::from_u16(source).unwrap_or(Self::Invalid)
155    }
156}
157
158/// 3249-3250 (49-50) of the binary header.
159#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
160#[repr(C)]
161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162pub enum CorrelatedDataTraces {
163    Unspecified = 0,
164    No = 1,
165    Yes = 2,
166    Invalid,
167}
168
169impl CorrelatedDataTraces {
170    /// NB: We give a result here to make life simpler for ourselves down the line.
171    pub fn new(source: u16) -> Self {
172        Self::from_u16(source).unwrap_or(Self::Invalid)
173    }
174}
175
176/// From bytes 3251-3252 (51-52) of the binary header.
177#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
178#[repr(C)]
179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
180pub enum BinaryGainRecovered {
181    Unspecified = 0,
182    Yes = 1,
183    No = 2,
184    Invalid,
185}
186
187impl BinaryGainRecovered {
188    /// NB: We give a result here to make life simpler for ourselves down the line.
189    pub fn new(source: u16) -> Self {
190        Self::from_u16(source).unwrap_or(Self::Invalid)
191    }
192}
193
194/// From bytes 3253-3254 (53-54) of the binary header.
195#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
196#[repr(C)]
197#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
198pub enum AmplitudeRecoveryMethod {
199    Unspecified = 0,
200    None = 1,
201    SphericalDivergence = 2,
202    Agc = 3,
203    Other = 4,
204    Invalid,
205}
206
207impl AmplitudeRecoveryMethod {
208    /// NB: We give a result here to make life simpler for ourselves down the line.
209    pub fn new(source: u16) -> Self {
210        Self::from_u16(source).unwrap_or(Self::Invalid)
211    }
212}
213
214/// From bytes 3255-3256 (55-56) of the binary header.
215#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
216#[repr(C)]
217#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
218pub enum MeasurementSystem {
219    Unspecified = 0,
220    Meters = 1,
221    Feet = 2,
222    Invalid,
223}
224
225impl MeasurementSystem {
226    /// NB: We give a result here to make life simpler for ourselves down the line.
227    pub fn new(source: u16) -> Self {
228        Self::from_u16(source).unwrap_or(Self::Invalid)
229    }
230}
231
232/// From bytes 3257-3258 (57-58) of the binary header.
233#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
234#[repr(C)]
235#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
236pub enum ImpulseSignalPolarity {
237    Unspecified = 0,
238    IncreasePressureMinus = 1,
239    IncreasePressurePlus = 2,
240    Invalid,
241}
242
243impl ImpulseSignalPolarity {
244    /// NB: We give a result here to make life simpler for ourselves down the line.
245    pub fn new(source: u16) -> Self {
246        Self::from_u16(source).unwrap_or(Self::Invalid)
247    }
248}
249
250/// From bytes 3259-3260 (59-60) of the binary header.
251#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
252#[repr(C)]
253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
254pub enum VibratoryPolarityCode {
255    Unspecified = 0,
256    From338 = 1,
257    From23 = 2,
258    From68 = 3,
259    From113 = 4,
260    From158 = 5,
261    From203 = 6,
262    From248 = 7,
263    From293 = 8,
264    Invalid,
265}
266
267impl VibratoryPolarityCode {
268    /// NB: We give a result here to make life simpler for ourselves down the line.
269    pub fn new(source: u16) -> Self {
270        Self::from_u16(source).unwrap_or(Self::Invalid)
271    }
272}
273
274/// From bytes 3503-3504 (303-304) of the binary header.
275#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
276#[repr(C)]
277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
278pub enum FixedLengthTraces {
279    Yes = 1,
280    No = 0,
281}
282
283impl FixedLengthTraces {
284    /// NB: We give a result here to make life simpler for ourselves down the line.
285    pub fn new(source: u16) -> Result<Self, RsgError> {
286        Self::from_u16(source).ok_or_else(|| RsgError::ParseEnum {
287            f: "FixedLengthTraces".to_string(),
288            code: source,
289        })
290    }
291
292    /// Convert to bool.
293    pub fn yes(self) -> bool {
294        self == Self::Yes
295    }
296    /// Convert to bool
297    pub fn no(self) -> bool {
298        self == Self::No
299    }
300}
301
302/// From bytes 3511-3512 (311-312) of the binary header.
303/// Alternatively bytes 167-168 of a standard trace header.
304#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
305#[repr(C)]
306#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
307pub enum TimeBasisCode {
308    Unspecified = 0,
309    Local = 1,
310    GreenwichGMT = 2,
311    Other = 3,
312    CoordinatedUTC = 4,
313    GlobalGPS = 5,
314    Invalid,
315}
316
317impl TimeBasisCode {
318    /// NB: We give a result here to make life simpler for ourselves down the line.
319    pub fn new(source: u16) -> Self {
320        Self::from_u16(source).unwrap_or(Self::Invalid)
321    }
322}
323
324/// From bytes 29-30 of the standard trace header.
325#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
326#[repr(C)]
327#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
328pub enum TraceIdCode {
329    Other = -1,
330    Unknown = 0,
331    TimeDomainSeismic = 1,
332    Dead = 2,
333    Dummy = 3,
334    TimeBreak = 4,
335    Uphole = 5,
336    Sweep = 6,
337    Timing = 7,
338    Waterbreak = 8,
339    NearFieldGunSig = 9,
340    FarFieldGunSig = 10,
341    SeismicPressureSensor = 11,
342    MulticomponentVertical = 12,
343    MulticomponentCrossLine = 13,
344    MulticomponentInLine = 14,
345    RotatedVertical = 15,
346    RotatedTransverse = 16,
347    RotatedRadial = 17,
348    VibratorReactionMass = 18,
349    VibratorBaseplate = 19,
350    VibratorEstimatedGroundForce = 20,
351    VibratorReference = 21,
352    TimeVelocityPairs = 22,
353    TimeDepthPairs = 23,
354    DepthVelocityPairs = 24,
355    DepthDomainSeismic = 25,
356    GravityPotential = 26,
357    EFVertical = 27,
358    EFCrossLine = 28,
359    EFInLine = 29,
360    RotatedEFVertical = 30,
361    RotatedEFTransverse = 31,
362    RotatedEFRadial = 32,
363    MFVertical = 33,
364    MFCrossLine = 34,
365    MFInLine = 35,
366    RotatedMFVertical = 36,
367    RotatedMFTransverse = 37,
368    RotatedMFRadial = 38,
369    RotatedSensorPitch = 39,
370    RotatedSensorRoll = 40,
371    RotatedSensorYaw = 41,
372    Invalid,
373}
374
375impl TraceIdCode {
376    /// NB: We give a result here to make life simpler for ourselves down the line.
377    pub fn new(source: i16) -> Self {
378        Self::from_i16(source).unwrap_or(Self::Invalid)
379    }
380}
381
382/// From bytes 35-36 of the standard trace header.
383#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
384#[repr(C)]
385#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
386pub enum DataUse {
387    Unspecified = 0,
388    Production = 1,
389    Test = 2,
390    Invalid,
391}
392
393impl DataUse {
394    /// NB: We give a result here to make life simpler for ourselves down the line.
395    pub fn new(source: u16) -> Self {
396        Self::from_u16(source).unwrap_or(Self::Invalid)
397    }
398}
399
400/// From bytes 89-90 of the standard trace header.
401#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
402#[repr(C)]
403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
404pub enum CoordinateUnits {
405    Unspecified = 0,
406    Length = 1,
407    SecondsOfArc = 2,
408    DegreesDecimal = 3,
409    DegreesMinutesSeconds = 4,
410    Invalid,
411}
412
413impl CoordinateUnits {
414    /// NB: We give a result here to make life simpler for ourselves down the line.
415    pub fn new(source: u16) -> Self {
416        Self::from_u16(source).unwrap_or(Self::Invalid)
417    }
418}
419
420///From bytes 119-120 of the standard trace header.
421#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
422#[repr(C)]
423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
424pub enum GainType {
425    Unspecified = 0,
426    Fixed = 1,
427    Binary = 2,
428    FloatingPoint = 3,
429    Invalid,
430}
431
432impl GainType {
433    /// NB: We give a result here to make life simpler for ourselves down the line.
434    pub fn new(source: u16) -> Self {
435        Self::from_u16(source).unwrap_or(Self::Invalid)
436    }
437}
438
439// From bytes 125-126 of the standard trace header.
440#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
441#[repr(C)]
442#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
443pub enum Correlated {
444    Unspecified = 0,
445    No = 1,
446    Yes = 2,
447    Invalid,
448}
449
450impl Correlated {
451    /// NB: We give a result here to make life simpler for ourselves down the line.
452    pub fn new(source: u16) -> Self {
453        Self::from_u16(source).unwrap_or(Self::Invalid)
454    }
455}
456
457/// From bytes 133-134 of the standard trace header.
458#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
459#[repr(C)]
460#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
461pub enum SweepType {
462    Unspecified = 0,
463    Linear = 1,
464    Parabolic = 2,
465    Exponential = 3,
466    Other = 4,
467    Invalid,
468}
469
470impl SweepType {
471    /// NB: We give a result here to make life simpler for ourselves down the line.
472    pub fn new(source: u16) -> Self {
473        Self::from_u16(source).unwrap_or(Self::Invalid)
474    }
475}
476
477// Taper type is also found in bytes 139-140 of the standard trace header.
478
479// Time Basis code is covered above. (but is found in bytes 157-158 of the STH)
480
481/// Found in bytes 179-180 of the standard trace header.
482#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
483#[repr(C)]
484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
485pub enum OverTravel {
486    Unspecified = 0,
487    Up = 1,
488    Down = 2,
489    Invalid,
490}
491
492impl OverTravel {
493    /// NB: We give a result here to make life simpler for ourselves down the line.
494    pub fn new(source: u16) -> Self {
495        Self::from_u16(source).unwrap_or(Self::Invalid)
496    }
497}
498
499/// Found in bytes 203-204 of the standard trace header.
500#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
501#[repr(C)]
502#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
503pub enum TraceValueUnit {
504    Other = -1,
505    Unknown = 0,
506    Pascal = 1,
507    Volts = 2,
508    Millivolts = 3,
509    Amperes = 4,
510    Meters = 5,
511    MetersPerSecond = 6,
512    MetersPerSecond2 = 7,
513    Newton = 8,
514    Watt = 9,
515    Invalid,
516}
517
518impl TraceValueUnit {
519    /// NB: We give a result here to make life simpler for ourselves down the line.
520    pub fn new(source: i16) -> Self {
521        Self::from_i16(source).unwrap_or(Self::Invalid)
522    }
523}
524
525/// Found in bytes 211-212 of the standard trace header.
526#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
527#[repr(C)]
528#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
529pub enum TransductionUnits {
530    Other = -1,
531    Unknown = 0,
532    Pascal = 1,
533    Volts = 2,
534    Millivolts = 3,
535    Amperes = 4,
536    Meters = 5,
537    MetersPerSecond = 6,
538    MetersPerSecond2 = 7,
539    Newton = 8,
540    Watt = 9,
541    Invalid,
542}
543
544impl TransductionUnits {
545    /// NB: We give a result here to make life simpler for ourselves down the line.
546    pub fn new(source: i16) -> Self {
547        Self::from_i16(source).unwrap_or(Self::Invalid)
548    }
549}
550
551/// Found in bytes 217-218 of the standard trace header.
552#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
553#[repr(C)]
554#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
555pub enum SourceType {
556    Unknown = 0,
557    VibratoryVertical = 1,
558    VibratoryCrossLine = 2,
559    VibratoryInLine = 3,
560    ImpulsiveVertical = 4,
561    ImpulsiveCrossLine = 5,
562    ImpulsiveInLine = 6,
563    DistributedImpulsiveVertical = 7,
564    DistributedImpulsiveCrossLine = 8,
565    DistributedImpulsiveInLine = 9,
566    Invalid,
567}
568
569impl SourceType {
570    /// NB: We give a result here to make life simpler for ourselves down the line.
571    pub fn new(source: i16) -> Self {
572        Self::from_i16(source).unwrap_or(Self::Invalid)
573    }
574}
575
576/// Found in bytes 231-232 of the standard trace header.
577#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, ToPrimitive)]
578#[repr(C)]
579#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
580pub enum SourceMeasurementUnit {
581    Other = -1,
582    Unknown = 0,
583    Joule = 1,
584    KiloWatt = 2,
585    Pascal = 3,
586    Bar = 4,
587    BarMeter = 5,
588    Newton = 6,
589    Kilograms = 7,
590    Invalid,
591}
592
593impl SourceMeasurementUnit {
594    /// NB: We give a result here to make life simpler for ourselves down the line.
595    pub fn new(source: i16) -> Self {
596        Self::from_i16(source).unwrap_or(Self::Invalid)
597    }
598}