├── vr_testOFF.go ├── .gitignore ├── DLIS_SPEC ├── V2_fm.zip ├── Glossary.htm ├── V1_word.zip ├── Chapter 3.pdf ├── 2 - Data Organization.htm ├── 3 - Logical Record Syntax.htm ├── 7 - Semantics Dictionaries.htm ├── B - Representation Codes.htm ├── Chapter 3_files │ ├── image211.gif │ ├── image213.gif │ ├── image214.gif │ ├── image215.gif │ ├── image216.gif │ ├── image217.gif │ ├── image218.gif │ ├── image219.gif │ ├── image220.gif │ └── image221.gif ├── Chapter 7_files │ ├── image225.gif │ ├── image226.gif │ ├── image227.gif │ ├── image228.gif │ ├── image229.gif │ ├── image230.gif │ ├── image231.gif │ ├── image232.gif │ ├── image233.gif │ ├── image234.gif │ ├── image235.gif │ └── image236.gif ├── D - Changeable Attributes.htm ├── 6 - Semantics Transient Data.htm ├── 4 - Semantic Terminology and Rules.htm ├── 5 - Semantics Static and Frame Data.htm ├── Chapter 2 - Data Organization_files │ ├── image175.gif │ ├── image180.gif │ └── image182.gif ├── Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files │ ├── image184.gif │ ├── image185.gif │ ├── image186.gif │ ├── image187.gif │ ├── image188.gif │ └── rp66v1_sec4_fig1.gif ├── Chapter 5 SEMANTICS STATIC AND FRAME DATA_files │ ├── image190.gif │ ├── image198.gif │ ├── image201.gif │ ├── image204.gif │ ├── image205.gif │ ├── image206.gif │ ├── image207.gif │ ├── image208.gif │ └── image210.gif ├── E - Checksum Algorithm.htm ├── A - Logical Record Types.htm ├── C - Property Indicators.htm ├── 1 - Introduction.htm ├── 0 - Preface.htm └── F - Unit Symbols.htm ├── LAS_LIS ├── LAS_30a.zip ├── lis-79.pdf ├── LAS_3_File_Structure.pdf ├── Las2_Update_Feb2017.pdf └── LAS12_Standards.txt ├── dclose.go ├── eflr_testOFF.go ├── val_test.go ├── lrs_testOFF.go ├── sul_testOFF.go ├── run.go ├── lrs_encrypt.go ├── parsers_test.go ├── lrs_header.go ├── iflr_type.go ├── reader_test.go.OFF ├── eflr_type.yaml ├── reader.go ├── sul.go ├── lr_attribs.go ├── parsers.go ├── eflr_type.go ├── README.md ├── LRS.go ├── vr.go ├── lrs_trailer.go ├── repcode.go ├── val.go ├── eflr_parse.go └── repcode_test.go.OFF /vr_testOFF.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dlis 2 | *.dls 3 | *~ 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /DLIS_SPEC/V2_fm.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/V2_fm.zip -------------------------------------------------------------------------------- /LAS_LIS/LAS_30a.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/LAS_LIS/LAS_30a.zip -------------------------------------------------------------------------------- /LAS_LIS/lis-79.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/LAS_LIS/lis-79.pdf -------------------------------------------------------------------------------- /DLIS_SPEC/Glossary.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Glossary.htm -------------------------------------------------------------------------------- /DLIS_SPEC/V1_word.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/V1_word.zip -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3.pdf -------------------------------------------------------------------------------- /LAS_LIS/LAS_3_File_Structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/LAS_LIS/LAS_3_File_Structure.pdf -------------------------------------------------------------------------------- /LAS_LIS/Las2_Update_Feb2017.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/LAS_LIS/Las2_Update_Feb2017.pdf -------------------------------------------------------------------------------- /DLIS_SPEC/2 - Data Organization.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/2 - Data Organization.htm -------------------------------------------------------------------------------- /DLIS_SPEC/3 - Logical Record Syntax.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/3 - Logical Record Syntax.htm -------------------------------------------------------------------------------- /DLIS_SPEC/7 - Semantics Dictionaries.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/7 - Semantics Dictionaries.htm -------------------------------------------------------------------------------- /DLIS_SPEC/B - Representation Codes.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/B - Representation Codes.htm -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image211.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image211.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image213.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image213.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image214.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image214.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image215.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image215.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image216.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image216.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image217.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image217.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image218.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image218.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image219.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image219.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image220.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image220.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 3_files/image221.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 3_files/image221.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image225.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image225.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image226.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image226.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image227.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image227.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image228.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image228.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image229.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image229.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image230.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image230.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image231.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image231.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image232.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image232.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image233.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image233.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image234.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image234.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image235.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image235.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 7_files/image236.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 7_files/image236.gif -------------------------------------------------------------------------------- /DLIS_SPEC/D - Changeable Attributes.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/D - Changeable Attributes.htm -------------------------------------------------------------------------------- /DLIS_SPEC/6 - Semantics Transient Data.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/6 - Semantics Transient Data.htm -------------------------------------------------------------------------------- /DLIS_SPEC/4 - Semantic Terminology and Rules.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/4 - Semantic Terminology and Rules.htm -------------------------------------------------------------------------------- /DLIS_SPEC/5 - Semantics Static and Frame Data.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/5 - Semantics Static and Frame Data.htm -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 2 - Data Organization_files/image175.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 2 - Data Organization_files/image175.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 2 - Data Organization_files/image180.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 2 - Data Organization_files/image180.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 2 - Data Organization_files/image182.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 2 - Data Organization_files/image182.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image184.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image184.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image185.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image185.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image186.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image186.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image187.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image187.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image188.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/image188.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image190.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image190.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image198.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image198.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image201.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image201.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image204.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image204.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image205.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image205.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image206.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image206.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image207.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image207.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image208.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image208.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image210.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 5 SEMANTICS STATIC AND FRAME DATA_files/image210.gif -------------------------------------------------------------------------------- /DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/rp66v1_sec4_fig1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k1m190r/dlis/HEAD/DLIS_SPEC/Chapter 4 SEMANTIC TERMINOLOGY AND RULES_files/rp66v1_sec4_fig1.gif -------------------------------------------------------------------------------- /dclose.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "io" 5 | "log" 6 | ) 7 | 8 | func dclose(c io.Closer) { 9 | if err := c.Close(); err != nil { 10 | log.Printf("error with deferred closing: %v", err) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /eflr_testOFF.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestEFLR(t *testing.T) { 9 | // t.Log(EFLR) 10 | for i, r := range eflr { 11 | fmt.Print(i, r) 12 | fmt.Println() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /val_test.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func _TestFN(t *testing.T) { 8 | var v1 = S("hello") 9 | 10 | if v1.IsErr() { 11 | t.Log(v1) 12 | return 13 | } 14 | t.Logf("val: %v", v1) 15 | } 16 | -------------------------------------------------------------------------------- /lrs_testOFF.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestBits(t *testing.T) { 9 | b1 := byte(0x01) 10 | for b := range make([]int, 8) { 11 | fmt.Printf("%b ", b1< 1 { 21 | return LRType{"RESERVED", "RESERVED", []string{"RESERVED"}} 22 | } 23 | return iflr[int(code)] 24 | } 25 | 26 | // ParseIFLR parses IFLR 27 | func ParseIFLR(s *LRS) { 28 | fmt.Println("ParseIFLR is not yet implemented.") 29 | } 30 | -------------------------------------------------------------------------------- /reader_test.go.OFF: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | var fname = "test/TestDataSet.dlis" 10 | 11 | //var fname = "test/n802b.dls" 12 | 13 | // TestNewDLISReader tests dlis reader from 14 | func TestNewDLISReader(t *testing.T) { 15 | 16 | // open file for read only 17 | f, err := os.Open(fname) 18 | if err != nil { 19 | log.Printf("error opening file %s : %v", fname, err) 20 | return 21 | } 22 | defer dclose(f) 23 | 24 | // dlis reader, read SUL 25 | dlisread := NewDLISReader(f) 26 | 27 | for i := 0; i < 1; i++ { 28 | vr := dlisread.ReadVR() 29 | if len(vr.Err) != 0 { 30 | t.Log(vr) 31 | break 32 | } 33 | 34 | for { 35 | lrs := vr.ReadLRS() 36 | if lrs == nil { 37 | break 38 | } 39 | t.Log(lrs) 40 | } 41 | 42 | t.Log(vr) 43 | } 44 | 45 | t.Log(dlisread) 46 | } 47 | -------------------------------------------------------------------------------- /eflr_type.yaml: -------------------------------------------------------------------------------- 1 | # http://w3.energistics.org/rp66/V1/rp66v1_appa.html 2 | # A.2 Explicitly Formatted Logical Record# 3 | 4 | # Code inplied by the index of the array 5 | # Type, Description, AllowableSetTypes [] 6 | 7 | [ 8 | [FHLR, "File Header", [FILE-HEADER]], #0 9 | [OLR, Origin, [ORIGIN, WELL-REFERENCE]], #1 10 | [AXIS, "Coordinate Axis", [AXIS]], #2 11 | [CHANNL, "Channel-related information", [CHANNEL]], #3 12 | [FRAME, "Frame Data", [FRAME, PATH]], #4 13 | [STATIC, "Static Data", [CALIBRATION, CALIBRATION-COEFFICIENT, 14 | CALIBRATION-MEASUREMENT, COMPUTATION, EQUIPMENT, GROUP, 15 | PARAMETER, PROCESS, SPICE, TOOL, ZONE]], #5 16 | [SCRIPT, "Textual Data", [COMMENT]], #6 17 | [UPDATE, "Update Data", [UPDATE]], #7 18 | [UDI, "Unformatted Data Identifier", [NO-FORMAT]], #8 19 | [LNAME, "Long Name", [LONG-NAME]], #9 20 | [SPEC, "Specification", [ATTRIBUTE, CODE, EFLR, IFLR, OBJECT-TYPE, 21 | REPRESENTATION-CODE, SPECIFICATION, UNIT-SYMBOL]], #10 22 | [DICT, "Dictionary", [BASE-DICTIONARY, IDENTIFIER, LEXICON, OPTION]], #11 23 | ] 24 | -------------------------------------------------------------------------------- /reader.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | ) 9 | 10 | // LR logical record, keeps all the LRS parsing results 11 | // Sets, Templates, Objects 12 | type LR []*LRS 13 | 14 | // LF logical file is set of LR 15 | // LF starts with File Header LR and ends on the next FHLR 16 | type LF []LR 17 | 18 | // Reader is dlis.Reader that does all the reading 19 | type Reader struct { 20 | FileName string 21 | Label SULT 22 | VRCount int // VR records read 23 | Err []error 24 | 25 | // reader for the underlying file 26 | r io.Reader 27 | 28 | // LogFiles set of all LF from DLIS file 29 | LogFiles []LF 30 | } 31 | 32 | // NewDLISReader reads the SUL and preps the rest of reading 33 | func NewDLISReader(r io.Reader) (ret *Reader) { 34 | // get the label 35 | ret = new(Reader) 36 | 37 | // read Storage Unit Label 38 | err := ret.Label.Read(r) 39 | if err != nil { 40 | log.Printf("error reading Storage Label: %v", err) 41 | ret.Err = append(ret.Err) 42 | return 43 | } 44 | 45 | // buffered reader 46 | ret.r = bufio.NewReaderSize(r, ret.Label.MaxRecLen) 47 | 48 | return 49 | } 50 | 51 | // ReadAll reads the whole DLIS 52 | 53 | // ReadVR reads next VR from the dlis 54 | func (r *Reader) ReadVR() (vr *VR) { 55 | vr = NewVR(r.r) 56 | r.VRCount++ 57 | return 58 | } 59 | 60 | func (r *Reader) String() string { 61 | return fmt.Sprintf("DLIS Reader\n%s\nVRCount:%d\nErr: %v\n", 62 | r.Label.String(), r.VRCount, r.Err) 63 | } 64 | -------------------------------------------------------------------------------- /sul.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // SUL $2.3.2 = storage unit label first 80 bytes (0x50) of Visible Envelop 11 | // Fig 2-7. Only one SUL per SU, before LF. 12 | // whole of SUL is ASCII 13 | type SULT struct { 14 | SeqNum string // 4 sequence number 15 | DLISVersion string // 5 "V1.00" - most likely 16 | Struct string // 6 storage unit structure, "RECORD" = Record Storage Unit 17 | MaxRecLen int // 5 max rec length, applies to Visible Records $2.3.6, $2.3.6.5 abs max is 16,384 (2^14) 18 | SetID string // 60 storage set identifier 19 | } 20 | 21 | func trimSlice(buf []byte) string { 22 | return strings.TrimSpace(string(buf)) 23 | } 24 | 25 | func (s *SULT) String() string { 26 | return fmt.Sprintf( 27 | "Storage Unit Label\nSeqNum: %s; DLISVersion: %s; Struct: %s; MaxRecLen: %d;\nSetID: %s\n", 28 | s.SeqNum, s.DLISVersion, s.Struct, s.MaxRecLen, s.SetID) 29 | } 30 | 31 | func (s *SULT) Read(f io.Reader) error { 32 | // SUL is exacly 80 bytes 33 | var buf = make([]byte, 80) 34 | n, err := f.Read(buf) 35 | if err != nil { 36 | return err 37 | } 38 | if n != 80 { 39 | return fmt.Errorf("expecting len(SUL)==80 bytes, but it is %d", n) 40 | } 41 | 42 | s.SeqNum = trimSlice(buf[0:4]) // 4 43 | s.DLISVersion = trimSlice(buf[4:9]) // 5 44 | s.Struct = trimSlice(buf[9:15]) // 6 45 | s.SetID = trimSlice(buf[20:80]) // rest of it 46 | 47 | s.MaxRecLen, err = strconv.Atoi(trimSlice(buf[15:20])) // 5 48 | if err != nil { 49 | return err 50 | } 51 | 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /lr_attribs.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import "fmt" 4 | 5 | type LRAttribs struct { // byte Figure 2-3. 6 | Explicit, // or Indirect 7 | NotFirst, // Not First 8 | NotLast, // Not Last 9 | Encrypted, 10 | HasEncryptPacket, 11 | HasChecksum, // in LRS Trailer 12 | HasTrailingLen, // in LRS Trailer 13 | HasPadding bool // in LRS Trailer 14 | obyte byte // orignal byte 15 | } 16 | 17 | func (a *LRAttribs) String() string { 18 | aa := []string{} 19 | 20 | // c conditional, t,f = true false 21 | setf := func(c bool, t, f string) { 22 | if c { 23 | aa = append(aa, t) 24 | } else { 25 | aa = append(aa, f) 26 | } 27 | } 28 | 29 | setf(a.Explicit, "Explicit", "Implicit") 30 | setf(a.NotFirst, "Not First", "") 31 | setf(a.NotLast, "Not Last", "") 32 | setf(a.Encrypted, "Encrypted", "") 33 | setf(a.HasEncryptPacket, "Has EncryptionPacket", "") 34 | setf(a.HasChecksum, "Has Checksum", "") 35 | setf(a.HasTrailingLen, "Has TrailingLen", "") 36 | setf(a.HasPadding, "Has Padding", "") 37 | 38 | return fmt.Sprintf("[%b], %v", a.obyte, aa) 39 | } 40 | 41 | func (a *LRAttribs) Parse(b byte) { 42 | a.obyte = b 43 | a.Explicit = checkBit(b, 7) 44 | a.NotFirst = checkBit(b, 6) 45 | a.NotLast = checkBit(b, 5) 46 | a.Encrypted = checkBit(b, 4) 47 | a.HasEncryptPacket = checkBit(b, 3) 48 | a.HasChecksum = checkBit(b, 2) 49 | a.HasTrailingLen = checkBit(b, 1) 50 | a.HasPadding = checkBit(b, 0) 51 | } 52 | 53 | func checkBit(b byte, bit uint) bool { 54 | // gimmick to check if bit 7 (most significant) is set 55 | // using (1 << 6) to make bit number explicit 56 | return ((1 << bit) & b) != 0 57 | } 58 | -------------------------------------------------------------------------------- /parsers.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "strconv" 7 | ) 8 | 9 | // P is list of parsers 10 | var P *V 11 | 12 | // PFn actual list of parsers 13 | var PFn []FN 14 | 15 | func SUL(v *V) *V { 16 | // assume to receive at least 80 bytes in []byte 17 | inbuf := v.B() 18 | if inbuf == nil || len(inbuf) < 80 { 19 | return E(errors.New("expected []byte len(80) but see nil")) 20 | } 21 | // return [4]*V 22 | val := NewV(make([]*V, 5)) 23 | vs := val.V() // value struct 24 | 25 | // Seq Number as int 26 | seqNumStr := string(bytes.TrimSpace(inbuf[0:4])) // len == 4 27 | seqNum, err := strconv.Atoi(seqNumStr) 28 | if err != nil { 29 | val.AddE(err) 30 | } 31 | vs[0] = I(seqNum) 32 | 33 | // DLIS Version as string 34 | ver := string(bytes.TrimSpace(inbuf[4:9])) // 5 35 | vs[1] = S(ver) 36 | 37 | // Structure as string - likely "RECORD" 38 | struc := string(bytes.TrimSpace(inbuf[9:15])) // 6 39 | vs[2] = S(struc) 40 | 41 | // Max Rec Length non negative int 42 | recLenStr := string(bytes.TrimSpace(inbuf[15:20])) // 5 43 | recLen, err := strconv.Atoi(recLenStr) 44 | if err != nil { 45 | val.AddE(err) 46 | } 47 | if recLen < 0 { // max rec len cannot be negative 48 | val.AddE(errors.New("SUL record length cannot be negative")) 49 | } 50 | vs[3] = I(recLen) 51 | 52 | // Storage Set ID 53 | storeSetID := string(bytes.TrimSpace(inbuf[20:80])) // 60 54 | vs[4] = S(storeSetID) 55 | 56 | return val 57 | } 58 | 59 | func init() { 60 | P = NewFn(make([]FN, 100)) 61 | PFn = P.Fs() 62 | 63 | // 0: return 0 64 | PFn[0] = func(v *V) *V { 65 | return I(0) 66 | } 67 | 68 | // 50: 2.3.2 Storage Unit Label (SUL) 69 | PFn[50] = SUL 70 | } 71 | -------------------------------------------------------------------------------- /eflr_type.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | // http://w3.energistics.org/rp66/V1/rp66v1_appa.html 4 | // A.2 Explicitly Formatted Logical Record 5 | 6 | // LRType logical record type 7 | type LRType struct { 8 | Type string 9 | Description string 10 | AllowableSetTypes []string 11 | } 12 | 13 | // Code inplied by the index of the array 14 | // Code, Type, Description, AllowableSetTypes [] 15 | 16 | var eflr = []LRType{ 17 | {"FHLR", "File Header", []string{"FILE-HEADER"}}, // 0 18 | {"OLR", "Origin", []string{"ORIGIN", "WELL-REFERENCE"}}, // 1 19 | {"AXIS", "Coordinate Axis", []string{"AXIS"}}, // 2 20 | {"CHANNL", "Channel-related information", []string{"CHANNEL"}}, // 3 21 | {"FRAME", "Frame Data", []string{"FRAME", "PATH"}}, // 4 22 | {"STATIC", "Static Data", []string{"CALIBRATION", "CALIBRATION-COEFFICIENT", 23 | "CALIBRATION-MEASUREMENT", "COMPUTATION", "EQUIPMENT", "GROUP", "PARAMETER", 24 | "PROCESS", "SPICE", "TOOL", "ZONE"}}, // 5 25 | {"SCRIPT", "Textual Data", []string{"COMMENT"}}, // 6 26 | {"UPDATE", "Update Data", []string{"UPDATE"}}, // 7 27 | {"UDI", "Unformatted Data Identifier", []string{"NO-FORMAT"}}, // 8 28 | {"LNAME", "Long Name", []string{"LONG-NAME"}}, // 9 29 | {"SPEC", "Specification", []string{"ATTRIBUTE", "CODE", "EFLR", "IFLR", "OBJECT-TYPE", 30 | "REPRESENTATION-CODE", "SPECIFICATION", "UNIT-SYMBOL"}}, // 10 31 | {"DICT", "Dictionary", []string{"BASE-DICTIONARY", "IDENTIFIER", "LEXICON", "OPTION"}}, // 11 32 | } 33 | 34 | func EFLRType(code byte) LRType { 35 | // 12 onwards is reserved 36 | if code > 11 { 37 | return LRType{"RESERVED", "RESERVED", []string{"RESERVED"}} 38 | } 39 | return eflr[int(code)] 40 | } 41 | -------------------------------------------------------------------------------- /DLIS_SPEC/E - Checksum Algorithm.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Appendix 7 | E 8 | 9 |

Appendix E

10 |

CHECKSUM ALGORITHM

12 |

A checksum may appear in the Logical Record Segment Trailer. 13 | It includes everything in the Logical Record Segment which precedes the 14 | checksum value. The checksum value itself and the Trailing Length, if present, 15 | are not included in the checksum.

16 |

When encryption is used, the checksum is computed 17 | after the Logical Record Segment Body and Pad Bytes have been 18 | encrypted.

19 |

The checksum is a 16-bit integer quantity computed using a 20 | cyclic-redundancy type checksum algorithm. This algorithm is described below. 21 | Note that this algorithm assumes that there are an even number of bytes in the 22 | data block.

23 | 25 |

1) c=0 initialize 16-bit checksum to zero

26 |

2) loop i=1,n,2 loop over the data two bytes at a time

27 |

3) t=byte(i+1)*256+byte(i) compute a 16-bit addend by concatenating the next 28 | two bytes of data

