LAS files are flat ASCII files that can easily be read using any text editor, whereas DLIS files are structured binary files containing tables of information about the logging environment as well as the logging data. DLIS files are much harder to work with and can’t easily be opened in a text editor, which can hinder understanding what is contained within them.
Luckily, a couple of great Python libraries have been developed, making accessing data from LAS and DLIS files much easier.
lasio is a library designed to easily read and work with LAS files, even those with any issues resulting from improper formatting or other errors.
dlsio is a Python library developed by Equinor ASA to read DLIS files and Log Information Standard 79 (LIS79) files. The library has been designed to reduce the burden and effort of exploring these files without having a detailed understanding of the DLIS structure.
Using these two libraries, we will explore how to extract data from a DLIS file and export it to a LAS file. This will allow us to create a file format that with much easier to work with and also smaller in file size as it will contain the relevant data we need.
If you want to see other articles on how to work with these file formats, the following may be of interest:
- Loading Multiple Well Log LAS Files Using Python
- Convert CSV Files to LAS files with Python
- Exploring the Contents of DLIS Files with Python
- Loading Well Log Data From DLIS using Python
Importing Libraries and Loading Data
For this tutorial, we are going to need two main libraries. DLISIO allows us to read and work with the contents of DLIS files, and LASIO, which allows us to work with LAS files.
from dlisio import dlis
After importing the libraries, we next to read the DLIS file. This is done using the following syntax.
f, *tail = dlis.load('Data/NLOG Data/NPN_TVN-1_23_Dec_2009_E3_Main_SONIC_057PUC.DLIS')
As DLIS files can contain multiple logical files (representing different logging passes or different levels of processing), we need to separate these out into two variables:
*tail. If there are multiple logical files, the first one will be placed into the
f variable, and the remainder will be placed in the
We can apply similar logic to extract the origin information from the selected logical file. As this file contains a single origin, we can call upon the
describe method on the
origin, *origin_tail = f.origins origin.describe()
When we run the above code, we get back the following summary detailing the origins of this dataset. We will be able to use this information when we build our LAS file.
Creating a LAS File
Before we begin extracting data, we first need to create a blank LAS file object. This can be done like so:
las_file = lasio.LASFile()
Once the file has been created, we can confirm it is blank by calling upon the following.las_file.curves
This will return an empty list (
 ), which is what we need at this stage.
In order to make things easier for ourselves, we can extract some key information from the DLIS file to variables. In this example, we will extract the well name, the field name and the operating company.
If we were looking to make this code reusable, this is one way to do it and avoids you having to provide that information manually each and every time.
well_name = origin.well_name
field_name = origin.field_name
operator = origin.company
Now that we have the key information in variable form, we can start populating our LAS file header. This is done by accessing the key properties from the LAS file and setting the
HeaderItem to the new values.
You will notice that we have manually added a date, as this property does not appear to be exposed by DLISIO.
las_file.well['WELL'] = lasio.HeaderItem('WELL', value=well_name)
las_file.well['FLD'] = lasio.HeaderItem('FLD', value=field_name)
las_file.well['COMP'] = lasio.HeaderItem('COMP', value=operator)
las_file.well['DATE'] = '2009-12-23'
Extracting Data from DLIS and Writing it to LAS Format
As DLIS files can contain vast numbers of logging curves and arrays, we may want to consider extracting a small selection of the data. This prevents us from being overwhelmed by too many irrelevant curves for our intended use case.
For this example, we will extract the following curves.
Note that we need to extract the ‘TDEP’ curve, which is our primary reference depth curve.
columns_to_extract = ['TDEP', 'BS', 'DT', 'DTSM', 'VPVS']
Now that we have prepared our LAS file and extracted the header data from the DLIS file, we can now loop through the channels within a frame in the DLIS.
For this example, we will access content within the first frame. If you want to see how to check the contents of DLIS files (this file in particular), you can find out how to do that in the article below.
Also, the following code assumes that all curves have a single dimension. I.e. no borehole image array data or acoustic waveforms. Again, I recommend checking my previous article for one way to handle this.
frame = f.frames for channel in frame.channels: # If the channel name is in the list of channels to extract if channel.name in columns_to_extract: curves = channel.curves() # If the channel name is 'TDEP', convert to 'DEPT' if channel.name == 'TDEP': channel_name = 'DEPT' description = 'DEPTH' # If the units are 0.1 in then convert to metres if channel.units == '0.1 in': curves = curves * 0.00254 unit = 'm' else: unit = channel.units else: description = channel.long_name channel_name = channel.name unit = channel.units # Add the data to the LAS file las_file.append_curve( channel_name, curves, unit=unit, descr=description )
As you can see in the code above, we essentially loop through all available channels (curves) within the selected frame and check if their names match the ones we are trying to select.
If we come across a curve on our list, we first check if it is the TDEP (depth) curve; if it is, we need to make a few minor adjustments. This involves changing the name to DEPT, and checking if the units are in 0.1 in. If they are, we need to convert the depth units to metres.
Once we have checked if we have a depth curve, all other curves will be extracted using their stored information.
After the curve has been checked, we can append it to the LAS file object and pass in the relevant information.
Once the LAS object has been created, we can check that our curve information has been passed over by using the following call.
This will return the following list with the information for each curve. We can see that the names, units, and descriptions have all been added successfully, and based on the shape of the data, we can assume that the data values have been passed over as well.
Now that we have the header information and curve data setup, we can begin writing out our LAS file using the following command.
If no errors are created when writing, we can open the LAS file in our favourite text editor. When we do this, we should see the following file.
You will notice that we still have missing information within the header section. This can be edited directly within the text editor, or you can use additional code to ensure these parameters are written out like what we did with the date.
You will also notice that the depth range is inverted, which is normal with some LAS files. Your favourite petrophysics software package should easily read it.
If we want further confirmation that our file has been created correctly, we can load it back into our notebook using the
new_las = lasio.read('output.las')
When we view the header sections of the LAS file, we get back the following output, which confirms that the data has been read correctly.
This tutorial shows how we can easily convert data stored within a DLIS file to a more readable LAS file format. This was achieved using two very popular Python libraries: DLISIO and LASIO.
The process illustrated here mainly applies to single-dimension logging curves. Any array data or high-resolution data needs to be assessed differently.
Data Used In this Tutorial
Data from NLOG.nl is free to download and use. Full details of the data licence can be found here, but a summary of the usage is provided here from the Intellectual Property Rights section:
NLOG.NL does not claim any rights (except domain names, trademark rights, patents and other intellectual property rights) in respect of information provided on or through this website. Users are permitted to copy, to download and to disclose in any way, to distribute or to simplify the information provided on this website without the prior written permission of NLOG.NL or the lawful consent of the entitled party. Users are also permitted to copy, duplicate, process or edit the information and/or layout, provided NLOG.NL is quoted as the source.