This describes the LIS LogPass class that encapsulates a Log Pass.
The LogPass module is located in TotalDepth/src/TotalDepth/LIS/core and can be imported thus:
from TotalDepth.LIS.core import LogPass
The LogPass module contains a single class LogPass that is fundamental to the way that TotalDepth handles LIS binary data.
A Log Pass is defined as a single continuous recording of log data. “Main Log”, “Repeat Section” are seperate examples of Log Pass(es).
Event to extrapolate X axis
Event to read bytes from frame
Event to seek to the start of a new Logical Record
Event to skip bytes in frame
Specialisation of exception for LogPass.
Specialisation of exception for LogPass __init__().
Raised when and internal KeyError is raised in a FrameSet access.
Raised when FrameSet access is required but there has been no call to setFrameSet().
Raised on access when there is no frame data loaded by addType01Data().
Contains the information about a log pass which is defined as a LIS Data Format Specification Record (DFSR) plus any number of Type 0/1 Logical Records.
A LogPass must be created with a LIS DFSR and a LIS file ID. It can be then informed with addType01Data() which records the file positions of Type 0/1 records. When required the actual frame data can be populated with setFrameSet().
theDfsr - The DFSR.
theFileId - The ID of the file, this will be checked against any File object passed to me.
xAxisIndex - The index of the DSB block that describes the X axis, if indirect X this is ignored.
Add an Type 0/1 logical record entry.
tellLr - the Logical Record start position in the file.
lrType - the type of the IFLR. Will raise an ExceptionLogPass if this does not match the DFSR.
lrLen - the length of the Logical record, not including the LRH.
xAxisVal - the value of the X Axis of the first frame of the Logical Record.
Given a curve as a Mnem.Mnem() this returns the units as a bytes object.
Given a curve as a Mnem.Mnem() this returns the units as a string.
The DFSR used for construction.
Returns the estimated frame number from the X axis, and EngValue.
The Frame Set as a FrameSet.FrameSet() object or None if not initialised.
Returns a long (multiline) descriptive string of the Frame Set or N/A if not initialised.
This generates a name and units for each value in a frame in the current frame set. It is useful for heading up a frame dump.
This generates a name and units for sub-channel in a frame in the current frame set. It is useful for heading up a accumulate() dump.
Wrapper around the frameset generator, in fact this returns exactly that generator.
Returns True is theMnem is in this LogPass (i.e. is in the DFSR).
Returns the IFLR type that this LogPass describes.
True if indirect X axis, False if explicit X axis channel.
Returns a long (multiline) descriptive string.
The NULL or absent value as specified in the DFSR.
The number of bytes in the underlying frame set (i.e. LIS) representation for the curve data. Returns None if the frame set is not initialised.
Returns all of the OUTP Mnems in this LogPass (i.e. is in the DFSR).
Returns a sorted, unique list of external channel indexes for a list of mnemonics. May raise a ExceptionLogPassKeyError.
The Logical Record Run Length Encoding as a Rle.RLEType01() object.
Populates the frames set.
theFile - The File object. Will raise an ExceptionLogPass is the file ID does not match that in the constructor.
theFrSl - A slice object that describes when LogPass frames are to be used (default all). Will raise an ExceptionLogPass is there are no frames to load i.e. addType01Data() has not been called.
theChList - A list of external channel indexes (i.e. DSB block indexes) to populate the frame set with (default all).
Loads a FramesSet using ‘external’ values from a File object. theChS is a list of channel mnemonics or None for all channels. Xstart, Xstop are EngVal of the start stop. frStep is not number of frames to step over, default means all frames.
The total number of frames.
The Frame plan, a Type01Plan.FrameSetPlan() object.
The EngVal (value, units) of the X axis of the first frame.
The numerical value of the X axis of the first frame.
The numerical value of the X axis of the first frame in ‘optical’ units.
The channel index that corresponds to the X axis.
The EngVal (value, units) of the X axis of the first frame.
The numerical value of the X axis of the last frame.
The numerical value of the X axis of the last frame in ‘optical’ units.
The numerical value of the X axis frame spacing. This is is the extreme range of X axis values divided by the number of frames - 1. This is +ve if the Xaxis increases, -ve if it decreases.
The numerical value of the X axis frame spacing. This is is the extreme range of X axis values divided by the number of frames - 1.
The units of the X axis.
Returns the actual units to ‘optical’ i.e. user friendly units. For example if the Xaxis was in b’.1IN’ the ‘optical’ units would be b’FEET”.
Typically a LogPass will be created directly or via a LIS FileIndexer. The latter technique is recommended as it is simpler.
LogPass objects are used via a three step process and this reflects the sequential process of reading a LIS file:
A LogPass object needs to be constructed with an instance of a LogiRec.LrDFSRRead. The LogPass will take a reference to the DFSR so the caller need not. The caller can always access the DFSR with the .dfsr property.
Assuming myF is a LIS File object positioned at the start of the DFSR:
myLp = LogPass.LogPass(LogiRec.LrDFSRRead(myF), 'FileID')
At this stage no FrameSet is created so the resource usage is minimal.
The method addType01Data(tellLr, lrType, lrLen, xAxisVal) adds the position of an IFLR that contain frame data. This method takes these arguments:
Argument | Description |
---|---|
tellLr | The Logical Record start position (as a size_t) in the file. |
lrType | The type of the IFLR [0 | 1]. Will raise an ExceptionLogPass if this does not match the DFSR. |
lrLen | The length of the Logical Record in bytes, not including the LRH. |
xAxisVal | The value of the X Axis as a number of the first frame of the Logical Record. |
This call should be made for each relevant IFLR as they are encountered in sequence.
At this stage no FrameSet is created and the arguments are encoded into an RLE object so the resource usage is minimal.
Once the preceding stages have been done the LogPass can be populated any number of times from the LIS file.
The method setFrameSet(theFile, theFrSl=None, theChList=None) constructs a new frame set with the appropriate values.
Argument | Description |
---|---|
theFile | The File object. Will raise an ExceptionLogPass is the file ID does not match that used in the constructor. |
theFrSl | A slice object that describes when LogPass frames are to be used (default all). Will raise an ExceptionLogPass if there are no frames to load i.e. addType01Data() has not been called. |
theChList | A list of external channel indexes (i.e. DSB block indexes) to populate the frame set with (default all). |
Setting a frame set for all frames and all channels:
myLogPass.setFrameSet(myFile)
# The above line is equivalent to:
myLogPass.setFrameSet(myFile, theFrSl=None, theChList=None)
Setting a frame set for frames [0:16:4] i.e. frame indexes (0,4,8,12) and channels [0, 4, 7]
myLogPass.setFrameSet(myFile, theFrSl=slice(0,16,4), theChList=[0, 4, 7])
Any previous FrameSet will be freed and a new FrameSet of the appropriate dimension is created so the resource usage can be significant.
A FileIndexer [TotalDepth.LIS.core.FileIndexer.FileIndex] object will perform the necessary construction of a LogPass and the population with Logical Record positions with addType01Data() leaving the user just to call setFrameSet(). Thus a FileIndex object imposes low resource usage until the user wishes to populate the frame set.
An indexer will index a LIS file that has multiple Log Passes (e.g. repeat section, main log etc.) so the indexer provides an iteration method for Log Passes:
myFilePath = "Spam/Eggs.LIS"
# Open a LIS file, keepGoing for luck!
myFi = File.FileRead(myFilePath, theFileId=myFilePath, keepGoing=True)
# Index the LIS file
myIdx = FileIndexer.FileIndex(myFi)
# Ask the index for all the LogPass objects, these do not have the frameSet populated yet
for aLp in myIdx.genLogPasses():
# Load the FrameSet, all channels [None], all frames [None]
aLp.logPass.setFrameSet(myFi, None, None)
# The FrameSet is fully populated here...
# Do something with it...
The unit tests are in test/TestLogPass.py. This should take under a second to execute.
Running the tests under coverage:
$ coverage run test/TestLogPass.py
TestClass.py script version "0.8.0", dated 10 Jan 2011
Author: Paul Ross
Copyright (c) Paul Ross
testSetUpTearDown (__main__.TestLogPass_LowLevel)
TestLogPass_LowLevel: Tests setUp() and tearDown(). ... ok
test_00 (__main__.TestLogPass_LowLevel)
TestLogPass_LowLevel.test_00(): Construction. ... ok
test_01 (__main__.TestLogPass_LowLevel)
TestLogPass_LowLevel.test_01(): _sliceFromList(). ... ok
test_02 (__main__.TestLogPass_LowLevel)
TestLogPass_LowLevel.test_02(): exercise various properties. ... ok
test_10 (__main__.TestLogPass_LowLevel)
TestLogPass_LowLevel.test_10(): nullValue(). ... ok
8<-------------- snip ------------------>8
test_00 (__main__.TestLogPass_UpIndirect)
TestLogPass_UpIndirect.test_00(): 3 LR, 5 fr, 4 ch. setFrameSet() All. ... ok
test_01 (__main__.TestLogPass_UpIndirect)
TestLogPass_UpIndirect.test_01(): 3 LR, 5 fr, 4 ch. setFrameSet() theFrSl=slice(0,16,2). ... ok
test_02 (__main__.TestLogPass_UpIndirect)
TestLogPass_UpIndirect.test_02(): 3 LR, 5 fr, 4 ch. setFrameSet() theFrSl=slice(2,4,2). ... ok
test_03 (__main__.TestLogPass_UpIndirect)
TestLogPass_UpIndirect.test_03(): 3 LR, 5 fr, 4 ch. setFrameSet() theFrSl=slice(1,5,2). ... ok
test_10 (__main__.TestLogPass_UpIndirect)
TestLogPass_UpIndirect.test_10(): genFrameSetHeadings() ... ok
----------------------------------------------------------------------
Ran 54 tests in 0.507s
OK
CPU time = 0.510 (S)
Bye, bye!
$ coverage report -m
Name Stmts Miss Cover Missing
----------------------------------------------------------------------------------------------------------
8<-------------- snip ------------------>8
LogPass 273 27 90% 142, 167, 182, 187, 203, 216-218, 232, 258, 273-275, 319, 324, 412, 416, 457-459, 513, 527, 541, 557, 572, 646-647
8<-------------- snip ------------------>8
----------------------------------------------------------------------------------------------------------
TOTAL 4586 1783 61%