29 |

4) c=c+t add the addend to the checksum

30 |

5) if carry c=c+1 add carry to checksum

31 |

6) c=c*2 left shift checksum

32 |

7) if carry c=c+1 add carry to checksum

33 |

8) endloop

35 |

36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Reading and writing DLIS in go 2 | Spec: http://w3.energistics.org/rp66/v1/Toc/main.html 3 | 4 | 5 | #### NEXT 6 | 7 | Re-write in maplang 8 | 9 | Use abuse maps: 10 | - maps make it clear if something is missing 11 | 12 | 13 | 14 | Think about the run.go Run(*V) *V, how does it work? It takes a *V which is slice of *V and think of them as one feeding the other. Values are simply get imbeded into the next? 15 | 16 | 17 | Let code deal with io.Reader, *V deals only with []byte to values 18 | 19 | Default value objects are closures, that generate default value. 20 | 21 | Overhaul to keep the io.Reader around. LRS is a temporary transient structure that needs to go away. Need to get to object data as soon as possible. 22 | 23 | Start overhaul with SUL. 24 | 25 | eflr_parse.go - `parseSet()` must build the actual template to follow by the object. 26 | 27 | How object would use the Template? How does attrib know it parces Template or object? 28 | 29 | Once object data gets parsed just throw it into a chan with large buffer, on the other side collect it for disk persistance asap. Try to stay as wait free as possible. 30 | 31 | #### older notes 32 | 33 | repcode.go - use the funcs from `RepCode` var to build up the template. 34 | 35 | reader.go - start with `NewDLISReader()` reading SUL as example. Everything is constructed as simple sequence of `func(in []byte) (Val, int)`. `Val` is universal value type. Calling function must know the expected return type. 36 | 37 | 38 | ### How to read the code 39 | 40 | #### reader.go 41 | 42 | Everything starts with reader.go `NewDLISReader()` which takes an `io.Reader` and returns `dlis.Reader`. Use `ReadVR()` of `dlis.Reader` to get next Visible Record. Then `ReadLRS()` to get next Logical Record Segment. (See example in reader_test.go). 43 | 44 | 45 | #### IDEA 46 | 47 | Construct the reader for each part as sequence of the functions based on the either predefined format as per spec, or construct it at run time based on the data read from the dlis. Such that prior data defines next reader. 48 | 49 | -------------------------------------------------------------------------------- /LRS.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | ) 7 | 8 | /////////////////////////////////////////////////////////////////////////////// 9 | // Logical Format $2.2 10 | 11 | // LRS Logical Record Segment is interface between LF and Physical Format 12 | // it applies to whole of LR not LRS, redundancy is intentional 13 | type LRS struct { 14 | Header LRSH 15 | EncryptPacket *LRSEP // optional 16 | 17 | body []byte // LRS Body $2.2.2.3 18 | Trailer *LRST // optional 19 | 20 | // Parse whatever it present here 21 | Set Set // must, pass it along with template to next 22 | RedundantSetCount int // 0 means none 23 | ReplacementSets []Set // 0 means never 24 | Template Template // must 25 | Objects []Object // object types are restricted by the Set, at least 1 26 | 27 | Err []error 28 | } 29 | 30 | func (s *LRS) String() string { 31 | trailer := "" 32 | if s.Trailer != nil { 33 | trailer = s.Trailer.String() 34 | } 35 | return fmt.Sprintf( 36 | "Logical Record Segment\n%sBody Len:%d\n%s\nErr: %v\n", 37 | s.Header.String(), len(s.body), trailer, s.Err) 38 | } 39 | 40 | // NewLRS constructs new LRS from []byte slice 41 | // b - is remainder of the VR body 42 | func NewLRS(b []byte) (s *LRS) { 43 | s = new(LRS) 44 | 45 | // read 2 bytes of Length 46 | s.Header.Length = int(binary.BigEndian.Uint16(b[:2])) 47 | // Check this must be even and min 16 48 | 49 | // read next 2 bytes Attribs and Type 50 | s.Header.Attribs.Parse(b[2]) // 3rd 51 | s.Header.Type = b[3] // 4th 52 | s.Header.bytes = b[:4] // keep header raw bytes for later checksum 53 | 54 | // Read rest of the segment body 55 | s.body = b[4:s.Header.Length] 56 | 57 | s.parse() 58 | 59 | return 60 | } 61 | 62 | func (s *LRS) parse() { 63 | ats := s.Header.Attribs 64 | if ats.Encrypted || ats.HasEncryptPacket { 65 | ParseEncryption(s) 66 | } 67 | 68 | if ats.HasChecksum || ats.HasTrailingLen || ats.HasPadding { 69 | ParseLRSTrailer(s) 70 | } 71 | 72 | if ats.Explicit { 73 | ParseEFLR(s) 74 | 75 | } else { 76 | ParseIFLR(s) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vr.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | // VR is Visible Record 11 | type VR struct { 12 | Length int // unit16 UNORM, len of whole VR struct, 20 is min 13 | FormatVersion int // unit16 $2.3.6.2 0xFF01, USHORT = 1 - always 14 | LRSCount int // Count of LRS records read 15 | Err []error 16 | body []byte // this is reader for the body 17 | bodyOffset int 18 | } 19 | 20 | func (vr *VR) String() string { 21 | return fmt.Sprintf( 22 | "Visible Record: Len: %d; FormatVer: %X; LRSCount: %d\nErrors: %v", 23 | vr.Length, vr.FormatVersion, vr.LRSCount, vr.Err) 24 | } 25 | 26 | // NewVR makes new Visual Record and returns it's address 27 | // Stop if VR.Err != nil 28 | func NewVR(r io.Reader) (vr *VR) { 29 | vr = new(VR) 30 | 31 | buff := make([]byte, 2) 32 | 33 | // read 2 bytes of Length 34 | n, err := io.ReadFull(r, buff) // r.Read(buff) 35 | if err != nil { 36 | vr.Err = append(vr.Err, err) 37 | return 38 | } 39 | if n != 2 { // should read 2 bytes 40 | vr.Err = append(vr.Err, 41 | errors.New("Visible Record error reading Lenth")) 42 | return 43 | } 44 | vr.Length = int(binary.BigEndian.Uint16(buff)) 45 | 46 | // read next 2 bytes of FormatVersion 47 | n, err = r.Read(buff) 48 | if err != nil { 49 | vr.Err = append(vr.Err, err) 50 | return 51 | } 52 | if n != 2 { // should read 2 bytes 53 | vr.Err = append(vr.Err, 54 | errors.New("Visible Record error reading FormatVersion")) 55 | return 56 | } 57 | vr.FormatVersion = int(binary.BigEndian.Uint16(buff)) 58 | 59 | // check that it is 0xFF01 60 | if vr.FormatVersion != 0xFF01 { 61 | vr.Err = append(vr.Err, fmt.Errorf( 62 | "Expected Visible Record FormatVersion to be 0xFF01 but it is %d", 63 | vr.FormatVersion)) 64 | } 65 | 66 | // read the rest of the VR in to the temp buff 67 | restLen := vr.Length - 4 // -4 bytes for Lenght and FormatVersion 68 | vr.body = make([]byte, restLen) 69 | n, err = r.Read(vr.body) 70 | if err != nil { 71 | vr.Err = append(vr.Err, err) 72 | return 73 | } 74 | if n != int(restLen) { // should read restLen number of bytes 75 | vr.Err = append(vr.Err, fmt.Errorf( 76 | "visible record error reading the body of record. Expected %d, actual %d", 77 | restLen, n)) 78 | return 79 | } 80 | 81 | return 82 | } 83 | 84 | // ReadLRS returns next LRS 85 | func (vr *VR) ReadLRS() (l *LRS) { 86 | if vr.bodyOffset >= (vr.Length - 4) { 87 | // the VR is exausted return nil 88 | return nil 89 | } 90 | l = NewLRS(vr.body[vr.bodyOffset:]) 91 | vr.bodyOffset += l.Header.Length 92 | vr.LRSCount++ 93 | return 94 | } 95 | -------------------------------------------------------------------------------- /lrs_trailer.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "log" 7 | ) 8 | 9 | // LRST Logical Record Segment Trailer $2.2.2.4 10 | type LRST struct { 11 | // LRST is meant to be read backwards from end to front 12 | // this is allow backwards traversal 13 | 14 | // padding is to achive minimum size of LRS and Even LRS length 15 | PadBytes []byte // null if not present, Pad Count and Pad Bytes 16 | PadCount *int // USHORT, uint8, can be one indicating self 17 | CheckSum *int // UNORM, uint16 optional, see LRSH.Attribs bit 6, App E 18 | Length *int // UNORM, uint16, optional, UNORM, Trailing Length, 19 | // Copy from LRS Header Len, every LRS or none, to allow traversal backwards 20 | } 21 | 22 | func (t *LRST) String() string { 23 | msg := []string{} 24 | if t.PadBytes != nil { 25 | msg = append(msg, fmt.Sprintf("PadBytes, last is Count: %v", t.PadBytes)) 26 | } 27 | if t.CheckSum != nil { 28 | msg = append(msg, fmt.Sprintf("CheckSum: %d", *t.CheckSum)) 29 | } 30 | if t.Length != nil { 31 | msg = append(msg, fmt.Sprintf("Traling Length: %d", *t.Length)) 32 | } 33 | return fmt.Sprintf("Trailer:%v", msg) 34 | } 35 | 36 | // ParseLRSTrailer parses trailer backwards 37 | func ParseLRSTrailer(s *LRS) { 38 | // parse backward from Len -> CheckSum -> PadCount -> PadBytes 39 | 40 | var t LRST 41 | s.Trailer = &t 42 | ats := s.Header.Attribs 43 | 44 | if ats.HasTrailingLen { 45 | // last 2 bytes of the body 46 | st := len(s.body) - 2 47 | tlen := int(binary.BigEndian.Uint16(s.body[st:])) 48 | t.Length = &tlen 49 | 50 | // body now is but last 2 bytes 51 | s.body = s.body[:st] 52 | } 53 | 54 | if ats.HasChecksum { 55 | // last 2 bytes of the body 56 | st := len(s.body) - 2 57 | tcs := int(binary.BigEndian.Uint16(s.body[st:])) 58 | t.CheckSum = &tcs 59 | if cs, ok := checkSum(s); !ok { // checksum failed 60 | s.Err = append(s.Err, fmt.Errorf( 61 | "checksum failed. expected: %X found %X", 62 | t.CheckSum, cs)) 63 | } 64 | // body now is but last 2 bytes 65 | s.body = s.body[:st] 66 | } 67 | 68 | if ats.HasPadding { 69 | st := len(s.body) - 1 // last byte 70 | pc := int(s.body[st]) 71 | t.PadCount = &pc 72 | 73 | // st-pc pad count 1 or more 74 | st = len(s.body) - pc 75 | t.PadBytes = s.body[st:] 76 | // body now is but last pc bytes 77 | s.body = s.body[:st] 78 | } 79 | } 80 | 81 | func checkSum(s *LRS) (int, bool) { 82 | // http://w3.energistics.org/rp66/v1/rp66v1_appe.html 83 | 84 | log.Fatal("checkSum in lrs_trailer is not implemented.") 85 | // return the sum and if it is failed... 86 | 87 | // Sum includes everything in the LRS which precedes the checksum value. 88 | // The checksum value itself and the Trailing Length, if present, are not included. 89 | // need to merge the header, encryption packet and pad bytes 90 | 91 | // When encryption is used, the checksum is computed after the 92 | // Logical Record Segment Body and Pad Bytes have been encrypted. 93 | 94 | /* assume even number of bytes 95 | 1) c=0 initialize 16-bit checksum to zero 96 | 2) loop i=1,n,2 loop over the data two bytes at a time 97 | 3) t=byte(i+1)*256+byte(i) compute a 16-bit addend by concatenating the next two bytes of data 98 | 4) c=c+t add the addend to the checksum 99 | 5) if carry c=c+1 add carry to checksum 100 | 6) c=c*2 left shift checksum 101 | 7) if carry c=c+1 add carry to checksum 102 | 8) endloop 103 | */ 104 | 105 | return 0, true 106 | } 107 | -------------------------------------------------------------------------------- /DLIS_SPEC/A - Logical Record Types.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Appendix A: Logical Record Types 5 | 6 | 7 | 8 |

