spdv4

SPD V4 format driver and support functions

Write Driver Options

These are contained in the WRITESUPPORTEDOPTIONS module level variable.

Name Use
SCALING_BUT_NO_DATA_WARNING Warn when scaling set for a column that doesn’t get created. Defaults to True
HDF5_CHUNK_SIZE Set the HDF5 chunk size when creating columns. Defaults to 250.
pylidar.lidarformats.spdv4.GAIN_NAME = 'GAIN'

For storing in hdf5 attributes

pylidar.lidarformats.spdv4.HEADER_ARRAY_FIELDS = ('BANDWIDTHS', 'WAVELENGTHS', 'VERSION_SPD', 'VERSION_DATA', 'RGB_FIELD')

fields in the header that are actually arrays

pylidar.lidarformats.spdv4.HEADER_ESSENTIAL_FIELDS = ('SPATIAL_REFERENCE', 'VERSION_DATA')

VERSION_SPD always created by pylidar

pylidar.lidarformats.spdv4.HEADER_FIELDS = {'AZIMUTH_MAX': <type 'numpy.float64'>, 'AZIMUTH_MIN': <type 'numpy.float64'>, 'BANDWIDTHS': <type 'numpy.float32'>, 'BIN_SIZE': <type 'numpy.float32'>, 'BLOCK_SIZE_POINT': <type 'numpy.uint16'>, 'BLOCK_SIZE_PULSE': <type 'numpy.uint16'>, 'BLOCK_SIZE_RECEIVED': <type 'numpy.uint16'>, 'BLOCK_SIZE_TRANSMITTED': <type 'numpy.uint16'>, 'BLOCK_SIZE_WAVEFORM': <type 'numpy.uint16'>, 'CAPTURE_DATETIME': <type 'str'>, 'CREATION_DATETIME': <type 'str'>, 'FIELD_OF_VIEW': <type 'numpy.float32'>, 'GENERATING_SOFTWARE': <type 'str'>, 'HEIGHT_MAX': <type 'numpy.float32'>, 'HEIGHT_MIN': <type 'numpy.float32'>, 'INDEX_TLX': <type 'numpy.float64'>, 'INDEX_TLY': <type 'numpy.float64'>, 'INDEX_TYPE': <type 'numpy.uint16'>, 'NUMBER_BINS_X': <type 'numpy.uint32'>, 'NUMBER_BINS_Y': <type 'numpy.uint32'>, 'NUMBER_OF_POINTS': <type 'numpy.uint64'>, 'NUMBER_OF_PULSES': <type 'numpy.uint64'>, 'NUMBER_OF_WAVEFORMS': <type 'numpy.uint64'>, 'NUM_OF_WAVELENGTHS': <type 'numpy.uint16'>, 'POINT_DENSITY': <type 'numpy.float32'>, 'PULSE_ACROSS_TRACK_SPACING': <type 'numpy.float32'>, 'PULSE_ALONG_TRACK_SPACING': <type 'numpy.float32'>, 'PULSE_ANGULAR_SPACING_SCANLINE': <type 'numpy.float32'>, 'PULSE_ANGULAR_SPACING_SCANLINE_IDX': <type 'numpy.float32'>, 'PULSE_DENSITY': <type 'numpy.float32'>, 'PULSE_ENERGY': <type 'numpy.float32'>, 'PULSE_FOOTPRINT': <type 'numpy.float32'>, 'PULSE_INDEX_METHOD': <type 'numpy.uint16'>, 'RANGE_MAX': <type 'numpy.float32'>, 'RANGE_MIN': <type 'numpy.float32'>, 'RGB_FIELD': <type 'str'>, 'SCANLINE_IDX_MAX': <type 'numpy.uint32'>, 'SCANLINE_IDX_MIN': <type 'numpy.uint32'>, 'SCANLINE_MAX': <type 'numpy.uint16'>, 'SCANLINE_MIN': <type 'numpy.uint16'>, 'SENSOR_APERTURE_SIZE': <type 'numpy.float32'>, 'SENSOR_BEAM_DIVERGENCE': <type 'numpy.float32'>, 'SENSOR_BEAM_EXIT_DIAMETER': <type 'numpy.float32'>, 'SENSOR_HEIGHT': <type 'numpy.float32'>, 'SENSOR_MAX_SCAN_ANGLE': <type 'numpy.float32'>, 'SENSOR_PULSE_REPETITION_FREQ': <type 'numpy.float32'>, 'SENSOR_SCAN_RATE': <type 'numpy.float32'>, 'SENSOR_SPEED': <type 'numpy.float32'>, 'SENSOR_TEMPORAL_BIN_SPACING': <type 'numpy.float64'>, 'SPATIAL_REFERENCE': <type 'str'>, 'SYSTEM_IDENTIFIER': <type 'str'>, 'USER_META_DATA': <type 'str'>, 'VERSION_DATA': <type 'numpy.uint8'>, 'VERSION_SPD': <type 'numpy.uint8'>, 'WAVEFORM_BIT_RES': <type 'numpy.uint16'>, 'WAVELENGTHS': <type 'numpy.float32'>, 'X_MAX': <type 'numpy.float64'>, 'X_MIN': <type 'numpy.float64'>, 'Y_MAX': <type 'numpy.float64'>, 'Y_MIN': <type 'numpy.float64'>, 'ZENITH_MAX': <type 'numpy.float64'>, 'ZENITH_MIN': <type 'numpy.float64'>, 'Z_MAX': <type 'numpy.float64'>, 'Z_MIN': <type 'numpy.float64'>}

