зеркало из https://github.com/softlandia/glasio.git
v0.2.3
This commit is contained in:
Родитель
f2ff4d7df5
Коммит
d236bf29cd
6
HIST.md
6
HIST.md
|
@ -1,4 +1,8 @@
|
|||
## ver 0.2.2 // 2020.06.25 ##
|
||||
## ver 0.2.3 // 2020.06.28 ##
|
||||
|
||||
- все тесты проходят, версия подготовленная к переходу от прямых параметров к использованию хранящихся в специализированных контейнерах
|
||||
|
||||
## ver 0.2.2 // 2020.06.25 ##
|
||||
|
||||
- read all parameters to section containers / чтение всех параметров из заголовка в соответствующие контейнеры
|
||||
- пока только чтение и хранение, в работе не используется
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
**file: data\more_20_warnings.las**
|
||||
0, line: 24, "__WRN__ STEP parameter equal 0"
|
||||
1, line: 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
0, line: 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
1, line: 24, "__WRN__ STEP parameter equal 0"
|
||||
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,5 +1,5 @@
|
|||
line: 24, "__WRN__ STEP parameter equal 0"
|
||||
line: 24, "__WRN__ STRT: 0.000 == STOP: 0.000"
|
||||
line: 24, "__WRN__ STEP parameter equal 0"
|
||||
line: 24, "error convert string: '6.2.24' to number, set to NULL"
|
||||
line: 25, "line contains 5 columns, expected: 6"
|
||||
line: 25, "error convert string: '528.07202215.58' to number, set to NULL"
|
||||
|
|
239
las.go
239
las.go
|
@ -70,12 +70,72 @@ var (
|
|||
MaxWarningCount int = 20
|
||||
)
|
||||
|
||||
//method for get values from header containers ////////////////
|
||||
|
||||
func (las *Las) parFloat(name string, defValue float64) float64 {
|
||||
v := defValue
|
||||
if p, ok := las.VerSec.params[name]; ok {
|
||||
v, _ = strconv.ParseFloat(p.Val, 64)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (las *Las) parStr(name, defValue string) string {
|
||||
v := defValue
|
||||
if p, ok := las.VerSec.params[name]; ok {
|
||||
v = p.Val
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// WRAP - return wrap parameter of las file
|
||||
// if parameter not exist, then return "NO"
|
||||
func (las *Las) WRAP() string {
|
||||
return las.parStr("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", "--")
|
||||
}
|
||||
|
||||
//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
|
||||
las.Ver = 2.0 //<VER>
|
||||
las.Wrap = "NO"
|
||||
las.nRows = ExpPoints
|
||||
las.rows = make([]string, 0, las.nRows)
|
||||
|
@ -104,99 +164,11 @@ func NewLas(outputCP ...cpd.IDCodePage) *Las {
|
|||
return las
|
||||
}
|
||||
|
||||
// selectSection - analize first char after ~
|
||||
// ~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
|
||||
}
|
||||
}
|
||||
|
||||
// IsWraped - return true if WRAP == YES
|
||||
func (las *Las) IsWraped() bool {
|
||||
return strings.Contains(strings.ToUpper(las.Wrap), "Y")
|
||||
}
|
||||
|
||||
// SaveWarning - save to file all warning
|
||||
func (las *Las) SaveWarning(fileName string) error {
|
||||
if las.Warnings.Count() == 0 {
|
||||
return nil
|
||||
}
|
||||
oFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
las.SaveWarningToFile(oFile)
|
||||
oFile.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveWarningToWriter - store all warning to writer, return count lines writed to
|
||||
func (las *Las) SaveWarningToWriter(writer *bufio.Writer) int {
|
||||
n := las.Warnings.Count()
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
for _, w := range las.Warnings {
|
||||
writer.WriteString(w.String())
|
||||
writer.WriteString("\n")
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// SaveWarningToFile - store all warning to file, file not close. return count warning writed
|
||||
func (las *Las) SaveWarningToFile(oFile *os.File) int {
|
||||
if oFile == nil {
|
||||
return 0
|
||||
}
|
||||
if las.Warnings.Count() == 0 {
|
||||
return 0
|
||||
}
|
||||
oFile.WriteString("**file: " + las.FileName + "**\n")
|
||||
n := las.Warnings.SaveWarningToFile(oFile)
|
||||
oFile.WriteString("\n")
|
||||
return n
|
||||
}
|
||||
|
||||
func (las *Las) addWarning(w TWarning) {
|
||||
if las.Warnings.Count() < las.maxWarningCount {
|
||||
las.Warnings = append(las.Warnings, w)
|
||||
if las.Warnings.Count() == las.maxWarningCount {
|
||||
las.Warnings = append(las.Warnings, TWarning{0, 0, -1, "*maximum count* of warning reached, change parameter 'maxWarningCount' in 'glas.ini'"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetMnemonic - return Mnemonic from dictionary by Log Name,
|
||||
// if Mnemonic not found return ""
|
||||
// if Dictionary is nil, then return ""
|
||||
func (las *Las) GetMnemonic(logName string) string {
|
||||
if (las.LogDic == nil) || (las.VocDic == nil) {
|
||||
return "" //"-"
|
||||
}
|
||||
_, ok := (*las.LogDic)[logName]
|
||||
if ok { //GOOD - название каротажа равно мнемонике
|
||||
return logName
|
||||
}
|
||||
v, ok := (*las.VocDic)[logName]
|
||||
if ok { //POOR - название загружаемого каротажа найдено в словаре подстановок, мнемоника найдена
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetRows - get internal field 'rows'
|
||||
func (las *Las) GetRows() []string {
|
||||
return las.rows
|
||||
|
@ -292,6 +264,7 @@ func (las *Las) LoadHeader() (int, error) {
|
|||
//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)
|
||||
sec.params[p.Name] = p
|
||||
if err != nil {
|
||||
las.addWarning(TWarning{directOnRead, secNum, i, fmt.Sprintf("param: '%s' error: %v", s, err)})
|
||||
|
@ -300,6 +273,26 @@ func (las *Las) LoadHeader() (int, error) {
|
|||
return las.currentLine, nil
|
||||
}
|
||||
|
||||
// selectSection - analize first char after ~
|
||||
// ~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
|
||||
|
@ -670,3 +663,71 @@ func (las *Las) SetNull(aNull float64) {
|
|||
}
|
||||
las.Null = aNull
|
||||
}
|
||||
|
||||
// SaveWarning - save to file all warning
|
||||
func (las *Las) SaveWarning(fileName string) error {
|
||||
if las.Warnings.Count() == 0 {
|
||||
return nil
|
||||
}
|
||||
oFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
las.SaveWarningToFile(oFile)
|
||||
oFile.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveWarningToWriter - store all warning to writer, return count lines writed to
|
||||
func (las *Las) SaveWarningToWriter(writer *bufio.Writer) int {
|
||||
n := las.Warnings.Count()
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
for _, w := range las.Warnings {
|
||||
writer.WriteString(w.String())
|
||||
writer.WriteString("\n")
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// SaveWarningToFile - store all warning to file, file not close. return count warning writed
|
||||
func (las *Las) SaveWarningToFile(oFile *os.File) int {
|
||||
if oFile == nil {
|
||||
return 0
|
||||
}
|
||||
if las.Warnings.Count() == 0 {
|
||||
return 0
|
||||
}
|
||||
oFile.WriteString("**file: " + las.FileName + "**\n")
|
||||
n := las.Warnings.SaveWarningToFile(oFile)
|
||||
oFile.WriteString("\n")
|
||||
return n
|
||||
}
|
||||
|
||||
func (las *Las) addWarning(w TWarning) {
|
||||
if las.Warnings.Count() < las.maxWarningCount {
|
||||
las.Warnings = append(las.Warnings, w)
|
||||
if las.Warnings.Count() == las.maxWarningCount {
|
||||
las.Warnings = append(las.Warnings, TWarning{0, 0, -1, "*maximum count* of warning reached, change parameter 'maxWarningCount' in 'glas.ini'"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetMnemonic - return Mnemonic from dictionary by Log Name,
|
||||
// if Mnemonic not found return ""
|
||||
// if Dictionary is nil, then return ""
|
||||
func (las *Las) GetMnemonic(logName string) string {
|
||||
if (las.LogDic == nil) || (las.VocDic == nil) {
|
||||
return "" //"-"
|
||||
}
|
||||
_, ok := (*las.LogDic)[logName]
|
||||
if ok { //GOOD - название каротажа равно мнемонике
|
||||
return logName
|
||||
}
|
||||
v, ok := (*las.VocDic)[logName]
|
||||
if ok { //POOR - название загружаемого каротажа найдено в словаре подстановок, мнемоника найдена
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
10
las_param.go
10
las_param.go
|
@ -34,6 +34,14 @@ type HeaderSection struct {
|
|||
parse ParseHeaderParam // function for parse one line
|
||||
}
|
||||
|
||||
// uniqueName - return unique name
|
||||
func (hs HeaderSection) uniqueName(name string) string {
|
||||
if _, ok := hs.params[name]; ok {
|
||||
return name + strconv.Itoa(len(hs.params))
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// ParseHeaderParam - function to parse one line of header
|
||||
// return new of added parameter and warning
|
||||
// on success TWarning.Empty() == true
|
||||
|
@ -92,7 +100,7 @@ func NewWelSection() HeaderSection {
|
|||
}
|
||||
|
||||
// welParse12 - parse string and create parameter of section ~W
|
||||
// this version for las version less then 2.0
|
||||
// this version for las version 1.2
|
||||
func welParse12(s string, i int) (HeaderParam, TWarning) {
|
||||
p := NewHeaderParam(s, i)
|
||||
if p.Name == "WELL" {
|
||||
|
|
|
@ -64,7 +64,9 @@ func TestSummaryRead(t *testing.T) {
|
|||
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.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))
|
||||
|
|
|
@ -295,11 +295,12 @@ type tSecFill struct {
|
|||
well,
|
||||
null,
|
||||
ver,
|
||||
wrap string //версия las файла
|
||||
wrap string
|
||||
nCurvs int
|
||||
}
|
||||
|
||||
var dSecFill = []tSecFill{
|
||||
{fp.Join("data/expand_points_01.las"), 7, "12-Сплошная", "-9999.00", "1.20", "NO"},
|
||||
{fp.Join("data/expand_points_01.las"), 7, "12-Сплошная", "-9999.00", "1.20", "NO", 4},
|
||||
}
|
||||
|
||||
func TestSection(t *testing.T) {
|
||||
|
@ -313,5 +314,6 @@ func TestSection(t *testing.T) {
|
|||
assert.Equal(t, tmp.wrap, las.VerSec.params["WRAP"].Val)
|
||||
assert.Equal(t, tmp.null, las.WelSec.params["NULL"].Val)
|
||||
assert.Equal(t, tmp.well, las.WelSec.params["WELL"].Val)
|
||||
assert.Equal(t, tmp.nCurvs, len(las.CurSec.params))
|
||||
}
|
||||
}
|
||||
|
|
2
ver.txt
2
ver.txt
|
@ -1 +1 @@
|
|||
0.2.2
|
||||
0.2.3
|
||||
|
|
Загрузка…
Ссылка в новой задаче