Appendix A:
Logical Record Types

9 |

A.1 Indirectly Formatted Logical Records

Numeric codes 10 | 0-127 are reserved for Public IFLRs. Codes 128-255 are reserved for Private 11 | IFLRs. 12 |

Figure A-1 defines numeric codes for Public Indirectly Formatted Logical 13 | Record Types. 14 |

15 | 16 | 17 | 18 | 23 | 28 | 33 | 38 | 42 |
Code 19 | Type 20 | Desciption 21 | Data Descriptor Reference Object Type 22 |
0 24 | FDATA 25 | Frame Data 26 | FRAME 27 |
1 29 | NOFORMAT 30 | Unformatted Data 31 | NO-FORMAT 32 |
2-126 34 | ... 35 | undefined, reserved 36 | -- 37 |
127 39 | EOD 40 | End of Data 41 | --
Figure A-1. Numeric Codes for Public IFLR 43 | Types
44 |

A.2 Explicitly Formatted Logical Records

Numeric codes 45 | 0-127 are reserved for Public EFLRs. Codes 128-255 are reserved for Private 46 | EFLRs. Figure A-2 defines numeric codes for Explicitly Formatted Logical 47 | Record Types. 48 |

49 | 50 | 51 | 52 | 57 | 62 | 67 | 69 | 74 | 79 | 84 | 86 | 91 | 93 | 95 | 97 | 99 | 101 | 103 | 105 | 107 | 109 | 111 | 117 | 122 | 127 | 132 | 137 | 139 | 141 | 143 | 145 | 147 | 149 | 151 | 156 | 158 | 160 | 162 | 166 |
Code 53 | Type 54 | Description 55 | Allowable Set Types 56 |
0 58 | FHLR 59 | File Header 60 | FILE-HEADER 61 |
1 63 | OLR 64 | Origin 65 | ORIGIN 66 |
WELL-REFERENCE 68 |
2 70 | AXIS 71 | Coordinate Axis 72 | AXIS 73 |
3 75 | CHANNL 76 | Channel-related information 77 | CHANNEL 78 |
4 80 | FRAME 81 | Frame Data 82 | FRAME 83 |
PATH 85 |
5 87 | STATIC 88 | Static Data 89 | CALIBRATION 90 |
CALIBRATION-COEFFICIENT 92 |
CALIBRATION-MEASUREMENT 94 |
COMPUTATION 96 |
EQUIPMENT 98 |
GROUP 100 |
PARAMETER 102 |
PROCESS 104 |
SPICE 106 |
TOOL 108 |
ZONE 110 |
6 112 | SCRIPT 113 | Textual Data 114 | COMMENT 115 | MESSAGE 116 |
7 118 | UPDATE 119 | Update Data 120 | UPDATE 121 |
8 123 | UDI 124 | Unformatted Data Identifier 125 | NO-FORMAT 126 |
9 128 | LNAME 129 | Long Name 130 | LONG-NAME 131 |
10 133 | SPEC 134 | Specification 135 | ATTRIBUTE 136 |
CODE 138 |
EFLR 140 |
IFLR 142 |
OBJECT-TYPE 144 |
REPRESENTATION-CODE 146 |
SPECIFICATION 148 |
UNIT-SYMBOL 150 |
11 152 | DICT 153 | Dictionary 154 | BASE-DICTIONARY 155 |
IDENTIFIER 157 |
LEXICON 159 |
OPTION 161 |
12-127 163 | - 164 | undefined, reserved 165 | -
Figure A-2. Numeric Codes for Public EFLR 167 | Types

168 | -------------------------------------------------------------------------------- /repcode.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "math" 7 | ) 8 | 9 | // http://w3.energistics.org/rp66/v1/rp66v1_appb.html 10 | 11 | // Funcs 12 | 13 | // FSINGL RepCode 2 14 | func FSINGL(in []byte) *Val { 15 | if len(in) < 4 { 16 | err := fmt.Errorf("length of input slice %v < 4", len(in)) 17 | return &Val{e: err} 18 | } 19 | f := float64(math.Float32frombits(binary.BigEndian.Uint32(in[:4]))) 20 | return &Val{f: &f, c: 4} 21 | } 22 | 23 | // FDOUBL RepCode 7 24 | func FDOUBL(in []byte) *Val { 25 | if len(in) < 8 { 26 | err := fmt.Errorf("length of input slice %v < 4", len(in)) 27 | return &Val{e: err} 28 | } 29 | f := math.Float64frombits(binary.BigEndian.Uint64(in[:8])) 30 | return &Val{f: &f, c: 8} 31 | } 32 | 33 | // USHORT RepCode 15 34 | func USHORT(in []byte) *Val { 35 | if len(in) < 1 { 36 | err := fmt.Errorf("length of input slice %v < 1", len(in)) 37 | return &Val{e: err} 38 | } 39 | i := int(in[0]) 40 | return &Val{i: &i, c: 1} 41 | } 42 | 43 | // UNORM RepCode 16 44 | func UNORM(in []byte) *Val { 45 | i := int(binary.BigEndian.Uint16(in[:2])) 46 | return &Val{i: &i, c: 2} 47 | } 48 | 49 | // ULONG RepCode 17 50 | func ULONG(in []byte) *Val { 51 | i := int(binary.BigEndian.Uint32(in[:4])) 52 | return &Val{i: &i, c: 4} 53 | } 54 | 55 | // UVARI RepCode 18 56 | func UVARI(in []byte) *Val { 57 | b1 := in[0] 58 | if checkBit(b1, 7) { // 59 | if checkBit(b1, 6) { // 4 bytes 60 | tmp := [4]byte{b1 & 0x3F} // first byte with mask 0011_1111 61 | copy(tmp[1:], in[1:4]) // remaining 3 bytes 62 | i := int(binary.BigEndian.Uint32(tmp[:])) 63 | return &Val{i: &i, c: 4} 64 | } 65 | // 2 bytes 66 | tmp := [2]byte{b1 & 0x3F} // first byte with mask 0011_1111 67 | tmp[1] = in[1] 68 | i := int(binary.BigEndian.Uint16(tmp[:])) 69 | return &Val{i: &i, c: 2} 70 | 71 | } 72 | // single byte 73 | i := int(b1) 74 | return &Val{i: &i, c: 1} // bit 7 is 0 75 | } 76 | 77 | // IDENT RepCode 19 78 | func IDENT(in []byte) *Val { 79 | v := USHORT(in) 80 | ln := *v.i 81 | 82 | if ln == 0 { 83 | s := "" 84 | return &Val{s: &s} 85 | } 86 | 87 | // only allowed 33-96, 123-126 88 | // TODO check for allowed 89 | s := string(in[1:(1 + ln)]) 90 | return &Val{s: &s, c: (1 + ln)} 91 | } 92 | 93 | // ASCII RepCode 20 94 | func ASCII(in []byte) *Val { 95 | v := UVARI(in) 96 | idlen := v.c 97 | asciilen := *v.i 98 | 99 | if idlen == 0 { 100 | s := "" 101 | return &Val{s: &s, c: (idlen + asciilen)} 102 | } 103 | 104 | s := string(in[idlen : idlen+asciilen]) 105 | return &Val{s: &s, c: (idlen + asciilen)} 106 | } 107 | 108 | // ORIGIN RepCode 22 equivalent to UVARY 109 | var ORIGIN = UVARI 110 | 111 | // OBNAME RepCode 23 112 | // ORIGIN, USHORT, IDENT 113 | func OBNAME(in []byte) *Val { 114 | // ORIGIN 115 | v := ORIGIN(in) 116 | olen := v.c 117 | 118 | // COPY 119 | vc := USHORT(in[olen:]) 120 | v.v = vc // chain vc into v 121 | clen := vc.c 122 | 123 | // IDENT 124 | vi := IDENT(in[(olen + clen):]) 125 | vc.v = vi // chain vi into vc 126 | 127 | return v 128 | } 129 | 130 | // UNITS RepCode 27 131 | func UNITS(in []byte) *Val { 132 | v := USHORT(in) 133 | ln := *v.i 134 | 135 | if ln == 0 { 136 | s := "" 137 | return &Val{s: &s} 138 | } 139 | 140 | /* Allowed TODO 141 | lower case letters [a, b, c, ..., z] 142 | upper case letters [A, B, C, ..., Z] 143 | digits [0, 1, 2, ..., 9] 144 | blank [ ] 145 | hyphen or minus sign [-] 146 | dot or period [.] 147 | slash [/] 148 | parentheses [(, )] 149 | */ 150 | 151 | s := string(in[1:(1 + ln)]) 152 | return &Val{s: &s, c: (1 + ln)} 153 | } 154 | 155 | // RepCode holds all the information about REPCODE, most importantly it has 156 | // Read function that reads actual repcode 157 | var RepCode = []struct { 158 | // Code is index 159 | Name string 160 | Size int // # of bytes 161 | Descirption string 162 | 163 | Read func([]byte) *Val 164 | }{ 165 | {}, // 0 is not present 166 | {"FSHORT", 2, "Low precision floating point", nil}, // 1 167 | 168 | {"FSINGL", 4, "IEEE single precision floating point", FSINGL}, // 2 169 | 170 | {"FSING1", 8, "Validated single precision floating point", nil}, // 3 171 | {"FSING2", 12, "Two-way validated single precision floating point", nil}, // 4 172 | {"ISINGL", 4, "IBM single precision floating point", nil}, // 5 173 | {"VSINGL", 4, "VAX single precision floating point", nil}, // 6 174 | 175 | {"FDOUBL", 8, "IEEE double precision floating point", FDOUBL}, // 7 176 | 177 | {"FDOUB1", 16, "Validated double precision floating point", nil}, // 8 178 | {"FDOUB2", 24, "Two-way validated double precision floating point", nil}, // 9 179 | {"CSINGL", 8, "Single precision complex", nil}, // 10 180 | {"CDOUBL", 16, "Double precision complex", nil}, // 11 181 | {"SSHORT", 1, "Short signed integer", nil}, // 12 182 | {"SNORM", 2, "Normal signed integer", nil}, // 13 183 | {"SLONG", 4, "Long signed integer", nil}, // 14 184 | 185 | {"USHORT", 1, "Short unsigned integer", USHORT}, // 15 186 | {"UNORM", 2, "Normal unsigned integer", UNORM}, // 16 187 | {"ULONG", 4, "Long unsigned integer", ULONG}, // 17 188 | {"UVARI", 0, "Variable-length unsigned integer 1, 2, or 4", UVARI}, // 18 189 | {"IDENT", 0, "Variable-length identifier", IDENT}, // 19 190 | {"ASCII", 0, "Variable-length ASCII character string", ASCII}, // 20 191 | 192 | {"DTIME", 8, "Date and time", nil}, // 21 193 | 194 | // 23 http://www.energistics.org/geosciences/geology-standards/rp66-organization-codes 195 | {"ORIGIN", 0, "Origin reference", ORIGIN}, // 22 196 | {"OBNAME", 0, "Object name", OBNAME}, // 23 197 | 198 | {"OBJREF", 0, "Object reference", nil}, // 24 199 | {"ATTREF", 0, "Attribute reference", nil}, // 25 200 | {"STATUS", 1, "Boolean status", nil}, // 26 201 | {"UNITS", 0, "Units expression", UNITS}, // 27 202 | 203 | // rp66.v2 has up to repcode 42, we'll keep up to 50 reserved 204 | {}, // 28 205 | {}, // 29 206 | {}, // 30 207 | {}, // 31 208 | {}, // 32 209 | {}, // 33 210 | {}, // 34 211 | {}, // 35 212 | {}, // 36 213 | {}, // 37 214 | {}, // 38 215 | {}, // 39 216 | {}, // 40 217 | {}, // 41 218 | {}, // 42 219 | {}, // 43 220 | {}, // 44 221 | {}, // 45 222 | {}, // 46 223 | {}, // 47 224 | {}, // 48 225 | {}, // 49 226 | 227 | {}, // 50 SUL 228 | {}, // 51 229 | {}, // 52 230 | {}, // 53 231 | 232 | } 233 | -------------------------------------------------------------------------------- /val.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | // Val is "universal value" 9 | type Val struct { 10 | // payload with a value 11 | s *string 12 | i *int 13 | f *float64 14 | v *Val 15 | 16 | c int 17 | e error 18 | } 19 | 20 | // VL is value of the V 21 | // only one of the {b, s, i, fl, fn, v, e} can have value 22 | // everything but one must be nil 23 | // multiple values are returned as v. e.g. int + count is v of len==2 24 | type VL struct { 25 | // only let methods return the value 26 | b []byte 27 | s []string 28 | i []int 29 | fl []float64 30 | fn []FN 31 | 32 | v []*V // to return a tuple of different types 33 | e []error 34 | 35 | z interface{} // for anything else 36 | } 37 | 38 | // V []value or function 39 | type V struct { 40 | // keep the values internal only let actions read them 41 | v *VL 42 | Fn FN // acccessale directly 43 | } 44 | 45 | // FN is simply a func that takes V and returns V 46 | type FN func(*V) *V 47 | 48 | // IsFn checks if Fn is not nil 49 | func (v *V) IsFn() bool { 50 | if v == nil || v.Fn == nil { 51 | return false 52 | } 53 | return true 54 | } 55 | 56 | // B returns a []byte or nil 57 | func (v *V) B() []byte { 58 | if v == nil || v.v == nil { 59 | return nil 60 | } 61 | return v.v.b 62 | } 63 | 64 | // reusiable error 65 | var errlen = NewE([]error{ 66 | errors.New("unexpected error slice must have at least one value"), 67 | }) 68 | 69 | // NewB makes new V.v.b of type []byte 70 | func NewB(b []byte) *V { 71 | if len(b) == 0 { 72 | return errlen 73 | } 74 | return &V{v: &VL{b: b}} 75 | } 76 | 77 | // B boxes single byte into *V 78 | func B(b byte) *V { 79 | return NewB([]byte{b}) 80 | } 81 | 82 | // S returns []string or nil 83 | func (v *V) S() []string { 84 | if v == nil || v.v == nil { 85 | return nil 86 | } 87 | return v.v.s 88 | } 89 | 90 | // NewS makes new V.v.s of type []string 91 | func NewS(s []string) *V { 92 | if len(s) == 0 { 93 | return errlen 94 | } 95 | return &V{v: &VL{s: s}} 96 | } 97 | 98 | // S boxes single string into *V 99 | func S(s string) *V { 100 | return NewS([]string{s}) 101 | } 102 | 103 | // I returns []int or nil 104 | func (v *V) I() []int { 105 | if v == nil || v.v == nil { 106 | return nil 107 | } 108 | 109 | return v.v.i 110 | } 111 | 112 | // NewI makes new V.v.i of type []int 113 | func NewI(i []int) *V { 114 | if len(i) == 0 { 115 | return errlen 116 | } 117 | return &V{v: &VL{i: i}} 118 | } 119 | 120 | // I boxes single int into *V 121 | func I(i int) *V { 122 | return NewI([]int{i}) 123 | } 124 | 125 | // Fl returns []float64 or nil 126 | func (v *V) Fl() []float64 { 127 | if v == nil || v.v == nil { 128 | return nil 129 | } 130 | return v.v.fl 131 | } 132 | 133 | // NewFl makes new V.v.fl of type []float64 134 | func NewFl(fl []float64) *V { 135 | if len(fl) == 0 { 136 | return errlen 137 | } 138 | return &V{v: &VL{fl: fl}} 139 | } 140 | 141 | // Fl boxes single float64 into *V 142 | func Fl(fl float64) *V { 143 | return NewFl([]float64{fl}) 144 | } 145 | 146 | // Fs returns []FN or nil 147 | func (v *V) Fs() []FN { 148 | if v == nil || v.v == nil { 149 | return nil 150 | } 151 | return v.v.fn 152 | } 153 | 154 | // NewFn makes new V.v.fn of type []FN 155 | func NewFn(fn []FN) *V { 156 | if len(fn) == 0 { 157 | return errlen 158 | } 159 | return &V{v: &VL{fn: fn}} 160 | } 161 | 162 | // Fn boxes single byte into *V 163 | func Fn(fn FN) *V { 164 | return NewFn([]FN{fn}) 165 | } 166 | 167 | // V returns []*V or nil 168 | func (v *V) V() []*V { 169 | if v == nil || v.v == nil { 170 | return nil 171 | } 172 | return v.v.v 173 | } 174 | 175 | // NewV makes new V.v.v of type []*V 176 | func NewV(v []*V) *V { 177 | if len(v) == 0 { 178 | return errlen 179 | } 180 | return &V{v: &VL{v: v}} 181 | } 182 | 183 | // Vs boxes single *V inside of another *V 184 | func Vs(vl *V) *V { 185 | return NewV([]*V{vl}) 186 | } 187 | 188 | // E return []error or nil 189 | func (v *V) E() []error { 190 | if v == nil || v.v == nil { 191 | return nil 192 | } 193 | return v.v.e 194 | } 195 | 196 | // NewE makes new V.v.e of type []error 197 | func NewE(e []error) *V { 198 | if len(e) == 0 { 199 | // have to repeated otheriwise get an init loop error 200 | errlen := NewE([]error{ 201 | errors.New("unexpected error slice must have at least one value"), 202 | }) 203 | return errlen 204 | } 205 | return &V{v: &VL{e: e}} 206 | } 207 | 208 | // E boxes single error into *V 209 | func E(e error) *V { 210 | return NewE([]error{e}) 211 | } 212 | 213 | // AddE adds error to the the V.v.e 214 | func (v *V) AddE(e error) *V { 215 | if v == nil || v.v == nil { 216 | return E(e) 217 | } 218 | 219 | if len(v.v.e) == 0 { 220 | v.v.e = []error{e} 221 | } else { 222 | v.v.e = append(v.v.e, e) 223 | } 224 | 225 | return v 226 | } 227 | 228 | // Z return interface or nil of v.v.z 229 | func (v *V) Z() interface{} { 230 | if v == nil || v.v == nil { 231 | return nil 232 | } 233 | return v.v.z 234 | } 235 | 236 | // NewZ make new V.v.z of type interface{} 237 | func NewZ(z interface{}) *V { 238 | return &V{v: &VL{z: z}} 239 | } 240 | 241 | // Z boxes inteface{} into *V 242 | // redundant but here for consistency of interface 243 | var Z = NewZ 244 | 245 | // Any returns any value that is not nil or and error value 246 | // use the type switch to get the value 247 | func (v *V) Any() interface{} { 248 | if v == nil || v.v == nil { 249 | return nil 250 | } 251 | 252 | if v.Fn != nil { 253 | return v.Fn 254 | } 255 | 256 | val := v.v 257 | 258 | if val.b != nil { 259 | if len(val.b) == 0 { 260 | return errlen 261 | } 262 | return val.s 263 | } 264 | 265 | if val.s != nil { 266 | if len(val.s) == 0 { 267 | return errlen 268 | } 269 | return val.s 270 | } 271 | 272 | if val.i != nil { 273 | if len(val.i) == 0 { 274 | return errlen 275 | } 276 | return val.i 277 | } 278 | 279 | if val.fl != nil { 280 | if len(val.fl) == 0 { 281 | return errlen 282 | } 283 | return val.fl 284 | } 285 | 286 | if val.fn != nil { 287 | if len(val.fn) == 0 { 288 | return errlen 289 | } 290 | return val.fn 291 | } 292 | 293 | if val.v != nil { 294 | if len(val.v) == 0 { 295 | return errlen 296 | } 297 | return val.v 298 | } 299 | 300 | if val.e != nil { 301 | if len(val.e) == 0 { 302 | return errlen 303 | } 304 | 305 | return val.e 306 | } 307 | 308 | err := errors.New( 309 | "unexpected error one of the {b, s, i, fl, fs, v, e} must have value") 310 | 311 | return NewE([]error{err}) 312 | } 313 | 314 | func (v *V) String() string { 315 | return fmt.Sprintf("%v", v.Any()) 316 | } 317 | 318 | // IsErr returns true if V.v.e has an error 319 | func (v *V) IsErr() bool { 320 | if v == nil || v.v == nil { 321 | return false 322 | } 323 | if len(v.v.e) != 0 { 324 | return true 325 | } 326 | return false 327 | } 328 | -------------------------------------------------------------------------------- /DLIS_SPEC/C - Property Indicators.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Appendix C: PROPERTY INDICATORS 5 | 6 | 7 | 8 |

