зеркало из https://github.com/softlandia/glasio.git
v0.2.4
This commit is contained in:
Родитель
d236bf29cd
Коммит
769b1052a0
6
HIST.md
6
HIST.md
|
@ -1,4 +1,8 @@
|
|||
## ver 0.2.3 // 2020.06.28 ##
|
||||
## ver 0.2.4 // 2020.06.28 ##
|
||||
|
||||
- полностью переведено на хранение параметров в специализированных контейнерах, прямые поля параметров удалены
|
||||
|
||||
## ver 0.2.3 // 2020.06.28 ##
|
||||
|
||||
- все тесты проходят, версия подготовленная к переходу от прямых параметров к использованию хранящихся в специализированных контейнерах
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ lasin
|
|||
coverage 91%
|
||||
folder "data" contain files for testing, no remove/change/add
|
||||
|
||||
## technical info ##
|
||||
|
||||
if las file contane duplicated of any parameter, then used first
|
||||
on curve section used all curves name, duplicated renamed
|
||||
|
||||
## warnings generated when reading a LAS file ##
|
||||
|
||||
### warning format ###
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
STOP.M 1660.000000:
|
||||
STEP.M -0.1250:
|
||||
STEP.M -0.1200:
|
||||
NULL. -999.2500:
|
||||
NULL. -999.2111:
|
||||
COMP. COMPANY: # ANY OIL COMPANY LTD.
|
||||
WELL. WELL: ANY ET AL OIL WELL #12
|
||||
FLD . FIELD: EDAM
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
#
|
||||
# las ¤«ï ¯à®¢¥àª¨ ¢â®¬ â¨ç¥áª®£® 㢥«¨ç¥¨ï á« ©á®¢ ¯à¨ ç⥨¨
|
||||
# à áè¨à¥¨¥ ¤®«¦® ¡ëâì ¢ë¯®«¥® ¤¢ à § , ¤¢¥ § ¯¨á¨ ¢ "las.warning.md"
|
||||
#
|
||||
|
||||
~Version Information
|
||||
VERS. 1.20: CP866 CWLS log ASCII Standard - VERSION 1.20
|
||||
WRAP. NO : One line per depth step
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
**file: data\more_20_warnings.las**
|
||||
0, line: 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
1, line: 24, "__WRN__ STEP parameter equal 0"
|
||||
0, line: 24, "__WRN__ STEP parameter equal 0"
|
||||
1, line: 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
2, line: 24, "error convert string: '6.2.24' to number, set to NULL"
|
||||
3, line: 25, "line contains 5 columns, expected: 6"
|
||||
4, line: 25, "error convert string: '528.07202215.58' to number, set to NULL"
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
0, 24, "__WRN__ STEP parameter equal 0"
|
||||
1, 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
2, 24, "error convert string: '6.2.24' to number, set to NULL"
|
||||
3, 25, "line contains 5 columns, expected: 6"
|
||||
4, 25, "error convert string: '528.07202215.58' to number, set to NULL"
|
||||
5, 25, "for column 6 data not present, value set to NULL"
|
||||
6, 27, "error convert string: '6.2.24' to number, set to NULL"
|
||||
7, 29, "error convert string: '5.97.5' to number, set to NULL"
|
||||
8, 31, "error convert string: '6.47.3' to number, set to NULL"
|
||||
9, 33, "depth not monotony"
|
||||
10, 33, "error convert string: '5.97.5' to number, set to NULL"
|
||||
11, 35, "depth not monotony"
|
||||
12, 35, "error convert string: '5.47.7' to number, set to NULL"
|
||||
13, 37, "depth not monotony"
|
||||
14, 37, "error convert string: '4.7.3' to number, set to NULL"
|
||||
15, 38, "error convert string: '4.7.3' to number, set to NULL"
|
||||
16, 40, "line contains 1 columns, expected: 6"
|
||||
17, 40, "depth not monotony"
|
||||
18, 40, "for column 2 data not present, value set to NULL"
|
||||
19, 40, "for column 3 data not present, value set to NULL"
|
||||
20, 40, "for column 4 data not present, value set to NULL"
|
||||
21, 40, "for column 5 data not present, value set to NULL"
|
||||
22, 40, "for column 6 data not present, value set to NULL"
|
||||
23, 41, "line contains 9 columns, expected: 6"
|
||||
24, 41, "depth not monotony"
|
||||
25, 42, "depth not monotony"
|
||||
26, 43, "depth not monotony"
|
||||
27, 45, "dept:'--177' not numeric, line ignore"
|
||||
28, 46, "depth not monotony"
|
||||
29, 48, "depth not monotony"
|
||||
30, 49, "depth not monotony"
|
||||
31, 50, "depth not monotony"
|
||||
32, 54, "line contains 13 columns, expected: 6"
|
||||
33, 54, "depth not monotony"
|
||||
34, 55, "line contains 7 columns, expected: 6"
|
||||
35, 55, "dept:'-x' not numeric, line ignore"
|
||||
36, 56, "line contains 5 columns, expected: 6"
|
||||
37, 56, "dept:'a1' not numeric, line ignore"
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
this example program uses the softlandia / glasio package to read a LAS file
|
||||
|
||||
the program reads the input las file and displays warnings on the console
|
||||
the program reads the input las file and put warnings to the console
|
|
@ -1,15 +1,10 @@
|
|||
#
|
||||
# las ¤«ï ¯à®¢¥àª¨ ¢â®¬ â¨ç¥áª®£® 㢥«¨ç¥¨ï á« ©á®¢ ¯à¨ ç⥨¨
|
||||
# à áè¨à¥¨¥ ¤®«¦® ¡ëâì ¢ë¯®«¥® ¤¢ à § , ¤¢¥ § ¯¨á¨ ¢ "las.warning.md"
|
||||
#
|
||||
|
||||
~Version Information
|
||||
VERS. 1.20: cp_866 CWLS log ASCII Standard - VERSION 1.20
|
||||
VERS. 1.20: cp_866
|
||||
WRAP. NO : One line per depth step
|
||||
~Well Information
|
||||
STRT .M 1.0 : Start depth
|
||||
STOP .M 1.0 : Stop depth
|
||||
STEP .M 0.10 : Step
|
||||
STRT .M 0.0 : Start depth
|
||||
STOP .M 0.0 : Stop depth
|
||||
STEP .M 0.0 : Step
|
||||
NULL . -9999.00 : Null value
|
||||
WELL . WELL : 12-‘¯«®è ï
|
||||
~Curve Information
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/softlandia/glasio"
|
||||
)
|
||||
|
||||
// Sample
|
||||
// Sample
|
||||
// read one file and print to stdout all warnings:
|
||||
// warning number, number of line in las file, message
|
||||
func main() {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
VERS. 2.0 : glas (c) softlandia@gmail.com
|
||||
WRAP. NO : ONE LINE PER DEPTH STEP
|
||||
~Well information
|
||||
STRT.M 1.000 :START DEPTH
|
||||
STOP.M 1.000 :STOP DEPTH
|
||||
STRT.M 0.000 :START DEPTH
|
||||
STOP.M 0.000 :STOP DEPTH
|
||||
STEP.M 0.100 :STEP
|
||||
NULL. -9999.000 :NULL VALUE
|
||||
WELL. 12-Ñïëîøíàÿ :WELL
|
|
@ -0,0 +1,24 @@
|
|||
~Version Information
|
||||
VERS. 1.20: cp_866
|
||||
WRAP. NO : One line per depth step
|
||||
~Well Information
|
||||
STRT .M 0.0 : Start depth
|
||||
STOP .M 0.0 : Stop depth
|
||||
STEP .M 0.0 : Step
|
||||
NULL . -9999.00 : Null value
|
||||
WELL . WELL : 12-‘¯«®è ï
|
||||
~Curve Information
|
||||
DEPT .M : 1 DEPTH
|
||||
<EFBFBD>‘ .¤.¥¤. :
|
||||
<EFBFBD>‘.ãá«.¥¤. : et
|
||||
<EFBFBD>‘ . :
|
||||
~Parameter Information
|
||||
EKB .M 72.7 : Elevation,Kelly Bushing
|
||||
~ASCII Log Data
|
||||
1.000 -9999.000 -9999.000 2.000
|
||||
1.100 -9999.000 11.535 1.000
|
||||
1.200 -9999.000 -9999.000 5.000
|
||||
1.300 0.762 -9999.000 5.000
|
||||
1.400 0.707 16.053 1.000
|
||||
1.500 0.000 -9999.000 0.000
|
||||
1.600 0.000 -9999.000 -9999.000
|
|
@ -0,0 +1,7 @@
|
|||
**file: ex01.las**
|
||||
0, line: 18, "__WRN__ STEP parameter equal 0"
|
||||
1, line: 18, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
2, line: 21, "depth not monotony"
|
||||
3, line: 22, "depth not monotony"
|
||||
4, line: 23, "depth not monotony"
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
**file: expand_points_01.las**
|
||||
0, line: 23, "__WRN__ STRT: 1.000 == STOP: 1.000"
|
||||
1, line: 26, "depth not monotony"
|
||||
2, line: 27, "depth not monotony"
|
||||
3, line: 28, "depth not monotony"
|
||||
|
|
@ -7,6 +7,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/softlandia/cpd"
|
||||
|
||||
|
@ -15,24 +16,24 @@ import (
|
|||
|
||||
func main() {
|
||||
|
||||
test1()
|
||||
test2()
|
||||
readAndSave()
|
||||
makeAndSave()
|
||||
}
|
||||
|
||||
// reads las file
|
||||
// writes messages file
|
||||
// reads las file
|
||||
// writes messages file
|
||||
// and writes the repaired las files
|
||||
func test1() {
|
||||
func readAndSave() {
|
||||
//test file "1.las"
|
||||
las := glasio.NewLas()
|
||||
n, err := las.Open("expand_points_01.las")
|
||||
n, err := las.Open("ex01.las")
|
||||
if n != 7 {
|
||||
fmt.Printf("TEST read expand_points_01.las ERROR, n = %d, must 7\n", n)
|
||||
fmt.Printf("TEST read ex01.las ERROR, n = %d, must 7\n", n)
|
||||
fmt.Println(err)
|
||||
}
|
||||
las.SaveWarning("expand_points_01.warning.md")
|
||||
las.SaveWarning("ex01.warning.md")
|
||||
|
||||
err = las.Save("expand_points_01+.las")
|
||||
err = las.Save("ex01+.las")
|
||||
if err != nil {
|
||||
fmt.Println("TEST save -1.las ERROR: ", err)
|
||||
}
|
||||
|
@ -40,24 +41,30 @@ func test1() {
|
|||
las = nil
|
||||
}
|
||||
|
||||
// writes simple las file
|
||||
func test2() {
|
||||
var s = `~W
|
||||
NULL. -99.99:
|
||||
STRT.m 00.21:
|
||||
STOP.m 10.01:
|
||||
STEP.m 00.01:
|
||||
WELL. Примерная-101 / бис:`
|
||||
|
||||
// make las object from string in memory and writes simple las file
|
||||
func makeAndSave() {
|
||||
//make object, the file will be saved in encoding CP866
|
||||
las := glasio.NewLas(cpd.CP866)
|
||||
las.Null = -99.99
|
||||
las.Rkb = 100.01
|
||||
las.Strt = 0.201
|
||||
las.Stop = 10.01
|
||||
las.Step = 0.01
|
||||
las.Well = "Примерная-101/бис"
|
||||
//parse string s as las file, only section ~W
|
||||
las.Load(strings.NewReader(s))
|
||||
//make curve depth
|
||||
d := glasio.NewLasCurve("DEPT", las)
|
||||
sp := glasio.NewLasCurve("SP.mV :spontaniously", las)
|
||||
//make curve sp
|
||||
sp := glasio.NewLasCurve("SP.mV", las)
|
||||
for i := 0; i < 5; i++ {
|
||||
d.D = append(d.D, float64(i))
|
||||
sp.D = append(sp.D, float64(i))
|
||||
sp.V = append(sp.V, float64(i) / 100)
|
||||
d.D = append(d.D, las.STRT()+las.STEP()*float64(i))
|
||||
sp.D = append(sp.D, d.D[i])
|
||||
sp.V = append(sp.V, float64(i)/100)
|
||||
}
|
||||
las.Logs = append(las.Logs, d)
|
||||
las.Logs = append(las.Logs, sp)
|
||||
err := las.Save("empty.las")
|
||||
err := las.Save("simple.las")
|
||||
log.Printf("err: %v", err)
|
||||
}
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
VERS. 2.0 : glas (c) softlandia@gmail.com
|
||||
WRAP. NO : ONE LINE PER DEPTH STEP
|
||||
~Well information
|
||||
STRT.M 0.201 :START DEPTH
|
||||
STRT.M 0.210 :START DEPTH
|
||||
STOP.M 10.010 :STOP DEPTH
|
||||
STEP.M 0.010 :STEP
|
||||
NULL. -99.990 :NULL VALUE
|
||||
WELL. <20>ਬ¥à ï-101/¡¨á :WELL
|
||||
WELL. <20>ਬ¥à ï-101 / ¡¨á :WELL
|
||||
~Curve Information Section
|
||||
DEPT.M :
|
||||
SP.mV :
|
||||
~ASCII Log Data
|
||||
# DEPT | SP |
|
||||
0.0000 0.0000
|
||||
1.0000 0.0100
|
||||
2.0000 0.0200
|
||||
3.0000 0.0300
|
||||
4.0000 0.0400
|
||||
0.2100 0.0000
|
||||
0.2200 0.0100
|
||||
0.2300 0.0200
|
||||
0.2400 0.0300
|
||||
0.2500 0.0400
|
235
las.go
235
las.go
|
@ -25,30 +25,20 @@ import (
|
|||
// Las - class to store las file
|
||||
// input code page autodetect
|
||||
// at read file always code page converted to UTF
|
||||
// at save file code page converted to specifyed in Las.toCodePage
|
||||
// at save file code page converted to specifyed in Las.oCodepage
|
||||
//TODO add pointer to cfg
|
||||
//TODO при создании объекта las есть возможность указать кодировку записи, нужна возможность указать явно кодировку чтения
|
||||
type Las struct {
|
||||
rows []string // buffer for read source file, only converted to UTF-8 no any othe change
|
||||
nRows int // actually count of lines in source file
|
||||
FileName string // file name from load
|
||||
File *os.File // the file from which we are reading
|
||||
Reader io.Reader // reader created from File, provides decode from codepage to UTF-8
|
||||
scanner *bufio.Scanner // scanner
|
||||
Ver float64 // version 1.0, 1.2 or 2.0
|
||||
Wrap string // YES || NO
|
||||
Strt float64 // start depth
|
||||
Stop float64 // stop depth
|
||||
Step float64 // depth step
|
||||
Null float64 // value interpreted as empty
|
||||
Well string // well name
|
||||
Rkb float64 // altitude KB
|
||||
Logs LasCurves // store all logs
|
||||
LogDic *map[string]string // external dictionary of standart log name - mnemonics
|
||||
VocDic *map[string]string // external vocabulary dictionary of log mnemonic
|
||||
Warnings TLasWarnings // slice of warnings occure on read or write
|
||||
oCodepage cpd.IDCodePage // codepage to save, default xlib.CpWindows1251. to special value, specify at make: NewLas(cp...)
|
||||
iDuplicate int // index of duplicated mnemonic, increase by 1 if found duplicated
|
||||
currentLine int // index of current line in readed file
|
||||
maxWarningCount int // default maximum warning count
|
||||
stdNull float64 // default null value
|
||||
|
@ -72,17 +62,17 @@ var (
|
|||
|
||||
//method for get values from header containers ////////////////
|
||||
|
||||
func (las *Las) parFloat(name string, defValue float64) float64 {
|
||||
func (las *Las) parFloat(sec HeaderSection, name string, defValue float64) float64 {
|
||||
v := defValue
|
||||
if p, ok := las.VerSec.params[name]; ok {
|
||||
if p, ok := sec.params[name]; ok {
|
||||
v, _ = strconv.ParseFloat(p.Val, 64)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (las *Las) parStr(name, defValue string) string {
|
||||
func (las *Las) parStr(sec HeaderSection, name, defValue string) string {
|
||||
v := defValue
|
||||
if p, ok := las.VerSec.params[name]; ok {
|
||||
if p, ok := sec.params[name]; ok {
|
||||
v = p.Val
|
||||
}
|
||||
return v
|
||||
|
@ -91,54 +81,51 @@ func (las *Las) parStr(name, defValue string) string {
|
|||
// NULL - return null value of las file as float64
|
||||
// if parameter NULL in las file not exist, then return StdNull (by default -999.25)
|
||||
func (las *Las) NULL() float64 {
|
||||
return las.parFloat("NULL", StdNull)
|
||||
return las.parFloat(las.WelSec, "NULL", StdNull)
|
||||
}
|
||||
|
||||
// STOP - return depth stop value of las file as float64
|
||||
// if parameter STOP in las file not exist, then return StdNull (by default -999.25)
|
||||
func (las *Las) STOP() float64 {
|
||||
return las.parFloat("STOP", StdNull)
|
||||
return las.parFloat(las.WelSec, "STOP", StdNull)
|
||||
}
|
||||
|
||||
// STRT - return depth start value of las file as float64
|
||||
// if parameter NULL in las file not exist, then return StdNull (by default -999.25)
|
||||
func (las *Las) STRT() float64 {
|
||||
return las.parFloat("STRT", StdNull)
|
||||
return las.parFloat(las.WelSec, "STRT", StdNull)
|
||||
}
|
||||
|
||||
// STEP - return depth step value of las file as float64
|
||||
// if parameter not exist, then return StdNull (by default -999.25)
|
||||
func (las *Las) STEP() float64 {
|
||||
return las.parFloat("STEP", StdNull)
|
||||
return las.parFloat(las.WelSec, "STEP", StdNull)
|
||||
}
|
||||
|
||||
// VERS - return version of las file as float64
|
||||
// if parameter VERS in las file not exist, then return 2.0
|
||||
func (las *Las) VERS() float64 {
|
||||
return las.parFloat("VERS", 2.0)
|
||||
return las.parFloat(las.VerSec, "VERS", 2.0)
|
||||
}
|
||||
|
||||
// WRAP - return wrap parameter of las file
|
||||
// if parameter not exist, then return "NO"
|
||||
func (las *Las) WRAP() string {
|
||||
return las.parStr("WRAP", "NO")
|
||||
return las.parStr(las.VerSec, "WRAP", "NO")
|
||||
}
|
||||
|
||||
// WELL - return well name
|
||||
// if parameter WELL in las file not exist, then return "--"
|
||||
func (las *Las) WELL() string {
|
||||
return las.parStr("WELL", "--")
|
||||
return las.parStr(las.WelSec, "WELL", "")
|
||||
}
|
||||
|
||||
//NewLas - make new object Las class
|
||||
//autodetect code page at load file
|
||||
//code page to save by default is cpd.CP1251
|
||||
func NewLas(outputCP ...cpd.IDCodePage) *Las {
|
||||
las := &Las{} //new(Las)
|
||||
las.Ver = 2.0 //<VER>
|
||||
las.Wrap = "NO"
|
||||
las.nRows = ExpPoints
|
||||
las.rows = make([]string, 0, las.nRows)
|
||||
las := new(Las)
|
||||
las.rows = make([]string, 0, ExpPoints /*las.nRows*/)
|
||||
las.Logs = make([]LasCurve, 0)
|
||||
las.VerSec = NewVerSection()
|
||||
las.WelSec = NewWelSection()
|
||||
|
@ -147,9 +134,6 @@ func NewLas(outputCP ...cpd.IDCodePage) *Las {
|
|||
las.OthSec = NewOthSection()
|
||||
las.maxWarningCount = MaxWarningCount
|
||||
las.stdNull = StdNull
|
||||
las.Strt = StdNull
|
||||
las.Stop = StdNull
|
||||
las.Step = StdNull
|
||||
if len(outputCP) > 0 {
|
||||
las.oCodepage = outputCP[0]
|
||||
} else {
|
||||
|
@ -159,14 +143,12 @@ func NewLas(outputCP ...cpd.IDCodePage) *Las {
|
|||
las.LogDic = nil
|
||||
//external log dictionary
|
||||
las.VocDic = nil
|
||||
//счётчик повторяющихся мнемоник, увеличивается каждый раз на 1, используется при переименовании мнемоники
|
||||
las.iDuplicate = 0
|
||||
return las
|
||||
}
|
||||
|
||||
// IsWraped - return true if WRAP == YES
|
||||
func (las *Las) IsWraped() bool {
|
||||
return strings.Contains(strings.ToUpper(las.Wrap), "Y")
|
||||
return strings.Contains(strings.ToUpper(las.WRAP()), "Y")
|
||||
}
|
||||
|
||||
// GetRows - get internal field 'rows'
|
||||
|
@ -182,25 +164,20 @@ func (las *Las) ReadRows() int {
|
|||
return len(las.rows)
|
||||
}
|
||||
|
||||
// Open -
|
||||
func (las *Las) Open(fileName string) (int, error) {
|
||||
// Load - load las from reader
|
||||
// you can make reader from string or othe containers and send as input parameters
|
||||
func (las *Las) Load(reader io.Reader) (int, error) {
|
||||
var err error
|
||||
las.File, err = os.Open(fileName)
|
||||
if err != nil {
|
||||
return 0, err //FATAL error - file not exist
|
||||
if reader == nil {
|
||||
return 0, errors.New("Load received nil reader")
|
||||
}
|
||||
defer las.File.Close()
|
||||
las.FileName = fileName
|
||||
//create Reader, this reader decode to UTF-8
|
||||
las.Reader, err = cpd.NewReader(las.File)
|
||||
//create Reader, this reader decode to UTF-8 from reader
|
||||
las.Reader, err = cpd.NewReader(reader)
|
||||
if err != nil {
|
||||
return 0, err //FATAL error - file cannot be decoded to UTF-8
|
||||
}
|
||||
// prepare file to read
|
||||
las.scanner = bufio.NewScanner(las.Reader)
|
||||
// ePoints - содержит теперь количество строк в las файле
|
||||
// соответственно слайсы для хранения кривых будут создаваться этой длины
|
||||
//las.ePoints = las.ReadRows()
|
||||
las.ReadRows()
|
||||
m, _ := las.LoadHeader()
|
||||
stdChecker := NewStdChecker()
|
||||
|
@ -215,7 +192,7 @@ func (las *Las) Open(fileName string) (int, error) {
|
|||
}
|
||||
if r.strtWrong() {
|
||||
h := las.GetStrtFromData() // return las.Null if cannot find strt in the data section.
|
||||
if h == las.Null {
|
||||
if h == las.NULL() {
|
||||
las.addWarning(TWarning{directOnRead, lasSecWellInfo, -1, fmt.Sprint("__WRN__ STRT parameter on data is wrong setting to 0")})
|
||||
las.setStrt(0)
|
||||
}
|
||||
|
@ -223,7 +200,7 @@ func (las *Las) Open(fileName string) (int, error) {
|
|||
}
|
||||
if r.stepWrong() {
|
||||
h := las.GetStepFromData() // return las.Null if cannot calculate step from data
|
||||
if h == las.Null {
|
||||
if h == las.NULL() {
|
||||
las.addWarning(TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprint("__WRN__ STEP parameter on data is wrong")})
|
||||
}
|
||||
las.setStep(h)
|
||||
|
@ -231,9 +208,20 @@ func (las *Las) Open(fileName string) (int, error) {
|
|||
return las.LoadDataSec(m)
|
||||
}
|
||||
|
||||
// Open - read las file
|
||||
func (las *Las) Open(fileName string) (int, error) {
|
||||
var err error
|
||||
las.File, err = os.Open(fileName)
|
||||
if err != nil {
|
||||
return 0, err //FATAL error - file not exist
|
||||
}
|
||||
defer las.File.Close()
|
||||
las.FileName = fileName
|
||||
return las.Load(las.File)
|
||||
}
|
||||
|
||||
/*LoadHeader - read las file and load all section before ~A
|
||||
returns the row number with which the data section begins, until return nil in any case
|
||||
secName: 0 - empty, 1 - Version, 2 - Well info, 3 - Curve info, 4 - A data
|
||||
1. читаем строку
|
||||
2. если коммент или пустая в игнор
|
||||
3. если начало секции, определяем какой
|
||||
|
@ -242,63 +230,55 @@ func (las *Las) Open(fileName string) (int, error) {
|
|||
*/
|
||||
func (las *Las) LoadHeader() (int, error) {
|
||||
var (
|
||||
err error
|
||||
sec HeaderSection
|
||||
)
|
||||
secNum := 0
|
||||
//secNum := 0
|
||||
las.currentLine = 0
|
||||
for i, s := range las.rows {
|
||||
for _, s := range las.rows {
|
||||
s = strings.TrimSpace(s)
|
||||
las.currentLine++
|
||||
if isIgnoredLine(s) {
|
||||
continue
|
||||
}
|
||||
if s[0] == '~' { //start new section
|
||||
secNum = las.selectSection(rune(s[1]))
|
||||
if secNum == lasSecData {
|
||||
if las.isDataSection(rune(s[1])) {
|
||||
break // reached the data section, stop load header
|
||||
}
|
||||
sec = las.section(rune(s[1]))
|
||||
continue
|
||||
}
|
||||
//not comment, not empty and not new section => parameter, read it
|
||||
err = las.ReadParameter(s, secNum)
|
||||
p, _ := sec.parse(s, las.currentLine)
|
||||
p.Name = sec.uniqueName(p.Name)
|
||||
p, w := sec.parse(s, las.currentLine)
|
||||
if !w.Empty() {
|
||||
las.addWarning(w)
|
||||
}
|
||||
p.Name = sec.uniqueName(p.Name) //TODO if a duplicate of any parameter is detected, a warning should be generated
|
||||
sec.params[p.Name] = p
|
||||
if err != nil {
|
||||
las.addWarning(TWarning{directOnRead, secNum, i, fmt.Sprintf("param: '%s' error: %v", s, err)})
|
||||
if sec.name == 'C' { //for ~Curve section need additional actions
|
||||
err := las.readCurveParam(s) //make new curve from "s" and store to container "Logs"
|
||||
if err != nil {
|
||||
las.addWarning(TWarning{directOnRead, 3, las.currentLine, fmt.Sprintf("param: '%s' error: %v", s, err)})
|
||||
}
|
||||
}
|
||||
}
|
||||
return las.currentLine, nil
|
||||
}
|
||||
|
||||
// selectSection - analize first char after ~
|
||||
// isDataSection - return true if data section reached
|
||||
func (las *Las) isDataSection(r rune) bool {
|
||||
return (r == 0x41) || (r == 0x61)
|
||||
}
|
||||
|
||||
// ~V - section vertion
|
||||
// ~W - well info section
|
||||
// ~C - curve info section
|
||||
// ~A - data section
|
||||
func (las *Las) selectSection(r rune) int {
|
||||
switch r {
|
||||
case 0x76, 0x56: //86, 118: //V, v
|
||||
return lasSecVersion //version section
|
||||
case 0x77, 0x57: //W, w
|
||||
return lasSecWellInfo //well info section
|
||||
case 0x43, 0x63: //C, c
|
||||
return lasSecCurInfo //curve section
|
||||
case 0x41, 0x61: //A, a
|
||||
return lasSecData //data section
|
||||
default:
|
||||
return lasSecIgnore
|
||||
}
|
||||
}
|
||||
|
||||
func (las *Las) section(r rune) HeaderSection {
|
||||
switch r {
|
||||
case 0x56, 0x76: //V, v
|
||||
return las.VerSec //version section
|
||||
case 0x57, 0x77: //W, w
|
||||
if las.Ver < 2.0 {
|
||||
if las.VERS() < 2.0 {
|
||||
las.WelSec.parse = welParse12 //change parser, by default using parser 2.0
|
||||
}
|
||||
return las.WelSec //well info section
|
||||
|
@ -318,62 +298,11 @@ func (las *Las) storeHeaderWarning(chkResults CheckResults) {
|
|||
}
|
||||
}
|
||||
|
||||
// ReadParameter - read one parameter
|
||||
func (las *Las) ReadParameter(s string, secNum int) error {
|
||||
switch secNum {
|
||||
case lasSecVersion:
|
||||
return las.readVersionParam(s)
|
||||
case lasSecWellInfo:
|
||||
return las.ReadWellParam(s)
|
||||
case lasSecCurInfo:
|
||||
return las.readCurveParam(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (las *Las) readVersionParam(s string) error {
|
||||
var err error
|
||||
p := NewHeaderParam(s, 0)
|
||||
switch p.Name {
|
||||
case "VERS":
|
||||
las.Ver, err = strconv.ParseFloat(p.Val, 64)
|
||||
case "WRAP":
|
||||
las.Wrap = p.Val
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//ReadWellParam - read parameter from WELL section
|
||||
func (las *Las) ReadWellParam(s string) error {
|
||||
var err error
|
||||
p := NewHeaderParam(s, 0)
|
||||
switch p.Name {
|
||||
case "STRT":
|
||||
las.Strt, err = strconv.ParseFloat(p.Val, 64)
|
||||
case "STOP":
|
||||
las.Stop, err = strconv.ParseFloat(p.Val, 64)
|
||||
case "STEP":
|
||||
las.Step, err = strconv.ParseFloat(p.Val, 64)
|
||||
case "NULL":
|
||||
las.Null, err = strconv.ParseFloat(p.Val, 64)
|
||||
case "WELL":
|
||||
if las.Ver < 2.0 {
|
||||
las.Well = p.Desc
|
||||
} else {
|
||||
las.Well = wellNameFromParam(p)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
las.addWarning(TWarning{directOnRead, lasSecWellInfo, -1, fmt.Sprintf("detected param: %v, unit:%v, value: %v\n", p.Name, p.Unit, p.Val)})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//Разбор одной строки с мнемоникой каротажа
|
||||
//Разбираем а потом сохраняем в slice
|
||||
//Каждый каротаж характеризуется тремя именами
|
||||
//Name - имя каротажа, повторятся не может, если есть повторение, то Name строится добавлением к IName индекса
|
||||
//IName - имя каротажа в исходном файле, может повторятся
|
||||
//Name - ключ в map хранилище, повторятся не может. если в исходном есть повторение, то Name строится добавлением к IName индекса
|
||||
//Mnemonic - мнемоника, берётся из словаря, если в словаре не найдено, то ""
|
||||
func (las *Las) readCurveParam(s string) error {
|
||||
l := NewLasCurve(s, las)
|
||||
|
@ -398,9 +327,9 @@ func (las *Las) LoadDataSec(m int) (int, error) {
|
|||
err error
|
||||
dept float64
|
||||
)
|
||||
n := len(las.Logs) // количество каротажей, столько колонок данных ожидаем
|
||||
dataRows := las.rows[m:] // reslice to lines with data only
|
||||
nullAsStr := strconv.FormatFloat(las.Null, 'f', 5, 64) // Null as string
|
||||
n := len(las.Logs) // количество каротажей, столько колонок данных ожидаем
|
||||
dataRows := las.rows[m:] // reslice to lines with data only
|
||||
nullAsStr := strconv.FormatFloat(las.NULL(), 'f', 5, 64) // Null as string
|
||||
las.currentLine = m - 1
|
||||
for _, line := range dataRows {
|
||||
las.currentLine++
|
||||
|
@ -441,7 +370,7 @@ func (las *Las) LoadDataSec(m int) (int, error) {
|
|||
v, err = strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
las.addWarning(TWarning{directOnRead, lasSecData, las.currentLine, fmt.Sprintf("error convert string: '%s' to number, set to NULL", s)})
|
||||
v = las.Null
|
||||
v = las.NULL()
|
||||
}
|
||||
las.Logs[j].D = append(las.Logs[j].D, dept)
|
||||
las.Logs[j].V = append(las.Logs[j].V, v)
|
||||
|
@ -510,11 +439,11 @@ func (las *Las) SaveToBuf(useMnemonic bool) ([]byte, error) {
|
|||
fmt.Fprintf(&b, _LasVersion, 2.0) //file is always saved in 2.0 format
|
||||
fmt.Fprint(&b, _LasWrap)
|
||||
fmt.Fprint(&b, _LasWellInfoSec)
|
||||
fmt.Fprintf(&b, _LasStrt, las.Strt)
|
||||
fmt.Fprintf(&b, _LasStop, las.Stop)
|
||||
fmt.Fprintf(&b, _LasStep, las.Step)
|
||||
fmt.Fprintf(&b, _LasNull, las.Null)
|
||||
fmt.Fprintf(&b, _LasWell, las.Well)
|
||||
fmt.Fprintf(&b, _LasStrt, las.STRT())
|
||||
fmt.Fprintf(&b, _LasStop, las.STOP())
|
||||
fmt.Fprintf(&b, _LasStep, las.STEP())
|
||||
fmt.Fprintf(&b, _LasNull, las.NULL())
|
||||
fmt.Fprintf(&b, _LasWell, las.WELL())
|
||||
fmt.Fprint(&b, _LasCurvSec)
|
||||
fmt.Fprint(&b, _LasCurvDept)
|
||||
|
||||
|
@ -554,13 +483,13 @@ func (las *Las) IsEmpty() bool {
|
|||
func (las *Las) GetStrtFromData() float64 {
|
||||
iFile, err := os.Open(las.FileName)
|
||||
if err != nil {
|
||||
return las.Null //не обрабатывается в тесте
|
||||
return las.NULL() //не обрабатывается в тесте
|
||||
}
|
||||
defer iFile.Close()
|
||||
|
||||
_, iScanner, err := xlib.SeekFileStop(las.FileName, "~A")
|
||||
if (err != nil) || (iScanner == nil) {
|
||||
return las.Null //не обрабатывается в тесте
|
||||
return las.NULL() //не обрабатывается в тесте
|
||||
}
|
||||
|
||||
s := ""
|
||||
|
@ -576,12 +505,12 @@ func (las *Las) GetStrtFromData() float64 {
|
|||
}
|
||||
dept1, err = strconv.ParseFloat(s[:k], 64)
|
||||
if err != nil {
|
||||
return las.Null //не обрабатывается в тесте
|
||||
return las.NULL() //не обрабатывается в тесте
|
||||
}
|
||||
return dept1
|
||||
}
|
||||
//если мы попали сюда, то всё грусно, в файле после ~A не нашлось двух строчек с данными... или пустые строчки или комменты
|
||||
return las.Null
|
||||
return las.NULL()
|
||||
}
|
||||
|
||||
// GetStepFromData - return step from data section
|
||||
|
@ -591,13 +520,13 @@ func (las *Las) GetStrtFromData() float64 {
|
|||
func (las *Las) GetStepFromData() float64 {
|
||||
iFile, err := os.Open(las.FileName)
|
||||
if err != nil {
|
||||
return las.Null //не обрабатывается в тесте
|
||||
return las.NULL() //не обрабатывается в тесте
|
||||
}
|
||||
defer iFile.Close()
|
||||
|
||||
_, iScanner, err := xlib.SeekFileStop(las.FileName, "~A")
|
||||
if (err != nil) || (iScanner == nil) {
|
||||
return las.Null
|
||||
return las.NULL()
|
||||
}
|
||||
|
||||
s := ""
|
||||
|
@ -616,7 +545,7 @@ func (las *Las) GetStepFromData() float64 {
|
|||
dept1, err = strconv.ParseFloat(s[:k], 64)
|
||||
if err != nil {
|
||||
// case if the data row in the first position (dept place) contains not a number
|
||||
return las.Null
|
||||
return las.NULL()
|
||||
}
|
||||
j++
|
||||
if j == 2 {
|
||||
|
@ -626,42 +555,42 @@ func (las *Las) GetStepFromData() float64 {
|
|||
dept2 = dept1
|
||||
}
|
||||
//bad case, data section not contain two rows with depth
|
||||
return las.Null //не обрабатывается в тесте
|
||||
return las.NULL() //не обрабатывается в тесте
|
||||
}
|
||||
|
||||
func (las *Las) setStep(h float64) {
|
||||
las.Step = h
|
||||
las.WelSec.params["STEP"] = HeaderParam{strconv.FormatFloat(h, 'f', -1, 64), "STEP", "", "", "", "step of index", 8}
|
||||
}
|
||||
|
||||
func (las *Las) setStrt(strt float64) {
|
||||
las.Strt = strt
|
||||
las.WelSec.params["STRT"] = HeaderParam{strconv.FormatFloat(strt, 'f', -1, 64), "STRT", "", "", "", "first index value", 6}
|
||||
}
|
||||
|
||||
// IsStrtEmpty - return true if parameter Strt not exist in file
|
||||
func (las *Las) IsStrtEmpty() bool {
|
||||
return las.Strt == StdNull
|
||||
return las.STRT() == StdNull
|
||||
}
|
||||
|
||||
// IsStopEmpty - return true if parameter Stop not exist in file
|
||||
func (las *Las) IsStopEmpty() bool {
|
||||
return las.Stop == StdNull
|
||||
return las.STOP() == StdNull
|
||||
}
|
||||
|
||||
// IsStepEmpty - return true if parameter Step not exist in file
|
||||
func (las *Las) IsStepEmpty() bool {
|
||||
return las.Step == StdNull
|
||||
return las.STEP() == StdNull
|
||||
}
|
||||
|
||||
// SetNull - change parameter NULL in WELL INFO section and in all logs
|
||||
func (las *Las) SetNull(aNull float64) {
|
||||
func (las *Las) SetNull(null float64) {
|
||||
for _, l := range las.Logs { //loop by logs
|
||||
for i := range l.V { //loop by dept step
|
||||
if l.V[i] == las.Null {
|
||||
l.V[i] = aNull
|
||||
if l.V[i] == las.NULL() {
|
||||
l.V[i] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
las.Null = aNull
|
||||
las.WelSec.params["NULL"] = HeaderParam{strconv.FormatFloat(null, 'f', -1, 64), "NULL", "", "", "", "null value", las.WelSec.params["NULL"].lineNo}
|
||||
}
|
||||
|
||||
// SaveWarning - save to file all warning
|
||||
|
|
|
@ -70,16 +70,6 @@ func (crs CheckResults) wellWrong() bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// isFatal - return true if CheckResults contains at least one check result with fatal error
|
||||
func (crs CheckResults) isFatal() bool {
|
||||
for _, c := range crs {
|
||||
if c.err != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// fatal - return first not nil error if CheckResults contains at least one check result with fatal error
|
||||
func (crs CheckResults) fatal() error {
|
||||
for _, c := range crs {
|
||||
|
@ -99,7 +89,7 @@ type Checker map[string]Check
|
|||
// если проверка прошла безошибочно, то её в результатах не будет
|
||||
// полученный map содержит только ошибки
|
||||
func (c Checker) check(las *Las) CheckResults {
|
||||
res := make(CheckResults, 0)
|
||||
res := make(CheckResults)
|
||||
// key - имя проверки
|
||||
// chk - сам проверщик
|
||||
for key, chk := range c {
|
||||
|
@ -111,15 +101,6 @@ func (c Checker) check(las *Las) CheckResults {
|
|||
return res
|
||||
}
|
||||
|
||||
/*
|
||||
// NewDeptChecker - creation of a new checker to check the depth of monotony
|
||||
func NewDeptChecker() Checker {
|
||||
return Checker{
|
||||
"DPTM": Check{"DPTM", "~A", "Dept step monotony", deptMonotony},
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// NewStdChecker - создание нового ПРОВЕРЩИКА las файла.
|
||||
// WRAP = ON
|
||||
// section ~Curve is empty
|
||||
|
@ -164,17 +145,17 @@ func curvesIsEmpty(chk Check, las *Las) CheckRes {
|
|||
}
|
||||
|
||||
func stepCheck(chk Check, las *Las) CheckRes {
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprint("__WRN__ STEP parameter equal 0")}, nil, las.Step != 0.0}
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprint("__WRN__ STEP parameter equal 0")}, nil, las.STEP() != 0.0}
|
||||
}
|
||||
|
||||
func nullCheck(chk Check, las *Las) CheckRes {
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprint("__WRN__ NULL parameter equal 0")}, nil, las.Null != 0.0}
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprint("__WRN__ NULL parameter equal 0")}, nil, las.NULL() != 0.0}
|
||||
}
|
||||
|
||||
func strtStop(chk Check, las *Las) CheckRes {
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprintf("__WRN__ STRT: %4.3f == STOP: %4.3f", las.Strt, las.Stop)}, nil, las.Strt != las.Stop}
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprintf("__WRN__ STRT: %4.3f == STOP: %4.3f", las.STRT(), las.STOP())}, nil, las.STRT() != las.STOP()}
|
||||
}
|
||||
|
||||
func wellIsEmpty(chk Check, las *Las) CheckRes {
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprintf("__WRN__ WELL: '%s' is empty", las.Well)}, nil, len(las.Well) != 0}
|
||||
return CheckRes{chk.name, TWarning{directOnRead, lasSecWellInfo, las.currentLine, fmt.Sprintf("__WRN__ WELL: '%s' is empty", las.WELL())}, nil, len(las.WELL()) != 0}
|
||||
}
|
||||
|
|
|
@ -24,16 +24,15 @@ type tLoadHeader struct {
|
|||
}
|
||||
|
||||
var dLoadHeader = []tLoadHeader{
|
||||
{fp.Join("data/more_20_warnings.las"), 1.2, "NO", 0.0, 0.0, 1.0, -32768.0, "6"}, // in file STEP=0.0 but this incorrect, Open() must replace STEP to actual from data
|
||||
{fp.Join("data/expand_points_01.las"), 1.2, "NO", 1.0, 1.0, 0.1, -9999.00, "12-Сплошная"},
|
||||
{fp.Join("data/2.0/cp1251_2.0_well_name.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"},
|
||||
{fp.Join("data/2.0/cp1251_2.0_based.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1/бис(ё)"},
|
||||
{fp.Join("data/expand_points_01.las"), 1.2, "NO", 1.0, 1.0, 0.1, -9999.00, "12-Сплошная"},
|
||||
{fp.Join("data/expand_points_01.las"), 1.2, "NO", 1.0, 1.0, 0.1, -9999.0, "12-Сплошная"},
|
||||
{fp.Join("data/1.2/sample.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "ANY ET AL OIL WELL #12"},
|
||||
{fp.Join("data/2.0/sample_2.0.las"), 2.0, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "AAAAA_2"},
|
||||
{fp.Join("data/broken_parameter.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"}, // file contain error on STRT
|
||||
{fp.Join("data/broken_header.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"}, // file contain only part of header
|
||||
{fp.Join("data/more_20_warnings.las"), 1.2, "NO", 0.0, 0.0, 0.0, -32768.0, "6"}, // TODO STEP=0.0 but this incorrect, LoadHeader must replace STEP to actual from data
|
||||
{fp.Join("data/duplicate_step.las"), 1.2, "NO", 1670.0, 1660.0, -0.1200, -999.2500, "ANY ET AL OIL WELL #12"}, // duplicate_step.las contains two line with STEP:: STEP.M -0.1250: STEP.M -0.1200: using LAST parameter
|
||||
{fp.Join("data/duplicate_step.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2111, "ANY ET AL OIL WELL #12"}, // duplicate_step.las contains two line with STEP:: STEP.M -0.1250: STEP.M -0.1200: using LAST parameter
|
||||
{fp.Join("data/encodings_utf8.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "Скв #12Ω"}, // well name contain unicode char
|
||||
{fp.Join("test_files/warning-test-files/01-STOP-02.las"), 2.0, "NO", 0.0, -999.2500, 0.1, -999.25, "Скв #12"}, // STOP not exist
|
||||
}
|
||||
|
@ -43,28 +42,41 @@ func TestLoadHeader(t *testing.T) {
|
|||
for _, tmp := range dLoadHeader {
|
||||
las = NewLas()
|
||||
las.Open(tmp.fn)
|
||||
las.LoadHeader()
|
||||
assert.Equal(t, tmp.ver, las.Ver, fmt.Sprintf("<LoadHeader> file '%s' readed VER: %f, expected %f", las.FileName, las.Ver, tmp.ver))
|
||||
assert.Equal(t, tmp.wrap, las.Wrap, fmt.Sprintf("<LoadHeader> file '%s' readed WRAP: %s, expected %s", las.FileName, las.Wrap, tmp.wrap))
|
||||
assert.Equal(t, tmp.strt, las.Strt, fmt.Sprintf("<LoadHeader> file '%s' readed STRT: %f, expected %f", las.FileName, las.Strt, tmp.strt))
|
||||
assert.Equal(t, tmp.stop, las.Stop, fmt.Sprintf("<LoadHeader> file '%s' readed STOP: %f, expected %f", las.FileName, las.Stop, tmp.stop))
|
||||
assert.Equal(t, tmp.step, las.Step, fmt.Sprintf("<LoadHeader> file '%s' readed STEP: %f, expected %f", las.FileName, las.Step, tmp.step))
|
||||
assert.Equal(t, tmp.null, las.Null, fmt.Sprintf("<LoadHeader> file '%s' readed NULL: %f, expected %f", las.FileName, las.Null, tmp.null))
|
||||
assert.Equal(t, tmp.well, las.Well, fmt.Sprintf("<LoadHeader> file '%s' readed WELL: %s, expected %s", las.FileName, las.Well, tmp.well))
|
||||
assert.Equal(t, tmp.ver, las.VERS(), fmt.Sprintf("<LoadHeader> file '%s' readed VER: %f, expected %f", las.FileName, las.VERS(), tmp.ver))
|
||||
assert.Equal(t, tmp.wrap, las.WRAP(), fmt.Sprintf("<LoadHeader> file '%s' readed WRAP: %s, expected %s", las.FileName, las.WRAP(), tmp.wrap))
|
||||
assert.Equal(t, tmp.null, las.NULL(), fmt.Sprintf("<LoadHeader> file '%s' readed NULL: %f, expected %f", las.FileName, las.NULL(), tmp.null))
|
||||
assert.Equal(t, tmp.strt, las.STRT(), fmt.Sprintf("<LoadHeader> file '%s' readed STRT: %f, expected %f", las.FileName, las.STRT(), tmp.strt))
|
||||
assert.Equal(t, tmp.stop, las.STOP(), fmt.Sprintf("<LoadHeader> file '%s' readed STOP: %f, expected %f", las.FileName, las.STOP(), tmp.stop))
|
||||
assert.Equal(t, tmp.step, las.STEP(), fmt.Sprintf("<LoadHeader> file '%s' readed STEP: %f, expected %f", las.FileName, las.STEP(), tmp.step))
|
||||
assert.Equal(t, tmp.well, las.WELL(), fmt.Sprintf("<LoadHeader> file '%s' readed WELL: %s, expected %s", las.FileName, las.WELL(), tmp.well))
|
||||
}
|
||||
}
|
||||
|
||||
var dLoadLasHeader = []tLoadHeader{
|
||||
{fp.Join("data/expand_points_01.las"), 1.2, "NO", 1.0, 1.0, 0.1, -9999.00, "12-Сплошная"},
|
||||
{fp.Join("data/2.0/cp1251_2.0_well_name.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"},
|
||||
{fp.Join("data/2.0/cp1251_2.0_based.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1/бис(ё)"},
|
||||
{fp.Join("data/1.2/sample.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "ANY ET AL OIL WELL #12"},
|
||||
{fp.Join("data/2.0/sample_2.0.las"), 2.0, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "AAAAA_2"},
|
||||
{fp.Join("data/broken_parameter.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"}, // file contain error on STRT
|
||||
{fp.Join("data/broken_header.las"), 2.0, "NO", 0.0, 39.9, 0.3, -999.25, "Примерная-1 / бис(ё)"}, // file contain only part of header
|
||||
{fp.Join("data/more_20_warnings.las"), 1.2, "NO", 0.0, 0.0, 0.0, -32768.0, "6"}, // TODO STEP=0.0 but this incorrect, LoadLasHeader do not any repairs
|
||||
{fp.Join("data/duplicate_step.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2111, "ANY ET AL OIL WELL #12"}, // duplicate_step.las contains two line with STEP:: STEP.M -0.1250: STEP.M -0.1200: using LAST parameter
|
||||
{fp.Join("data/encodings_utf8.las"), 1.2, "NO", 1670.0, 1660.0, -0.1250, -999.2500, "Скв #12Ω"}, // well name contain unicode char
|
||||
{fp.Join("test_files/warning-test-files/01-STOP-02.las"), 2.0, "NO", 0.0, -999.2500, 0.1, -999.25, "Скв #12"}, // STOP not exist
|
||||
}
|
||||
|
||||
func TestLoadLasHeader(t *testing.T) {
|
||||
for _, tmp := range dLoadHeader {
|
||||
for _, tmp := range dLoadLasHeader {
|
||||
las, err := LoadLasHeader(tmp.fn)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tmp.ver, las.Ver, fmt.Sprintf("<LoadHeader> file '%s' readed VER: %f, expected %f", las.FileName, las.Ver, tmp.ver))
|
||||
assert.Equal(t, tmp.wrap, las.Wrap, fmt.Sprintf("<LoadHeader> file '%s' readed WRAP: %s, expected %s", las.FileName, las.Wrap, tmp.wrap))
|
||||
assert.Equal(t, tmp.strt, las.Strt, fmt.Sprintf("<LoadHeader> file '%s' readed STRT: %f, expected %f", las.FileName, las.Strt, tmp.strt))
|
||||
assert.Equal(t, tmp.stop, las.Stop, fmt.Sprintf("<LoadHeader> file '%s' readed STOP: %f, expected %f", las.FileName, las.Stop, tmp.stop))
|
||||
assert.Equal(t, tmp.step, las.Step, fmt.Sprintf("<LoadHeader> file '%s' readed STEP: %f, expected %f", las.FileName, las.Step, tmp.step))
|
||||
assert.Equal(t, tmp.null, las.Null, fmt.Sprintf("<LoadHeader> file '%s' readed NULL: %f, expected %f", las.FileName, las.Null, tmp.null))
|
||||
assert.Equal(t, tmp.well, las.Well, fmt.Sprintf("<LoadHeader> file '%s' readed WELL: %s, expected %s", las.FileName, las.Well, tmp.well))
|
||||
assert.Equal(t, tmp.ver, las.VERS(), fmt.Sprintf("<LoadHeader> file '%s' readed VER: %f, expected %f", las.FileName, las.VERS(), tmp.ver))
|
||||
assert.Equal(t, tmp.wrap, las.WRAP(), fmt.Sprintf("<LoadHeader> file '%s' readed WRAP: %s, expected %s", las.FileName, las.WRAP(), tmp.wrap))
|
||||
assert.Equal(t, tmp.strt, las.STRT(), fmt.Sprintf("<LoadHeader> file '%s' readed STRT: %f, expected %f", las.FileName, las.STRT(), tmp.strt))
|
||||
assert.Equal(t, tmp.stop, las.STOP(), fmt.Sprintf("<LoadHeader> file '%s' readed STOP: %f, expected %f", las.FileName, las.STOP(), tmp.stop))
|
||||
assert.Equal(t, tmp.step, las.STEP(), fmt.Sprintf("<LoadHeader> file '%s' readed STEP: %f, expected %f", las.FileName, las.STEP(), tmp.step))
|
||||
assert.Equal(t, tmp.null, las.NULL(), fmt.Sprintf("<LoadHeader> file '%s' readed NULL: %f, expected %f", las.FileName, las.NULL(), tmp.null))
|
||||
assert.Equal(t, tmp.well, las.WELL(), fmt.Sprintf("<LoadHeader> file '%s' readed WELL: %s, expected %s", las.FileName, las.WELL(), tmp.well))
|
||||
}
|
||||
//test error case
|
||||
las, err := LoadLasHeader("not_exist_file.las") //file not exist
|
||||
|
|
84
las_param.go
84
las_param.go
|
@ -30,6 +30,7 @@ type HeaderParam struct {
|
|||
|
||||
// HeaderSection - contain parameters of Well section
|
||||
type HeaderSection struct {
|
||||
name rune
|
||||
params map[string]HeaderParam
|
||||
parse ParseHeaderParam // function for parse one line
|
||||
}
|
||||
|
@ -43,13 +44,16 @@ func (hs HeaderSection) uniqueName(name string) string {
|
|||
}
|
||||
|
||||
// ParseHeaderParam - function to parse one line of header
|
||||
// return new of added parameter and warning
|
||||
// return new of added parameter and warning
|
||||
// on success TWarning.Empty() == true
|
||||
// s - string readed from source file
|
||||
// i - number of line in source file
|
||||
type ParseHeaderParam func(s string, i int) (HeaderParam, TWarning)
|
||||
|
||||
// NewVerSection - create section ~V
|
||||
func NewVerSection() HeaderSection {
|
||||
sec := HeaderSection{}
|
||||
sec.name = 'V'
|
||||
sec.params = make(map[string]HeaderParam)
|
||||
sec.parse = defParse
|
||||
return sec
|
||||
|
@ -64,6 +68,7 @@ func defParse(s string, i int) (HeaderParam, TWarning) {
|
|||
// NewOthSection - create section ~W
|
||||
func NewOthSection() HeaderSection {
|
||||
sec := HeaderSection{}
|
||||
sec.name = 'O'
|
||||
sec.params = make(map[string]HeaderParam)
|
||||
sec.parse = defParse
|
||||
return sec
|
||||
|
@ -72,6 +77,7 @@ func NewOthSection() HeaderSection {
|
|||
// NewParSection - create section ~W
|
||||
func NewParSection() HeaderSection {
|
||||
sec := HeaderSection{}
|
||||
sec.name = 'P'
|
||||
sec.params = make(map[string]HeaderParam)
|
||||
sec.parse = defParse
|
||||
return sec
|
||||
|
@ -80,6 +86,7 @@ func NewParSection() HeaderSection {
|
|||
// NewCurSection - create section ~C
|
||||
func NewCurSection() HeaderSection {
|
||||
sec := HeaderSection{}
|
||||
sec.name = 'C'
|
||||
sec.params = make(map[string]HeaderParam)
|
||||
sec.parse = curParse // parser for section ~C
|
||||
return sec
|
||||
|
@ -94,6 +101,7 @@ func curParse(s string, i int) (HeaderParam, TWarning) {
|
|||
// NewWelSection - create section ~W
|
||||
func NewWelSection() HeaderSection {
|
||||
sec := HeaderSection{}
|
||||
sec.name = 'W'
|
||||
sec.params = make(map[string]HeaderParam)
|
||||
sec.parse = welParse20 // by default using 2.0 version parser
|
||||
return sec
|
||||
|
@ -140,16 +148,6 @@ func (p *HeaderParam) wellName20() {
|
|||
p.Unit = ""
|
||||
}
|
||||
|
||||
func wellNameFromParam(p *HeaderParam) string {
|
||||
if len(p.Unit) == 0 {
|
||||
return p.Val
|
||||
}
|
||||
if len(p.Val) == 0 {
|
||||
return p.Unit //TODO не тестируется
|
||||
}
|
||||
return p.Unit + " " + p.Val
|
||||
}
|
||||
|
||||
//PrepareParamStr - prepare string to parse, replace many space to one, replace tab to space, replace combination of separator to one
|
||||
func PrepareParamStr(s string) string {
|
||||
s = strings.ReplaceAll(s, "\t", " ")
|
||||
|
@ -158,6 +156,24 @@ func PrepareParamStr(s string) string {
|
|||
return strings.TrimSpace(s)
|
||||
}
|
||||
|
||||
// NewHeaderParam - create new object LasParam
|
||||
// STRT. m 10.0 : start
|
||||
// field[0] field[1] field[2] field[3]
|
||||
func NewHeaderParam(s string, i int) *HeaderParam {
|
||||
par := new(HeaderParam)
|
||||
par.lineNo = i
|
||||
paramFields := ParseParamStr(s)
|
||||
par.Name = paramFields[0]
|
||||
par.Unit = paramFields[1]
|
||||
par.Val = paramFields[2]
|
||||
if (len(par.Val) == 0) && (len(par.Unit) > 0) {
|
||||
par.Val = par.Unit
|
||||
par.Unit = ""
|
||||
}
|
||||
par.Desc = paramFields[3]
|
||||
return par
|
||||
}
|
||||
|
||||
// ParseParamStr - parse string from las file
|
||||
// return slice with 4 string and error if occure
|
||||
// before process input string 2 or more space replace on 1 space
|
||||
|
@ -198,6 +214,19 @@ func ParseParamStr(s string) (f [4]string) {
|
|||
return
|
||||
}
|
||||
|
||||
// NewCurveHeaderParam - create new object LasParam
|
||||
// STRT. m 10.0 : start
|
||||
// field[0] field[1] field[2] field[3]
|
||||
func NewCurveHeaderParam(s string, i int) *HeaderParam {
|
||||
par := new(HeaderParam)
|
||||
par.lineNo = i
|
||||
paramFields := ParseCurveStr(s)
|
||||
par.Name = paramFields[0]
|
||||
par.Unit = paramFields[1]
|
||||
par.Desc = paramFields[2]
|
||||
return par
|
||||
}
|
||||
|
||||
const defCurveName = "-EL-" // curve name for null input
|
||||
|
||||
// ParseCurveStr - parse input string to 3 separated string
|
||||
|
@ -235,37 +264,6 @@ func ParseCurveStr(s string) (f [3]string) {
|
|||
return
|
||||
}
|
||||
|
||||
// NewHeaderParam - create new object LasParam
|
||||
// STRT. m 10.0 : start
|
||||
// field[0] field[1] field[2] field[3]
|
||||
func NewHeaderParam(s string, i int) *HeaderParam {
|
||||
par := new(HeaderParam)
|
||||
par.lineNo = i
|
||||
paramFields := ParseParamStr(s)
|
||||
par.Name = paramFields[0]
|
||||
par.Unit = paramFields[1]
|
||||
par.Val = paramFields[2]
|
||||
if (len(par.Val) == 0) && (len(par.Unit) > 0) {
|
||||
par.Val = par.Unit
|
||||
par.Unit = ""
|
||||
}
|
||||
par.Desc = paramFields[3]
|
||||
return par
|
||||
}
|
||||
|
||||
// NewCurveHeaderParam - create new object LasParam
|
||||
// STRT. m 10.0 : start
|
||||
// field[0] field[1] field[2] field[3]
|
||||
func NewCurveHeaderParam(s string, i int) *HeaderParam {
|
||||
par := new(HeaderParam)
|
||||
par.lineNo = i
|
||||
paramFields := ParseCurveStr(s)
|
||||
par.Name = paramFields[0]
|
||||
par.Unit = paramFields[1]
|
||||
par.Desc = paramFields[2]
|
||||
return par
|
||||
}
|
||||
|
||||
//LasCurve - class to store one log in Las
|
||||
type LasCurve struct {
|
||||
HeaderParam
|
||||
|
@ -357,7 +355,7 @@ func (curves LasCurves) UniqueName(curveName string) string {
|
|||
// количество кривых в контейнере
|
||||
// два хеша от строк с именами всех кривых
|
||||
func (curves LasCurves) Cmp(otheCurves LasCurves) (res bool) {
|
||||
res = (len(curves) == len(curves))
|
||||
res = (len(curves) == len(otheCurves))
|
||||
if res {
|
||||
curvesName := make([]string, 0, len(curves))
|
||||
for _, k := range curves {
|
||||
|
|
|
@ -37,8 +37,10 @@ var dReadWellParamStep = []tReadWellParamStep{
|
|||
func TestReadWellParam(t *testing.T) {
|
||||
las := NewLas()
|
||||
for i, tmp := range dReadWellParamStep {
|
||||
las.ReadWellParam(tmp.s)
|
||||
assert.Equal(t, tmp.v, las.Step, fmt.Sprintf("<ReadWellParam> on test %d return STEP: '%f' expect: '%f'\n", i, las.Step, tmp.v))
|
||||
//las.ReadWellParam(tmp.s)
|
||||
hp, _ := las.WelSec.parse(tmp.s, 0)
|
||||
las.WelSec.params["STEP"] = hp
|
||||
assert.Equal(t, tmp.v, las.STEP(), fmt.Sprintf("<ReadWellParam> on test %d return STEP: '%f' expect: '%f'\n", i, las.STEP(), tmp.v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ var dSummaryCheck = []tSummaryCheck{
|
|||
{fp.Join("data/1001178549.las"), 2.0, "YES", 1783.5, 1784.5, 0.25, -999.25, "1-28", 27, 0, true},
|
||||
{fp.Join("data/alog.las"), 1.20, "NO", 0, 0, 0.05, -999.25, "", 9, 24, false},
|
||||
{fp.Join("data/autodepthindex_F.las"), 1.20, "NO", 0, 100, 1, -999.25, "ANY ET AL OIL WELL #12", 2, 101, false},
|
||||
{fp.Join("data/barebones2.las"), 2.0, "NO", -999.25, -999.25, -999.25, 0, "", 0, 0, true}, // step и null не правятся, отсутствует секция Curve, ошибка заголовка
|
||||
{fp.Join("data/barebones2.las"), 2.0, "NO", -999.25, -999.25, -999.25, -999.25, "", 0, 0, true}, // step и null не правятся, отсутствует секция Curve, ошибка заголовка
|
||||
{fp.Join("data/blank_line.las"), 2.0, "NO", -999.25, -999.25, 0.0833333333333333, -999.25, "", 1, 0, true},
|
||||
{fp.Join("data/data_characters.las"), 2.0, "NO", 0, 0, 10, -999.25, "", 4, 0, true},
|
||||
{fp.Join("data/duplicate_step.las"), 1.2, "NO", 1670, 1660, -0.12, -999.25, "ANY ET AL OIL WELL #12", 8, 3, false},
|
||||
{fp.Join("data/duplicate_step.las"), 1.2, "NO", 1670, 1660, -0.125, -999.2111, "ANY ET AL OIL WELL #12", 8, 3, false},
|
||||
{fp.Join("data/encodings_utf8.las"), 1.2, "NO", 1670, 1660, -0.125, -999.25, "Скв #12Ω", 8, 3, false},
|
||||
{fp.Join("data/encodings_utf8_20.las"), 2.0, "NO", 1670, 1660, -0.125, -999.25, "Скв #12Ω", 8, 3, false},
|
||||
{fp.Join("data/encodings_utf8wbom.las"), 1.2, "NO", 1670, 1660, -0.125, -999.25, "Скважина #12Ω", 8, 3, false},
|
||||
|
@ -63,16 +63,19 @@ func TestSummaryRead(t *testing.T) {
|
|||
las := NewLas()
|
||||
n, _ := las.Open(tmp.fn)
|
||||
assert.Equal(t, tmp.nums, n, fmt.Sprintf("<TestSummaryRead> nums fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.ver, las.VERS(), fmt.Sprintf("<TestSummaryRead> ver fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.wrap, las.WRAP(), fmt.Sprintf("<TestSummaryRead> wrap fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.strt, las.STRT(), fmt.Sprintf("<TestSummaryRead> strt fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.stop, las.STOP(), fmt.Sprintf("<TestSummaryRead> stop fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.step, las.STEP(), fmt.Sprintf("<TestSummaryRead> step fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.null, las.NULL(), fmt.Sprintf("<TestSummaryRead> null fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.well, las.WELL(), fmt.Sprintf("<TestSummaryRead> null fail on file: '%s'\n", tmp.fn))
|
||||
//две проверки касающиеся секции кривых
|
||||
//кривые попадают в два контейнера: las.Logs и las.CurSec.params
|
||||
assert.Equal(t, tmp.curv, len(las.Logs), fmt.Sprintf("<TestSummaryRead> curves fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.curv, len(las.CurSec.params), fmt.Sprintf("<TestSummaryRead> curves fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.ver, las.Ver, fmt.Sprintf("<TestSummaryRead> ver fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.ver, las.VERS(), fmt.Sprintf("<TestSummaryRead> ver fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.wrap, las.Wrap, fmt.Sprintf("<TestSummaryRead> wrap fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.strt, las.Strt, fmt.Sprintf("<TestSummaryRead> strt fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.stop, las.Stop, fmt.Sprintf("<TestSummaryRead> stop fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.step, las.Step, fmt.Sprintf("<TestSummaryRead> step fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.null, las.Null, fmt.Sprintf("<TestSummaryRead> null fail on file: '%s'\n", tmp.fn))
|
||||
assert.Equal(t, tmp.well, las.Well)
|
||||
//проверки по данным
|
||||
//if tmp.nums
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,11 +119,13 @@ func TestLasCheck(t *testing.T) {
|
|||
s = lasLog.msgCurve.String(fp.Join("data/test-curve-sec-empty-mnemonic+.las"))
|
||||
assert.Contains(t, s, "test-curve-sec-empty-mnemonic+.las'##")
|
||||
|
||||
// проверка на возврат nil
|
||||
// проверка на возврат nil при невозможности выполнить проверку
|
||||
lasLog, err := LasDeepCheck(fp.Join("data/test-curve-sec-empty-mnemonic+.las"), fp.Join("data/mnemonic.-"), fp.Join("data/dic.ini"))
|
||||
assert.Nil(t, lasLog)
|
||||
assert.NotNil(t, err)
|
||||
lasLog, err = LasDeepCheck(fp.Join("data/test-curve-sec-empty-mnemonic+.las"), fp.Join("data/mnemonic.ini"), fp.Join("data/dic.-"))
|
||||
assert.Nil(t, lasLog)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
lasLog, err = LasDeepCheck(fp.Join("data/test-curve-sec-empty-mnemonic+.las"), fp.Join("data/mnemonic.ini"), fp.Join("data/dic.ini"))
|
||||
assert.Nil(t, err)
|
||||
|
@ -152,6 +157,7 @@ func TestLasCheck(t *testing.T) {
|
|||
// случай если файла нет "data/-.las"
|
||||
lasLog, err = LasDeepCheck(fp.Join("data/-.las"), fp.Join("data/mnemonic.ini"), fp.Join("data/dic.ini"))
|
||||
assert.NotNil(t, lasLog)
|
||||
assert.NotNil(t, err)
|
||||
assert.NotNil(t, lasLog.errorOnOpen)
|
||||
|
||||
// случай если las файл WRAP
|
||||
|
|
26
las_test.go
26
las_test.go
|
@ -103,7 +103,7 @@ func TestGetStrtFromData(t *testing.T) {
|
|||
for _, tmp := range dGetDataStrt {
|
||||
las := NewLas()
|
||||
las.Open(tmp.fn)
|
||||
assert.Equal(t, tmp.st, las.Strt, fmt.Sprintf("<TestGetStepFromData> fail on file '%s' \n", tmp.fn))
|
||||
assert.Equal(t, tmp.st, las.STRT(), fmt.Sprintf("<TestGetStrtFromData> fail on file '%s' \n", tmp.fn))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,24 +123,24 @@ func TestGetStepFromData(t *testing.T) {
|
|||
for _, tmp := range dGetDataStep {
|
||||
las := NewLas()
|
||||
las.Open(tmp.fn)
|
||||
assert.Equal(t, tmp.st, las.Step, fmt.Sprintf("<TestGetStepFromData> fail on file '%s' \n", tmp.fn))
|
||||
assert.Equal(t, tmp.st, las.STEP(), fmt.Sprintf("<TestGetStepFromData> fail on file '%s' \n", tmp.fn))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLasSetNull(t *testing.T) {
|
||||
las := NewLas()
|
||||
las.Open(fp.Join("data/expand_points_01.las"))
|
||||
assert.Equal(t, -9999.00, las.Null)
|
||||
assert.Equal(t, -9999.00, las.NULL())
|
||||
las.SetNull(-999.25)
|
||||
assert.Equal(t, -999.25, las.Null)
|
||||
assert.Equal(t, -999.25, las.NULL())
|
||||
las.Save("-tmp.las")
|
||||
|
||||
las = NewLas()
|
||||
las.Open("-tmp.las")
|
||||
assert.Equal(t, -999.25, las.Null)
|
||||
assert.Equal(t, -999.25, las.NULL())
|
||||
log := las.Logs[1]
|
||||
assert.Equal(t, las.Null, log.V[2])
|
||||
assert.Equal(t, las.Null, las.Logs[2].V[6])
|
||||
assert.Equal(t, las.NULL(), log.V[2])
|
||||
assert.Equal(t, las.NULL(), las.Logs[2].V[6])
|
||||
err := os.Remove("-tmp.las")
|
||||
assert.Nil(t, err, fmt.Sprintf("%v", err))
|
||||
}
|
||||
|
@ -179,11 +179,11 @@ func TestLasSave(t *testing.T) {
|
|||
//os.Remove(tmp.fn)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, n)
|
||||
assert.Equal(t, tmp.newNull, las.Null)
|
||||
assert.Equal(t, tmp.strt, las.Strt)
|
||||
assert.Equal(t, tmp.stop, las.Stop)
|
||||
assert.Equal(t, tmp.step, las.Step)
|
||||
assert.Equal(t, tmp.well, las.Well)
|
||||
assert.Equal(t, tmp.newNull, las.NULL())
|
||||
assert.Equal(t, tmp.strt, las.STRT())
|
||||
assert.Equal(t, tmp.stop, las.STOP())
|
||||
assert.Equal(t, tmp.step, las.STEP())
|
||||
assert.Equal(t, tmp.well, las.WELL())
|
||||
assert.Equal(t, "DEPT", las.Logs[0].Name)
|
||||
assert.Equal(t, 1.1, las.Logs[0].D[1])
|
||||
assert.Equal(t, 1.0, las.Logs[0].V[0])
|
||||
|
@ -195,7 +195,7 @@ func TestLasSave(t *testing.T) {
|
|||
func TestSetNullOnEmptyLas(t *testing.T) {
|
||||
las := NewLas()
|
||||
las.SetNull(-1000)
|
||||
assert.Equal(t, -1000.0, las.Null)
|
||||
assert.Equal(t, -1000.0, las.NULL())
|
||||
}
|
||||
|
||||
func TestLasIsEmpty(t *testing.T) {
|
||||
|
|
24
las_util.go
24
las_util.go
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
fp "path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/softlandia/cpd"
|
||||
)
|
||||
|
@ -21,10 +22,10 @@ func isIgnoredLine(s string) bool {
|
|||
// два las равны если равны их основные параметры: STRT, STOP, STEP, NULL, количество точек в данных,
|
||||
// а также количество кривых и совпадают имена кривых
|
||||
func cmpLas(correct, las *Las) (res bool) {
|
||||
res = (correct.Strt == las.Strt)
|
||||
res = res && (correct.Stop == las.Stop)
|
||||
res = res && (correct.Step == las.Step)
|
||||
res = res && (correct.Null == las.Null)
|
||||
res = (correct.STRT() == las.STRT())
|
||||
res = res && (correct.STOP() == las.STOP())
|
||||
res = res && (correct.STEP() == las.STEP())
|
||||
res = res && (correct.NULL() == las.NULL())
|
||||
res = res && (correct.NumPoints() == las.NumPoints())
|
||||
res = res && correct.Logs.Cmp(las.Logs)
|
||||
return res
|
||||
|
@ -53,11 +54,13 @@ func makeSampleLas(
|
|||
} else {
|
||||
las = NewLas(cp)
|
||||
}
|
||||
las.Null = null
|
||||
las.Strt = strt
|
||||
las.Stop = stop
|
||||
las.Step = step
|
||||
las.Well = well
|
||||
las.VerSec.params["VERS"] = HeaderParam{"2.0", "VERS", "", "", "", "glasio (c) softlandia@gmail.com", 2}
|
||||
las.VerSec.params["WRAP"] = HeaderParam{"NO", "WRAP", "", "", "", "one line per depth step", 3}
|
||||
las.WelSec.params["NULL"] = HeaderParam{strconv.FormatFloat(null, 'f', -1, 64), "NULL", "", "", "", "null value", 5}
|
||||
las.WelSec.params["STRT"] = HeaderParam{strconv.FormatFloat(strt, 'f', -1, 64), "STRT", "", "", "", "first index value", 6}
|
||||
las.WelSec.params["STOP"] = HeaderParam{strconv.FormatFloat(stop, 'f', -1, 64), "STOP", "", "", "", "last index value", 7}
|
||||
las.WelSec.params["STEP"] = HeaderParam{strconv.FormatFloat(step, 'f', -1, 64), "STEP", "", "", "", "step of index", 8}
|
||||
las.WelSec.params["WELL"] = HeaderParam{well, "WELL", "", "", "", "well", 9}
|
||||
|
||||
curve := NewLasCurve("DEPT.m :", las)
|
||||
curve.D = append(curve.D, 1.0, 1.1, 1.2, 1.3, 1.4)
|
||||
|
@ -71,6 +74,8 @@ func makeSampleLas(
|
|||
}
|
||||
|
||||
// LoadLasHeader - utility function, if need read only header without data
|
||||
// read header as is
|
||||
// not repaire any parameters: step, stop, etc...
|
||||
func LoadLasHeader(fileName string) (*Las, error) {
|
||||
las := NewLas()
|
||||
iFile, err := os.Open(fileName)
|
||||
|
@ -85,7 +90,6 @@ func LoadLasHeader(fileName string) (*Las, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//las.ePoints = las.ReadRows()
|
||||
las.ReadRows()
|
||||
las.LoadHeader()
|
||||
return las, nil
|
||||
|
|
|
@ -9,8 +9,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
//defWarningCount = 10
|
||||
//warningUNDEF = 0
|
||||
directOnRead = 1
|
||||
directOnWrite = 2
|
||||
)
|
||||
|
|
97
linter.md
97
linter.md
|
@ -0,0 +1,97 @@
|
|||
las.go:679:21: Error return value of `writer.WriteString` is not checked (errcheck)
|
||||
writer.WriteString(w.String())
|
||||
^
|
||||
las.go:680:21: Error return value of `writer.WriteString` is not checked (errcheck)
|
||||
writer.WriteString("\n")
|
||||
^
|
||||
las.go:693:19: Error return value of `oFile.WriteString` is not checked (errcheck)
|
||||
oFile.WriteString("**file: " + las.FileName + "**\n")
|
||||
^
|
||||
las.go:695:19: Error return value of `oFile.WriteString` is not checked (errcheck)
|
||||
oFile.WriteString("\n")
|
||||
^
|
||||
las_header_test.go:44:11: Error return value of `las.Open` is not checked (errcheck)
|
||||
las.Open(tmp.fn)
|
||||
^
|
||||
las_logger.go:50:16: Error return value of `f.WriteString` is not checked (errcheck)
|
||||
f.WriteString(msg)
|
||||
^
|
||||
las_logger.go:82:16: Error return value of `f.WriteString` is not checked (errcheck)
|
||||
f.WriteString(s)
|
||||
^
|
||||
las_logger.go:84:15: Error return value of `f.WriteString` is not checked (errcheck)
|
||||
f.WriteString("\n")
|
||||
^
|
||||
las_test.go:50:10: Error return value of `las.Open` is not checked (errcheck)
|
||||
las.Open(fp.Join("data/more_20_warnings.las"))
|
||||
^
|
||||
las_test.go:57:10: Error return value of `las.Open` is not checked (errcheck)
|
||||
las.Open(fp.Join("data/more_20_warnings.las"))
|
||||
^
|
||||
las_test.go:62:17: Error return value of `las.SaveWarning` is not checked (errcheck)
|
||||
las.SaveWarning(fp.Join("data/more_20_warnings.wrn"))
|
||||
^
|
||||
las_test.go:136:10: Error return value of `las.Save` is not checked (errcheck)
|
||||
las.Save("-tmp.las")
|
||||
^
|
||||
las_test.go:277:11: Error return value of `las.Save` is not checked (errcheck)
|
||||
las.Save(tmp.fn)
|
||||
^
|
||||
las_util.go:94:16: Error return value of `las.LoadHeader` is not checked (errcheck)
|
||||
las.LoadHeader()
|
||||
^
|
||||
las_constants.go:13:2: `_LasMnemonicFormat` is unused (deadcode)
|
||||
_LasMnemonicFormat = "#MNEM.UNIT DATA :DESCRIPTION\n"
|
||||
^
|
||||
las_constants.go:18:2: `_LasRkb` is unused (deadcode)
|
||||
_LasRkb = " RKB.M %8.3f :KB or GL\n"
|
||||
^
|
||||
las_constants.go:19:2: `_LasXcoord` is unused (deadcode)
|
||||
_LasXcoord = " XWELL.M %8.3f :Well head X coordinate\n"
|
||||
^
|
||||
las_constants.go:20:2: `_LasYcoord` is unused (deadcode)
|
||||
_LasYcoord = " YWELL.M %8.3f :Well head Y coordinate\n"
|
||||
^
|
||||
las_constants.go:21:2: `_LasOilComp` is unused (deadcode)
|
||||
_LasOilComp = " COMP. %-43.43s:OIL COMPANY\n"
|
||||
^
|
||||
las_constants.go:23:2: `_LasField` is unused (deadcode)
|
||||
_LasField = " FLD . %-43.43s:FIELD\n"
|
||||
^
|
||||
las_constants.go:24:2: `_LasLoc` is unused (deadcode)
|
||||
_LasLoc = " LOC . %-43.43s:LOCATION\n"
|
||||
^
|
||||
las_constants.go:25:2: `_LasCountry` is unused (deadcode)
|
||||
_LasCountry = " CTRY. %-43.43s:COUNTRY\n"
|
||||
^
|
||||
las_constants.go:26:2: `_LasServiceComp` is unused (deadcode)
|
||||
_LasServiceComp = " SRVC. %-43.43s:SERVICE COMPANY\n"
|
||||
^
|
||||
las_constants.go:27:2: `_LasDate` is unused (deadcode)
|
||||
_LasDate = " DATE. %-43.43s:DATE\n"
|
||||
^
|
||||
las_constants.go:28:2: `_LasAPI` is unused (deadcode)
|
||||
_LasAPI = " API . %-43.43s:API NUMBER\n"
|
||||
^
|
||||
las_constants.go:29:2: `_LasUwi` is unused (deadcode)
|
||||
_LasUwi = " UWI . %-43.43s:UNIVERSAL WELL INDEX\n"
|
||||
^
|
||||
las_constants.go:31:2: `_LasCurvFormat` is unused (deadcode)
|
||||
_LasCurvFormat = "#MNEM.UNIT :DESCRIPTION\n"
|
||||
^
|
||||
las_warning.go:13:2: `directOnWrite` is unused (deadcode)
|
||||
directOnWrite = 2
|
||||
^
|
||||
las_summary_test.go:25:2: `werr` is unused (structcheck)
|
||||
werr bool //не используется
|
||||
^
|
||||
las_test.go:73:5: ineffectual assignment to `err` (ineffassign)
|
||||
f, err := os.Create(fp.Join("data/w1_more_20_warnings.txt"))
|
||||
^
|
||||
las_checker.go:102:28: S1019: should use make(CheckResults) instead (gosimple)
|
||||
res := make(CheckResults, 0)
|
||||
^
|
||||
las_logger.go:102:23: func `(*tMMnemonic).save` is unused (unused)
|
||||
las_checker.go:74:25: func `CheckResults.isFatal` is unused (unused)
|
||||
las_logger.go:48:21: func `(*tCheckMsg).save` is unused (unused)
|
||||
las_logger.go:79:22: func `(*tCurvRprt).save` is unused (unused)
|
2
ver.txt
2
ver.txt
|
@ -1 +1 @@
|
|||
0.2.3
|
||||
0.2.4
|
||||
|
|
Загрузка…
Ссылка в новой задаче