This commit is contained in:
softlandia 2020-05-20 03:31:08 +04:00
Родитель 547df2ae77
Коммит 95916aede5
11 изменённых файлов: 112 добавлений и 94 удалений

Просмотреть файл

@ -1,4 +1,10 @@
## ver 0.1.9 // 2020.05.19 ##
## ver 0.1.10 // 2020.05.20 ##
- make public fields to access dept slice LasCurve.D and data curve LasCurve.V
- make public las.SetActuallyNumberPoints(int)
- update example/simple
## ver 0.1.9 // 2020.05.19 ##
- minor refactoring

Просмотреть файл

@ -0,0 +1,9 @@
# simply #
this folder contains a very simple example of using softlandia / glasio to manipulate a LAS file
__function test1 ()__ reads the file "expand_points_01.las"
saves messages created upon opening to the file "expand_points_01.warning.las"
saves the repaired file "expand_points_01 + .las"
__function test2 ()__ creates a las object with one curve in memory, writes this object to the file "simple.las"

Просмотреть файл

@ -1,13 +0,0 @@
~VERSION INFORMATION
VERS. 2.0 :glas (c) softlandia@gmail.com
WRAP. NO : ONE LINE PER DEPTH STEP
~WELL INFORMATION
STRT.M 0.201 :START DEPTH
STOP.M 10.010 :STOP DEPTH
STEP.M 0.010 :STEP
NULL. -99.990 :NULL VALUE
WELL. <20>ਬ¥à­ ï-101/¡¨á :WELL
~Curve Information Section
DEPT.M :
~ASCII Log Data
# DEPT |

Просмотреть файл

