Skip to content

Python bindings ๐Ÿ Getting started

han16nah edited this page Oct 26, 2021 · 20 revisions

This page will give an introduction on using HELIOS++ python bindings with pyhelios. pyhelios allows to:

  • Access and modify simulation configurations
  • Launch one or multiple simulations from your python script
  • Read point measurements and process further in combination with other python modules

Importing pyhelios

For the precompiled distribution, pyhelios.pyd is located in the run-folder. To find and import the file in a python script, the run path has to be added to the python path.

# adapt the following paths if necessary
helios_path = '../helios-plusplus-win'
helios_run_path = 'run/'

# Add paths to helios root directory and run directory to python path
sys.path.append(helios_path)
sys.path.append(helios_run_path)

# PyHelios import
import pyhelios

Configure simulation context and build a simulation

# Sim context.
# Set logging.
pyhelios.loggingQuiet()
# pyhelios.loggingSilent()
# pyhelios.loggingDefault()
# pyhelios.loggingVerbose()
# pyhelios.loggingVerbose2()

# Set seed for default random number generator.
pyhelios.setDefaultRandomnessGeneratorSeed("123")

# print current helios version
print(pyhelios.getVersion())
# Build simulation parameters
sim = pyhelios.Simulation(
    'data/surveys/' + survey_path, # surveyPath
    'assets/',                     # assetsPath
    'output/',                     # outputPath
    0,          # Num Threads - 0 by default
    True,       # LAS v1.4 output - False by default
    False,      # LAS v1.0 output - False by default
    False,      # ZIP output - False by default
    )

There are two flags to configure how the output is received. To start surveys from a python script, but then perform further analysis separately on the resulting XYZ or LAS files, we might set sim.finalOutput = False and sim.exportToFile = True. To directly process the output in the python file but not additionally export it to output\Survey Playback, we might set sim.finalOutput = True and sim.exportToFile = False

By default, both flags are set tu True.

# Enable final output from the python script
sim.finalOutput = True    # True by default
# Enable export to file
sim.exportToFile = True   # True by default

Set the simulation frequency. With a frequency of 0 (default), pausing and callbacks are not possible.

sim.simFrequency = 100    # 0 by default

Load the survey:

sim.loadSurvey(
        True,       # Leg Noise Disabled FLAG      - False by default
        True,       # Rebuild Scene FLAG           - False by default
        False,      # Write Waveform FLAG          - False by default
        False,      # Calc Echowidth FLAG          - False by default
        False,      # Full Wave Noise FLAG         - False by default
        True        # Platform Noise Disabled FLAG - True by default
    )

Starting and pausing and simulation status

A built simulation is started with

sim.start()

With various functions, we can find out the simulation status.

  • sim.isStarted()
  • sim.isRunning()
  • sim.isPaused()
  • sim.isStopped()
  • sim.isFinished()

Example:

if sim.isStarted():
    print('Simulation has started!')

Output:

Simulation has started!

Simulations can also be paused, resumed and stopped:

  • sim.start()
  • sim.pause()
  • sim.stop()

Example:

import time

time.sleep(10)
sim.pause()

if sim.isPaused():
    print('Simulation is paused!')
    
if not sim.isRunning():
    print('Simulation is not running.')
    
time.sleep(5)
sim.resume()

if sim.isRunning():
    print('Simulation has resumed!')

if sim.isFinished():
    print('Simulation has finished.') 

Output:

Simulation is paused!
Sim is not running.
Simulation has resumed!
Simulation has finished.

Output handling

The simulation output, i.e. measurement and trajectory points, can be accessed using sim.join(), if final output was enabled (sim.finalOutput = True).

# Create instance of PyHeliosOutputWrapper class using sim.join(). 
# Contains attributes 'measurements' and 'trajectories' which are Python wrappers of classes that contain the output vectors.
output = sim.join()

# Create instances of vector classes by accessing 'measurements' and 'trajectories' attributes of output wrapper.
measurements = output.measurements
trajectories = output.trajectories

# Each element of vectors contains a measurement point or point in trajectory respectively. Access through getPosition().
starting_point = trajectories[0].getPosition()
end_point = trajectories[len(trajectories) -1].getPosition()

# Access individual x, y and z vals.
print('Trajectory starting point : ({x}, {y}, {z})'.format(
    x=starting_point.x, y=starting_point.y, z=starting_point.z))

print('Trajectory end point : ({x}, {y}, {z})'.format(
    x=end_point.x, y=end_point.y, z=end_point.z))

The package pyheliostools contains additional tools for output handling (pyheliostools/output_handling.py). These allow to convert the trajectory and point outputs to lists or numpy arrays. If not executing python from the helios root directory, the path to the helios root directory has to be added to the python path, so the package is found.

import pyheliostools as pht
import numpy

output = sim.join()
measurements_list, trajectory_list = pht.outputToList(output)
measurements_array, trajectory_array = pht.outputToNumpy(output)

Columns of the measurements list/array:

   0      1      2      3      4      5      6      7      8        9         10            11              12            13              14          15 
[pos.x, pos.y, pos.z, ori.x, ori.y, ori.z, dir.x, dir.y, dir.z, intensity, echoWidth, NumberOfReturns, ReturnNumber, FullwaveIndex, classification, gpsTime]

Columns of the measurements list/array:

   0      1      2      3       4      5     6
[pos.x, pos.y, pos.z, gpsTime, roll, pitch, yaw]

Hint: If the hitObjectId should be included in the measurements array and numerical scenepart IDs are used, line 37 in pyheliostools\output_handling can be changed to:

int(meas.hitObjectId)

Next steps

To allow you to dive more into scene manipulation with pyhelios, we have compiled some information on a separate page.