Существует ли пакет R для анализа геофизических файлов "Log Ascii Standard" (файлы.las)?

Существует ли пакет R, который может читать файлы.las, т.е. стандартные файлы Schlumberger Log Ascii?
Он должен быть способен читать файлы las 2.0.

Пожалуйста, обратите внимание:

  • Я не говорю о файлах LIDAR .las здесь.
  • Я говорю о геофизических файлах регистрации скважин (а не файлов регистрации для компьютерных приложений, демонов и т. П.)

Поиск R и Las и Logfiles в интернете дает мне слишком много красных селедок.

Обновления от комментариев:

Я также рассматриваю сценарии или API, которые могли бы использовать языковые привязки для R.

Пока я нашел следующие скрипты:

Однако все эти сценарии пока кажутся мне не очень зрелыми.

Существует также бесплатный программный пакет "Log Data Toolbox " от Schlumberger, но он работает только под Windows и может иметь проблемы совместимости с неанглийскими версиями Windows (если я правильно помню).

Существует сложный Java-апплет из Канзасской геологической службы, но он немного вялый для больших входных файлов.las.

Есть проект ruby и проект python. Также, смотрите эту ссылку для хорошего набора примеров файлов las.

3 ответа

Отвечая на мой собственный вопрос:

Теперь есть библиотека Python, lasio, которая работает довольно хорошо. Он может быть вызван из R, возможно через функцию system2(); и вывод может быть извлечен в R структур данных. Другой возможностью было бы сериализовать объекты lasfile в JSON, сохранить в файл и повторно импортировать из R. Возможно, я дополню этот ответ примером кода, но сейчас у меня нет времени.

Ответ 2020:

lastools - это пакет R на github, который читает файлы Log Ascii Standard v2.0.

Он также обеспечивает базовое построение и запись в файл формата las.

Для установки из командной строки r (можно установить и другими способами):

devtools::install_github("Gitmaxwell/lastools")

Пример загрузки lastools, чтения las-файла и отображения содержимого в R:

library(lastools)
las_file <- "your-sample.las"
las <- read_las(las_file)
print(las)

Я сделал для моего личного (подходит для моих целей) использовать программу чтения логов журнала las2. Он состоит из 2 шагов: 1. создать список файлов *.las для чтения и добавления 2. прочитать количество файлов *.las и добавить в один фрейм данных. Оба кода протестированы на наборе файлов *.las, созданных из стандартных коммерческих пакетов в 2016 году - в Windows 10 под R 3.2.4 (64-битная версия)

Code-1 для чтения и создания простого списка файлов *.las файлов для запуска Code-2

# Read the file having list of well-log LAS files
# Create a R-Object [wellname, path, filename] for LAS reader
# Create filelist from DOS prompt dir *.las > filelist.dat
# G Srikanth 29-May-2016
#
library(stringr)
defaultworkdir <- readline("What is the file path? ")
setwd(defaultworkdir)
welllistfile <- readline("What is the well list file? ")
listfilelines <- readLines(con = welllistfile, skipNul = TRUE)
#
#      search for "Directory of " to get the LAS data folder = lasfolder
#      search for "File(s)" to get the number of files = nlasfiles, linenumber
#      the data file names are before the "Files(s)" line = lasfilenames() char vector of length nlasfiles
#
oneline <- listfilelines[grep("Directory of ",listfilelines)]
lasfilepath <- sub(" Directory of ","",oneline)
oneline <- listfilelines[grep(" File",listfilelines)]
# modified from http://stackru.com/questions/2261079/how-to-trim-leading-and-trailing-whitespace-in-r
numberoflasfiles <- as.numeric(word(sub("^\\s+", "", oneline),1))

# file names occur from - to in the DOS list read-in
fromline <- as.numeric(grep(" File",listfilelines)) -numberoflasfiles

# extract the last word from the fromline - numberoflasfiles times and load into suitable data structure
#     tail(strsplit(oneline,split=" ")[[1]],1)   --- taken from 
#     http://stackru.com/questions/17658216/extract-last-word-in-string-in-r

lasfile <- c(1:numberoflasfiles)
for (n in 1 : numberoflasfiles) 
{
  oneline <- listfilelines[fromline]
  lasfile[n] <- tail(strsplit(oneline,split=" ")[[1]],1)
  fromline=fromline+1
}
# print (lasfile)
rm(fromline)
lasfile<- paste(lasfilepath,"\\",lasfile,sep="")
# print(lasfile)
# temp <- readLines(con=lasfile[1], skipNul = TRUE) 
#
save(lasfile,file="lasfiles.Rdat")

Code-2 Читает много *.las файлов и создает один фрейм данных

# Read the list of lasfiles to read
# open each las file and get data

# G Srikanth 29 May 2016

#                                                   install.packages("data.table")
# 1. set working directory and read the file list
library(stringr)
library(data.table)
defaultworkdir <- readline("What is the file path? ")
setwd(defaultworkdir)
lasfilelist <- readline("What is the well list file? ")
load(lasfilelist)
welllogdata <- data.frame()