9 |

Appendix C:
PROPERTY INDICATORS

Property 10 | Indicators are used to indicate the general intrinsic properties of the data 11 | associated with an Object (typically, but not exclusively, a Channel Object) 12 | and the general processing steps that have been performed to create that data. 13 | The Property Indicators listed below are not mutually exclusive and may be 14 | associated in various combinations with the data of a particular Object. 15 |

It is important to understand the general nature of Property Indicators. 16 | They are intended to provide broad classifications for Objects. Such 17 | classifications can help the Consumer decide how to handle the Object, i.e., 18 | based on what has been done to the data of an Object decide what needs to be 19 | done next. For example, the Property Indicator that the data associated with a 20 | Channel has been filtered does not indicate what the specific filtering 21 | algorithm was. However, it may indicate that additional filtering is 22 | unnecessary. 23 |

Property Indicators are dictionary-controlled Codes (Representation Code 24 | IDENT). 25 |

26 | 27 | 28 | 29 | 32 | 35 | 38 | 44 | 48 | 52 | 57 | 60 | 64 | 68 | 72 | 76 | 81 | 85 | 88 | 92 | 96 | 101 | 105 | 113 | 116 | 119 | 122 | 126 | 130 | 134 | 137 | 142 | 145 | 149 |
Property Indicator Options 30 | Description 31 |
AVERAGED 33 | The data is the average of two or more other data sources. 34 |
CALIBRATED 36 | A calibration process has been applied to the data. 37 |
CHANGED-INDEX 39 | The data has been resampled along an index that is different 40 | from its original sampling index. For example, data that was 41 | originally sampled according to time is resampled according to 42 | depth. 43 |
COMPUTED 45 | The data is an output of a transform, e.g., function former, 46 | based on input data from a single tool. 47 |
DEPTH-MATCHED 49 | The data has been aligned along its depth index against a 50 | reference data source. 51 |
DERIVED 53 | The data is an output of empirical equations or is the solution 54 | of log response equations based on input data from more than one 55 | tool. 56 |
FILTERED 58 | A filtering process has been applied to the data. 59 |
HOLE-SIZE-CORRECTED 61 | The data has been corrected for hole size effect based on the 62 | value of a hole size input. 63 |
INCLINOMETRY-CORRECTED 65 | The data has been corrected to standard directional references 66 | (vertical axis and North axis). 67 |
LITHOLOGY-CORRECTED 69 | The data has been computed or corrected based on the value of a 70 | matrix lithology parameter. 71 |
LOCAL-COMPUTATION 73 | The data is the result of locally-defined computational 74 | expressions. Such data is normally experimental. 75 |
LOCALLY-DEFINED 77 | The Object's Name has been created by the operator. This Name 78 | might not be dictionary-controlled and may have no semantic 79 | association with the Object's data. 80 |
MODELLED 82 | The data is the output of a theoretical model and is not derived 83 | from any measured quantity. 84 |
MUDCAKE-CORRECTED 86 | The data has been corrected for mud cake effect. 87 |
NORMALIZED 89 | The data has been corrected so that its range corresponds to a 90 | prescribed norm. 91 |
OVER-SAMPLED 93 | Interpolated data samples have been added to the original data 94 | to align this data with other data. 95 |
PATCHED 97 | The original data values have been replaced at specific levels. 98 | This is normally done to remove spurious values (e.g., 99 | spikes). 100 |
PRESSURE-CORRECTED 102 | The data has been corrected for hydrostatic pressure (mud 103 | weight). 104 |
RE-SAMPLED 106 | The data has been resampled along its original index. For 107 | example, as the result of a depth correction process it is 108 | determined that the original index values are incorrect. Using 109 | a curve fitting process it is possible to determine new data values 110 | for the original index values that represent the original signal 111 | more accurately. 112 |
SALINITY-CORRECTED 114 | The data has been corrected for salinity effect. 115 |
SAMPLED-DOWNWARD 117 | The original sampling direction is downward. 118 |
SAMPLED-UPWARD 120 | The original sampling direction is upward. 121 |
SPEED-CORRECTED 123 | The data has been corrected for variations of the downhole tool 124 | speed. 125 |
SPLICED 127 | The data has been obtained by concatenating two or more other 128 | data sources. 129 |
SQUARED 131 | The data is the result of a squaring process, i.e., a process 132 | that converts a smooth function into a step function. 133 |
STACKED 135 | The data is the sum of two or more other data sources. 136 |
STANDARD-DEVIATION 138 | The data represents the estimated standard deviation, due to 139 | environmental factors or incoherence of the computational model, 140 | of another data source. 141 |
STANDOFF-CORRECTED 143 | The data has been corrected for standoff effect. 144 |
TEMPERATURE-CORRECTED 146 | The data has been corrected for temperature effect based on 147 | the value of a temperature source. 148 |
UNDER-SAMPLED 150 | Some of the original data samples have been discarded to reduce 151 | the amount of data or to align this data with other data. 152 |

153 | -------------------------------------------------------------------------------- /DLIS_SPEC/1 - Introduction.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 1 7 | Introduction 8 | 9 |

1 Introduction 10 | 11 |

1.1 Aim: Why Introduce a New 12 | Standard? 13 |

A considerable investment exists 14 | in data recorded under current formats, as well as in software to read and 15 | process that data. For these reasons, changes in the way logging information 16 | is recorded are bound to create inconveniences for both the service companies 17 | that write the data and the oil companies that read the data.

19 |

However, as service companies have developed new 20 | capabilities in data acquisition and have extended new services to clients, the 21 | need to offer flexibility not available under current log data recording 22 | formats is evident.

23 |

A number of enhanced data recording techniques have been 24 | designed in response to the requirements of new logging technologies and 25 | methods, as well as to requests from clients for more complete information on 26 | the recorded data. While some of the enhancements could have been implemented 27 | within current formats, others required the introduction of new concepts and 28 | mechanisms for the representation of information. The result is a more 29 | efficient and powerful standard for log information recording which is referred 30 | to as the Digital Log Interchange Standard (DLIS).

31 |

The following sections outline the nature of the most 32 | significant enhancements incorporated in the DLIS.

34 |

1.2 Data Objects

35 |

The DLIS provides a more powerful mechanism for recording 36 | Frame Data, Static Information, and 37 | Transient Information by means of a uniform syntax and an "object 38 | oriented" approach.

39 |

Frame Data consists of the values of Data 40 | Channels as stored in Frames. Static Information is information that 41 | establishes an environment in which Frame Data can be understood. Transient 42 | Information is information that occurs during the processing of Frame Data or 43 | that modifies Static Information.

44 |

New mechanisms for information representations offer greater 45 | compactness, uniformity and coherence. The standard supports the definition of 46 | Objects that are described in terms of Attributes and may be 47 | organized in Sets. This general technique for defining and representing 48 | new information allows the range of information items that can be represented 49 | under the DLIS to be extended indefinitely.

51 |

1.3 Origins

52 |

The DLIS provides a means for unambiguous identification of 53 | Data Channels by using Origin information. The Origin concept provides for 54 | uniquely tagging Data Channels from different borehole passes and descents in 55 | such a way that they subsequently can be merged and still remain 56 | distinguishable. Origin Objects also provide summary information about the 57 | circumstances surrounding the recording of Channels. For example, the well 58 | identification, the date and time, and the original file specification are 59 | recorded as Attributes of Origin Objects.

61 |

1.4 Multiple Frame Types

63 |

Perhaps the most significant new capability is the allowance 64 | for defining and recording of multiple Frame types in a single data file. 65 | This permits Frames to be organized by indexing (i.e., time-based Frames can 66 | co-exist with depth-based Frames), or by sampling rate (i.e., distinct Frames 67 | to collect data at 6" and 2" intervals). This capability facilitates making 68 | measurements with different tools at different depth intervals. The sampling 69 | frequency can be adjusted to the depth resolution of the measurements, 70 | permitting optimization of the amount of recorded data. Additionally, the 71 | possibility of interleaving Frames of different types within a log file permits 72 | embedding station measurements within a continuous depth log data 73 | file.

74 |

1.5 Update Objects

75 |

Under current formats, Parameters are set before the start 76 | of a log run and then recorded at the beginning of the data file. Even though 77 | the operator or the system may change certain Parameters during the log, these 78 | changes go unrecorded. This has led to difficulties in processing the data 79 | after the fact.

80 |

The DLIS permits changes to be recorded in the form of 81 | Update Objects, so that Parameters can be correctly updated when a log is 82 | processed.

83 |

1.6 Source References and Calibration Objects 84 |

85 |

The DLIS introduces two new types of information in the form 86 | of source references and Calibration Objects.

87 |

Source references are a mechanism for data Channels to 88 | specify their immediate source history to a Tool or Process Object, and for 89 | Process Objects to specify their input and output Channels. This allows a path 90 | to be traced from a computed or acquired Channel all the way back through its 91 | source history.

92 |

Calibration Objects provide a greatly improved way of 93 | recording calibration measurements. Associated with each calibrated Channel, 94 | the new Objects allow recording of extensive information about the 95 | calibration.

96 |

1.7 Data Encryption

98 |

Though the actual methods for encryption lie outside the 99 | domain of the DLIS, the standard does allow for encryption at the level of the 100 | bodies of Logical Records.

101 |

1.8 Logical Record

102 |

The DLIS introduces a more efficient approach to mapping 103 | logical structures to the physical structure of the recording medium. Multiple 104 | Logical Records can be packed into the same physical record. Additional 105 | mechanisms for Logical Record continuation permit independence from physical 106 | record boundaries. Improved data recovery capability is provided by a checksum 107 | at the Logical Record Segment level and both header and trailer Logical Record 108 | Lengths.

109 | -------------------------------------------------------------------------------- /DLIS_SPEC/0 - Preface.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PREFACE 5 | 6 | 7 | 8 |

PREFACE

9 | 48 |
49 | 50 |

SPECIAL NOTES

API RP66 V1 was originally 51 | published by the API in May 1991 with a clause indicating that it would not be 52 | considered an operative API styandard five years after its publication date, 53 | unless reaffirmed or republished. This document, POSC RP66 V1, is considered 54 | to be applicable indefinitely, i. e., until withdrawn or deprecated by POSC, 55 | with no requirement for periodic reaffirmation or extension. 56 |
57 | 58 |

ORGANIZATION

59 |

Structure: How Is This Document Organized?