Header fields have defined type in SPDV4

pylidar.lidarformats.spdv4.HEADER_TRANSLATION_DICT = {1: 'NUMBER_OF_POINTS'}

Translation of header field names

pylidar.lidarformats.spdv4.NULL_NAME = 'NULL'

For storing in hdf5 attributes

pylidar.lidarformats.spdv4.OFFSET_NAME = 'OFFSET'

For storing in hdf5 attributes

pylidar.lidarformats.spdv4.POINTS_ESSENTIAL_FIELDS = ('X', 'Y', 'Z', 'CLASSIFICATION')

RETURN_NUMBER always created by pylidar

pylidar.lidarformats.spdv4.POINT_FIELDS = {'AMPLITUDE_RETURN': <type 'numpy.uint16'>, 'BLUE': <type 'numpy.uint16'>, 'CLASSIFICATION': <type 'numpy.uint8'>, 'DEVIATION': <type 'numpy.uint16'>, 'ECHO_TYPE': <type 'numpy.uint16'>, 'GREEN': <type 'numpy.uint16'>, 'HEIGHT': <type 'numpy.uint16'>, 'INTENSITY': <type 'numpy.uint16'>, 'NIR': <type 'numpy.uint16'>, 'POINT_FLAGS': <type 'numpy.uint8'>, 'POINT_WAVELENGTH_IDX': <type 'numpy.uint8'>, 'RANGE': <type 'numpy.uint32'>, 'RED': <type 'numpy.uint16'>, 'RETURN_NUMBER': <type 'numpy.uint8'>, 'RHO_APP': <type 'numpy.uint32'>, 'WIDTH_RETURN': <type 'numpy.uint16'>, 'X': <type 'numpy.uint32'>, 'Y': <type 'numpy.uint32'>, 'Z': <type 'numpy.uint32'>}

Thes fields have defined type

pylidar.lidarformats.spdv4.POINT_SCALED_FIELDS = ('X', 'Y', 'Z', 'HEIGHT', 'RANGE', 'INTENSITY', 'AMPLITUDE_RETURN', 'WIDTH_RETURN')

need scaling applied

pylidar.lidarformats.spdv4.PULSES_ESSENTIAL_FIELDS = ()

Note: PULSE_ID, NUMBER_OF_RETURNS and PTS_START_IDX always created by pylidar

pylidar.lidarformats.spdv4.PULSE_FIELDS = {'AMPLITUDE_PULSE': <type 'numpy.uint16'>, 'AZIMUTH': <type 'numpy.uint32'>, 'H_ORIGIN': <type 'numpy.uint32'>, 'NUMBER_OF_RETURNS': <type 'numpy.uint8'>, 'NUMBER_OF_WAVEFORM_SAMPLES': <type 'numpy.uint8'>, 'PRISM_FACET': <type 'numpy.uint8'>, 'PTS_START_IDX': <type 'numpy.uint64'>, 'PULSE_FLAGS': <type 'numpy.uint8'>, 'PULSE_ID': <type 'numpy.uint64'>, 'PULSE_WAVELENGTH_IDX': <type 'numpy.uint8'>, 'SCANLINE': <type 'numpy.uint32'>, 'SCANLINE_IDX': <type 'numpy.uint16'>, 'SCAN_ANGLE_RANK': <type 'numpy.int16'>, 'SOURCE_ID': <type 'numpy.uint16'>, 'TIMESTAMP': <type 'numpy.uint64'>, 'WFM_START_IDX': <type 'numpy.uint64'>, 'WIDTH_PULSE': <type 'numpy.uint16'>, 'X_IDX': <type 'numpy.uint32'>, 'X_ORIGIN': <type 'numpy.uint32'>, 'Y_IDX': <type 'numpy.uint32'>, 'Y_ORIGIN': <type 'numpy.uint32'>, 'ZENITH': <type 'numpy.uint32'>, 'Z_ORIGIN': <type 'numpy.uint32'>}

