├── 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 | 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 | | Code
19 | | Type
20 | | Desciption
21 | | Data Descriptor Reference Object Type
22 | |
23 | | 0
24 | | FDATA
25 | | Frame Data
26 | | FRAME
27 | |
28 | | 1
29 | | NOFORMAT
30 | | Unformatted Data
31 | | NO-FORMAT
32 | |
33 | | 2-126
34 | | ...
35 | | undefined, reserved
36 | | --
37 | |
38 | | 127
39 | | EOD
40 | | End of Data
41 | | -- |
42 | Figure A-1. Numeric Codes for Public IFLR
43 | Types
44 | 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 | | Code
53 | | Type
54 | | Description
55 | | Allowable Set Types
56 | |
57 | | 0
58 | | FHLR
59 | | File Header
60 | | FILE-HEADER
61 | |
62 | | 1
63 | | OLR
64 | | Origin
65 | | ORIGIN
66 | |
67 | | WELL-REFERENCE
68 | |
69 | | 2
70 | | AXIS
71 | | Coordinate Axis
72 | | AXIS
73 | |
74 | | 3
75 | | CHANNL
76 | | Channel-related information
77 | | CHANNEL
78 | |
79 | | 4
80 | | FRAME
81 | | Frame Data
82 | | FRAME
83 | |
84 | | PATH
85 | |
86 | | 5
87 | | STATIC
88 | | Static Data
89 | | CALIBRATION
90 | |
91 | | CALIBRATION-COEFFICIENT
92 | |
93 | | CALIBRATION-MEASUREMENT
94 | |
95 | | COMPUTATION
96 | |
97 | | EQUIPMENT
98 | |
99 | | GROUP
100 | |
101 | | PARAMETER
102 | |
103 | | PROCESS
104 | |
105 | | SPICE
106 | |
107 | | TOOL
108 | |
109 | | ZONE
110 | |
111 | | 6
112 | | SCRIPT
113 | | Textual Data
114 | | COMMENT
115 | | MESSAGE
116 | |
117 | | 7
118 | | UPDATE
119 | | Update Data
120 | | UPDATE
121 | |
122 | | 8
123 | | UDI
124 | | Unformatted Data Identifier
125 | | NO-FORMAT
126 | |
127 | | 9
128 | | LNAME
129 | | Long Name
130 | | LONG-NAME
131 | |
132 | | 10
133 | | SPEC
134 | | Specification
135 | | ATTRIBUTE
136 | |
137 | | CODE
138 | |
139 | | EFLR
140 | |
141 | | IFLR
142 | |
143 | | OBJECT-TYPE
144 | |
145 | | REPRESENTATION-CODE
146 | |
147 | | SPECIFICATION
148 | |
149 | | UNIT-SYMBOL
150 | |
151 | | 11
152 | | DICT
153 | | Dictionary
154 | | BASE-DICTIONARY
155 | |
156 | | IDENTIFIER
157 | |
158 | | LEXICON
159 | |
160 | | OPTION
161 | |
162 | | 12-127
163 | | -
164 | | undefined, reserved
165 | | - |
166 | 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 | | Property Indicator Options
30 | | Description
31 | |
32 | | AVERAGED
33 | | The data is the average of two or more other data sources.
34 | |
35 | | CALIBRATED
36 | | A calibration process has been applied to the data.
37 | |
38 | | 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 | |
44 | | COMPUTED
45 | | The data is an output of a transform, e.g., function former,
46 | based on input data from a single tool.
47 | |
48 | | DEPTH-MATCHED
49 | | The data has been aligned along its depth index against a
50 | reference data source.
51 | |
52 | | 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 | |
57 | | FILTERED
58 | | A filtering process has been applied to the data.
59 | |
60 | | HOLE-SIZE-CORRECTED
61 | | The data has been corrected for hole size effect based on the
62 | value of a hole size input.
63 | |
64 | | INCLINOMETRY-CORRECTED
65 | | The data has been corrected to standard directional references
66 | (vertical axis and North axis).
67 | |
68 | | LITHOLOGY-CORRECTED
69 | | The data has been computed or corrected based on the value of a
70 | matrix lithology parameter.
71 | |
72 | | LOCAL-COMPUTATION
73 | | The data is the result of locally-defined computational
74 | expressions. Such data is normally experimental.
75 | |
76 | | 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 | |
81 | | MODELLED
82 | | The data is the output of a theoretical model and is not derived
83 | from any measured quantity.
84 | |
85 | | MUDCAKE-CORRECTED
86 | | The data has been corrected for mud cake effect.
87 | |
88 | | NORMALIZED
89 | | The data has been corrected so that its range corresponds to a
90 | prescribed norm.
91 | |
92 | | OVER-SAMPLED
93 | | Interpolated data samples have been added to the original data
94 | to align this data with other data.
95 | |
96 | | 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 | |
101 | | PRESSURE-CORRECTED
102 | | The data has been corrected for hydrostatic pressure (mud
103 | weight).
104 | |
105 | | 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 | |
113 | | SALINITY-CORRECTED
114 | | The data has been corrected for salinity effect.
115 | |
116 | | SAMPLED-DOWNWARD
117 | | The original sampling direction is downward.
118 | |
119 | | SAMPLED-UPWARD
120 | | The original sampling direction is upward.
121 | |
122 | | SPEED-CORRECTED
123 | | The data has been corrected for variations of the downhole tool
124 | speed.
125 | |
126 | | SPLICED
127 | | The data has been obtained by concatenating two or more other
128 | data sources.
129 | |
130 | | 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 | |
134 | | STACKED
135 | | The data is the sum of two or more other data sources.
136 | |
137 | | 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 | |
142 | | STANDOFF-CORRECTED
143 | | The data has been corrected for standoff effect.
144 | |
145 | | TEMPERATURE-CORRECTED
146 | | The data has been corrected for temperature effect based on
147 | the value of a temperature source.
148 | |
149 | | 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 |
9 |
10 | - This standard was prepared by the API Subcommittee on Recommended Format
11 | for Digital Well Log Data. The content is based on a concept and proposal
12 | originally submitted to API by Schlumberger Well Services. This publication
13 | was under jurisdiction of the American Petroleum Institute Production
14 | Department's Executive Committee on Drilling and Production Practices until
15 | June 1998, when Petrotechnical Open Software Corporation (POSC) accepted its
16 | stewardship.
17 |
- This publication specifies a format for digital well log data, called
18 | here the Digital Log Interchange Standard (DLIS). This format may be used
19 | for the recording of well log data on magnetic tape as well as on other
20 | storage media.
21 |
- Anyone may use this standard who desires to do so, subject to the terms of
22 | the POSC Software
23 | License Agreement.
42 |
43 |
- Suggestions for revisions or additions are invited and should be
44 | submitted to POSC.
45 |
- Requests for permission to reproduce any part of the material published
46 | herein shall be addressed to POSC.
47 |
48 |
49 |
50 | 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 |
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 | 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 | | Label
116 | | Restrictions
117 | | Comments
118 | |
119 | | DESCRIPTION
120 | | C = 1, R = ASCII
121 | | -
122 | |
123 | | OBJECT-TYPE
124 | | C = 1, R = IDENT
125 | | 1
127 | |
128 | | OBJECT-LIST
129 | | R = (OBNAME, OBJREF)
130 | | 2
132 | |
133 | | GROUP-LIST
134 | | R = OBNAME
135 | | 3
137 | |
138 | 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 |
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 | | Table 1: Base Units
19 | |
20 | | Unit Symbol
21 | | Unit Name
22 | |
23 | | A
24 | | ampere
25 | |
26 | | K
27 | | Kelvin
28 | |
29 | | cd
30 | | candela
31 | |
32 | | dAPI
33 | | API gravity
34 | |
35 | | dB
36 | | decibel
37 | |
38 | | gAPI
39 | | API gamma ray
40 | |
41 | | kg
42 | | kilogram
43 | |
44 | | m
45 | | meter
46 | |
47 | | mol
48 | | mole
49 | |
50 | | nAPI
51 | | API neutron
52 | |
53 | | rad
54 | | radian
55 | |
56 | | s
57 | | second
58 | |
59 | | sr
60 | | steradian |
61 | Following are Derived Units specified and used by the
63 | standard.
64 |
65 | Derived Units are administered by POSC.
66 |
67 |
68 |
69 |
70 | | Table 2: Derived Units
71 | |
72 | | Unit Symbol
73 | | Unit Expression
74 | | Offset
75 | | Unit Name
76 | |
77 | | Btu
78 | | 1055.05585262 J
79 |
80 | | -
81 | | British thermal unit (international)
82 | |
83 | | C
84 | | A.s
86 |
87 | | -
88 | | coulomb
89 | |
90 | | D
91 | | 0.9869233 um2
92 |
93 | | -
94 | | darcy
95 | |
96 | | GPa
97 | | 1E9 Pa
99 | | -
100 | | gigapascal
101 | |
102 | | Gal
103 | | cm/s2
106 | | -
107 | | Gal
108 | |
109 | | Hz
110 | | 1/s
111 |
112 | | -
113 | | hertz
114 | |
115 | | J
116 | | N.m
118 |
119 | | -
120 | | joule
121 | |
122 | | L
123 | | dm3
125 | | -
126 | | liter
127 | |
128 | | MHz
129 | | 1E6 Hz
131 | | -
132 | | megahertz
133 | |
134 | | MPa
135 | | 1E6 Pa
137 | | -
138 | | megapascal
139 | |
140 | | MeV
141 | | 1E6 eV
143 | | -
144 | | megaelectronvolt
145 | |
146 | | Mg
147 | | 1000 kg
149 | | -
150 | | thousand kilograms
151 | |
152 | | Mpsi
153 | | 1E6 psi
155 | | -
156 | | million pounds per square inch
157 | |
158 | | N
159 | | kg.m/s2
162 |
163 | | -
164 | | Newton
165 | |
166 | | Oe
167 | | 79.57747 A/m
169 | | -
170 | | oersted
171 | |
172 | | P
173 | | 0.1 Pa.s
176 | | -
177 | | poise
178 | |
179 | | Pa
180 | | N/m2
182 |
183 | | -
184 | | pascal
185 | |
186 | | S
187 | | A/V
189 |
190 | | -
191 | | siemens
192 | |
193 | | T
194 | | Wb/m2
197 | | -
198 | | tesla
199 | |
200 | | V
201 | | W/A
203 |
204 | | -
205 | | volt
206 | |
207 | | W
208 | | J/s
210 |
211 | | -
212 | | watt
213 | |
214 | | Wb
215 | | V.s
217 |
218 | | -
219 | | weber
220 | |
221 | | a
222 | | 3.155815E7 s
223 |
224 | | -
225 | | annum (sidereal year)
226 | |
227 | | acre
228 | | 627264E5/15499969 m2
229 |
230 | | -
231 | | acre
232 | |
233 | | atm
234 | | 101.325 kPa
235 |
236 | | -
237 | | standard atmosphere
238 | |
239 | | b
240 | | 1E-28 m2
242 | | -
243 | | barn
244 | |
245 | | bar
246 | | 100 kPa
248 | | -
249 | | bar
250 | |
251 | | bbl
252 | | 0.158987304 m3
253 |
254 | | -
255 | | barrel
256 | |
257 | | c
258 | | 360 deg
260 | | -
261 | | revolution (cycle)
262 | |
263 | | cP
264 | | 0.01 P
266 | | -
267 | | centipoise
268 | |
269 | | cal
270 | | 4.1868 J
272 | | -
273 | | calorie (international)
274 | |
275 | | cm
276 | | 0.01 m
278 | | -
279 | | centimeter
280 | |
281 | | cu
282 | | 0.1 1/m
284 | | -
285 | | capture unit
286 | |
287 | | d
288 | | 24 h
290 | | -
291 | | day
292 | |
293 | | daN
294 | | 10 N
296 | | -
297 | | decanewton
298 | |
299 | | deg
300 | | 0.0174532925198 rad
301 |
302 | | -
303 | | degree (angle)
304 | |
305 | | degC
306 | | K
307 | | -273.15
308 | | degree celsius
309 | |
310 | | degF
311 | | 5/9 degC
313 | | +32
314 | | degree fahrenheit
315 | |
316 | | dm
317 | | 0.1 m
319 | | -
320 | | decimeter
321 | |
322 | | eV
323 | | 1.60219E-19 J
324 |
325 | | -
326 | | electron volt
327 | |
328 | | fC
329 | | 1E-15 C
331 | | -
332 | | femtocoulomb
333 | |
334 | | ft
335 | | 12 in
337 | | -
338 | | foot
339 | |
340 | | g
341 | | 0.001 kg
343 | | -
344 | | gram
345 | |
346 | | gal
347 | | 1/42 bbl
349 | | -
350 | | gallon
351 | |
352 | | h
353 | | 60 min
355 | | -
356 | | hour
357 | |
358 | | in
359 | | 0.0254 m
361 | | -
362 | | inch
363 | |
364 | | kHz
365 | | 1000 Hz
367 | | -
368 | | kilohertz
369 | |
370 | | kPa
371 | | 1000 Pa
373 | | -
374 | | kilopascal
375 | |
376 | | kV
377 | | 1000 V
379 | | -
380 | | kilovolt
381 | |
382 | | keV
383 | | 1000 eV
385 | | -
386 | | kiloelectronvolt
387 | |
388 | | kgf
389 | | 9.806650 N
390 |
391 | | -
392 | | kilogram force
393 | |
394 | | km
395 | | 1000 m
397 | | -
398 | | kilometer
399 | |
400 | | lbf
401 | | 4.4482216152605 N
402 |
403 | | -
404 | | pound force
405 | |
406 | | lbm
407 | | 0.45359237 kg
408 |
409 | | -
410 | | pound mass (avoirdupois)
411 | |
412 | | mA
413 | | 0.001 A
415 | | -
416 | | milliampere
417 | |
418 | | mC
419 | | 0.001 C
421 | | -
422 | | millicoulomb
423 | |
424 | | mD
425 | | 0.9869233E-3 um2
426 |
427 | | -
428 | | millidarcy
429 | |
430 | | mGal
431 | | 0.001 Gal
433 | | -
434 | | milligal
435 | |
436 | | mL
437 | | 0.001 L
439 | | -
440 | | milliliter
441 | |
442 | | mS
443 | | 0.001 S
445 | | -
446 | | millisiemens
447 | |
448 | | mT
449 | | 0.001 T
451 | | -
452 | | millitesla
453 | |
454 | | mV
455 | | 0.001 V
457 | | -
458 | | millivolt
459 | |
460 | | mW
461 | | 0.001 W
463 | | -
464 | | milliwatt
465 | |
466 | | mg
467 | | 0.001 g
469 | | -
470 | | milligram
471 | |
472 | | min
473 | | 60 s
475 | | -
476 | | minute
477 | |
478 | | mm
479 | | 0.001 m
481 | | -
482 | | millimeter
483 | |
484 | | mohm
485 | | 0.001 ohm
487 | | -
488 | | milliohm
489 | |
490 | | ms
491 | | 0.001 s
493 | | -
494 | | millisecond
495 | |
496 | | nC
497 | | 1E-9 C
499 | | -
500 | | nanocoulomb
501 | |
502 | | nW
503 | | 1E-9 W
505 | | -
506 | | nanowatt
507 | |
508 | | ns
509 | | 1E-9 s
511 | | -
512 | | nanosecond
513 | |
514 | | ohm
515 | | V/A
517 |
518 | | -
519 | | ohm
520 | |
521 | | pC
522 | | 1E-12 C
524 | | -
525 | | picocoulomb
526 | |
527 | | pPa
528 | | 1E-12 Pa
530 | | -
531 | | picopascal
532 | |
533 | | ppdk
534 | | 1E-4
535 | | -
536 | | part per ten thousand
537 | |
538 | | ppk
539 | | 0.001
540 | | -
541 | | part per thousand
542 | |
543 | | ppm
544 | | 1E-6
545 | | -
546 | | part per million
547 | |
548 | | psi
549 | | lbf/in2
552 | | -
553 | | pound per square inch
554 | |
555 | | pu
556 | | 0.01 m3/m3
559 | | -
560 | | porosity unit
561 | |
562 | | t
563 | | 1000 kg
565 | | -
566 | | metric ton
567 | |
568 | | ton
569 | | 2000 lbm
571 | | -
572 | | U.S. short ton
573 | |
574 | | uA
575 | | 1E-6 A
577 | | -
578 | | microampere
579 | |
580 | | uC
581 | | 1E-6 C
583 | | -
584 | | microcoulomb
585 | |
586 | | uPa
587 | | 1E-6 Pa
589 | | -
590 | | micropascal
591 | |
592 | | uV
593 | | 1E-6 V
595 | | -
596 | | microvolt
597 | |
598 | | um
599 | | 1E-6 m
601 | | -
602 | | micrometer
603 | |
604 | | uohm
605 | | 1E-6 ohm
607 | | -
608 | | microohm
609 | |
610 | | upsi
611 | | 1E-6 psi
613 | | -
614 | | micropound per square inch
615 | |
616 | | 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
--------------------------------------------------------------------------------