#     load("lasfiles.Rdat")    name of saved file
#     determine number of well files
nwells <- length(lasfile)
uwi<-c(1:nwells)
# 2. Main read loop for each well las file in directory
for (wellno in 1:nwells)
{
  # 2a. Get uwi
  # 2b. Get curve names
  # 2c. Read the curve data

  # LAS files have all the headers within first 100 lines
  # read 100 lines into a vector
  headerlines <- readLines(con = lasfile[wellno], n=100L, ok=TRUE, skipNul = TRUE)
  # extract uwi  NOTE - many las files write only proper well name and not UWI. in such case replace UWI with WELL in next line
    oneline <- headerlines[grep(" UWI",headerlines)]
    # remove multiple spaces with gsub() extract 3rd word with word()
    #     ref: http://rfunction.com/archives/2354
    uwi[wellno]<-word(gsub("\\s+"," ",str_trim(oneline)),3)
  # extract curve information and data location
    #locate ~A  in the headerlines. This has the log names.
    oneline <- headerlines[grep("~A",headerlines)]# line having curves names
    oneline <- gsub("\\s+"," ",str_trim(oneline)) # trim leading trailing and extra blanks
    ncurves <- str_count(oneline, " ")
    # ncurves <- str_count(gsub("\\s+"," ",str_trim(headerlines[grep("~A",headerlines)]))," ")
    # The next record in data file is numeric las data.
    dataline <- as.numeric(grep("~A",headerlines)+1)
    curvenameline <- as.numeric(grep("~A",headerlines)- ncurves) 
    # curve names start at curvenameline and contine for ncurves. The first word in each line is curve name
    logname <- c(1:ncurves)
    for (nc in 1:ncurves)
    {
      logname[nc] <- word(gsub("\\s+"," ",str_trim(headerlines[curvenameline+(nc-1)])),1)
    }
  # read the data matrix from the line - dataline in the well las file
    # null value used in the las file
    lasnull <- word(gsub("\\s+"," ",str_trim(headerlines[grep(" NULL",headerlines)])),3)
    temp<- read.table(lasfile[wellno], header=F, na.strings=lasnull, skip=dataline-1, col.names = logname)
    temp <- merge(temp,uwi[wellno])
    names(temp) <- c(logname,"uwi")
  # concatenate this data into a single data-frame. use the lognames to merge.
    if (wellno == 1) welldata <- temp else welldata <- rbind.fill(welldata, temp)    #rbind doesnt merge with different names, Thanks to stackru!
        # to clean the logname vector between files
    rm(logname)
}
save(welldata,"welldata.Rdat")

Надеюсь, это полезно!

Пример файла *.las:

…
…
…
#MNEM           .UNIT                  API CODE            :DESCRIPTION
#----            ------          --------------            -----------------------------
DEPT            .ft                                        :                                                        Station Depth
INCL            .deg                                       :                                                        Hole inclination
AZIM            .deg                                       :                                                        Measured Azimuth
#-------------------------------------------------------------
#        DEPT         INCL         AZIM
~ASCII
0.00         0.00         0.00
36.00         0.33       123.98
126.00         0.17       183.28
218.00         0.19       202.04
308.00         0.24       191.24
398.00         0.21       198.60
495.00         0.02       179.55
…
…
…

Цель при чтении файла - игнорировать заголовок файла и копировать только те данные, которые пришли после (~ASCII) дополнительно строка заголовка каждого столбца. Таким образом, мы копируем весь файл и ищем в нем построчно, пока не достигнем строки (~ASCII), затем копируем строку перед ним (заголовок) и все, что было после него (данные), и мы удаляем строку (~ASCII).

Обратите внимание, что мы удаляем (#) символ из строки заголовка.

Последний шаг - преобразовать данные в таблицу, а затем записать их в виде файла CSV.

Полный код:

#remove all variables (cleanup)
rm(list=ls(all=TRUE))
gc()
MWD_filePath="MWD_file.las";
conn=file(MWD_filePath,open="r")
Ascii_txt=readLines(conn);
mwd_txt = 0;

for (i in 1:length(Ascii_txt)){
    if(Ascii_txt[i] == "~ASCII"){
    mwd_txt <- Ascii_txt[(i-1):length(Ascii_txt)]

    # remove (#) from the header line
    substr(mwd_txt[1], 1, 2) <- " ";

    # remove "~ASCII" line
    mwd_txt <- mwd_txt[-2]

    break;
    }

}
close(conn)
#mwd_txt;
mwd <- read.table(header = TRUE, text=mwd_txt);
#head(mwd)

#write the mwd data to file ... in CSV format
mwd_csv_file <- paste(MWD_filePath, ".csv", sep="");
write.csv(mwd, file = mwd_csv_file);
Другие вопросы по тегам