Thes fields have defined type

pylidar.lidarformats.spdv4.PULSE_SCALED_FIELDS = ('AZIMUTH', 'ZENITH', 'X_IDX', 'Y_IDX', 'X_ORIGIN', 'Y_ORIGIN', 'Z_ORIGIN', 'H_ORIGIN', 'AMPLITUDE_PULSE', 'WIDTH_PULSE')

need scaling applied

pylidar.lidarformats.spdv4.READSUPPORTEDOPTIONS = ()

driver options

pylidar.lidarformats.spdv4.RECEIVED_DTYPE

alias of numpy.uint32

class pylidar.lidarformats.spdv4.SPDV4File(fname, mode, controls, userClass)[source]

Class to support reading and writing of SPD Version 4.x files.

Uses h5py to handle access to the underlying HDF5 file.

close()[source]

Close all open file handles

createDataColumn(groupHandle, name, data)[source]

Creates a new data column under groupHandle with the given name with standard HDF5 params.

The type is the same as the numpy array data and data is written to the column

sets the chunk size to self.hdf5ChunkSize which can be overridden in the driver options.

static getDriverName()[source]

Name of this driver

getHeader()[source]

Return our attributes on the file

static getHeaderTranslationDict()[source]

Return dictionary with non-standard header names

getHeaderValue(name)[source]

Just extract the one value and return it

getNativeDataType(colName, arrayType)[source]

Return the native dtype (numpy.int16 etc)that a column is stored as internally after scaling is applied. Provided so scaling can be adjusted when translating between formats.

Note that for ‘non essential’ columns this will depend on the data type that the column was to begin with.

arrayType is one of the lidarprocessor.ARRAY_TYPE_* constants

getNullValue(colName, arrayType, scaled=True)[source]

Get the ‘null’ value for the given column.

arrayType is one of the lidarprocessor.ARRAY_TYPE_* constants

getPixelGrid()[source]

Return the PixelGridDefn for this file

getScaling(colName, arrayType)[source]

Returns the scaling (gain, offset) for the given column name reads from our cache since only written to file on close

Raises generic.LiDARArrayColumnError if no scaling (yet) set for this column.

getScalingColumns(arrayType)[source]

arrayType is one of the lidarprocessor.ARRAY_TYPE_* constants

getTotalNumberPulses()[source]

Return the total number of pulses

static getTranslationDict(arrayType)[source]

Translation dictionary between formats

hasSpatialIndex()[source]

Return True if we have a spatial index.

prepareDataForWriting(data, name, arrayType)[source]

Prepares data for writing to a field.

arrayType is one of the ARRAY_TYPE values from .generic.

Does unscaling if possible unless name ends with ‘_U’. Raises exception if column needs to have scale and offset defined, but aren’t.

Returns the data to write, plus the ‘hdfname’ which is the field name the data should be written to. This has the ‘_U’ removed.

preparePointsForWriting(points, mask)[source]

Called from writeData(). Massages what the user has passed into something we can write back to the file.

preparePulsesForWriting(pulses)[source]

Called from writeData(). Massages what the user has passed into something we can write back to the file.

prepareReceivedForWriting(received, waveformInfo)[source]

Called from writeData(). Massages what the user has passed into something we can write back to the file.

prepareTransmittedForWriting(transmitted, waveformInfo)[source]

Called from writeData(). Massages what the user has passed into something we can write back to the file.

prepareWaveformInfoForWriting(waveformInfo)[source]

Flattens the waveformInfo back out so it can be written

static readFieldAndUnScale(handle, name, selection, unScaled=False)[source]

Given a h5py handle, field name and selection does any unscaling if asked (unScaled=False).

static readFieldsAndUnScale(handle, colNames, selection)[source]

Given a list of column names returns a structured array of the data. If colNames is a string, a single un-structred array will be returned. It will work out of any of the column names end with ‘_U’ and deal with them appropriately. selection should be a h5space.H5Space.

readPointsByPulse(colNames=None)[source]

Return a 2d masked structured array of point that matches the pulses.

readPointsForExtent(colNames=None)[source]

Read all the points within the given extent as 1d structured array.