This document is divided 60 | into seven chapters, six appendices, and a glossary. 61 |
62 |
Chapter 1: 63 |
INTRODUCTION 64 |
Chapter 2: 65 |
DATA ORGANIZATION, a description of the physical and logical hierarchies, 66 | their organizations and relationships 67 |
Chapter 3: 68 |
LOGICAL RECORD SYNTAX, a description of how logical records are 69 | represented 70 |
Chapter 4: 71 |
SEMANTIC TERMINOLOGY AND RULES, a summary of important concepts and 72 | general rules for defining elements of the standard 73 |
Chapter 5: 74 |
SEMANTICS: STATIC AND FRAME DATA, a description of Frames, the Objects 75 | required to define them, and the Objects which establish the parameters and 76 | environment for processing Frames 77 |
Chapter 6: 78 |
SEMANTICS: TRANSIENT DATA, a description of the Objects that convey 79 | messages and signify changes during acquisition and processing of Frames 80 |
Chapter 7: 81 |
SEMANTICS: DICTIONARIES, a description of the Objects that specify the 82 | semantic structure of the standard and that specify dictionary-controlled 83 | names used by the standard 84 |
Appendix A: 85 |
LOGICAL RECORD TYPES, a list of defined Types for Public and Private 86 | Logical Records 87 |
Appendix B: 88 |
REPRESENTATION CODES, a list of Representation Codes 89 |
Appendix C: 90 |
PROPERTY INDICATORS, a list of indicators used to designate the 91 | processing or corrections performed on data 92 |
Appendix D: 93 |
CHANGEABLE ATTRIBUTES, a list of those defined Attributes that are 94 | permitted to be changed (i.e., updated) in a Logical File 95 |
Appendix E: 96 |
CHECKSUM ALGORITHM, a description of the algorithm used to compute the 97 | Checksum in the Logical Record Segment Trailer. 98 |
Appendix F: 99 |
UNIT SYMBOLS, a list of symbols for base units and selected derived units 100 | 101 |
Glossary
102 |
103 | 104 |

Notation: How Is This Document Written?

Numerous 105 | cases of unusual capitalization appear in this document. Capitalized terms 106 | have special, formal, technical connotations in a DLIS context; these terms do 107 | not retain their normal English connotations. When such a special term is 108 | first introduced, it is italicized. 109 |

Acronyms are fully defined before they are used. 110 |

Many figures include comment numbers that associate a particular item with a 111 | comment that appears below the figure. For example, 112 | 113 | 114 | 115 | 119 | 123 | 128 | 133 | 138 |
Label 116 | Restrictions 117 | Comments 118 |
DESCRIPTION 120 | C = 1, R = ASCII 121 | - 122 |
OBJECT-TYPE 124 | C = 1, R = IDENT 125 | 1 127 |
OBJECT-LIST 129 | R = (OBNAME, OBJREF) 130 | 2 132 |
GROUP-LIST 134 | R = OBNAME 135 | 3 137 |
Figure 5-25. Attributes of Group 139 | Object
140 |

Comments: 141 |

142 | 
143 | 144 |
1. The OBJECT-TYPE Attribute specifies ... 145 | 146 |
2. The OBJECT-LIST Attribute is a List of references to ... 147 | 148 |
3. The GROUP-LIST Attribute is a List of references to ... 149 |
150 |
151 |
152 | 153 |

Trademarks

154 |
155 |
The following is a mark of Schlumberger: 156 |
Schlumberger 157 |
The following is a mark of Digital Equipment Corporation: 158 |
VAX 159 |
The following is a mark of AT&T: 160 |
UNIX 161 |
The following is a mark of IBM: 162 |
IBM
163 | -------------------------------------------------------------------------------- /eflr_parse.go: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | // 3 - Logical Record Syntax 9 | // http://w3.energistics.org/rp66/v1/rp66v1_sec3.html 10 | 11 | // Roles holds roles for the Components 12 | var Roles = []struct { 13 | Role string 14 | Type string 15 | }{ 16 | {"ABSATR", "Absent Attribute"}, // 000 0 17 | 18 | {"ATTRIB", "Attribute"}, // 001 1 19 | {"INVATR", "Invariant Attribute"}, // 010 2 20 | 21 | {"OBJECT", "Object"}, // 011 3 22 | 23 | {"reserved", "-"}, // 100 4 24 | 25 | {"RDSET", "Redundant Set"}, // 101 5 26 | {"RSET", "Replacement Set"}, // 110 6 27 | {"SET", "Set"}, // 111 7 28 | 29 | } 30 | 31 | // SetChars is Set Characteristics 32 | var SetChars = []struct { 33 | Chars string 34 | RepCode int 35 | Default *Val 36 | }{ 37 | {}, {}, {}, 38 | 39 | {"Name", 19, &Val{}}, // 3 40 | 41 | {"Type", 19, nil}, // 4 19 IDENT 42 | 43 | {}, {}, {}, {}, 44 | } 45 | 46 | func parseSet(s *LRS) { 47 | fmt.Print("\nS: ") 48 | 49 | if len(s.body) == 0 { 50 | fmt.Println("End of LRS body") 51 | return 52 | } 53 | 54 | // get byte one 55 | b1 := s.body[0] 56 | 57 | // restart body from 1+ 58 | s.body = s.body[1:] 59 | 60 | var set Set 61 | 62 | if checkBit(b1, 4) { // Type must 63 | repc := SetChars[4].RepCode // get repcode 64 | v := RepCode[repc].Read(s.body[:]) 65 | if v.e != nil { 66 | log.Printf("unexpected error parsing set type: %v", v) 67 | return 68 | } 69 | set.Type = *v.s 70 | ln := v.c 71 | 72 | fmt.Print(" Type:", set.Type) 73 | 74 | s.body = s.body[ln:] 75 | } else { 76 | // if bit 4 is not set this is undefined 77 | log.Println("Set must have a type, bit 4 is not set.") 78 | return 79 | } 80 | 81 | if checkBit(b1, 3) { // Name 82 | repc := SetChars[3].RepCode 83 | v := RepCode[repc].Read(s.body[:]) 84 | if v.e != nil { 85 | log.Printf("unexpected error parsing set name: %v", v) 86 | } 87 | set.Name = v.s 88 | ln := v.c 89 | 90 | fmt.Print(" Name:", set.Name) 91 | 92 | s.body = s.body[ln:] 93 | } 94 | 95 | // save set 96 | s.Set = set 97 | } 98 | 99 | // ObjectChars is set Characteristics 100 | var ObjectChars = []struct { 101 | Chars string 102 | RepCode int 103 | Default interface{} 104 | }{ 105 | {}, {}, {}, {}, 106 | 107 | {"Name", 23, nil}, // 4 108 | 109 | {}, {}, {}, {}, 110 | } 111 | 112 | func parseObject(s *LRS) { 113 | fmt.Print("\nO: ") 114 | 115 | if len(s.body) == 0 { 116 | fmt.Println("End of LRS body") 117 | return 118 | } 119 | 120 | // get byte one 121 | b1 := s.body[0] 122 | 123 | // restart body from 1+ 124 | s.body = s.body[1:] 125 | 126 | if checkBit(b1, 4) { // Name 127 | repc := ObjectChars[4].RepCode 128 | v := RepCode[repc].Read(s.body[:]) 129 | ln := v.c 130 | 131 | fmt.Print(" Name:", v) 132 | 133 | s.body = s.body[ln:] 134 | 135 | } 136 | } 137 | 138 | // AttribChars is set Characteristics 139 | var AttribChars = []struct { 140 | Chars string 141 | RepCode int 142 | Default interface{} 143 | }{ 144 | {"Value", 19, nil}, // 0: 0 here means it's repcode is defined by the REPCODE 19 145 | // Value is defined by Count of REPCODE type Units 146 | // If count is 0 the value is "undefined" 147 | {"Units", 27, byte(0)}, // 1: 27 UNITS 148 | {"REPCODE", 15, 19}, // 2: 15 USHORT 149 | {"Count", 18, 1}, // 3: 18 UVARI 150 | {"Label", 19, byte(0)}, // 4: 19 IDENT 151 | 152 | {}, {}, {}, 153 | } 154 | 155 | func parseAttrib(s *LRS) { 156 | fmt.Print("\nA: ") 157 | 158 | if len(s.body) == 0 { 159 | fmt.Println("End of LRS body") 160 | return 161 | } 162 | 163 | // get byte one 164 | b1 := s.body[0] 165 | 166 | // restart body from 1+ 167 | s.body = s.body[1:] 168 | 169 | if checkBit(b1, 4) { // Label 170 | repc := AttribChars[4].RepCode 171 | v := RepCode[repc].Read(s.body[:]) 172 | ln := v.c 173 | fmt.Print(" Label:", *v.s) 174 | s.body = s.body[ln:] 175 | } 176 | 177 | if checkBit(b1, 3) { // Count 178 | repc := AttribChars[3].RepCode 179 | v := RepCode[repc].Read(s.body[:]) 180 | ln := v.c 181 | fmt.Print(" Count:", *v.i) 182 | s.body = s.body[ln:] 183 | } 184 | 185 | if checkBit(b1, 2) { // REPCODE 186 | repc := AttribChars[2].RepCode 187 | v := RepCode[repc].Read(s.body[:]) 188 | ln := v.c 189 | fmt.Print(" Repcode:", *v.i) 190 | s.body = s.body[ln:] 191 | } 192 | 193 | if checkBit(b1, 1) { // Units 194 | repc := AttribChars[1].RepCode 195 | v := RepCode[repc].Read(s.body[:]) 196 | ln := v.c 197 | fmt.Print(" Units:", *v.s) 198 | s.body = s.body[ln:] 199 | } 200 | 201 | if checkBit(b1, 0) { // Value 202 | // check the value of REPCODE otherwise default to 19 203 | // value of the REPCODE in the template 204 | repc := AttribChars[0].RepCode 205 | v := RepCode[repc].Read(s.body[:]) 206 | ln := v.c 207 | fmt.Print(" Value:", *v.i) 208 | s.body = s.body[ln:] 209 | } 210 | 211 | } 212 | 213 | // ParseEFLR parses the LRS body into Components 214 | // TODO need to decide what happens to Components 215 | func ParseEFLR(s *LRS) { 216 | fmt.Printf("\nLRS Type: %+v", EFLRType(s.Header.Type).Description) 217 | 218 | for { 219 | if len(s.body) == 0 { 220 | fmt.Println("\nEnd of LRS body") 221 | return 222 | } 223 | 224 | // Fig 3-1 225 | b := s.body[0] // first byte is a role and characteristic 226 | role := b >> 5 // first 3 bits (highest order) is a role 227 | 228 | switch role { 229 | case 0: // Absent 230 | // TODO absent is parsed based on prior content... on template... 231 | fmt.Println("Absent argument") 232 | fmt.Println("Something is wrong...?") 233 | return 234 | 235 | case 1, 2: // Attribute roles 236 | parseAttrib(s) 237 | 238 | case 3: // Object role 239 | // TODO use the parsing template 240 | parseObject(s) 241 | 242 | case 4: // Reserved 243 | fmt.Println("Reserved Role for ELFR Component. Undefined behaviour.") 244 | 245 | case 5, 6, 7: // Set role 246 | // TODO build up a parsing template 247 | parseSet(s) 248 | 249 | } 250 | } 251 | } 252 | 253 | // $3.2 Explicitly Formatted Logical Record (EFLR) 254 | // Template for columns/ attributes, and the their characteristics 255 | // Table of information 256 | // Rows are Objects 257 | // Columns are Attributes of Objects 258 | // Alternatively viewed as Set of Objects, of the Type Defined by Template 259 | 260 | // Each EFLR contains one and only one Set. 261 | // Set maybe of several different types implied by the EFLR Type. 262 | 263 | // Set is 1+ Object of same type, preceded by Template. 264 | // Each Object has 1+ Attributes. 265 | // Sets, Objects and Attributes have Characteristics 266 | 267 | // $3.2.2 EFLR Component 268 | 269 | // Notation 270 | 271 | // "null" REPCODE len bytes all 0 272 | 273 | // 0' null ASCII or IDENT, zero length string, 1 byte = 0 274 | 275 | // "reserved" bit is zero 276 | 277 | // $3.2.2.1 Descriptor 278 | 279 | // First byte of Component is Descriptor 280 | // Bits 1-3 Role Fig 3-2 281 | // Format Fig 3-3, 3-4, 3-5 282 | 283 | // Descriptor is 284 | type Descriptor struct { 285 | Role byte // bits 1-3, Fig 3-2 286 | Format byte 287 | // Role Set (101, 110, 111): Fig 3-3, bit 4 - Type IDENT, 5 - Name IDENT 288 | // defaults: Type - not defined, Name - 0' 289 | // Role Obj (011): Fig - 3-4, bit 4 - Name OBNAME 290 | // Role Attrib (001, 010): Fig 3-5, Label, Count, RepCode, Units, Value 291 | // Value 0+ Elements of RepCode with Units, # of Elements is Count 292 | // if Count==0 Value is undef ie Absent Value 293 | } 294 | 295 | // Component describe entities: Set, Objects, Attributes 296 | type Component struct { 297 | Descriptor Descriptor // first byte 298 | } 299 | 300 | // Set keeps the description of set 301 | type Set struct { 302 | Type string // must 303 | Name *string // optional 304 | // Redundant sets are repeats 305 | // Replacement sets replaces some attribs .... 306 | } 307 | 308 | type Attribute struct { 309 | Label *string // must for template, must not for object attribs 310 | // default is 0' zero byte 311 | 312 | Count *int // UVARI default 1, if count is 0 Value is undefined ie absent 313 | RepCode *int // default is 19 IDENT 314 | Units *string // UNITS 27 default 0' 315 | Value *Val // of the RepCode type 316 | } 317 | 318 | // Object contains objects 319 | type Object struct { 320 | Name struct { 321 | O, C int 322 | I string 323 | } // must 324 | Attributes []Attribute 325 | // trailing attributes can be omitted 326 | // otherwise they must be present, as 0x00 absent as minimum 327 | // missing implies global default 328 | } 329 | 330 | // Template specify: presence, order and default Character 331 | // of the Attributes in the Objects in the Set 332 | type Template struct { 333 | Attributes []Attribute 334 | // Label is must 335 | // default as per Attrib 336 | // can have Invariant Attrib, appear only in Template 337 | } 338 | 339 | // LRSB interpretation as EFLR 340 | type EFLR struct { 341 | Set Set 342 | Template Template 343 | Objects []Object 344 | // Descriptor byte // $3.2.2.1 Bits 1-3 Role, 4-Type (Objects in the Set), 5-Name 345 | } 346 | -------------------------------------------------------------------------------- /repcode_test.go.OFF: -------------------------------------------------------------------------------- 1 | package dlis 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestRepCode(t *testing.T) { 9 | // for each RepCode get test cases with expected values 10 | for repCode, expRepVal := range RepCodeTest { 11 | 12 | readfn := RepCode[repCode].Read 13 | if readfn == nil { 14 | t.Logf("no function to test for REPCODE: %v", repCode) 15 | continue 16 | } 17 | 18 | if (expRepVal.In == nil) || (len(expRepVal.In) == 0) { 19 | t.Logf("no test cases for REPCODE: %v", repCode) 20 | continue 21 | } 22 | 23 | if (len(expRepVal.In) != len(expRepVal.Ret)) || (len(expRepVal.In) != len(expRepVal.Len)) { 24 | t.Logf("REPCODE: %v length of test cases is unequal.", repCode) 25 | continue 26 | } 27 | 28 | // for each test case 29 | for tstidx := range expRepVal.In { 30 | in := expRepVal.In[tstidx] 31 | 32 | exTp := expRepVal.Type 33 | exLn := expRepVal.Len[tstidx] 34 | exRet := expRepVal.Ret[tstidx] 35 | 36 | // run 37 | retVal := readfn(in) 38 | retLen := retVal.c 39 | 40 | // check type 41 | if exTp != reflect.TypeOf(retVal).Kind() { 42 | t.Logf("REPCODE: %v return type expected %v but found %v\n", 43 | repCode, exTp, reflect.TypeOf(retVal).Kind()) 44 | t.Fail() 45 | continue 46 | } 47 | 48 | // check length 49 | if exLn != retLen { 50 | t.Logf("REPCODE: %v return length expected %v but found %v\n", 51 | repCode, exLn, retLen) 52 | t.Fail() 53 | continue 54 | } 55 | 56 | // check value 57 | switch { 58 | case retVal.i != nil: 59 | ev, ok := exRet.(int) 60 | if !ok { 61 | t.Logf("REPCODE: %v expected: %v of type %T, but found: %v of type %T", 62 | repCode, exRet, exRet, retVal, retVal) 63 | t.Fail() 64 | continue 65 | } 66 | 67 | if ev != rv { 68 | t.Logf("REPCODE: %v expected %v != returned %v", 69 | repCode, ev, rv) 70 | t.Fail() 71 | continue 72 | } 73 | 74 | case float32: 75 | ev, ok := exRet.(float32) 76 | if !ok { 77 | t.Logf("REPCODE: %v expected: %v of type %T, but found: %v of type %T", 78 | repCode, exRet, exRet, retVal, retVal) 79 | t.Fail() 80 | continue 81 | } 82 | 83 | if ev != rv { 84 | t.Logf("REPCODE: %v expected %v != returned %v", repCode, ev, rv) 85 | t.Fail() 86 | continue 87 | } 88 | 89 | case float64: 90 | ev, ok := exRet.(float64) 91 | if !ok { 92 | t.Logf("REPCODE: %v expected: %v of type %T, but found: %v of type %T", 93 | repCode, exRet, exRet, retVal, retVal) 94 | t.Fail() 95 | continue 96 | } 97 | 98 | if ev != rv { 99 | t.Logf("REPCODE: %v expected %v != returned %v", repCode, ev, rv) 100 | t.Fail() 101 | continue 102 | } 103 | 104 | case OBNAME: 105 | t.Log("repcode_test.go OBNAME to be done") 106 | continue 107 | 108 | default: 109 | t.Logf("Unknown type %v\n", reflect.TypeOf(rv)) 110 | t.Fail() 111 | } 112 | } 113 | } 114 | } 115 | 116 | var RepCodeTest = []struct { 117 | In [][]byte // test cases 118 | Ret []interface{} // value 119 | Type reflect.Kind // type, this doesn't change 120 | Len []int // length 121 | 122 | }{ 123 | {}, // 0 is not present 124 | 125 | // {"FSHORT", 2, "Low precision floating point", nil}, // 1 126 | {}, 127 | 128 | // {"FSINGL", 4, "IEEE single precision floating point", func}, // 2 129 | { 130 | In: [][]byte{ 131 | []byte("FILE"), // case 0 132 | []byte("NAME"), // case 1 133 | }, 134 | Ret: []interface{}{ 135 | float32(12883.0673828125), // case 0 136 | float32(810766656), // case 1 137 | }, 138 | Type: reflect.Float32, 139 | Len: []int{4, 4}, 140 | }, 141 | 142 | // {"FSING1", 8, "Validated single precision floating point", nil}, // 3 143 | {}, 144 | 145 | // {"FSING2", 12, "Two-way validated single precision floating point", nil}, // 4 146 | {}, 147 | 148 | // {"ISINGL", 4, "IBM single precision floating point", nil}, // 5 149 | {}, 150 | 151 | // {"VSINGL", 4, "VAX single precision floating point", nil}, // 6 152 | {}, 153 | 154 | // {"FDOUBL", 8, "IEEE double precision floating point",func }, // 7 155 | { 156 | In: [][]byte{ 157 | []byte("CREATION"), // case 0 158 | []byte("PRODUCER"), // case 1 159 | }, 160 | Ret: []interface{}{ 161 | float64(2.0570785880292664E16), // case 0 162 | float64(8.480444221488923E78), // case 1 163 | }, 164 | Type: reflect.Float64, 165 | Len: []int{8, 8}, 166 | }, 167 | 168 | // {"FDOUB1", 16, "Validated double precision floating point", nil}, // 8 169 | {}, 170 | 171 | // {"FDOUB2", 24, "Two-way validated double precision floating point", nil}, // 9 172 | {}, 173 | 174 | // {"CSINGL", 8, "Single precision complex", nil}, // 10 175 | {}, 176 | 177 | // {"CDOUBL", 16, "Double precision complex", nil}, // 11 178 | {}, 179 | 180 | // {"SSHORT", 1, "Short signed integer", nil}, // 12 181 | {}, 182 | 183 | // {"SNORM", 2, "Normal signed integer", nil}, // 13 184 | {}, 185 | 186 | // {"SLONG", 4, "Long signed integer", nil}, // 14 187 | {}, 188 | 189 | // {"USHORT", 1, "Short unsigned integer", func}, // 15 190 | { 191 | In: [][]byte{ 192 | []byte("a"), 193 | []byte("b"), 194 | []byte("c"), 195 | }, 196 | Ret: []interface{}{ 197 | int(97), 198 | int(98), 199 | int(99), 200 | }, 201 | Type: reflect.Int, 202 | Len: []int{1, 1, 1}, 203 | }, 204 | 205 | // {"UNORM", 2, "Normal unsigned integer", func}, // 16 206 | { 207 | In: [][]byte{ 208 | []byte("ab"), 209 | []byte("cd"), 210 | []byte("ef"), 211 | }, 212 | Ret: []interface{}{ 213 | int(24930), 214 | int(25444), 215 | int(25958), 216 | }, 217 | Type: reflect.Int, 218 | Len: []int{2, 2, 2}, 219 | }, 220 | 221 | // {"ULONG", 4, "Long unsigned integer", func}, // 17 222 | { 223 | In: [][]byte{ 224 | []byte("abcd"), 225 | []byte("xyz "), 226 | []byte("1234"), 227 | }, 228 | Ret: []interface{}{ 229 | int(1633837924), 230 | int(2021227040), 231 | int(825373492), 232 | }, 233 | Type: reflect.Int, 234 | Len: []int{4, 4, 4}, 235 | }, 236 | 237 | // {"UVARI", 0, "Variable-length unsigned integer 1, 2, or 4", func}, // 18 238 | { 239 | In: [][]byte{ 240 | []byte("a"), 241 | []byte{0xAA, 0xAA}, // A = 1010 -> 2 = 0010 242 | []byte{0xCC, 0xCC, 0xCC, 0xCC}, // C = 1100 -> 0 = 0000 243 | }, 244 | Ret: []interface{}{ 245 | int(97), 246 | int(10922), 247 | int(214748364), 248 | }, 249 | Type: reflect.Int, 250 | Len: []int{1, 2, 4}, 251 | }, 252 | /* 253 | {"IDENT", 0, "Variable-length identifier", 254 | func(in []byte) (interface{}, int) { 255 | ln := in[0] 256 | if ln == 0 { 257 | return "", 0 258 | } 259 | // only allowed 33-96, 123-126 260 | // TODO check for allowed 261 | return string(in[1 : 1+ln]), int(1 + ln) 262 | }}, // 19 263 | 264 | {"ASCII", 0, "Variable-length ASCII character string", 265 | func(in []byte) (interface{}, int) { 266 | b1 := in[0] 267 | 268 | if b1 == 0 { 269 | return "", 1 270 | } 271 | 272 | var idlen, asciilen int 273 | if checkBit(7, uint(b1)) { // 274 | if checkBit(6, uint(b1)) { // 4 bytes 275 | tmp := [4]byte{b1 & 0x3F} // first byte with mask 0011_1111 276 | copy(tmp[1:], in[1:4]) // remaining 3 bytes 277 | idlen = 4 278 | asciilen = int(binary.BigEndian.Uint32(tmp[:])) 279 | } else { // 2 bytes 280 | tmp := [2]byte{b1 & 0x3F} // first byte with mask 0011_1111 281 | tmp[1] = in[1] 282 | idlen = 2 283 | asciilen = int(binary.BigEndian.Uint16(tmp[:])) 284 | } 285 | } else { 286 | // single byte 287 | idlen = 1 288 | asciilen = int(b1) // bit 7 is 0 289 | } 290 | 291 | return string(in[idlen : idlen+asciilen]), (idlen + asciilen) 292 | }}, // 20 293 | 294 | // {"DTIME", 8, "Date and time", nil}, // 21 295 | 296 | {"ORIGIN", 0, "Origin reference", 297 | func(in []byte) (interface{}, int) { 298 | b1 := in[0] 299 | if checkBit(7, uint(b1)) { // 300 | if checkBit(6, uint(b1)) { // 4 bytes 301 | tmp := [4]byte{b1 & 0x3F} // first byte with mask 0011_1111 302 | copy(tmp[1:], in[1:4]) // remaining 3 bytes 303 | return int(binary.BigEndian.Uint32(tmp[:])), 4 304 | } else { // 2 bytes 305 | tmp := [2]byte{b1 & 0x3F} // first byte with mask 0011_1111 306 | tmp[1] = in[1] 307 | return int(binary.BigEndian.Uint16(tmp[:])), 2 308 | } 309 | } 310 | // single byte 311 | return int(b1), 1 // bit 7 is 0 312 | }}, // 22 313 | 314 | {"OBNAME", 0, "Object name", 315 | func(in []byte) (interface{}, int) { 316 | 317 | // ORIGIN 318 | b1 := in[0] 319 | var olen, origin int 320 | if checkBit(7, uint(b1)) { // 321 | if checkBit(6, uint(b1)) { // 4 bytes 322 | tmp := [4]byte{b1 & 0x3F} // first byte with mask 0011_1111 323 | copy(tmp[1:], in[1:4]) // remaining 3 bytes 324 | olen = 4 325 | origin = int(binary.BigEndian.Uint32(tmp[:])) 326 | } else { // 2 bytes 327 | tmp := [2]byte{b1 & 0x3F} // first byte with mask 0011_1111 328 | tmp[1] = in[1] 329 | olen = 2 330 | origin = int(binary.BigEndian.Uint16(tmp[:])) 331 | } 332 | } else { 333 | // single byte 334 | olen = 1 335 | origin = int(b1) // bit 7 is 0 336 | } 337 | 338 | // COPY 339 | copy := int(in[olen]) 340 | 341 | // IDENT 342 | ln := int(in[olen+1]) 343 | ident := "" 344 | if ln == 0 { 345 | ident = "" 346 | } else { 347 | ident = string(in[olen+2 : olen+2+ln]) 348 | } 349 | // only allowed 33-96, 123-126 350 | // TODO check for allowed 351 | 352 | return struct { 353 | Origin, Copy int 354 | Ident string 355 | }{ 356 | origin, copy, ident, 357 | }, int(olen + 2 + ln) 358 | }}, // 23 359 | 360 | // {"OBJREF", 0, "Object reference", nil}, // 24 361 | // {"ATTREF", 0, "Attribute reference", nil}, // 25 362 | // {"STATUS", 1, "Boolean status", nil}, // 26 363 | // {"UNITS", 0, "Units expression", nil}, // 27 364 | */ 365 | } 366 | -------------------------------------------------------------------------------- /DLIS_SPEC/F - Unit Symbols.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Appendix F: Unit Symbols 5 | 6 | 7 | 8 |
Appendix F: Unit Symbols
9 |