@ -1,4 +1,4 @@
// glas
// glas
// Copyright 2018 softlandia@gmail.com
// Обработка las файлов. Построение словаря и замена мнемоник на справочные
@ -13,30 +13,15 @@ import (
"github.com/softlandia/glasio"
)
//============================================================================
func main() {
test1()
test2()
}
// write empty las file
func test2() {
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/бис"
curve := glasio.NewLasCurve("SP.mV :spontaniously")
las.Logs["SP"] = curve
curve.Init(0, "SP", "SP", 5)
err := las.Save("empty.las")
log.Printf("err: %v", err)
}
// read and write las files
// reads las file
// writes messages file
// and writes the repaired las files
func test1() {
//test file "1.las"
las := glasio.NewLas()
@ -54,3 +39,29 @@ func test1() {
las = nil
}
// writes simple las file
func test2() {
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/бис"
d := glasio.NewLasCurve("DEPT")
d.Init(0, "DEPT", "DEPT", 5)
sp := glasio.NewLasCurve("SP.mV :spontaniously")
sp.Init(1, "SP", "SP", 5)
for i := 0; i < 5; i++ {
d.D[i] = float64(i)
d.V[i] = float64(i) / 100
sp.D[i] = float64(i)
sp.V[i] = float64(i) / 100
}
las.Logs["DEPT"] = d
las.Logs["SP"] = sp
las.SetActuallyNumberPoints(5)
err := las.Save("empty.las")
log.Printf("err: %v", err)
}

57
las.go
Просмотреть файл

@ -64,7 +64,7 @@ type LasWellInfo struct {
wrap string
wellName string
null float64
oCodepage cpd.IDCodePage
oCodepage cpd.IDCodePage //TODO проверить нужно ли это поле
}
// Las - class to store las file
@ -151,9 +151,9 @@ func (las *Las) setStep(h float64) {
//SetNull - change parameter NULL in WELL INFO section and in all logs
func (las *Las) SetNull(aNull float64) error {
for _, l := range las.Logs { //loop by logs
for i := range l.log { //loop by dept step
if l.log[i] == las.Null {
l.log[i] = aNull
for i := range l.V { //loop by dept step
if l.V[i] == las.Null {
l.V[i] = aNull
}
}
}
@ -513,12 +513,12 @@ func (las *Las) expandDept(d *LasCurve) {
las.ePoints *= 2
//expand first log - dept
newDept := make([]float64, las.ePoints)
copy(newDept, d.dept)
d.dept = newDept
copy(newDept, d.D)
d.D = newDept
newLog := make([]float64, las.ePoints)
copy(newLog, d.dept)
d.log = newLog
copy(newLog, d.D)
d.V = newLog
las.Logs[d.Name] = *d
//loop over other logs
@ -527,12 +527,12 @@ func (las *Las) expandDept(d *LasCurve) {
for j := 1; j < n; j++ {
l, _ = las.logByIndex(j)
newDept := make([]float64, las.ePoints)
copy(newDept, l.dept)
l.dept = newDept
copy(newDept, l.D)
l.D = newDept
newLog := make([]float64, las.ePoints)
copy(newLog, l.log)
l.log = newLog
copy(newLog, l.V)
l.V = newLog
las.Logs[l.Name] = *l
}
}
@ -588,19 +588,19 @@ func (las *Las) ReadDataSec(fileName string) (int, error) {
i--
continue
}
d.dept[i] = dept
d.D[i] = dept
// проверка шага у первых двух точек данных и сравнение с параметром step
//TODO данную проверку следует делать через Checker
if i > 1 {
if math.Pow(((dept-d.dept[i-1])-las.Step), 2) > 0.1 {
las.addWarning(TWarning{directOnRead, lasSecData, las.currentLine, fmt.Sprintf("actual step %5.2f ≠ global STEP %5.2f", (dept - d.dept[i-1]), las.Step)})
if math.Pow(((dept-d.D[i-1])-las.Step), 2) > 0.1 {
las.addWarning(TWarning{directOnRead, lasSecData, las.currentLine, fmt.Sprintf("actual step %5.2f ≠ global STEP %5.2f", (dept - d.D[i-1]), las.Step)})
}
}
// проверка шага между точками [i-1, i] и точками [i-2, i-1] обнаружение немонотонности колонки глубин
if i > 2 {
if math.Pow(((dept-d.dept[i-1])-(d.dept[i-1]-d.dept[i-2])), 2) > 0.1 {
las.addWarning(TWarning{directOnRead, lasSecData, las.currentLine, fmt.Sprintf("step %5.2f ≠ previously step %5.2f", (dept - d.dept[i-1]), (d.dept[i-1] - d.dept[i-2]))})
dept = d.dept[i-1] + las.Step
if math.Pow(((dept-d.D[i-1])-(d.D[i-1]-d.D[i-2])), 2) > 0.1 {
las.addWarning(TWarning{directOnRead, lasSecData, las.currentLine, fmt.Sprintf("step %5.2f ≠ previously step %5.2f", (dept - d.D[i-1]), (d.D[i-1] - d.D[i-2]))})
dept = d.D[i-1] + las.Step
}
}
@ -627,8 +627,8 @@ func (las *Las) ReadDataSec(fileName string) (int, error) {
las.nPoints = i
return i, errors.New("internal ERROR, func (las *Las) readDataSec()::las.logByIndex(j) return error")
}
l.dept[i] = dept
l.log[i] = v
l.D[i] = dept
l.V[i] = v
s = strings.TrimSpace(s[iSpace+1:])
}
//остаток - последняя колонка
@ -642,12 +642,12 @@ func (las *Las) ReadDataSec(fileName string) (int, error) {
las.nPoints = i
return i, errors.New("internal ERROR, func (las *Las) readDataSec()::las.logByIndex(j) return error on last column")
}
l.dept[i] = dept
l.log[i] = v
l.D[i] = dept
l.V[i] = v
}
//i - actually readed lines and add (.) to data array
//crop logs to actually len
err = las.setActuallyNumberPoints(i)
err = las.SetActuallyNumberPoints(i)
if err != nil {
return 0, err
}
@ -659,16 +659,17 @@ func (las *Las) NumPoints() int {
return las.nPoints
}
//Dept - return slice of DEPT curve (first column)
// Dept - return slice of DEPT curve (first column)
func (las *Las) Dept() []float64 {
d, err := las.logByIndex(0)
if err != nil {
return nil
}
return d.dept
return d.D
}
func (las *Las) setActuallyNumberPoints(numPoints int) error {
// SetActuallyNumberPoints - crop all curve to numPoints count of data
func (las *Las) SetActuallyNumberPoints(numPoints int) error {
if numPoints <= 0 {
las.nPoints = 0
return errors.New("internal ERROR, func (las *Las) setActuallyNumberPoints(), actually number of points <= 0")
@ -757,14 +758,14 @@ func (las *Las) SaveToBuf(useMnemonic bool) ([]byte, error) {
fmt.Fprintf(&b, "%s\n", sb.String())
dept, _ := las.logByIndex(0)
for i := 0; i < las.nPoints; i++ { //loop by dept (.)
fmt.Fprintf(&b, "%-9.3f ", dept.dept[i])
fmt.Fprintf(&b, "%-9.3f ", dept.D[i])
for j := 1; j < n; j++ { //loop by logs
l, err = las.logByIndex(j)
if err != nil {
las.addWarning(TWarning{directOnWrite, lasSecData, i, "logByIndex() return error, log not found, panic"})
return nil, errors.New("logByIndex() return error, log not found, panic")
}
fmt.Fprintf(&b, "%-9.3f ", l.log[i])
fmt.Fprintf(&b, "%-9.3f ", l.V[i])
}
fmt.Fprintln(&b)
}

Просмотреть файл

@ -127,14 +127,14 @@ func NewLasParam(s string) *LasParam {
// по умолчанию строка параметра разбирается на 4 составляющие: "имя параметра, ед измерения, значение, коментарий"
// между точкой и двоеточием ожидается единица измерения и значение параметра
// для параметра WELL пробел после точки также разбивает строку на две: ед измерения и значение
// но ТОЛЬКО для этого параметра единица измерения не существет и делать этого не следует
// но ТОЛЬКО для этого параметра единица измерения не существует и делать этого не следует
// таким образом собираем обратно в одно значение то, что ВОЗМОЖНО разбилось
func wellNameFromParam(p *LasParam) string {
if len(p.Unit) == 0 {
return p.Val
}
if len(p.Val) == 0 {
return p.Unit
return p.Unit //TODO не тестируется
}
return p.Unit + " " + p.Val
}
@ -143,8 +143,8 @@ func wellNameFromParam(p *LasParam) string {
type LasCurve struct {
LasParam
Index int
dept []float64
log []float64
D []float64
V []float64
}
// Cmp - compare current curve with another
@ -158,15 +158,15 @@ func (o *LasCurve) Cmp(curve LasCurve) (res bool) {
//SetLen - crop logs to actually len
//new len must be > 0 and < exist length
func (o *LasCurve) SetLen(n int) {
if (n <= 0) || n >= len(o.dept) {
if (n <= 0) || n >= len(o.D) {
return
}
t := make([]float64, n)
copy(t, o.dept)
o.dept = t
copy(t, o.D)
o.D = t
t = make([]float64, n)
copy(t, o.log)
o.log = t
copy(t, o.V)
o.V = t
}
// Init - initialize LasCurve, set index, name, mnemonic, make slice for store data
@ -175,8 +175,8 @@ func (o *LasCurve) Init(index int, mnemonic, name string, size int) {
o.Index = index
o.Mnemonic = mnemonic
o.Name = name
o.dept = make([]float64, size)
o.log = make([]float64, size)
o.D = make([]float64, size)
o.V = make([]float64, size)
}
//NewLasCurve - create new object LasCurve
@ -201,11 +201,15 @@ func (o LasCurve) String() string {
type LasCurves map[string]LasCurve
// Text - return string represent all curves parameters: IName, Name, Unit etc
//TODO need realization
func (o LasCurves) Text() string {
return "-"
}
// Cmp - compare current curves container with another
// сравниваются:
// количество кривых в контейнере
// два хеша от строк с именами всех кривых
func (o LasCurves) Cmp(curves LasCurves) (res bool) {
res = (len(o) == len(curves))
if res {

Просмотреть файл

@ -185,32 +185,32 @@ func TestNewLasCurveFromString(t *testing.T) {
func TestLasCurveSetLen(t *testing.T) {
curve := NewLasCurve("SP.mV :self")
curve.Init(0, "SP", "SP", 5)
curve.dept[0] = 0.1
curve.dept[1] = 0.2
curve.dept[2] = 0.3
curve.dept[3] = 0.4
curve.dept[4] = 0.5
curve.D[0] = 0.1
curve.D[1] = 0.2
curve.D[2] = 0.3
curve.D[3] = 0.4
curve.D[4] = 0.5
curve.SetLen(3)
assert.Equal(t, 3, len(curve.dept))
assert.Equal(t, 3, len(curve.log))
assert.Equal(t, 0.3, curve.dept[2])
assert.Equal(t, 3, len(curve.D))
assert.Equal(t, 3, len(curve.V))
assert.Equal(t, 0.3, curve.D[2])
curve.SetLen(4) //nothing to do, size of data slice not change
assert.Equal(t, 3, len(curve.dept))
assert.Equal(t, 3, len(curve.log))
assert.Equal(t, 3, len(curve.D))
assert.Equal(t, 3, len(curve.V))
curve.SetLen(0) //nothing to do, size of data slice not change
assert.Equal(t, 3, len(curve.dept))
assert.Equal(t, 3, len(curve.log))
assert.Equal(t, 3, len(curve.D))
assert.Equal(t, 3, len(curve.V))
curve.SetLen(-5) //nothing to do, size of data slice not change
assert.Equal(t, 3, len(curve.dept))
assert.Equal(t, 3, len(curve.log))
assert.Equal(t, 3, len(curve.D))
assert.Equal(t, 3, len(curve.V))
curve.SetLen(2)
assert.Equal(t, 2, len(curve.dept))
assert.Equal(t, 2, len(curve.log))
assert.Equal(t, 0.2, curve.dept[1])
assert.Equal(t, 2, len(curve.D))
assert.Equal(t, 2, len(curve.V))
assert.Equal(t, 0.2, curve.D[1])
}
func TestLasCurveString(t *testing.T) {

Просмотреть файл

@ -98,7 +98,7 @@ func TestTabulatedData(t *testing.T) {
assert.True(t, cmpLas(correct, las))
assert.True(t, correct.Logs.Cmp(las.Logs))
l := las.Logs["NPHI"]
assert.Equal(t, 0.451, l.log[1])
assert.Equal(t, 0.451, l.V[1])
assert.Equal(t, "NPHI", l.Name)
}

Просмотреть файл

@ -202,8 +202,8 @@ func TestLasSetNull(t *testing.T) {
las.Open("-tmp.las")
assert.Equal(t, -999.25, las.Null)
log := las.Logs["аПС"]
assert.Equal(t, las.Null, log.log[2])
assert.Equal(t, las.Null, las.Logs["аПС2"].log[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))
}

Просмотреть файл

@ -60,7 +60,7 @@ func makeSampleLas(
curve = NewLasCurve("BK.ohmm :laterolog")
curve.Init(len(las.Logs), "BK", "LL3", las.GetExpectedPointsCount(las.Strt, las.Stop, las.Step))
las.Logs["BK"] = curve
las.setActuallyNumberPoints(5)
las.SetActuallyNumberPoints(5)
return las
}

Просмотреть файл

@ -1 +1 @@
0.1.9
0.1.10