colNames can be a name or list of column names to return. By default all columns are returned.

readPointsForExtentByBins(extent=None, colNames=None, indexByPulse=False, returnPulseIndex=False)[source]

Return the points as a 3d structured masked array.

Note that because the spatial index on a SPDV4 file currently is on pulses this may miss points that are attached to pulses outside the current extent. If this is a problem then select an overlap large enough.

Pass indexByPulse=True to bin the points by the locations of the pulses
(using X_IDX and Y_IDX rather than the locations of the points) This is the default for non-cartesian indices.
Pass returnPulseIndex=True to also return a masked 3d array of
the indices into the 1d pulse array (as returned by readPulsesForExtent())
readPointsForRange(colNames=None)[source]

Read all the points for the specified range of pulses

readPulsesForExtent(colNames=None)[source]

Read all the pulses within the given extent as 1d structured array.

colNames can be a name or list of column names to return. By default all columns are returned.

readPulsesForExtentByBins(extent=None, colNames=None)[source]

Return the pulses as a 3d structured masked array.

readPulsesForRange(colNames=None)[source]

Read the specified range of pulses

readReceived()[source]

Return the 3d masked integer array of received for each of the current pulses. First axis is the waveform bin. Second axis is waveform number and last is pulse.

readTransmitted()[source]

Return the 3d masked integer array of transmitted for each of the current pulses. First axis is the waveform bin. Second axis is waveform number and last is pulse.

readWaveformInfo()[source]

Return 2d masked array of information about the waveforms.

setExtent(extent)[source]

Set the extent for reading or writing

setHeader(newHeaderDict)[source]

Update our cached dictionary

setHeaderValue(name, value)[source]

Just update one value in the header

setNativeDataType(colName, arrayType, dtype)[source]

Set the native dtype (numpy.int16 etc)that a column is stored as internally after scaling (if any) is applied.

arrayType is one of the lidarprocessor.ARRAY_TYPE_* constants

generic.LiDARArrayColumnError is raised if this cannot be set for the format.

The default behaviour is to create new columns in the correct type for the format, or if they are optional, in the same type as the input array.

setNullValue(colName, arrayType, value, scaled=True)[source]

Sets the ‘null’ value for the given column.

arrayType is one of the lidarprocessor.ARRAY_TYPE_* constants

We don’t write anything out at this stage as the scaling, if needed, mightn’t be set at this stage. The work is done when the file is closed.

setPixelGrid(pixGrid)[source]

Set the PixelGridDefn for the reading or writing

setPulseRange(pulseRange)[source]

Set the range of pulses to read

setScaling(colName, arrayType, gain, offset)[source]

Set the scaling for the given column name

updateHeaderFromData(points, pulses, waveformInfo)[source]

Given some data, updates the _MIN, _MAX etc

writeData(pulses=None, points=None, transmitted=None, received=None, waveformInfo=None)[source]

Write all the updated data. Pass None for data that do not need to be updated. It is assumed that each parameter has been read by the reading functions

writeStructuredArray(hdfHandle, structArray, generatedColumns, arrayType)[source]

Writes a structured array as named datasets under hdfHandle. Also writes columns in dictionary generatedColumns to the same place.

Only use for file creation.

class pylidar.lidarformats.spdv4.SPDV4FileInfo(fname)[source]

Class that gets information about a SPDV4 file and makes it available as fields.

static getDriverName()[source]

Name of this driver

static getHeaderTranslationDict()[source]

Return dictionary with non-standard header names

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_BRANCH = 11

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_BUILDING = 7

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_CREATED = 2

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_FOLIAGE = 10

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_GROUND = 3

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_HIGHVEGE = 6

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_LOWVEGE = 4

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_MEDVEGE = 5

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_RAIL = 13

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_TRUNK = 9

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_UNCLASSIFIED = 1

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_UNDEFINED = 0

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_WALL = 12

classification codes

pylidar.lidarformats.spdv4.SPDV4_CLASSIFICATION_WATER = 8

classification codes

pylidar.lidarformats.spdv4.SPDV4_INDEXTYPE_SIMPLEGRID = 0

types of spatial indices

pylidar.lidarformats.spdv4.SPDV4_INDEX_CARTESIAN = 1

types of indexing in the file

pylidar.lidarformats.spdv4.SPDV4_INDEX_CYLINDRICAL = 3

types of indexing in the file

pylidar.lidarformats.spdv4.SPDV4_INDEX_POLAR = 4

types of indexing in the file

pylidar.lidarformats.spdv4.SPDV4_INDEX_SCAN = 5