Following are the Base Units specified 11 | and used by the standard. 12 |
13 |
Base Units are administered by POSC. 14 |
15 | 16 | 17 | 18 | 20 | 23 | 26 | 29 | 32 | 35 | 38 | 41 | 44 | 47 | 50 | 53 | 56 | 59 |
Table 1: Base Units 19 |
Unit Symbol 21 | Unit Name 22 |
A 24 | ampere 25 |
K 27 | Kelvin 28 |
cd 30 | candela 31 |
dAPI 33 | API gravity 34 |
dB 36 | decibel 37 |
gAPI 39 | API gamma ray 40 |
kg 42 | kilogram 43 |
m 45 | meter 46 |
mol 48 | mole 49 |
nAPI 51 | API neutron 52 |
rad 54 | radian 55 |
s 57 | second 58 |
sr 60 | steradian
61 |

F.2 - Derived 62 | Units

Following are Derived Units specified and used by the 63 | standard. 64 |
65 |
Derived Units are administered by POSC. 66 |
67 | 68 | 69 | 70 | 72 | 77 | 83 | 90 | 96 | 102 | 109 | 115 | 122 | 128 | 134 | 140 | 146 | 152 | 158 | 166 | 172 | 179 | 186 | 193 | 200 | 207 | 214 | 221 | 227 | 233 | 239 | 245 | 251 | 257 | 263 | 269 | 275 | 281 | 287 | 293 | 299 | 305 | 310 | 316 | 322 | 328 | 334 | 340 | 346 | 352 | 358 | 364 | 370 | 376 | 382 | 388 | 394 | 400 | 406 | 412 | 418 | 424 | 430 | 436 | 442 | 448 | 454 | 460 | 466 | 472 | 478 | 484 | 490 | 496 | 502 | 508 | 514 | 521 | 527 | 533 | 538 | 543 | 548 | 555 | 562 | 568 | 574 | 580 | 586 | 592 | 598 | 604 | 610 | 616 |
Table 2: Derived Units 71 |
Unit Symbol 73 | Unit Expression 74 | Offset 75 | Unit Name 76 |
Btu 78 | 1055.05585262 J 79 | 80 | - 81 | British thermal unit (international) 82 |
C 84 | A.s 86 | 87 | - 88 | coulomb 89 |
D 91 | 0.9869233 um2 92 | 93 | - 94 | darcy 95 |
GPa 97 | 1E9 Pa 99 | - 100 | gigapascal 101 |
Gal 103 | cm/s2 106 | - 107 | Gal 108 |
Hz 110 | 1/s 111 | 112 | - 113 | hertz 114 |
J 116 | N.m 118 | 119 | - 120 | joule 121 |
L 123 | dm3 125 | - 126 | liter 127 |
MHz 129 | 1E6 Hz 131 | - 132 | megahertz 133 |
MPa 135 | 1E6 Pa 137 | - 138 | megapascal 139 |
MeV 141 | 1E6 eV 143 | - 144 | megaelectronvolt 145 |
Mg 147 | 1000 kg 149 | - 150 | thousand kilograms 151 |
Mpsi 153 | 1E6 psi 155 | - 156 | million pounds per square inch 157 |
N 159 | kg.m/s2 162 | 163 | - 164 | Newton 165 |
Oe 167 | 79.57747 A/m 169 | - 170 | oersted 171 |
P 173 | 0.1 Pa.s 176 | - 177 | poise 178 |
Pa 180 | N/m2 182 | 183 | - 184 | pascal 185 |
S 187 | A/V 189 | 190 | - 191 | siemens 192 |
T 194 | Wb/m2 197 | - 198 | tesla 199 |
V 201 | W/A 203 | 204 | - 205 | volt 206 |
W 208 | J/s 210 | 211 | - 212 | watt 213 |
Wb 215 | V.s 217 | 218 | - 219 | weber 220 |
a 222 | 3.155815E7 s 223 | 224 | - 225 | annum (sidereal year) 226 |
acre 228 | 627264E5/15499969 m2 229 | 230 | - 231 | acre 232 |
atm 234 | 101.325 kPa 235 | 236 | - 237 | standard atmosphere 238 |
b 240 | 1E-28 m2 242 | - 243 | barn 244 |
bar 246 | 100 kPa 248 | - 249 | bar 250 |
bbl 252 | 0.158987304 m3 253 | 254 | - 255 | barrel 256 |
c 258 | 360 deg 260 | - 261 | revolution (cycle) 262 |
cP 264 | 0.01 P 266 | - 267 | centipoise 268 |
cal 270 | 4.1868 J 272 | - 273 | calorie (international) 274 |
cm 276 | 0.01 m 278 | - 279 | centimeter 280 |
cu 282 | 0.1 1/m 284 | - 285 | capture unit 286 |
d 288 | 24 h 290 | - 291 | day 292 |
daN 294 | 10 N 296 | - 297 | decanewton 298 |
deg 300 | 0.0174532925198 rad 301 | 302 | - 303 | degree (angle) 304 |
degC 306 | K 307 | -273.15 308 | degree celsius 309 |
degF 311 | 5/9 degC 313 | +32 314 | degree fahrenheit 315 |
dm 317 | 0.1 m 319 | - 320 | decimeter 321 |
eV 323 | 1.60219E-19 J 324 | 325 | - 326 | electron volt 327 |
fC 329 | 1E-15 C 331 | - 332 | femtocoulomb 333 |
ft 335 | 12 in 337 | - 338 | foot 339 |
g 341 | 0.001 kg 343 | - 344 | gram 345 |
gal 347 | 1/42 bbl 349 | - 350 | gallon 351 |
h 353 | 60 min 355 | - 356 | hour 357 |
in 359 | 0.0254 m 361 | - 362 | inch 363 |
kHz 365 | 1000 Hz 367 | - 368 | kilohertz 369 |
kPa 371 | 1000 Pa 373 | - 374 | kilopascal 375 |
kV 377 | 1000 V 379 | - 380 | kilovolt 381 |
keV 383 | 1000 eV 385 | - 386 | kiloelectronvolt 387 |
kgf 389 | 9.806650 N 390 | 391 | - 392 | kilogram force 393 |
km 395 | 1000 m 397 | - 398 | kilometer 399 |
lbf 401 | 4.4482216152605 N 402 | 403 | - 404 | pound force 405 |
lbm 407 | 0.45359237 kg 408 | 409 | - 410 | pound mass (avoirdupois) 411 |
mA 413 | 0.001 A 415 | - 416 | milliampere 417 |
mC 419 | 0.001 C 421 | - 422 | millicoulomb 423 |
mD 425 | 0.9869233E-3 um2 426 | 427 | - 428 | millidarcy 429 |
mGal 431 | 0.001 Gal 433 | - 434 | milligal 435 |
mL 437 | 0.001 L 439 | - 440 | milliliter 441 |
mS 443 | 0.001 S 445 | - 446 | millisiemens 447 |
mT 449 | 0.001 T 451 | - 452 | millitesla 453 |
mV 455 | 0.001 V 457 | - 458 | millivolt 459 |
mW 461 | 0.001 W 463 | - 464 | milliwatt 465 |
mg 467 | 0.001 g 469 | - 470 | milligram 471 |
min 473 | 60 s 475 | - 476 | minute 477 |
mm 479 | 0.001 m 481 | - 482 | millimeter 483 |
mohm 485 | 0.001 ohm 487 | - 488 | milliohm 489 |
ms 491 | 0.001 s 493 | - 494 | millisecond 495 |
nC 497 | 1E-9 C 499 | - 500 | nanocoulomb 501 |
nW 503 | 1E-9 W 505 | - 506 | nanowatt 507 |
ns 509 | 1E-9 s 511 | - 512 | nanosecond 513 |
ohm 515 | V/A 517 | 518 | - 519 | ohm 520 |
pC 522 | 1E-12 C 524 | - 525 | picocoulomb 526 |
pPa 528 | 1E-12 Pa 530 | - 531 | picopascal 532 |
ppdk 534 | 1E-4 535 | - 536 | part per ten thousand 537 |
ppk 539 | 0.001 540 | - 541 | part per thousand 542 |
ppm 544 | 1E-6 545 | - 546 | part per million 547 |
psi 549 | lbf/in2 552 | - 553 | pound per square inch 554 |
pu 556 | 0.01 m3/m3 559 | - 560 | porosity unit 561 |
t 563 | 1000 kg 565 | - 566 | metric ton 567 |
ton 569 | 2000 lbm 571 | - 572 | U.S. short ton 573 |
uA 575 | 1E-6 A 577 | - 578 | microampere 579 |
uC 581 | 1E-6 C 583 | - 584 | microcoulomb 585 |
uPa 587 | 1E-6 Pa 589 | - 590 | micropascal 591 |
uV 593 | 1E-6 V 595 | - 596 | microvolt 597 |
um 599 | 1E-6 m 601 | - 602 | micrometer 603 |
uohm 605 | 1E-6 ohm 607 | - 608 | microohm 609 |
upsi 611 | 1E-6 psi 613 | - 614 | micropound per square inch 615 |
us 617 | 1E-6 s 619 | - 620 | microsecond
621 | -------------------------------------------------------------------------------- /LAS_LIS/LAS12_Standards.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | September 1st, 1990 4 | 5 | LAS 1.2 6 | 7 | A FLOPPY DISK 8 | 9 | STANDARD FOR LOG DATA 10 | 11 | 12 | 13 | BY 14 | 15 | Canadian Well Logging Society Floppy Disk Committee 16 | Suite 229, 640 - 5 Avenue, S.W. 17 | Calgary, Alberta 18 | T2P 3G4 19 | 20 | ABSTRACT 21 | 22 | The Canadian Well Logging Society's Floppy Disk Committee has designed a 23 | standard format for log data on floppy disks. It is known as the LAS 24 | format (Log ASCII Standard). LAS consists of files written in ASCII 25 | containing minimal header information and is intended for optical curves 26 | only. Details of the LAS format are described in this paper. 27 | 28 | The purpose of the LAS format is to supply basic digital log data 29 | to users of personal computers in a format that is quick and easy to use. 30 | 31 | INTRODUCTION 32 | 33 | Log analysts who use personal computers have, in the past, been entering 34 | log data into their machines mainly through a hand digitizing procedure 35 | because most personal computers are unable to handle data from magnetic tapes. 36 | The industry was beginning to address this inefficiency by making log data 37 | available on floppy disks in a variety of formats. It was at this point 38 | that the Canadian Well Logging Society set up the Floppy Disk Committee to 39 | design a standard for log data on floppy disks that would meet the needs of 40 | personal computer users. 41 | 42 | Various standards for digital well log data already exist. The LIS format 43 | (Log Information Standard) is one of the more popular standards. A more 44 | complete standard is presently being prepared by the American Petroleum 45 | Institute which is known as the DLIS format (Digital Log Interchange 46 | Standard). Both of these standards are very useful but because of their 47 | completeness, and resulting complexity, they do not address the needs of most 48 | personal computer users. 49 | 50 | Users of personal computers have serious space limitations and are normally 51 | only interested in the optically presented curves. They also want to get this 52 | data into their machines quickly and easily. The LAS format addresses these 53 | needs and can be compared to a "Reader's Digest" version of the LIS or DLIS 54 | formats. If more detailed log information is required, then the LIS or DLIS 55 | format should be used. The LAS format is intended to complement the LIS or 56 | DLIS formats as each has its own specific purpose. 57 | 58 | 59 | 60 | 61 | GENERAL DESCRIPTION 62 | 63 | The LAS format was designed to be easily understood by the user and at the 64 | same time contain enough flags to assist the programmer. The LAS format must 65 | always be written in ASCII. If it is written using a compression routine, in 66 | binary, or in any other form, an executable program must exist on the floppy 67 | disk that will convert the file back to LAS format. 68 | 69 | The LAS format consists of files. For example, a repeat section would make 70 | up one file and the main pass another. Each of the file names end in ".LAS" 71 | so that they can be easily recognized. An individual floppy disk must not 72 | contain partial files that continue onto a second floppy disk. Large files 73 | that do not fit on one floppy must be split into two or more files. 74 | 75 | Each file consists of numerous sections. These sections are not order 76 | specific except that the last section must always be the data section. The 77 | first section is usually the "VERSION" section containing the version number 78 | of the LAS format and identifies whether the data is in wrap mode. The "WELL 79 | INFORMATION" section contains information on the well name, location, and the 80 | start and stop depths of the data in this file. The "CURVE INFORMATION" 81 | section contains the curve mnemonics, units used, and the definitions of these 82 | mnemonics, in the order that they appear in the data section. The "PARAMETER" 83 | section contains informat on parameters or constants (such as mud 84 | resistivities) and is optional. The "OTHER" section is also optional and 85 | contains any other information or comments. The last section is always the 86 | "ASCII LOG DATA" section. Depth values should appear in the first column 87 | and each column of data must be separated by a space. 88 | 89 | More detailed LAS format specifications can be found in the Appendix. 90 | 91 | 92 | REFORMAT AND CERTIFY PROGRAMS 93 | 94 | To assist users of LAS formatted data, a program was written to modify 95 | LAS files into forms that may be more compatible to the user's needs. The 96 | program is called REFORMAT and can perform the following tasks: 97 | 98 | 1) Extract a specific depth interval 99 | 100 | 2) Extract specific curves 101 | 102 | 3) Reverse depth direction 103 | 104 | 4) Change sampling interval 105 | 106 | 5) Convert wrap mode to unwrap mode 107 | 108 | 6) Scan for non-standard characters which may be causing 109 | difficulties for some programs. 110 | 111 | The CERTIFY program was designed to verify that files meet the LAS standard. 112 | If the LAS standards are not met, it will identify the errors. In case of 113 | disagreement between this program and the printed LAS standard document, the 114 | document will be deemed to be correct. The CERTIFY program also includes 115 | documentation on the LAS standard. 116 | 117 | The REFORMAT and CERTIFY programs were written by Robin Winsor of Gulf 118 | Canada Resources Ltd. in ANSI standard "C" and compiled with a Microsoft C 5.1 119 | compiler. These programs are not part of the LAS standard. 120 | 121 | The author of these programs does not reserve any rights and does not 122 | warrant the program for any specific purpose. An LAS information package is 123 | available for $10.00 through the C.W.L.S. The package includes an executable 124 | form of the REFORMAT and CERTIFY programs, source code for REFORMAT, and two 125 | test LAS files on a 3.5 inch 720K DOS compatible floppy disk. 126 | 127 | The address is as follows: 128 | 129 | Canadian Well Logging Society 130 | 229, 640 - 5 Avenue, S.W. 131 | Calgary, Alberta 132 | CANADA T2P 3G4 133 | 134 | CONCLUSIONS 135 | 136 | The latest release of the LAS format is version 1.2 which was released in 137 | August of 1989. The CWLS Floppy Disk Committee will monitor the LAS format 138 | to address problems and make modifications to the standard as required. 139 | Feedback concerning the user's likes or dislikes would be greatly appreciated 140 | and should be sent to the CWLS to the attention of the Floppy Disk Committee. 141 | 142 | It is hoped that by creating the LAS format, more widespread use will be made 143 | of digital log data. 144 | 145 | 146 | APPENDIX 147 | 148 | LAS FORMAT SPECIFICATIONS FOR VERSION 1.2 149 | 150 | 151 | PART 1 GENERAL DESCRIPTION 152 | 153 | 154 | The LAS Format is designed to store log data on floppy disks. This standard 155 | is intended to simplify the exchange of digital log data between users. The 156 | general specifications of this format are as follows: 157 | 158 | 1) The floppy disk size, type, or density is not specified because 159 | conversion between them is straightforward. 160 | 161 | 2) It is the intent of this standard to store optically presented log 162 | curves although other curves may also be stored. Raw count rates, wave 163 | form data etc. are more efficiently stored on magnetic tape using LIS 164 | or DLIS format. 165 | 166 | 3) Floppy disks in the LAS format must be MS/DOS or PC/DOS compatible 167 | 168 | 4) The file will be written in ASCII. If the file is written using a 169 | compression method, in binary, or in any other form, an executable 170 | program must exist on the floppy to convert it back to LAS format. 171 | 172 | 5) An individual floppy disk must not contain partial files that continue 173 | onto a second floppy. Large files that do not fit onto one floppy must be 174 | split into two or more separate files. This may be achieved by splitting 175 | the curves or segmenting the depths. 176 | 177 | 6) All files in LAS format must end in ".LAS" so that they may be easily 178 | recognized. 179 | 180 | 7) The LAS format is a minimum standard. It is expected that most users and 181 | suppliers will exceed this minimum standard. 182 | 183 | 184 | PART 2 MAJOR COMPONENTS OF AN LAS FILE 185 | 186 | Each LAS file contains numerous sections and each section begins with a 187 | tilde (~) mark. The last section in an LAS file must always be the log data 188 | section. 189 | 190 | The sections that make up an LAS file are as follows: 191 | 192 | ~V - contains version and wrap mode information 193 | ~W - contains well identification 194 | ~C - contains curve information 195 | ~P - contains parameters or constants 196 | ~O - contains other information such as comments 197 | ~A - contains ASCII log data 198 | 199 | These sections are described in more detail in part four of this appendix. 200 | 201 | 202 | PART 3 FLAGS 203 | 204 | Flags are used to assist computers in identifying specific lines in a file. 205 | The following flags are used in the LAS format: 206 | 207 | a) "~" (tilde): The ASCII equivalent of this flag is decimal 126 208 | or hexadecimal 7E. This flag when used will be the first non-space 209 | and non-quotation character on a line. It is used to mark the 210 | beginning of a section in a file. The first letter directly after the 211 | tilde identifies the section. (See part two.) All upper case letters 212 | in the space following a tilde mark are reserved for use by the 213 | committee. The remainder of the line will be treated as comments. 214 | 215 | b) "#" (pound): The ASCII equivalent of this flag is decimal 35 or 216 | hexadecimal 23. This flag when used will be the first non-space and 217 | non-quotation character on a line. The Pound sign is used to indicate 218 | that the line is a comment line. Comment lines can appear anywhere 219 | above the data section. 220 | 221 | c) "." and ":" : In sections other than the data section, dots and 222 | colons are used to delimit information within the line. They are 223 | usually aligned for ease of reading. Information to the right of the 224 | colon is a detailed definition of the mnemonic that is located to the 225 | left of the colon. The dot is used to separate two mnemonics. Spaces 226 | may occur to the right or left of a dot or colon. 227 | 228 | 229 | PART 4 DETAILS 230 | 231 | The actual format for each of the sections discussed in this part of the 232 | paper is best understood by looking at the examples in the boxed areas. The 233 | exact spacing is not critical because computer programs will use the dots, 234 | colons and spaces to decipher each line. 235 | 236 | I) ~V (Version Information) 237 | 238 | -This section is mandatory and usually appears at the very beginning of the 239 | file. 240 | 241 | -It identifies which version of the LAS format is being used and whether 242 | wrap mode is used. 243 | 244 | -This section must contain the following lines: 245 | 246 | "VERS. 1.2: CWLS LOG ASCII STANDARD - VERSION 1.2" 247 | Refers to which version of LAS was used. 248 | 249 | "WRAP. YES: Multiple lines per depth step" 250 | OR 251 | "WRAP. NO: One line per depth step" 252 | Refers to whether a wrap around mode was used in the data section. 253 | If no wrap mode is used the line will have a maximum length of 256 254 | characters (including the carriage return and line feed). If wrap 255 | mode is used the depth value will be on its own line and all lines 256 | of data will be no longer than 80 characters (including carriage 257 | return and line feed). 258 | 259 | -Additional lines in the version section are optional. 260 | 261 | The following is an example of a Version Information Section. 262 | ----------------------------------------------------------------------------- 263 | ~Version Information Section 264 | VERS. 1.2: CWLS log ASCII Standard -VERSION 1.2 265 | WRAP. NO: One line per depth step 266 | ----------------------------------------------------------------------------- 267 | 268 | 269 | (II) ~W (Well Information) 270 | 271 | -This section is mandatory. 272 | 273 | -It identifies the well, its location and indicates the start and stop 274 | depths of the file. 275 | 276 | -This section must contain the following lines with the mnemonics as 277 | indicated: 278 | 279 | "STRT.M nnn.nn:" 280 | Refers to the first depth in the file. The "nnn.nn" refers to the 281 | depth value. The number of decimals used is not restricted. The ".M" 282 | refers to meters and can be replaced when other units are used. The 283 | start depth can be either greater or less than the stop depth. 284 | 285 | "STOP.M nnn.nn:" 286 | Refers to the last depth in the file. The "nnn.nn" refers to the 287 | depth value. The number of decimals used is not restricted. The ".M" 288 | refers to meters and can be replaced when other units are used. 289 | 290 | "STEP.M nnn.nn:" 291 | Refers to the depth increment used. A minus sign must precede the 292 | step value if the start depth is greater than the stop depth (ie, 293 | from TD to casing has a minus step value). A step value of zero 294 | indicates a variable step. 295 | 296 | "NULL. -nnn.nn:" 297 | Refers to null values. Two common ones in use are -9999 and -999.25. 298 | 299 | "COMP. COMPANY : " 300 | Refers to company name. 301 | 302 | "WELL. WELL:" 303 | Refers to the well name. 304 | 305 | "FLD. FIELD:" 306 | Refers to the field name. 307 | 308 | "LOC. LOCATION:" 309 | Refers to the well location. 310 | 311 | "PROV. PROVINCE:" 312 | Refers to the province. For areas outside Canada this line may be 313 | replaced by: 314 | "CNTY. COUNTY:" 315 | "STAT. STATE:" 316 | "CTRY. COUNTRY:" 317 | 318 | "SRVC. SERVICE COMPANY:" 319 | Refers to logging company. 320 | 321 | "DATE. DATE:" 322 | Refers to date logged. 323 | 324 | "UWI . UNIQUE WELL ID:" 325 | Refers to unique well identifier. (See References.) For areas 326 | outside of Canada this may be replaced by: 327 | 328 | "API . API NUMBER:" 329 | 330 | -Additional lines in the well information section are optional. There 331 | is no limit set on the number of additional lines. 332 | 333 | The following is an example of a Well Information Section. 334 | ----------------------------------------------------------------------------- 335 | ~Well Information Section 336 | #MNEM.UNIT Data Type Information 337 | #--------- ------------- ------------------------------ 338 | STRT.M 635.0000: 339 | STOP.M 400.0000: 340 | STEP.M -0.1250: 341 | NULL. -999.25: 342 | COMP. COMPANY: ANY OIL COMPANY INC. 343 | WELL. WELL: ANY ET AL A9-16-49-20 344 | FLD . FIELD: EDAM 345 | LOC . LOCATION: A9-16-49-20W3M 346 | PROV. PROVINCE: SASKATCHEWAN 347 | SRVC. SERVICE COMPANY: ANY LOGGING COMPANY INC. 348 | DATE. LOG DATE: 13-DEC-86 349 | UWI . UNIQUE WELL ID: 100091604920W300 350 | ----------------------------------------------------------------------------- 351 | 352 | (III) ~C (Curve Information) 353 | 354 | -This section is mandatory. 355 | -It describes the curve and its units in the order they appear in the 356 | data section of the file. 357 | 358 | -The mnemonics used are not restricted but must be defined on the line in 359 | which they appear. 360 | 361 | -API codes are optional. (See References.) 362 | 363 | -The curves described in this section must be present in the data set. 364 | 365 | -The first curve described should normally be depth. 366 | 367 | The following is an example of a Curve Information Section with API codes. 368 | ----------------------------------------------------------------------------- 369 | ~Curve Information Section 370 | #MNEM.UNIT API CODE Curve Description 371 | #--------- ------------- ------------------------------- 372 | DEPTH.M : 1 DEPTH 373 | RHOB .K/M3 7 350 02 00: 2 BULK DENSITY 374 | NPHI .VOL/VOL 7 890 00 00: 3 NEUTRON POROSITY - SANDSTONE 375 | MSFL .OHMM 7 220 01 00: 4 Rxo RESISTIVITY 376 | SFLA .OHMM 7 222 01 00: 5 SHALLOW RESISTIVITY 377 | ILM .OHMM 7 120 44 00: 6 MEDIUM RESISTIVITY 378 | ILD .OHMM 7 120 46 00: 7 DEEP RESISTIVITY 379 | SP .MV 7 010 01 00: 8 SPONTANEOUS POTENTIAL 380 | GR .GAPI 7 310 01 00: 9 GAMMA RAY 381 | CALI .MM 7 280 01 00: 10 CALIPER 382 | DRHO .K/M3 7 356 01 00: 11 DENSITY CORRECTION 383 | ----------------------------------------------------------------------------- 384 | 385 | 386 | (IV) ~P (Parameter Information) 387 | 388 | -This section is optional. It defines the values of various parameters 389 | relating to this well. 390 | 391 | -The mnemonics used are not restricted but must be defined on the line on 392 | which they appear. 393 | 394 | -There is no limit on the number of lines that can be used. 395 | 396 | The following is an example of a Parameter Information Section. 397 | ----------------------------------------------------------------------------- 398 | ~Parameter Information Section 399 | #MNEM.UNIT Value Description 400 | #--------- ------------- ------------------------------ 401 | BHT. DEGC 24.0000: Bottom Hole Temperature 402 | BS .MM 222.0000: Bit Size 403 | FD .K/M3 999.9999: Fluid Density 404 | MDEN.K/M3 2650.0000: Logging Matrix Density 405 | MATR. 1.0000: Neutron Matrix (1=Sand) 406 | FNUM. 1.0000: Tortuosity Constant Archie's (a) 407 | FEXP. 2.0000: Cementation Exponent Archie's (m) 408 | DFD .K/M3 1200.0000: Mud Weight 409 | DFV .S 50.0000: Mud Viscosity 410 | DFL .C3 8.0000: Mud Fluid Loss 411 | DFPH. 10.0000: Mud pH 412 | RMFS.OHMM 2.8200: Mud Filtrate Resistivity 413 | EKB .M 566.9700: Elevation Kelly Bushing 414 | EGL .M 563.6799: Elevation Ground Level 415 | ----------------------------------------------------------------------------- 416 | 417 | (V) ~O (Other Information) 418 | 419 | -This section is optional. Its intended use is as a remarks or comments 420 | section. 421 | 422 | (VI) ~A (ASCII LOG DATA) 423 | 424 | -The data section will always be the last section in a file. 425 | 426 | -Depths should always appear in the first column 427 | 428 | -Each column of data must be separated by at least one space. 429 | 430 | -A line of less than 256 characters (including a carriage return and line 431 | feed) will normally not be wrapped. Wrap mode will be used if the data is 432 | longer than 256 characters. 433 | 434 | -In wrap mode, depth will be on its own line. 435 | 436 | -In wrap mode a line of data will be no longer than 80 characters. This 437 | includes a carriage return and line feed. 438 | 439 | -If wrap mode is used, the decimal points must be aligned for ease of 440 | reading. 441 | 442 | -Exponents are not permitted. The curve section can be used to overcome 443 | this limitation by changing the units. 444 | 445 | 446 | References 447 | 448 | UWI codes : "Formation Water Resistivities of Canada", CWLS, 1987. 449 | 450 | API codes : "Recommended Standard Format for Recording Digital Well Log 451 | Data on Magnetic Tape", 452 | API - Bul. D-9, 3rd edition, 1981. 453 | 454 | 455 | 456 | 457 | 458 | EXAMPLE #1 - ILLUSTRATING THE LOG ASCII STANDARD IN UNWRAPPED MODE 459 | 460 | ----------------------------------------------------------------------------- 461 | ~VERSION INFORMATION 462 | VERS. 1.2: CWLS LOG ASCII STANDARD -VERSION 1.2 463 | WRAP. NO: ONE LINE PER DEPTH STEP 464 | ~WELL INFORMATION BLOCK 465 | #MNEM.UNIT DATA TYPE INFORMATION 466 | #--------- ------------- ------------------------------ 467 | STRT.M 1670.000000: 468 | STOP.M 1660.000000: 469 | STEP.M -0.1250: 470 | NULL. -999.2500: 471 | COMP. COMPANY: ANY OIL COMPANY LTD. 472 | WELL. WELL: ANY ET AL OIL WELL #12 473 | FLD . FIELD: EDAM 474 | LOC . LOCATION: A9-16-49-20W3M 475 | PROV. PROVINCE: SASKATCHEWAN 476 | SRVC. SERVICE COMPANY: ANY LOGGING COMPANY LTD. 477 | DATE. LOG DATE: 25-DEC-1988 478 | UWI . UNIQUE WELL ID: 100091604920W300 479 | ~CURVE INFORMATION 480 | #MNEM.UNIT API CODE CURVE DESCRIPTION 481 | #--------- ------------- ------------------------------ 482 | DEPT.M : 1 DEPTH 483 | DT .US/M : 2 SONIC TRANSIT TIME 484 | RHOB.K/M3 : 3 BULK DENSITY 485 | NPHI.V/V : 4 NEUTRON POROSITY 486 | SFLU.OHMM : 5 RXO RESISTIVITY 487 | SFLA.OHMM : 6 SHALLOW RESISTIVITY 488 | ILM .OHMM : 7 MEDIUM RESISTIVITY 489 | ILD .OHMM : 8 DEEP RESISTIVITY 490 | ~PARAMETER INFORMATION 491 | #MNEM.UNIT VALUE DESCRIPTION 492 | #--------- ------------- ------------------------------ 493 | BHT .DEGC 35.5000: BOTTOM HOLE TEMPERATURE 494 | BS .MM 200.0000: BIT SIZE 495 | FD .K/M3 1000.0000: FLUID DENSITY 496 | MATR. 0.0000: NEUTRON MATRIX(0=LIME,1=SAND,2=DOLO) 497 | MDEN. 2710.0000: LOGGING MATRIX DENSITY 498 | RMF .OHMM 0.2160: MUD FILTRATE RESISTIVITY 499 | DFD .K/M3 1525.0000: DRILL FLUID DENSITY 500 | ~Other 501 | Note: The logging tools became stuck at 625 meters causing the data 502 | between 625 meters and 615 meters to be invalid. 503 | ~A DEPTH DT RHOB NPHI SFLU SFLA ILM ILD 504 | 1670.000 123.450 2550.000 0.450 123.450 123.450 110.200 105.600 505 | 1669.875 123.450 2550.000 0.450 123.450 123.450 110.200 105.600 506 | 1669.750 123.450 2550.000 0.450 123.450 123.450 110.200 105.600 507 | 508 | 509 | 510 | 511 | EXAMPLE #2 - ILLUSTRATING THE MINIMUM REQUIREMENTS 512 | OF THE LOG ASCII STANDARD IN UNWRAPPED MODE. 513 | 514 | ---------------------------------------------------------------------------- 515 | ~V 516 | VERS. 1.2: CWLS log ASCII Standard -VERSION 1.2 517 | WRAP. NO: One line per depth step 518 | ~W 519 | STRT.M 635.0000: 520 | STOP.M 400.0000: 521 | STEP.M -0.1250: 522 | NULL. -999.25: 523 | COMP. COMPANY: ANY OIL COMPANY INC. 524 | WELL. WELL: ANY ET AL A9-16-49-20 525 | FLD . FIELD: EDAM 526 | LOC . LOCATION: A9-16-49-20W3M 527 | PROV. PROVINCE: SASKATCHEWAN 528 | SRVC. SERVICE COMPANY: ANY LOGGING COMPANY INC. 529 | DATE. LOG DATE: 13-DEC-86 530 | UWI . UNIQUE WELL ID: 100091604920W300 531 | ~C 532 | DEPT.M : DEPTH 533 | RHOB.K/M3 : BULK DENSITY 534 | NPHI.VOL/VOL : NEUTRON POROSITY - SANDSTONE 535 | MSFL.OHMM : Rxo RESISTIVITY 536 | SFLA.OHMM : SHALLOW RESISTIVITY 537 | ILM .OHMM : MEDIUM RESISTIVITY 538 | ILD .OHMM : DEEP RESISTIVITY 539 | SP .MV : SPONTANEOUS POTENTIAL 540 | ~A 541 | 635.0000 2256.0000 0.4033 22.0781 22.0781 20.3438 3.6660 123.4 542 | 634.8750 2256.0000 0.4033 22.0781 22.0781 20.3438 3.6660 123.4 543 | 544 | 545 | 546 | EXAMPLE #3 - ILLUSTRATING THE WRAPPED VERSION 547 | OF THE LOG ASCII STANDARD 548 | 549 | ---------------------------------------------------------------------------- 550 | 551 | ~Version Information 552 | VERS. 1.20: CWLS log ASCII Standard -VERSION 1.20 553 | WRAP. YES: Multiple lines per depth step 554 | ~Well Information 555 | #MNEM.UNIT Data Type Information 556 | #--------- ------------- ------------------------------ 557 | STRT.M 910.000: 558 | STOP.M 901.000: 559 | STEP.M -0.1250: 560 | NULL. -999.2500: Null value 561 | COMP. COMPANY: ANY OIL COMPANY INC. 562 | WELL. WELL: ANY ET AL XX-XX-XX-XX 563 | FLD . FIELD: WILDCAT 564 | LOC . LOCATION: XX-XX-XX-XXW3M 565 | PROV. PROVINCE: SASKATCHEWAN 566 | SRVC. SERVICE COMPANY: ANY LOGGING COMPANY INC. 567 | SON . SERVICE ORDER #: 142085 568 | DATE. LOG DATE: 13-DEC-86 569 | UWI . UNIQUE WELL ID: 570 | ~Curve Information 571 | #MNEM.UNIT API CODE Curve Description 572 | #--------- ------------- ------------------------------ 573 | DEPT.M : Depth 574 | DT .US/M : 1 Sonic Travel Time 575 | RHOB.K/M : 2 Density-Bulk Density 576 | NPHI.V/V : 3 Porosity -Neutron 577 | RX0 .OHMM : 4 Resistivity -Rxo 578 | RESS.OHMM : 5 Resistivity -Shallow 579 | RESM.OHMM : 6 Resistivity -Medium 580 | RESD.OHMM : 7 Resistivity -Deep 581 | SP .MV : 8 Spon. Potential 582 | GR .GAPI : 9 Gamma Ray 583 | CALI.MM : 10 Caliper 584 | DRHO.K/M3 : 11 Delta-Rho 585 | EATT.DBM : 12 EPT Attenuation 586 | TPL .NS/M : 13 TP -EPT 587 | PEF . : 14 PhotoElectric Factor 588 | FFI .V/V : 15 Porosity -NML FFI 589 | DCAL.MM : 16 Caliper-Differential 590 | RHGF.K/M3 : 17 Density-Formation 591 | RHGA.K/M3 : 18 Density-Apparent 592 | SPBL.MV : 19 Baselined SP 593 | GRC .GAPI : 20 Gamma Ray BHC 594 | PHIA.V/V : 21 Porosity -Apparent 595 | PHID.V/V : 22 Porosity -Density 596 | PHIE.V/V : 23 Porosity -Effective 597 | PHIN.V/V : 24 Porosity -Neut BHC 598 | PHIC.V/V : 25 Porosity -Total HCC 599 | R0 .OHMM : 26 Ro 600 | RWA .OHMM : 27 Rfa 601 | SW . : 28 Sw -Effective 602 | MSI . : 29 Sh Idx -Min 603 | BVW . : 30 BVW 604 | FGAS. : 31 Flag -Gas Index 605 | PIDX. : 32 Prod Idx 606 | FBH . : 33 Flag -Bad Hole 607 | FHCC. : 34 Flag -HC Correction 608 | LSWB. : 35 Flag -Limit SWB 609 | ~A Log data section 610 | 910.000000 611 | -999.2500 2692.7075 0.3140 19.4086 19.4086 13.1709 12.2681 612 | -1.5010 96.5306 204.7177 30.5822 -999.2500 -999.2500 3.2515 613 | -999.2500 4.7177 3025.0264 3025.0264 -1.5010 93.1378 0.1641 614 | 0.0101 0.1641 0.3140 0.1641 11.1397 0.3304 0.9529 615 | 0.0000 0.1564 0.0000 11.1397 0.0000 0.0000 0.0000 616 | 909.875000 617 | -999.2500 2712.6460 0.2886 23.3987 23.3987 13.6129 12.4744 618 | -1.4720 90.2803 203.1093 18.7566 -999.2500 -999.2500 3.7058 619 | -999.2500 3.1093 3004.6050 3004.6050 -1.4720 86.9078 0.1456 620 | -0.0015 0.1456 0.2886 0.1456 14.1428 0.2646 1.0000 621 | 0.0000 0.1456 0.0000 14.1428 0.0000 0.0000 0.0000 622 | 909.750000 623 | -999.2500 2692.8137 0.2730 22.5909 22.5909 13.6821 12.6146 624 | -1.4804 89.8492 201.9287 3.1551 -999.2500 -999.2500 4.3124 625 | -999.2500 1.9287 2976.4451 2976.4451 -1.4804 86.3465 0.1435 626 | 0.0101 0.1435 0.2730 0.1435 14.5674 0.2598 1.0000 627 | 0.0000 0.1435 0.0000 14.5674 0.0000 0.0000 0.0000 628 | 909.625000 629 | -999.2500 2644.3650 0.2765 18.4831 18.4831 13.4159 12.6900 630 | -1.5010 93.3999 201.5826 -6.5861 -999.2500 -999.2500 4.3822 631 | -999.2500 1.5826 2955.3528 2955.3528 -1.5010 89.7142 0.1590 632 | 0.0384 0.1590 0.2765 0.1590 11.8600 0.3210 0.9667 633 | 0.0000 0.1538 0.0000 11.8600 0.0000 0.0000 0.0000 634 | 909.500000 635 | -999.2500 2586.2822 0.2996 13.9187 13.9187 12.9195 12.7016 636 | -1.4916 98.1214 201.7126 -4.5574 -999.2500 -999.2500 3.5967 637 | -999.2500 1.7126 2953.5940 2953.5940 -1.4916 94.2670 0.1880 638 | 0.0723 0.1880 0.2996 0.1880 8.4863 0.4490 0.8174 639 | 0.0000 0.1537 0.0000 8.4863 0.0000 0.0000 0.0000 640 | 641 | --------------------------------------------------------------------------- 642 | 643 | UPDATE AUGUST 14, 1991 644 | 645 | The latest versions are as follows: 646 | 647 | LAS -version 1.2 648 | REFORMAT -version 2.0 (correcting errors in resampling and unwrap options) 649 | CERTIFY -version 1.0 650 | 651 | Please address any problems to: 652 | 653 | Mr. Case Struyk, Chairman 654 | C.W.L.S. Floppy Disk Committee 655 | Suite 229, 640 - 5 Avenue, S.W. 656 | Calgary, Alberta 657 | T2P 3G4 658 | tel: (403) 269 9366 --------------------------------------------------------------------------------