types of indexing in the file

pylidar.lidarformats.spdv4.SPDV4_INDEX_SPHERICAL = 2

types of indexing in the file

pylidar.lidarformats.spdv4.SPDV4_POINT_FLAGS_IGNORE = 1

flags for POINT_FLAGS

pylidar.lidarformats.spdv4.SPDV4_POINT_FLAGS_KEY_POINT = 8

flags for POINT_FLAGS

pylidar.lidarformats.spdv4.SPDV4_POINT_FLAGS_OVERLAP = 2

flags for POINT_FLAGS

pylidar.lidarformats.spdv4.SPDV4_POINT_FLAGS_SYNTHETIC = 4

flags for POINT_FLAGS

pylidar.lidarformats.spdv4.SPDV4_POINT_FLAGS_WAVEFORM = 16

flags for POINT_FLAGS

pylidar.lidarformats.spdv4.SPDV4_PULSE_FLAGS_IGNORE = 1

flags for PULSE_FLAGS

pylidar.lidarformats.spdv4.SPDV4_PULSE_FLAGS_OVERLAP = 2

flags for PULSE_FLAGS

pylidar.lidarformats.spdv4.SPDV4_PULSE_FLAGS_SCANLINE_DIRECTION = 4

flags for PULSE_FLAGS

pylidar.lidarformats.spdv4.SPDV4_PULSE_FLAGS_SCANLINE_EDGE = 8

flags for PULSE_FLAGS

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_END_WAVEFORM = 3

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_FIRST_RETURN = 0

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_GROUND = 6

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_LAST_RETURN = 1

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_MAX_INTENSITY = 5

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_ORIGIN = 4

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_START_WAVEFORM = 2

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_PULSE_INDEX_ZPLANE = 7

pulse indexing methods

pylidar.lidarformats.spdv4.SPDV4_SIMPLEGRID_COUNT_DTYPE

alias of numpy.uint32

pylidar.lidarformats.spdv4.SPDV4_SIMPLEGRID_INDEX_DTYPE

alias of numpy.uint32

pylidar.lidarformats.spdv4.SPDV4_VERSION_MAJOR = 4

version - major

pylidar.lidarformats.spdv4.SPDV4_VERSION_MINOR = 0

version - minor

pylidar.lidarformats.spdv4.SPDV4_WAVEFORM_FLAGS_BASELINE_FIXED = 4

flags for WAVEFORM_FLAGS

pylidar.lidarformats.spdv4.SPDV4_WAVEFORM_FLAGS_IGNORE = 1

flags for WAVEFORM_FLAGS

pylidar.lidarformats.spdv4.SPDV4_WAVEFORM_FLAGS_SATURATION_FIXED = 2

flags for WAVEFORM_FLAGS

pylidar.lidarformats.spdv4.TRANSMITTED_DTYPE

alias of numpy.uint32

pylidar.lidarformats.spdv4.WAVEFORMS_HEADER_UPDATE_DICT = {'RANGE': ('RANGE_MIN', 'RANGE_MAX')}

for updating the header

pylidar.lidarformats.spdv4.WAVEFORM_FIELDS = {'CHANNEL': <type 'numpy.uint8'>, 'NUMBER_OF_WAVEFORM_RECEIVED_BINS': <type 'numpy.uint16'>, 'NUMBER_OF_WAVEFORM_TRANSMITTED_BINS': <type 'numpy.uint16'>, 'RANGE_TO_WAVEFORM_START': <type 'numpy.uint32'>, 'RECEIVED_START_IDX': <type 'numpy.uint64'>, 'RECEIVE_WAVE_GAIN': <type 'numpy.float32'>, 'RECEIVE_WAVE_OFFSET': <type 'numpy.float32'>, 'TRANSMITTED_START_IDX': <type 'numpy.uint64'>, 'TRANS_WAVE_GAIN': <type 'numpy.float32'>, 'TRANS_WAVE_OFFSET': <type 'numpy.float32'>, 'WAVEFORM_FLAGS': <type 'numpy.uint8'>, 'WFM_WAVELENGTH_IDX': <type 'numpy.uint8'>}

Thes fields have defined type

pylidar.lidarformats.spdv4.WAVEFORM_SCALED_FIELDS = ('RANGE_TO_WAVEFORM_START',)

need scaling applied

pylidar.lidarformats.spdv4.WRITESUPPORTEDOPTIONS = ('SCALING_BUT_NO_DATA_WARNING', 'HDF5_CHUNK_SIZE')

driver options