![]() |
0.1.33
|
High-level interface for LiDAR point cloud operations. More...
High-level interface for LiDAR point cloud operations.
Supports synthetic scanning, point cloud filtering, triangulation, and leaf area density calculations.
Definition at line 171 of file LiDARCloud.py.
Public Member Functions | |
| __init__ (self) | |
| Initialize LiDARCloud. | |
| __enter__ (self) | |
| Context manager entry. | |
| __exit__ (self, exc_type, exc_val, exc_tb) | |
| Context manager exit - cleanup resources. | |
| __del__ (self) | |
| Fallback destructor for cleanup without context manage. | |
| int | addScan (self, Union[vec3, List[float], Tuple[float, float, float]] origin, int Ntheta, Tuple[float, float] theta_range, int Nphi, Tuple[float, float] phi_range, float exit_diameter, float beam_divergence, Optional[List[str]] column_format=None, float range_noise_stddev=0.0, float angle_noise_stddev=0.0, float scan_tilt_roll=0.0, float scan_tilt_pitch=0.0, float scan_azimuth_offset=0.0) |
| Add a LiDAR scan to the point cloud. | |
| int | addScanMoving (self, int Ntheta, Tuple[float, float] theta_range, int Nphi, Tuple[float, float] phi_range, float exit_diameter, float beam_divergence, List[float] traj_t, List[Union[vec3, List[float], Tuple[float, float, float]]] traj_pos, List[List[float]] traj_rot, float pulse_rate_hz, bool rot_is_quaternion=True, Optional[Union[vec3, List[float], Tuple[float, float, float]]] lever_arm=None, Optional[Union[vec3, List[float], Tuple[float, float, float]]] boresight_rpy=None, Optional[List[str]] column_format=None, float range_noise_stddev=0.0, float angle_noise_stddev=0.0, float t0=0.0) |
| Add a moving-platform (mobile/airborne) raster LiDAR scan driven by a 6-DOF pose trajectory. | |
| int | addScanSpinning (self, List[float] beam_elevation_angles, float azimuth_step, float pulse_rate_hz, List[float] traj_t, List[Union[vec3, List[float], Tuple[float, float, float]]] traj_pos, List[List[float]] traj_rot, bool rot_is_quaternion=True, float exit_diameter=0.0, float beam_divergence=0.0, Optional[Union[vec3, List[float], Tuple[float, float, float]]] lever_arm=None, Optional[Union[vec3, List[float], Tuple[float, float, float]]] boresight_rpy=None, Optional[List[str]] column_format=None, float range_noise_stddev=0.0, float angle_noise_stddev=0.0, float t0=0.0) |
| Add a continuously-spinning multibeam scan from physical instrument parameters. | |
| int | addScanMovingRaster (self, int Ntheta, Tuple[float, float] theta_range, int Nphi, Tuple[float, float] phi_range, float pulse_rate_hz, List[float] traj_t, List[Union[vec3, List[float], Tuple[float, float, float]]] traj_pos, List[List[float]] traj_quat, float exit_diameter=0.0, float beam_divergence=0.0, Optional[Union[vec3, List[float], Tuple[float, float, float]]] lever_arm=None, Optional[Union[vec3, List[float], Tuple[float, float, float]]] boresight_rpy=None, Optional[List[str]] column_format=None, float range_noise_stddev=0.0, float angle_noise_stddev=0.0, float t0=0.0) |
| Add a moving-platform raster scan: a fixed angular fan swept along a quaternion trajectory. | |
| int | addScanRisley (self, List[Union['RisleyPrism', List[float], Tuple[float,...]]] prisms, float refractive_index_air, float pulse_rate_hz, List[float] traj_t, List[Union[vec3, List[float], Tuple[float, float, float]]] traj_pos, List[List[float]] traj_rot, bool rot_is_quaternion=True, float exit_diameter=0.0, float beam_divergence=0.0, Optional[Union[vec3, List[float], Tuple[float, float, float]]] lever_arm=None, Optional[Union[vec3, List[float], Tuple[float, float, float]]] boresight_rpy=None, Optional[List[str]] column_format=None, float range_noise_stddev=0.0, float angle_noise_stddev=0.0, float t0=0.0) |
| Add a rotating-Risley-prism (Livox-style rosette) scan from physical instrument parameters. | |
| int | getScanCount (self) |
| Get total number of scans in the cloud. | |
| vec3 | getScanOrigin (self, int scanID) |
| Get origin of a specific scan. | |
| int | getScanSizeTheta (self, int scanID) |
| Get number of zenith scan points for a scan. | |
| int | getScanSizePhi (self, int scanID) |
| Get number of azimuthal scan points for a scan. | |
| float | getScanRangeNoiseStdDev (self, int scanID) |
| Get the range (along-beam) measurement noise standard deviation for a scan (meters). | |
| float | getScanAngleNoiseStdDev (self, int scanID) |
| Get the angular (beam-pointing) jitter standard deviation for a scan (radians). | |
| float | getScanTiltRoll (self, int scanID) |
| Get the global scanner tilt roll angle for a scan (radians; 0.0 if level). | |
| float | getScanTiltPitch (self, int scanID) |
| Get the global scanner tilt pitch angle for a scan (radians; 0.0 if level). | |
| float | getScanAzimuthOffset (self, int scanID) |
| Get the global scanner azimuth (heading) offset for a scan (radians; 0.0 if none). | |
| int | getScanPattern (self, int scanID) |
| Get the scan pattern for a scan. | |
| List[float] | getScanBeamZenithAngles (self, int scanID) |
| Get the per-channel beam zenith angles (radians) for a multibeam scan. | |
| ScanMode | getScanMode (self, int scanID) |
Get the high-level acquisition mode of a scan as a :class:ScanMode. | |
| int | getScanStepsPerRev (self, int scanID) |
| Get the number of azimuth firing steps per revolution (spinning scans; 0 otherwise). | |
| float | getScanRotationRate (self, int scanID) |
| Get the sensor-head rotation rate in revolutions/second (spinning scans; 0 otherwise). | |
| float | getScanRevolutions (self, int scanID) |
| Get the number of revolutions the sensor head made (spinning scans; 0 otherwise). | |
| List[RisleyPrism] | getScanRisleyPrisms (self, int scanID) |
Get the rotating wedge prisms of a Risley-prism scan as a list of :class:RisleyPrism. | |
| float | getScanRisleyRefractiveIndexAir (self, int scanID) |
| Get the refractive index of the medium surrounding a Risley scan's prisms (1.0 for non-Risley). | |
| ReturnMode | getScanReturnMode (self, int scanID) |
Get the return-reporting mode of a scan as a :class:ReturnMode (MULTI or SINGLE). | |
| setScanReturnMode (self, int scanID, Union[ReturnMode, int] return_mode) | |
| Set the return-reporting mode of a scan (ReturnMode.MULTI or ReturnMode.SINGLE). | |
| SingleReturnSelection | getScanSingleReturnSelection (self, int scanID) |
Get the single/limited-return selection policy as a :class:SingleReturnSelection. | |
| setScanSingleReturnSelection (self, int scanID, Union[SingleReturnSelection, int] selection) | |
| Set the single/limited-return selection policy (STRONGEST, FIRST, LAST, or STRONGEST_PLUS_LAST). | |
| int | getScanMaxReturns (self, int scanID) |
| Get the maximum returns per pulse used in single/limited-return mode (1 = single, N = N-return). | |
| setScanMaxReturns (self, int scanID, int max_returns) | |
| Set the maximum returns per pulse used in single/limited-return mode (must be >= 1). | |
| setSyntheticScanMemoryBudget (self, int bytes) | |
Set the soft memory budget (bytes) for :meth:syntheticScan's transient buffers. | |
| int | getSyntheticScanMemoryBudget (self) |
Get the soft memory budget (bytes) for :meth:syntheticScan's transient buffers. | |
| float | getScanPulseWidth (self, int scanID) |
| Get the pulse width / range resolution (meters) of a scan (0 = use syntheticScan argument). | |
| setScanPulseWidth (self, int scanID, float pulse_width) | |
| Set the pulse width / range resolution (meters) of a scan (0 = use syntheticScan argument). | |
| float | getScanDetectionThreshold (self, int scanID) |
| Get the detection threshold (energy fraction, noise floor) of a scan. | |
| setScanDetectionThreshold (self, int scanID, float detection_threshold) | |
| Set the detection threshold (energy fraction, noise floor) of a scan. | |
| addHitPoint (self, int scanID, Union[vec3, List[float], Tuple[float, float, float]] xyz, Union[vec3, SphericalCoord, List[float], Tuple[float, float]] direction, Optional[Union[RGBcolor, List[float], Tuple[float, float, float]]] color=None) | |
| Add a hit point to the point cloud. | |
| addHitPoints (self, int scanID, xyz_array, direction_array, color_array=None) | |
| Add many hit points to the point cloud in a single bulk call. | |
| addHitPointsWithData (self, int scanID, xyz_array, direction_array, data_labels=None, data_values=None, color_array=None) | |
| Add many hit points carrying a per-hit data map in a single bulk call. | |
| int | getHitCount (self) |
| Get total number of hit points in cloud. | |
| vec3 | getHitXYZ (self, int index) |
| Get coordinates of a hit point. | |
| vec3 | getHitOrigin (self, int index) |
| Get the (x,y,z) beam-emission origin of a hit point. | |
| SphericalCoord | getHitRaydir (self, int index) |
| Get ray direction of a hit point. | |
| RGBcolor | getHitColor (self, int index) |
| Get color of a hit point. | |
| int | getHitScanID (self, int index) |
| Get the scan ID a hit point belongs to. | |
| bool | doesHitDataExist (self, int index, str label) |
| Check whether a named scalar data value exists for a hit point. | |
| float | getHitData (self, int index, str label) |
| Get a named scalar data value for a hit point. | |
| List[float] | getHitDataAll (self, str label) |
| Bulk-export a named scalar data value for all hits in a single FFI call. | |
| Tuple[List[vec3], List[RGBcolor]] | getHitsXYZRGB (self) |
| Bulk-export coordinates and colors for all hits in a single FFI call. | |
| getHitsXYZRGBArrays (self) | |
| Bulk-export hit coordinates + colors as numpy arrays. | |
| getHitDataArray (self, str label) | |
| Bulk-export a named scalar field as an (getHitCount(),) float32 array, NaN where the label is absent for a hit. | |
| List[float] | getHitDataColumn (self, str label, float absent_value=-9999.0) |
| Bulk-export a named scalar column via the native cache-linear columnar path. | |
| int | getHitDataColumnIndex (self, str label) |
| Get the internal column slot index for a hit-data label. | |
| getHitDataColumnArray (self, str label, float absent_value=-9999.0) | |
Bulk-export a named scalar column as an (getHitCount(),) float64 numpy array via the columnar path (absent_value where the label is absent for a hit). | |
| getHitScanIDArray (self) | |
| Bulk-export the scan ID of every hit as an (getHitCount(),) int32 array. | |
| getHitMissArray (self) | |
| Bulk-export the miss flag of every hit as an (getHitCount(),) int32 array (1 == sky/miss, 0 == real surface return). | |
| deleteHitPoint (self, int index) | |
| Delete a hit point from the cloud. | |
| bool | isHitMiss (self, int index) |
| Return True if a hit is a "miss" (a fired pulse that returned nothing). | |
| bool | hasMisses (self) |
| Return True if the cloud contains at least one miss. | |
| bool | isMultiReturnData (self) |
| Return True if the cloud contains multi-return data. | |
| coordinateShift (self, Union[vec3, List[float], Tuple[float, float, float]] shift) | |
| Translate all hit points by a shift vector. | |
| coordinateRotation (self, Union[SphericalCoord, List[float], Tuple[float, float]] rotation) | |
| Rotate all hit points by spherical rotation angles. | |
| triangulateHitPoints (self, float Lmax, float max_aspect_ratio=4.0) | |
| Generate triangle mesh from hit points using Delaunay triangulation. | |
| int | getTriangleCount (self) |
| Get number of triangles in the mesh. | |
| dict | getTriangulationStats (self) |
| Filter diagnostics from the most recent triangulateHitPoints() call. | |
| getTriangleVerticesAll (self) | |
| Bulk-export every triangle's vertices and source scan in one call. | |
| setExternalTriangulation (self, vertices, scan_ids) | |
| Replace the internal triangulation with an externally-supplied mesh. | |
| distanceFilter (self, float maxdistance) | |
| Filter hit points by maximum distance from scanne. | |
| reflectanceFilter (self, float minreflectance) | |
| Filter hit points by minimum reflectance value. | |
| firstHitFilter (self) | |
| Keep only first return hit points. | |
| lastHitFilter (self) | |
| Keep only last return hit points. | |
| exportPointCloud (self, str filename, bool write_header=True) | |
| Export point cloud to ASCII file. | |
| exportLeafAreaUncertainty (self, str filename) | |
| Export per-voxel leaf-area sampling uncertainty to a self-describing ASCII file. | |
| exportScans (self, str filename) | |
| Export all scans to an XML metadata file plus one ASCII data file per scan. | |
| loadXML (self, str filename) | |
| Load scan metadata from XML file. | |
| disableMessages (self) | |
| Disable console output messages. | |
| enableMessages (self) | |
| Enable console output messages. | |
| addGrid (self, Union[vec3, List[float], Tuple[float, float, float]] center, Union[vec3, List[float], Tuple[float, float, float]] size, Union[List[int], Tuple[int, int, int]] ndiv, float rotation=0.0, Optional[Union[List[float], Tuple[float,...]]] column_z_offsets=None) | |
| Add a rectangular grid of voxel cells. | |
| addGridCell (self, Union[vec3, List[float], Tuple[float, float, float]] center, Union[vec3, List[float], Tuple[float, float, float]] size, float rotation=0.0) | |
| Add a single grid cell. | |
| int | getGridCellCount (self) |
| Get total number of grid cells. | |
| vec3 | getCellCenter (self, int index) |
| Get the true world-space center position of a grid cell. | |
| vec3 | getCellCenterUnrotated (self, int index) |
| Get the UNROTATED (axis-aligned lattice) center position of a grid cell. | |
| vec3 | getCellSize (self, int index) |
| Get size of a grid cell. | |
| float | getCellRotation (self, int index) |
| Get the azimuthal rotation of a grid cell about the z-axis, in degrees. | |
| float | getCellLeafArea (self, int index) |
| Get leaf area of a grid cell (m²) | |
| float | getCellLeafAreaDensity (self, int index) |
| Get leaf area density of a grid cell (m²/m³) | |
| int | getCellBeamCount (self, int index) |
| Get the beam count N that entered a grid cell during the leaf-area inversion. | |
| float | getCellRelativeDensityIndex (self, int index) |
| Get the relative density index (I_rdi) for a grid cell. | |
| float | getCellMeanPathLength (self, int index) |
| Get the mean beam path length (m) through a grid cell. | |
| float | getCellLADVariance (self, int index) |
| Get the per-voxel LAD sampling variance for a grid cell. | |
| getCellLeafAreaConfidenceInterval (self, int index, float confidence_level=0.95) | |
| Get the leaf-area confidence interval for a single grid cell. | |
| getGroupLADConfidenceInterval (self, List[int] indices, float confidence_level=0.95) | |
| Get the group-scale LAD confidence interval over a set of grid cells (recommended). | |
| float | getCellGtheta (self, int index) |
| Get G(theta) value for a grid cell. | |
| setCellGtheta (self, float Gtheta, int index) | |
| Set G(theta) value for a grid cell. | |
| calculateHitGridCell (self) | |
| Calculate hit point grid cell assignments. | |
| gapfillMisses (self) | |
| Gapfill sky/miss points where rays didn't hit geometry. | |
| int | gapfillMissesCount (self, Optional[int] scanID=None, bool gapfill_grid_only=False, bool add_flags=False) |
| Gapfill missing points and return only how many were added. | |
| int | getVirtualMissCount (self) |
| Number of gap-filled misses currently held in virtualized form. | |
| dict | getCroppedReturnStats (self) |
Returns the last :meth:calculateLeafArea call inferred from target_count. | |
| bool | hasVirtualMisses (self) |
| Whether any gap-filled miss is currently held in virtualized form. | |
| None | materializeMisses (self) |
| Convert every virtualized gap-filled miss into a stored hit point. | |
| SphericalCoord | getScanGridDirection (self, int scanID, int row, int column) |
| Beam direction at a scan-grid cell, from the model fitted during gap-filling. | |
| getHitXYZColumn (self) | |
| Read every hit's position in index order in one pass. | |
| getHitScanIDColumn (self) | |
| Read every hit's scan ID in index order in one pass. | |
| int | estimateHitPointMemory (self, int hit_count) |
Estimate the resident memory a cloud of hit_count points will occupy, in bytes. | |
| None | setMaxHitPoints (self, int max_hits) |
| Set the cap on stored hit points before loading fails with a diagnostic. | |
| int | getMaxHitPoints (self) |
| Current cap on stored hit points, or 0 if the check is disabled. | |
| None | reserveHitPoints (self, int hit_count) |
| Reserve capacity for hit points and every scalar-data column at once. | |
| None | setExactPathLengths (self, bool exact) |
| Keep every beam path length exactly, instead of binning them. | |
| bool | getExactPathLengths (self) |
| Whether path lengths are accumulated exactly. | |
| syntheticScan (self, Context context, Optional[int] rays_per_pulse=None, Optional[float] pulse_distance_threshold=None, bool scan_grid_only=False, bool record_misses=True, bool append=False, Optional[Union[ReturnMode, int]] return_mode=None, cancel_flag=None) | |
| Perform synthetic LiDAR scan of geometry in Context. | |
| calculateLeafArea (self, Context context, Optional[int] min_voxel_hits=None, Optional[float] element_width=None, Optional[Union[float, List[float]]] Gtheta=None) | |
| Calculate leaf area for each grid cell. | |
| calculateSyntheticLeafArea (self, Context context) | |
| Calculate synthetic leaf area (for validation of synthetic scans). | |
| calculateSyntheticGtheta (self, Context context) | |
| Calculate synthetic G(theta) (for validation of synthetic scans). | |
| exportTriangleNormals (self, str filename) | |
| Export triangle normal vectors to file. | |
| exportTriangleAreas (self, str filename) | |
| Export triangle areas to file. | |
| exportLeafAreas (self, str filename) | |
| Export leaf areas for each grid cell to file. | |
| exportLeafAreaDensities (self, str filename) | |
| Export leaf area densities for each grid cell to file. | |
| exportGtheta (self, str filename) | |
| Export G(theta) values for each grid cell to file. | |
| addTrianglesToContext (self, Context context) | |
| Add triangulated mesh to Context as triangle primitives. | |
| initializeCollisionDetection (self, Context context) | |
| Initialize CollisionDetection plugin for ray tracing. | |
| enableCDGPUAcceleration (self) | |
| Enable GPU acceleration for collision detection ray tracing. | |
| disableCDGPUAcceleration (self) | |
| Disable GPU acceleration (use CPU ray tracing) | |
| bool | isGPUAvailable (self) |
| Return True if a CUDA-capable GPU is available for collision-detection ray tracing. | |
| bool | isGPUAccelerationEnabled (self) |
| Return True if GPU acceleration is currently enabled for collision-detection ray tracing. | |
| setSyntheticScanProgressPointer (self, ptr) | |
Register an external per-scan progress counter polled during :meth:syntheticScan. | |
| None | createHitDataColumn (self, str label, HitDataType column_type) |
| Create a per-hit scalar-data column with an explicit storage type. | |
| HitDataType | getHitDataType (self, str label) |
| Storage type of an existing per-hit scalar-data column. | |
| List[float] | getHitDataColumnFloat32 (self, str label, float absent_value=-9999.0) |
| Bulk-export a named scalar column as 32-bit floats. | |
| getHitDataColumnFloat32Array (self, str label, float absent_value=-9999.0) | |
Bulk-export a named scalar column as a (getHitCount(),) float32 numpy array. | |
| List[int] | getHitDataColumnInt32 (self, str label, int absent_value=-9999) |
| Bulk-export a named scalar column as 32-bit signed integers. | |
| getHitDataColumnInt32Array (self, str label, int absent_value=-9999) | |
Bulk-export a named scalar column as a (getHitCount(),) int32 numpy array. | |
| None | addHitPointsBulk (self, int scanID, xyz, dir_spherical=None, Optional[List[str]] labels=None, values=None) |
| Bulk-ingest hit points through the native bulk path, with double-precision positions. | |
| None | deleteHitPoints (self, int first, int count) |
| Delete a contiguous range of hit points, preserving the order of the rest. | |
| None | setTriangulationSink (self, callback) |
Register a sink that receives each scan's triangles as :meth:triangulateHitPoints finishes it. | |
| None | setSyntheticScanHitSink (self, callback) |
Register a sink fired after each chunk of a :meth:syntheticScan lands in the cloud. | |
| int | getScanHitCount (self, int scanID) |
| Number of hit points (stored returns plus virtualized misses) belonging to one scan. | |
| List[int] | getScanHitIndices (self, int scanID) |
| Global indices of one scan's hit points, in the order the per-scan readers use. | |
| getScanHitXYZColumn (self, int scanID) | |
| Read one scan's hit positions in a single pass. | |
| List[float] | getScanHitDataColumn (self, int scanID, str label, float absent_value=-9999.0) |
| Read one scan's values of a scalar-data label in a single pass, as doubles. | |
| List[float] | getScanHitDataColumnFloat32 (self, int scanID, str label, float absent_value=-9999.0) |
| Read one scan's values of a scalar-data label as 32-bit floats. | |
| List[int] | getScanHitDataColumnInt32 (self, int scanID, str label, int absent_value=-9999) |
| Read one scan's values of a scalar-data label as 32-bit signed integers. | |
| None | calculateLeafAreaBlock (self, Context context, ijk_min, ijk_max, int min_voxel_hits, float element_width, Optional[Union[float, List[float]]] Gtheta=None) |
| Calculate leaf area for only a block of the voxel grid. | |
| Tuple[int, int, int] | getCellGlobalIJK (self, int index) |
| Lattice index (i, j, k) of a grid cell along x, y and z. | |
| Tuple[int, int, int] | getGridGlobalCount (self) |
Number of lattice cells along x, y and z (the ndiv passed to :meth:addGrid). | |
| int | getHitPointCapacity (self) |
| Number of hit points the cloud can hold before its arrays reallocate. | |
| setProgressCallback (self, callback) | |
Register a progress callback fired with (progress_fraction, message) during :meth:syntheticScan. | |
| bool | is_available (self) |
| Check if LiDAR is available in current build. | |
Static Public Member Functions | |
| float | getMissDistance () |
| Return the LIDAR_MISS_DISTANCE constant (meters): the distance at which a miss point is placed along its beam. | |
| int | getDefaultMaxHitPoints () |
| Default cap on the number of stored hit points in a cloud (100 million). | |
Protected Member Functions | |
| _dispatch_synthetic_scan (self, context_ptr, rays_per_pulse, pulse_distance_threshold, scan_grid_only, record_misses, append, return_mode) | |
| _check_cd_context_alive (self) | |
| Raise if the Context bound to collision detection has been destroyed. | |
| None | _validate_label (self, str label) |
| Validate a scalar-data label argument (shared by the column readers). | |
| None | _raise_pending_callback_error (self) |
| Re-raise an exception captured inside a streaming-sink callback, if any. | |
| None | _validate_scan_id (self, int scanID) |
| Validate a scan index argument (shared by the per-scan readers). | |
Static Protected Member Functions | |
| _validate_trajectory (traj_t, traj_pos, traj_rot, rot_stride, method) | |
| Shared trajectory validation/marshalling for moving/spinning scans. | |
Protected Attributes | |
| _cloud_ptr = lidar_wrapper.createLiDARcloud() | |
| _progress_callback_ref = None | |
| _triangulation_sink_ref = None | |
| _triangulation_sink_error = None | |
| _synthetic_hit_sink_ref = None | |
| _synthetic_hit_sink_error = None | |
| _cd_context = context | |
| pyhelios.LiDARCloud.LiDARCloud.__init__ | ( | self | ) |
Initialize LiDARCloud.
| LiDARError | If plugin not available in current build |
| RuntimeError | If cloud initialization fails |
Definition at line 180 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.__del__ | ( | self | ) |
Fallback destructor for cleanup without context manage.
Definition at line 220 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.__enter__ | ( | self | ) |
Context manager entry.
Definition at line 210 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.__exit__ | ( | self, | |
| exc_type, | |||
| exc_val, | |||
| exc_tb ) |
Context manager exit - cleanup resources.
Definition at line 214 of file LiDARCloud.py.
|
protected |
Raise if the Context bound to collision detection has been destroyed.
Definition at line 2389 of file LiDARCloud.py.
|
protected |
Definition at line 2115 of file LiDARCloud.py.
|
protected |
Re-raise an exception captured inside a streaming-sink callback, if any.
A Python exception raised inside a ctypes callback never propagates -- ctypes returns 0 and C++ takes that for success -- so the sink trampolines stash the exception and this re-raises it once the native call has returned.
Definition at line 2757 of file LiDARCloud.py.
|
protected |
Validate a scalar-data label argument (shared by the column readers).
Definition at line 2565 of file LiDARCloud.py.
|
protected |
Validate a scan index argument (shared by the per-scan readers).
Definition at line 2899 of file LiDARCloud.py.
|
staticprotected |
Shared trajectory validation/marshalling for moving/spinning scans.
Returns (t_list, pos_list, rot_list) of plain Python floats. rot_stride is 4 for quaternions or 3 for Euler triples; pass rot_stride=None to skip rotation validation.
Definition at line 418 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addGrid | ( | self, | |
| Union[vec3, List[float], Tuple[float, float, float]] | center, | ||
| Union[vec3, List[float], Tuple[float, float, float]] | size, | ||
| Union[List[int], Tuple[int, int, int]] | ndiv, | ||
| float | rotation = 0.0, | ||
| Optional[Union[List[float], Tuple[float, ...]]] | column_z_offsets = None ) |
Add a rectangular grid of voxel cells.
| center | Grid center position (vec3 or 3-element list) |
| size | Grid dimensions [x, y, z] (vec3 or 3-element list) |
| ndiv | Number of divisions [nx, ny, nz] (3-element list) |
| rotation | Azimuthal rotation angle (degrees, default 0.0) |
| column_z_offsets | Optional per-(x,y)-column vertical offset for terrain following, row-major as [j*ndiv[0] + i] with length ndiv[0]*ndiv[1]. Each vertical column of voxels is shifted in z by its column's offset so the grid can track an external terrain surface (e.g. a DEM). None (the default) builds an axis-regular grid. |
rotation is in degrees here, matching the native addGrid(). :meth:addGridCell takes its rotation in radians — the two native entry points genuinely differ, and PyHelios passes each through unchanged. :meth:getCellRotation reports degrees.Definition at line 1526 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addGridCell | ( | self, | |
| Union[vec3, List[float], Tuple[float, float, float]] | center, | ||
| Union[vec3, List[float], Tuple[float, float, float]] | size, | ||
| float | rotation = 0.0 ) |
Add a single grid cell.
| center | Cell center position (vec3 or 3-element list) |
| size | Cell dimensions [x, y, z] (vec3 or 3-element list) |
| rotation | Azimuthal rotation angle (radians, default 0.0) |
rotation is in radians here, whereas :meth:addGrid takes degrees. This asymmetry is inherited from the native API — the native addGridCell() stores the angle directly in the cell's radian field while addGrid() converts from degrees. :meth:getCellRotation reports degrees. Definition at line 1591 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addHitPoint | ( | self, | |
| int | scanID, | ||
| Union[vec3, List[float], Tuple[float, float, float]] | xyz, | ||
| Union[vec3, SphericalCoord, List[float], Tuple[float, float]] | direction, | ||
| Optional[Union[RGBcolor, List[float], Tuple[float, float, float]]] | color = None ) |
Add a hit point to the point cloud.
| scanID | Scan ID this hit belongs to |
| xyz | Hit point coordinates (vec3 or 3-element list) |
| direction | Ray direction (vec3/SphericalCoord or 2-3 element list) |
| color | Optional RGB color (RGBcolor or 3-element list) |
Definition at line 933 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addHitPoints | ( | self, | |
| int | scanID, | ||
| xyz_array, | |||
| direction_array, | |||
| color_array = None ) |
Add many hit points to the point cloud in a single bulk call.
This skips the per-point Python loop by passing contiguous buffers straight to the native library in one FFI call.
| scanID | Scan ID these hits belong to |
| xyz_array | Hit point coordinates, shape (N, 3) [x, y, z] |
| direction_array | Ray directions, shape (N, 3) [radius, elevation, azimuth] (azimuth is currently ignored, matching addHitPoint) |
| color_array | Optional RGB colors, shape (N, 3) [r, g, b] |
Definition at line 987 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.addHitPointsBulk | ( | self, | |
| int | scanID, | ||
| xyz, | |||
| dir_spherical = None, | |||
| Optional[List[str]] | labels = None, | ||
| values = None ) |
Bulk-ingest hit points through the native bulk path, with double-precision positions.
This is the native ``addHitPoints`` entry point, distinct from :meth:`addHitPoints` (a per-point shim taking float positions). It takes float64 coordinates, can derive beam directions automatically, and writes scalar-data columns directly.
| scanID | Scan ID these hits belong to (the scan must already exist) |
| xyz | Hit point coordinates, shape (N, 3) float64 |
| dir_spherical | Beam directions, shape (N, 3) as (radius, elevation, azimuth), or None to derive each direction from the point's position relative to the scan origin (what the ASCII loader does) |
| labels | Optional list of scalar-data column names (length k) |
| values | Required when labels is given: (N, k) float64 values. A NaN entry leaves that label absent on that point. |
| ValueError | If an array has the wrong shape, row counts disagree, or ``values`` is missing while labels was supplied |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2598 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addHitPointsWithData | ( | self, | |
| int | scanID, | ||
| xyz_array, | |||
| direction_array, | |||
| data_labels = None, | |||
| data_values = None, | |||
| color_array = None ) |
Add many hit points carrying a per-hit data map in a single bulk call.
Like addHitPoints, but also populates each hit's named-scalar data map — the in-memory equivalent of what the ASCII loader does for non-standard columns. This is the path multi-return LAD needs (timestamp/target_index/ target_count land in the map so gapfillMisses() can group beams by pulse).
| scanID | Scan ID these hits belong to (the scan must already exist) |
| xyz_array | Hit point coordinates, shape (N, 3) [x, y, z] |
| direction_array | Ray directions, shape (N, 3) [radius, elevation, azimuth]. Pass cart2sphere(xyz - origin) to match loadASCIIFile; the full SphericalCoord (incl. radius) is used. |
| data_labels | Optional list of data-map key names (length k) |
| data_values | Optional (N, k) values for those keys (float64) |
| color_array | Optional RGB colors, shape (N, 3) [r, g, b] |
Definition at line 1028 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.addScan | ( | self, | |
| Union[vec3, List[float], Tuple[float, float, float]] | origin, | ||
| int | Ntheta, | ||
| Tuple[float, float] | theta_range, | ||
| int | Nphi, | ||
| Tuple[float, float] | phi_range, | ||
| float | exit_diameter, | ||
| float | beam_divergence, | ||
| Optional[List[str]] | column_format = None, | ||
| float | range_noise_stddev = 0.0, | ||
| float | angle_noise_stddev = 0.0, | ||
| float | scan_tilt_roll = 0.0, | ||
| float | scan_tilt_pitch = 0.0, | ||
| float | scan_azimuth_offset = 0.0 ) |
Add a LiDAR scan to the point cloud.
| origin | Scanner position (vec3 or 3-element list/tuple) |
| Ntheta | Number of scan points in zenith direction |
| theta_range | Zenith angle range (min, max) in radians |
| Nphi | Number of scan points in azimuthal direction |
| phi_range | Azimuthal angle range (min, max) in radians |
| exit_diameter | Laser beam exit diameter (meters) |
| beam_divergence | Beam divergence angle (radians) |
| column_format | Optional list of column-format labels. Non-standard labels (anything other than geometry/standard tokens like x/y/z/r/g/b/raydir) cause syntheticScan to sample that named primitive data from the struck primitive onto each hit's data map, retrievable via getHitData(). Defaults to None (empty format). |
One label is special: "reflectivity_lidar" modulates each hit's "intensity" (intensity *= reflectivity) rather than being stored as its own hit-data key, so getHitData(i, "reflectivity_lidar") will NOT return it.
| range_noise_stddev | Standard deviation of Gaussian range (along-beam) measurement noise in meters. Only affects synthetic-scan generation. Defaults to 0.0 (noise disabled). |
| angle_noise_stddev | Standard deviation of Gaussian angular (beam-pointing) jitter in radians. Only affects synthetic-scan generation. Defaults to 0.0 (jitter disabled). |
| scan_tilt_roll | Global scanner tilt roll angle in radians, modeling residual tilt of the scanner spin axis away from plumb (right-hand rotation about the body lateral axis). Only affects synthetic-scan generation. Defaults to 0.0 (level). |
| scan_tilt_pitch | Global scanner tilt pitch angle in radians (right-hand rotation about the body forward/azimuth-zero axis). Only affects synthetic-scan generation. Defaults to 0.0 (level). |
| scan_azimuth_offset | Global scanner azimuth (heading) offset in radians, a right-hand rotation about the world +z axis applied on top of the azimuth sweep. Only affects synthetic-scan generation. Defaults to 0.0 (no offset). |
Definition at line 277 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.addScanMoving | ( | self, | |
| int | Ntheta, | ||
| Tuple[float, float] | theta_range, | ||
| int | Nphi, | ||
| Tuple[float, float] | phi_range, | ||
| float | exit_diameter, | ||
| float | beam_divergence, | ||
| List[float] | traj_t, | ||
| List[Union[vec3, List[float], Tuple[float, float, float]]] | traj_pos, | ||
| List[List[float]] | traj_rot, | ||
| float | pulse_rate_hz, | ||
| bool | rot_is_quaternion = True, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | lever_arm = None, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | boresight_rpy = None, | ||
| Optional[List[str]] | column_format = None, | ||
| float | range_noise_stddev = 0.0, | ||
| float | angle_noise_stddev = 0.0, | ||
| float | t0 = 0.0 ) |
Add a moving-platform (mobile/airborne) raster LiDAR scan driven by a 6-DOF pose trajectory.
Unlike :meth:`addScan`, the scanner pose changes during the sweep. For each pulse the synthetic-scan
generator computes its acquisition time ``t = t0 + ordinal / pulse_rate_hz``, interpolates the platform
pose at that time (linear position, SLERP orientation), and emits a per-pulse origin
``o = pos + R(q) * lever_arm`` and direction ``d = R(q) * R(boresight) * d_body``. Every resulting hit
and miss stores its own origin (hit-data "origin_x"/"origin_y"/"origin_z", retrievable via
:meth:`getHitOrigin`), timestamp ("timestamp"), and firing index ("pulse_id").
The static tilt roll/pitch/azimuth fields are NOT applied in this mode; attitude comes entirely
from the trajectory and the boresight misalignment. Because the pulses do not lie on a fixed
theta-phi grid they cannot be triangulated, so leaf-area inversion must use
:meth:`calculateLeafArea` with an explicit ``Gtheta``.
| Ntheta | Number of scan points in zenith direction (raster grid rows) |
| theta_range | Zenith angle range (min, max) in radians |
| Nphi | Number of scan points in azimuthal direction (raster grid columns) |
| phi_range | Azimuthal angle range (min, max) in radians |
| exit_diameter | Laser beam exit diameter (meters) |
| beam_divergence | Beam divergence angle (radians) |
| traj_t | Monotonically increasing trajectory sample times in seconds (length M) |
| traj_pos | Platform positions in world coordinates, one [x, y, z] (or vec3) per traj_t entry |
| traj_rot | Platform orientations, one entry per traj_t entry. Each entry is a length-4 quaternion (qx, qy, qz, qw, Hamilton body->world) when rot_is_quaternion is True, otherwise a length-3 roll/pitch/yaw Euler triple in radians (intrinsic Z-Y-X). |
| pulse_rate_hz | Pulse repetition rate in Hz (must be > 0) |
| rot_is_quaternion | Whether traj_rot holds quaternions (default True) or Euler angles |
| lever_arm | Sensor optical center in the platform body frame [x, y, z] meters (default origin) |
| boresight_rpy | Fixed sensor rotational misalignment [roll, pitch, yaw] radians (default 0) |
| column_format | Optional list of column-format labels (see addScan) |
| range_noise_stddev | Std. dev. of Gaussian range noise in meters (default 0) |
| angle_noise_stddev | Std. dev. of Gaussian angular jitter in radians (default 0) |
| t0 | Time of the first pulse in seconds (relative time; default 0) |
Definition at line 361 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.addScanMovingRaster | ( | self, | |
| int | Ntheta, | ||
| Tuple[float, float] | theta_range, | ||
| int | Nphi, | ||
| Tuple[float, float] | phi_range, | ||
| float | pulse_rate_hz, | ||
| List[float] | traj_t, | ||
| List[Union[vec3, List[float], Tuple[float, float, float]]] | traj_pos, | ||
| List[List[float]] | traj_quat, | ||
| float | exit_diameter = 0.0, | ||
| float | beam_divergence = 0.0, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | lever_arm = None, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | boresight_rpy = None, | ||
| Optional[List[str]] | column_format = None, | ||
| float | range_noise_stddev = 0.0, | ||
| float | angle_noise_stddev = 0.0, | ||
| float | t0 = 0.0 ) |
Add a moving-platform raster scan: a fixed angular fan swept along a quaternion trajectory.
High-level wrapper around :meth:`addScanMoving` for a non-spinning sensor on a moving platform. Specify the per-frame angular fan resolution plus the trajectory and PRF; Helios derives the per-pulse time sampling along the trajectory. Sets the scan's :class:`ScanMode` to ``MOVING_RASTER``.
| Ntheta | Number of zenith samples in the angular fan |
| theta_range | Zenith angle range (min, max) in radians |
| Nphi | Number of azimuth samples in the angular fan |
| phi_range | Azimuthal angle range (min, max) in radians |
| pulse_rate_hz | Pulse repetition rate (PRF) in Hz (must be > 0) |
| traj_t | Monotonically increasing trajectory sample times in seconds (length M) |
| traj_pos | Platform positions in world coordinates, one [x, y, z] (or vec3) per traj_t entry |
| traj_quat | Platform orientation quaternions (qx, qy, qz, qw, Hamilton body->world), one per traj_t entry |
| exit_diameter | Laser beam exit diameter (meters, default 0) |
| beam_divergence | Beam divergence angle (radians, default 0) |
| lever_arm | Sensor optical center in the platform body frame [x, y, z] meters (default origin) |
| boresight_rpy | Fixed sensor rotational misalignment [roll, pitch, yaw] radians (default 0) |
| column_format | Optional list of column-format labels (default ["x", "y", "z"]) |
| range_noise_stddev | Std. dev. of Gaussian range noise in meters (default 0) |
| angle_noise_stddev | Std. dev. of Gaussian angular jitter in radians (default 0) |
| t0 | Time of the first pulse in seconds (relative time; default 0) |
Definition at line 561 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.addScanRisley | ( | self, | |
| List[Union['RisleyPrism', List[float], Tuple[float, ...]]] | prisms, | ||
| float | refractive_index_air, | ||
| float | pulse_rate_hz, | ||
| List[float] | traj_t, | ||
| List[Union[vec3, List[float], Tuple[float, float, float]]] | traj_pos, | ||
| List[List[float]] | traj_rot, | ||
| bool | rot_is_quaternion = True, | ||
| float | exit_diameter = 0.0, | ||
| float | beam_divergence = 0.0, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | lever_arm = None, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | boresight_rpy = None, | ||
| Optional[List[str]] | column_format = None, | ||
| float | range_noise_stddev = 0.0, | ||
| float | angle_noise_stddev = 0.0, | ||
| float | t0 = 0.0 ) |
Add a rotating-Risley-prism (Livox-style rosette) scan from physical instrument parameters.
High-level entry point for a Livox rosette-pattern sensor (Mid-40/Mid-70/Avia). A single beam is refracted through a stack of continuously rotating wedge prisms, tracing a non-repetitive rosette that fills a circular field of view. The scan is stored as an Ntheta=1, Nphi=Npulses table, where Npulses = round(pulse_rate_hz * trajectory_duration). Sets the scan's :class:`ScanMode` to ``RISLEY_PRISM`` and :class:`ScanPattern` to ``RISLEY_PRISM``. Like a spinning scan it is always trajectory-driven; a stationary tripod capture is two coincident poses (same position and orientation) separated in time by the acquisition duration.
| prisms | Rotating wedge prisms in beam-traversal order (at least one; a Livox sensor uses two counter-rotating prisms). Each entry is a :class:RisleyPrism or a 4-element [wedge_angle, refractive_index, rotor_rate, phase] list/tuple (radians / unitless / rad-per-s / radians). |
| refractive_index_air | Refractive index of the medium surrounding the prisms (typically 1.0) |
| pulse_rate_hz | Pulse repetition rate (PRF) in Hz (must be > 0) |
| traj_t | Monotonically increasing trajectory sample times in seconds (length M) |
| traj_pos | Platform positions in world coordinates, one [x, y, z] (or vec3) per traj_t entry |
| traj_rot | Platform orientations, one per traj_t entry. Length-4 quaternion (qx, qy, qz, qw, Hamilton body->world) when rot_is_quaternion is True, otherwise length-3 roll/pitch/yaw Euler triple in radians (intrinsic Z-Y-X). |
| rot_is_quaternion | Whether traj_rot holds quaternions (default True) or Euler angles |
| exit_diameter | Laser beam exit diameter (meters, default 0) |
| beam_divergence | Beam divergence angle (radians, default 0) |
| lever_arm | Sensor optical center in the platform body frame [x, y, z] meters (default origin) |
| boresight_rpy | Fixed sensor rotational misalignment [roll, pitch, yaw] radians (default 0) |
| column_format | Optional list of column-format labels (default ["x", "y", "z"]) |
| range_noise_stddev | Std. dev. of Gaussian range noise in meters (default 0) |
| angle_noise_stddev | Std. dev. of Gaussian angular jitter in radians (default 0) |
| t0 | Time of the first pulse in seconds (relative time; default 0) |
Definition at line 644 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.addScanSpinning | ( | self, | |
| List[float] | beam_elevation_angles, | ||
| float | azimuth_step, | ||
| float | pulse_rate_hz, | ||
| List[float] | traj_t, | ||
| List[Union[vec3, List[float], Tuple[float, float, float]]] | traj_pos, | ||
| List[List[float]] | traj_rot, | ||
| bool | rot_is_quaternion = True, | ||
| float | exit_diameter = 0.0, | ||
| float | beam_divergence = 0.0, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | lever_arm = None, | ||
| Optional[Union[vec3, List[float], Tuple[float, float, float]]] | boresight_rpy = None, | ||
| Optional[List[str]] | column_format = None, | ||
| float | range_noise_stddev = 0.0, | ||
| float | angle_noise_stddev = 0.0, | ||
| float | t0 = 0.0 ) |
Add a continuously-spinning multibeam scan from physical instrument parameters.
High-level entry point for a rotating multi-channel sensor (Velodyne/Ouster/Hesai) on a moving (or stationary) platform. The azimuth grid, rotation rate, and revolution count are derived internally from the azimuth resolution, PRF, and trajectory duration; you never specify an azimuth range or step count. Sets the scan's :class:`ScanMode` to ``SPINNING``. For a stationary "spin in place" capture (a tripod), supply two coincident poses (same position and orientation) separated in time by the acquisition duration.
| beam_elevation_angles | Per-channel beam ELEVATION angles above the horizon, in radians (NOT zenith — elevation above the horizon, where zenith = pi/2 - elevation; this matches manufacturer spec sheets) |
| azimuth_step | Azimuth angular resolution in radians per firing step (must be > 0) |
| pulse_rate_hz | Pulse repetition rate (PRF) in Hz (must be > 0) |
| traj_t | Monotonically increasing trajectory sample times in seconds (length M) |
| traj_pos | Platform positions in world coordinates, one [x, y, z] (or vec3) per traj_t entry |
| traj_rot | Platform orientations, one per traj_t entry. Length-4 quaternion (qx, qy, qz, qw, Hamilton body->world) when rot_is_quaternion is True, otherwise length-3 roll/pitch/yaw Euler triple in radians (intrinsic Z-Y-X). |
| rot_is_quaternion | Whether traj_rot holds quaternions (default True) or Euler angles |
| exit_diameter | Laser beam exit diameter (meters, default 0) |
| beam_divergence | Beam divergence angle (radians, default 0) |
| lever_arm | Sensor optical center in the platform body frame [x, y, z] meters (default origin) |
| boresight_rpy | Fixed sensor rotational misalignment [roll, pitch, yaw] radians (default 0) |
| column_format | Optional list of column-format labels (default ["x", "y", "z"]) |
| range_noise_stddev | Std. dev. of Gaussian range noise in meters (default 0) |
| angle_noise_stddev | Std. dev. of Gaussian angular jitter in radians (default 0) |
| t0 | Time of the first pulse in seconds (relative time; default 0) |
Definition at line 485 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.addTrianglesToContext | ( | self, | |
| Context | context ) |
Add triangulated mesh to Context as triangle primitives.
Converts the triangulated point cloud mesh into Context triangle
primitives that can be used for further analysis or visualization.
.. warning::
Raises once a run's triangles have been streamed to a sink registered with
:meth:`setTriangulationSink` -- the mesh is released rather than stored, so there
is nothing to add. Clear the sink before triangulating if you need the stored mesh.
| context | Helios Context instance |
Definition at line 2350 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.calculateHitGridCell | ( | self | ) |
Calculate hit point grid cell assignments.
Definition at line 1749 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.calculateLeafArea | ( | self, | |
| Context | context, | ||
| Optional[int] | min_voxel_hits = None, | ||
| Optional[float] | element_width = None, | ||
| Optional[Union[float, List[float]]] | Gtheta = None ) |
Calculate leaf area for each grid cell.
Requires triangulation to have been performed first, UNLESS a ``Gtheta`` is supplied
(see below).
.. note::
The cloud must contain misses (transmitted beams that returned nothing) — the
inversion fails fast without them. Misses are produced by
``syntheticScan(..., record_misses=True)`` (the default) or by
:meth:`gapfillMisses`. Use :meth:`hasMisses` to check.
| context | Helios Context instance |
| min_voxel_hits | Optional minimum number of hits required per voxel |
| element_width | Optional characteristic vegetation element width (meters). When provided, per-voxel sampling uncertainty (Pimont et al. 2018) is computed alongside the leaf-area estimate and becomes available via :meth:getCellLADVariance, :meth:getCellLeafAreaConfidenceInterval, and :meth:getGroupLADConfidenceInterval. element_width <= 0 yields a sampling-only variance. |
| Gtheta | Optional caller-supplied mean leaf-projection coefficient G(theta), in (0,1] (0.5 = spherical/random leaf-angle distribution). May be a single scalar (broadcast to every voxel) or a sequence of one value per grid cell in grid-cell order — the latter supports a spatially-varying (e.g. vertically-varying) leaf-angle distribution. When provided, leaf area is computed via a beam-based inversion that uses each hit's per-pulse beam origin and does NOT require triangulation — the only supported path for moving-platform scans (see :meth:addScanMoving). Requires both min_voxel_hits and element_width to also be specified. |
A single float applies one G(theta) to every voxel. A sequence supplies one G(theta) per grid cell, in grid-cell order (the order of :meth:getCellCenter), for a canopy whose leaf-angle distribution varies in space, typically with height. Its length must equal :meth:getGridCellCount and every value must be in (0,1]. The per-cell form requires helios-core v1.3.85.
| TypeError | If ``context`` is not a Context |
| ValueError | If the argument combination is invalid, a G(theta) value is outside (0,1], or a per-cell sequence is empty or does not match the grid cell count |
| HeliosError | If the native inversion fails (for example, the cloud has no misses) |
| RuntimeError | If a per-cell ``Gtheta`` is given and the native library predates helios-core v1.3.85 |
Definition at line 2200 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.calculateLeafAreaBlock | ( | self, | |
| Context | context, | ||
| ijk_min, | |||
| ijk_max, | |||
| int | min_voxel_hits, | ||
| float | element_width, | ||
| Optional[Union[float, List[float]]] | Gtheta = None ) |
Calculate leaf area for only a block of the voxel grid.
The block form of :meth:`calculateLeafArea`, for inverting a large grid a tile at a time. Requires a regular lattice grid (as built by :meth:`addGrid`); use :meth:`getGridGlobalCount` for the lattice dimensions and :meth:`getCellGlobalIJK` to map a cell index to its lattice coordinate.
| context | Helios Context instance |
| ijk_min | Lattice index (i, j, k) of the block's first cell |
| ijk_max | Lattice index (i, j, k) of the block's last cell, inclusive |
| min_voxel_hits | Minimum number of beams that must have entered a voxel |
| element_width | Characteristic vegetation element width (m); <= 0 yields a sampling-only variance |
| Gtheta | Optional caller-supplied G(theta) in (0,1]. A single float applies one value to every voxel; a sequence supplies one value per grid cell (the whole grid, not just the block) in grid-cell order. When omitted, triangulation supplies G(theta) and must have been run. |
| TypeError | If ``context`` is not a Context |
| ValueError | If a lattice index is not 3 elements, or a G(theta) sequence is empty |
| HeliosError | If the grid is not a regular lattice, the block is out of range, or the inversion fails (for example, the cloud has no misses) |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2932 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.calculateSyntheticGtheta | ( | self, | |
| Context | context ) |
Calculate synthetic G(theta) (for validation of synthetic scans).
Uses exact primitive geometry to calculate G(theta), useful for validating synthetic scan accuracy.
| context | Helios Context instance containing primitive geometry |
Definition at line 2282 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.calculateSyntheticLeafArea | ( | self, | |
| Context | context ) |
Calculate synthetic leaf area (for validation of synthetic scans).
Uses exact primitive geometry to calculate leaf area, useful for validating synthetic scan accuracy.
| context | Helios Context instance containing primitive geometry |
Definition at line 2267 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.coordinateRotation | ( | self, | |
| Union[SphericalCoord, List[float], Tuple[float, float]] | rotation ) |
Rotate all hit points by spherical rotation angles.
| rotation | Rotation angles (SphericalCoord or 2-3 element list) |
Definition at line 1313 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.coordinateShift | ( | self, | |
| Union[vec3, List[float], Tuple[float, float, float]] | shift ) |
Translate all hit points by a shift vector.
| shift | Translation vector (vec3 or 3-element list) |
Definition at line 1295 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.createHitDataColumn | ( | self, | |
| str | label, | ||
| HitDataType | column_type ) |
Create a per-hit scalar-data column with an explicit storage type.
Call this *before* adding data carrying ``label`` to fix the column's storage type instead of letting it be inferred from the label name. An explicitly typed column is never an INT32 column rejects a value that is not a 32-bit integer, and a FLOAT32 column stores values at float precision.
| label | Label of the data value (e.g. "intensity") |
| column_type | A :class:HitDataType member |
| TypeError | If ``label`` is not a str or ``column_type`` is not a HitDataType |
| ValueError | If ``label`` is empty |
| HeliosError | If the column already exists with a different type |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2450 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.deleteHitPoint | ( | self, | |
| int | index ) |
Delete a hit point from the cloud.
Definition at line 1234 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.deleteHitPoints | ( | self, | |
| int | first, | ||
| int | count ) |
Delete a contiguous range of hit points, preserving the order of the rest.
Removes hits ``[first, first+count)``. Unlike :meth:`deleteHitPoint`, which fills the freed slot with the last hit, this keeps every surviving hit in its relative order -- so draining the tail of the cloud (the release step of a streaming :meth:`syntheticScan`, see :meth:`setSyntheticScanHitSink`) costs O(count) and leaves earlier indices unchanged.
| first | Index of the first hit to delete |
| count | Number of hits to delete |
| ValueError | If ``first`` or ``count`` is negative |
| HeliosError | If the range extends past the end of the cloud |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2623 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.disableCDGPUAcceleration | ( | self | ) |
Disable GPU acceleration (use CPU ray tracing)
Definition at line 2399 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.disableMessages | ( | self | ) |
Disable console output messages.
Definition at line 1482 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.distanceFilter | ( | self, | |
| float | maxdistance ) |
Filter hit points by maximum distance from scanne.
Definition at line 1420 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.doesHitDataExist | ( | self, | |
| int | index, | ||
| str | label ) |
Check whether a named scalar data value exists for a hit point.
Per-hit data computed by syntheticScan includes 'intensity', 'distance', 'timestamp', 'target_index', 'target_count', 'deviation', 'nRaysHit', plus any primitive-data labels listed in the scan's column_format.
Definition at line 1112 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.enableCDGPUAcceleration | ( | self | ) |
Enable GPU acceleration for collision detection ray tracing.
Definition at line 2394 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.enableMessages | ( | self | ) |
Enable console output messages.
Definition at line 1486 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.estimateHitPointMemory | ( | self, | |
| int | hit_count ) |
Estimate the resident memory a cloud of hit_count points will occupy, in bytes.
Each stored point costs the size of a hit point plus, for every scalar-data label the cloud carries, one double of value and one byte of presence -- the columnar store is dense, so every label costs on every point. Excludes virtualized misses and the transient of growing the arrays; see :meth:`reserveHitPoints` for that. Most accurate once at least one point exists, since it reads the labels created so far.
| hit_count | Number of hit points to estimate for |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1948 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportGtheta | ( | self, | |
| str | filename ) |
Export G(theta) values for each grid cell to file.
Definition at line 2323 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportLeafAreaDensities | ( | self, | |
| str | filename ) |
Export leaf area densities for each grid cell to file.
Definition at line 2317 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportLeafAreas | ( | self, | |
| str | filename ) |
Export leaf areas for each grid cell to file.
Definition at line 2311 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportLeafAreaUncertainty | ( | self, | |
| str | filename ) |
Export per-voxel leaf-area sampling uncertainty to a self-describing ASCII file.
The file has a ``#``-prefixed header and one row per grid cell: ``cell_index leaf_area beam_count I_rdi LAD_std_error ci_valid``. Requires that :meth:`calculateLeafArea` has been run with an ``element_width`` (the uncertainty overload).
Definition at line 1457 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportPointCloud | ( | self, | |
| str | filename, | ||
| bool | write_header = True ) |
Export point cloud to ASCII file.
| filename | Output file path. |
| write_header | If True (default), prepend a #-prefixed comment line listing the column field names (CloudCompare convention). The loader skips #-prefixed lines, so headered files round-trip through loadXML(). Set False for a bare data file. |
Definition at line 1445 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportScans | ( | self, | |
| str | filename ) |
Export all scans to an XML metadata file plus one ASCII data file per scan.
| filename | Path of the XML metadata file to write (e.g. "output/scans.xml"). One ASCII data file is auto-generated per scan, named by stripping the XML extension and appending "_<scanID>.xyz" (e.g. "output/scans_0.xyz"). The resulting XML can be re-loaded with loadXML() from the same working directory. |
Definition at line 1470 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportTriangleAreas | ( | self, | |
| str | filename ) |
Export triangle areas to file.
.. warning::
Raises once a run's triangles have been streamed to a sink registered with
:meth:`setTriangulationSink` -- the mesh is released rather than stored.
Definition at line 2305 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.exportTriangleNormals | ( | self, | |
| str | filename ) |
Export triangle normal vectors to file.
.. warning::
Raises once a run's triangles have been streamed to a sink registered with
:meth:`setTriangulationSink` -- the mesh is released rather than stored.
Definition at line 2294 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.firstHitFilter | ( | self | ) |
Keep only first return hit points.
Definition at line 1429 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.gapfillMisses | ( | self | ) |
Gapfill sky/miss points where rays didn't hit geometry.
Important for accurate leaf area calculations with real LiDAR data. Should be called before triangulation when processing real data. Misses synthesized here are stored in virtualized form -- as a per-cell occupancy bit plus a scan-wide angular model rather than as stored points -- so they cost no per-point storage. They are counted by :meth:`getHitCount` and readable through every accessor regardless. See :meth:`hasVirtualMisses` and :meth:`getVirtualMissCount`.
getHitsXYZRGB, :meth:getHitScanIDArray, :meth:getHitDataArray), which read virtualized misses in one pass. A Python loop over the per-index getters costs O(Nphi) on each such point. Definition at line 1770 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.gapfillMissesCount | ( | self, | |
| Optional[int] | scanID = None, | ||
| bool | gapfill_grid_only = False, | ||
| bool | add_flags = False ) |
Gapfill missing points and return only how many were added.
Identical to :meth:`gapfillMisses` except that the count is returned instead of the filled positions, which for a fine scan grid is a large allocation most callers discard.
| scanID | Scan to gapfill. None (the default) gapfills every scan, in which case gapfill_grid_only and add_flags are not used. |
| gapfill_grid_only | Fill only within the voxel grid's bounding box |
| add_flags | Add gapfillMisses_code as hit point data (0=original, 1=gapfilled) |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1792 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getCellBeamCount | ( | self, | |
| int | index ) |
Get the beam count N that entered a grid cell during the leaf-area inversion.
Returns -1 if :meth:`calculateLeafArea` has not been run for this cell.
Definition at line 1682 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getCellCenter | ( | self, | |
| int | index ) |
Get the true world-space center position of a grid cell.
For a grid created with a non-zero azimuthal ``rotation``, this is the lattice center rotated about the grid anchor (about +z), so it lies in the same rotated world frame as the hit points, scan origins, and grid bounding box. For an un-rotated grid it is simply the lattice center.
Definition at line 1627 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getCellCenterUnrotated | ( | self, | |
| int | index ) |
Get the UNROTATED (axis-aligned lattice) center position of a grid cell.
Companion to :meth:`getCellCenter`, which applies the grid's azimuthal rotation. This returns the center on the axis-aligned lattice instead; for an un-rotated grid the two are identical. Use this when the caller applies the grid rotation itself (e.g. rotating a whole voxel group about the grid center for display) — passing the rotated center to such code rotates the lattice twice.
Definition at line 1643 of file LiDARCloud.py.
| Tuple[int, int, int] pyhelios.LiDARCloud.LiDARCloud.getCellGlobalIJK | ( | self, | |
| int | index ) |
Lattice index (i, j, k) of a grid cell along x, y and z.
For a grid built by :meth:`addGrid` this is the cell's position in the ``ndiv.x`` by ``ndiv.y`` by ``ndiv.z`` lattice; cells are stored in the order ``k*ny*nx + j*nx + i``. It is the coordinate :meth:`calculateLeafAreaBlock` takes.
| index | Index of a grid cell |
| ValueError | If ``index`` is negative |
| HeliosError | If ``index`` is out of range |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2980 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellGtheta | ( | self, | |
| int | index ) |
Get G(theta) value for a grid cell.
Definition at line 1737 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellLADVariance | ( | self, | |
| int | index ) |
Get the per-voxel LAD sampling variance for a grid cell.
Returns -1 if uncertainty has not been computed (call :meth:`calculateLeafArea` with an ``element_width``).
Definition at line 1704 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellLeafArea | ( | self, | |
| int | index ) |
Get leaf area of a grid cell (m²)
Definition at line 1667 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getCellLeafAreaConfidenceInterval | ( | self, | |
| int | index, | ||
| float | confidence_level = 0.95 ) |
Get the leaf-area confidence interval for a single grid cell.
Returns a ``(valid, lower, upper)`` tuple. ``valid`` is False when the interval is gated out by the Pimont validity envelope (single-voxel intervals are often untrustworthy; prefer :meth:`getGroupLADConfidenceInterval`). Requires :meth:`calculateLeafArea` to have been run with an ``element_width``.
Definition at line 1716 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellLeafAreaDensity | ( | self, | |
| int | index ) |
Get leaf area density of a grid cell (m²/m³)
Definition at line 1673 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellMeanPathLength | ( | self, | |
| int | index ) |
Get the mean beam path length (m) through a grid cell.
Definition at line 1694 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellRelativeDensityIndex | ( | self, | |
| int | index ) |
Get the relative density index (I_rdi) for a grid cell.
Definition at line 1688 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getCellRotation | ( | self, | |
| int | index ) |
Get the azimuthal rotation of a grid cell about the z-axis, in degrees.
The units match the ``rotation`` argument of :meth:`addGrid`. Note that :meth:`addGridCell` takes its rotation in radians.
Definition at line 1661 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getCellSize | ( | self, | |
| int | index ) |
Get size of a grid cell.
Definition at line 1650 of file LiDARCloud.py.
| dict pyhelios.LiDARCloud.LiDARCloud.getCroppedReturnStats | ( | self | ) |
Returns the last :meth:calculateLeafArea call inferred from target_count.
A pulse's returns are ordered by range and a beam crosses the (convex) voxel grid in one contiguous segment. So when a cloud has had returns removed -- cropped to the grid, say -- but its surviving returns still carry the per-pulse ``target_index`` and ``target_count`` the scanner wrote, the inversion places each missing return from the surviving indices alone: indices below the smallest surviving index were before the first surviving return, indices above the largest were beyond the last one, and only indices between two surviving returns cannot be placed. Under the crop-to-grid assumption the second group is counted as transmitted through every voxel the beam pierces, so a cropped beam keeps the transmittance its full record implied; the third is left out and reported as ambiguous. A stand-in miss (a return flagged ``is_miss`` sharing the pulse's timestamp) is ignored for counting when the inference applies.
beams_with_hidden_returns – pulses with at least one return recoveredhidden_before – removed returns placed before the first surviving return (expected after any near-field culling; changes nothing)hidden_after – removed returns placed beyond the last surviving return (counted as transmitted)hidden_ambiguous – removed returns between two surviving returns (not counted; a non-zero value means the cloud was cropped INSIDE the grid)beams_ambiguous – pulses carrying at least one ambiguous removed returnstandins_ignored – stand-in misses left out because the count covered themAll zero before the first inversion and for a cloud whose pulses are complete.
| RuntimeError | If the native library predates this feature |
Definition at line 1848 of file LiDARCloud.py.
|
static |
Default cap on the number of stored hit points in a cloud (100 million).
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1986 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.getExactPathLengths | ( | self | ) |
Whether path lengths are accumulated exactly.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 2036 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getGridCellCount | ( | self | ) |
Get total number of grid cells.
Definition at line 1617 of file LiDARCloud.py.
| Tuple[int, int, int] pyhelios.LiDARCloud.LiDARCloud.getGridGlobalCount | ( | self | ) |
Number of lattice cells along x, y and z (the ndiv passed to :meth:addGrid).
| HeliosError | If the grid is empty or its cells do not form a regular lattice |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2995 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getGroupLADConfidenceInterval | ( | self, | |
| List[int] | indices, | ||
| float | confidence_level = 0.95 ) |
Get the group-scale LAD confidence interval over a set of grid cells (recommended).
Returns a ``(valid, mean_lad, lower, upper)`` tuple (Pimont et al. 2018, Eq. 39, assuming voxel independence). Requires :meth:`calculateLeafArea` to have been run with an ``element_width``.
Definition at line 1728 of file LiDARCloud.py.
| RGBcolor pyhelios.LiDARCloud.LiDARCloud.getHitColor | ( | self, | |
| int | index ) |
Get color of a hit point.
Definition at line 1094 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getHitCount | ( | self | ) |
Get total number of hit points in cloud.
Definition at line 1064 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getHitData | ( | self, | |
| int | index, | ||
| str | label ) |
Get a named scalar data value for a hit point.
Raises HeliosError if the label does not exist for this hit; guard with doesHitDataExist() when unsure.
Definition at line 1122 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getHitDataAll | ( | self, | |
| str | label ) |
Bulk-export a named scalar data value for all hits in a single FFI call.
Returns a list of length getHitCount(); entries are NaN where the label is absent for that hit. Much faster than looping getHitData() for large clouds.
Definition at line 1135 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitDataArray | ( | self, | |
| str | label ) |
Bulk-export a named scalar field as an (getHitCount(),) float32 array, NaN where the label is absent for a hit.
Definition at line 1176 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getHitDataColumn | ( | self, | |
| str | label, | ||
| float | absent_value = -9999.0 ) |
Bulk-export a named scalar column via the native cache-linear columnar path.
Faster than :meth:`getHitDataAll` for whole-field reads (a single cache-linear pass over the contiguous native column rather than per-hit tree lookups), and returns full float64 precision. Entries are ``absent_value`` where the label is absent for a hit. Returns a list of length getHitCount().
Definition at line 1190 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnArray | ( | self, | |
| str | label, | ||
| float | absent_value = -9999.0 ) |
Bulk-export a named scalar column as an (getHitCount(),) float64 numpy array via the columnar path (absent_value where the label is absent for a hit).
Definition at line 1209 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnFloat32 | ( | self, | |
| str | label, | ||
| float | absent_value = -9999.0 ) |
Bulk-export a named scalar column as 32-bit floats.
Reads a ``FLOAT32`` column without widening it to 8 bytes per hit; a ``FLOAT64`` or ``INT32`` column is converted element-wise. See :meth:`getHitDataColumn` for the double-precision counterpart.
| label | Label of the data value |
| absent_value | Value reported for hits that lack the label |
getHitCount| TypeError | If ``label`` is not a str |
| ValueError | If ``label`` is empty |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2502 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnFloat32Array | ( | self, | |
| str | label, | ||
| float | absent_value = -9999.0 ) |
Bulk-export a named scalar column as a (getHitCount(),) float32 numpy array.
See :meth:`getHitDataColumnFloat32`.
Definition at line 2514 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnIndex | ( | self, | |
| str | label ) |
Get the internal column slot index for a hit-data label.
Per-hit scalar data is stored column-wise; this resolves a label to its column slot for repeated bulk access without re-resolving the label by string. Returns -1 if the label has never been set on any hit.
Definition at line 1202 of file LiDARCloud.py.
| List[int] pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnInt32 | ( | self, | |
| str | label, | ||
| int | absent_value = -9999 ) |
Bulk-export a named scalar column as 32-bit signed integers.
Reads an ``INT32`` column without widening it.
| label | Label of the data value |
| absent_value | Value reported for hits that lack the label |
getHitCount| TypeError | If ``label`` is not a str |
| ValueError | If ``label`` is empty |
| HeliosError | If any value is not an integer in the 32-bit range (a fractional value, a NaN, or a timestamp) – read such a label with :meth:getHitDataColumn instead |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2542 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitDataColumnInt32Array | ( | self, | |
| str | label, | ||
| int | absent_value = -9999 ) |
Bulk-export a named scalar column as a (getHitCount(),) int32 numpy array.
See :meth:`getHitDataColumnInt32`.
Definition at line 2554 of file LiDARCloud.py.
| HitDataType pyhelios.LiDARCloud.LiDARCloud.getHitDataType | ( | self, | |
| str | label ) |
Storage type of an existing per-hit scalar-data column.
A column typed implicitly may since have widened to ``FLOAT64``.
| label | Label of the data value |
HitDataType| TypeError | If ``label`` is not a str |
| ValueError | If ``label`` is empty |
| HeliosError | If no column exists for the label (use :meth:getHitDataColumnIndex to test for existence without raising) |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2476 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitMissArray | ( | self | ) |
Bulk-export the miss flag of every hit as an (getHitCount(),) int32 array (1 == sky/miss, 0 == real surface return).
Definition at line 1226 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getHitOrigin | ( | self, | |
| int | index ) |
Get the (x,y,z) beam-emission origin of a hit point.
For moving-platform scans (see :meth:`addScanMoving`) this is the per-pulse emission origin recorded on the hit; for static scans it falls back to the single scan origin of the hit's scan.
Definition at line 1079 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getHitPointCapacity | ( | self | ) |
Number of hit points the cloud can hold before its arrays reallocate.
The counterpart of :meth:`reserveHitPoints`: use it to confirm a reservation took effect, or to see how much headroom remains before the next growth reallocation.
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 3010 of file LiDARCloud.py.
| SphericalCoord pyhelios.LiDARCloud.LiDARCloud.getHitRaydir | ( | self, | |
| int | index ) |
Get ray direction of a hit point.
Definition at line 1086 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getHitScanID | ( | self, | |
| int | index ) |
Get the scan ID a hit point belongs to.
Definition at line 1101 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitScanIDArray | ( | self | ) |
Bulk-export the scan ID of every hit as an (getHitCount(),) int32 array.
Definition at line 1217 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitScanIDColumn | ( | self | ) |
Read every hit's scan ID in index order in one pass.
See :meth:`getHitXYZColumn` for why this is preferred over a per-index loop.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1925 of file LiDARCloud.py.
Bulk-export coordinates and colors for all hits in a single FFI call.
Returns (positions, colors) where positions is a list of vec3 and colors a list of RGBcolor, each of length getHitCount(). Much faster than looping getHitXYZ()/getHitColor() for large clouds.
Definition at line 1147 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitsXYZRGBArrays | ( | self | ) |
Bulk-export hit coordinates + colors as numpy arrays.
Returns (xyz, rgb), each (getHitCount(), 3) float32. Empty (0,3) arrays when there are no hits.
Definition at line 1167 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getHitXYZ | ( | self, | |
| int | index ) |
Get coordinates of a hit point.
Definition at line 1068 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getHitXYZColumn | ( | self | ) |
Read every hit's position in index order in one pass.
Costs O(1) per hit even for virtualized gap-filled misses, which the per-index accessors resolve in O(Nphi). Prefer this to a Python loop over :meth:`getHitXYZ` whenever the whole cloud is being read.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1911 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getMaxHitPoints | ( | self | ) |
Current cap on stored hit points, or 0 if the check is disabled.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1976 of file LiDARCloud.py.
|
static |
Return the LIDAR_MISS_DISTANCE constant (meters): the distance at which a miss point is placed along its beam.
Definition at line 1286 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanAngleNoiseStdDev | ( | self, | |
| int | scanID ) |
Get the angular (beam-pointing) jitter standard deviation for a scan (radians).
Returns the value supplied to addScan() as ``angle_noise_stddev`` (0.0 if disabled).
Definition at line 734 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanAzimuthOffset | ( | self, | |
| int | scanID ) |
Get the global scanner azimuth (heading) offset for a scan (radians; 0.0 if none).
Definition at line 752 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getScanBeamZenithAngles | ( | self, | |
| int | scanID ) |
Get the per-channel beam zenith angles (radians) for a multibeam scan.
Returns an empty list for a raster scan.
Definition at line 772 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanCount | ( | self | ) |
Get total number of scans in the cloud.
Definition at line 699 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanDetectionThreshold | ( | self, | |
| int | scanID ) |
Get the detection threshold (energy fraction, noise floor) of a scan.
Definition at line 911 of file LiDARCloud.py.
| SphericalCoord pyhelios.LiDARCloud.LiDARCloud.getScanGridDirection | ( | self, | |
| int | scanID, | ||
| int | row, | ||
| int | column ) |
Beam direction at a scan-grid cell, from the model fitted during gap-filling.
Available once :meth:`gapfillMisses` has run on the scan through the row/column path. This is the same reconstruction used to place synthesized misses, exposed so a caller can check the fitted geometry against known directions.
| scanID | Scan index |
| row | Scan-grid row (zenith index) |
| column | Scan-grid column (azimuth index) |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1892 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanHitCount | ( | self, | |
| int | scanID ) |
Number of hit points (stored returns plus virtualized misses) belonging to one scan.
This is the length the per-scan readers fill -- :meth:`getScanHitIndices`, :meth:`getScanHitXYZColumn` and :meth:`getScanHitDataColumn`.
| scanID | Scan index |
| ValueError | If ``scanID`` is negative |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2780 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getScanHitDataColumn | ( | self, | |
| int | scanID, | ||
| str | label, | ||
| float | absent_value = -9999.0 ) |
Read one scan's values of a scalar-data label in a single pass, as doubles.
The per-scan counterpart of :meth:`getHitDataColumn`; see :meth:`getScanHitXYZColumn` for why this is preferred over filtering the whole cloud.
| scanID | Scan index |
| label | Label of the data value |
| absent_value | Value reported for hits that lack the label |
| TypeError | If ``label`` is not a str |
| ValueError | If ``scanID`` is negative or ``label`` is empty |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2851 of file LiDARCloud.py.
| List[float] pyhelios.LiDARCloud.LiDARCloud.getScanHitDataColumnFloat32 | ( | self, | |
| int | scanID, | ||
| str | label, | ||
| float | absent_value = -9999.0 ) |
Read one scan's values of a scalar-data label as 32-bit floats.
See :meth:`getScanHitDataColumn` and :meth:`getHitDataColumnFloat32`.
| TypeError | If ``label`` is not a str |
| ValueError | If ``scanID`` is negative or ``label`` is empty |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2869 of file LiDARCloud.py.
| List[int] pyhelios.LiDARCloud.LiDARCloud.getScanHitDataColumnInt32 | ( | self, | |
| int | scanID, | ||
| str | label, | ||
| int | absent_value = -9999 ) |
Read one scan's values of a scalar-data label as 32-bit signed integers.
See :meth:`getScanHitDataColumn` and :meth:`getHitDataColumnInt32`.
| TypeError | If ``label`` is not a str |
| ValueError | If ``scanID`` is negative or ``label`` is empty |
| HeliosError | If any value is not an integer in the 32-bit range |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2888 of file LiDARCloud.py.
| List[int] pyhelios.LiDARCloud.LiDARCloud.getScanHitIndices | ( | self, | |
| int | scanID ) |
Global indices of one scan's hit points, in the order the per-scan readers use.
A scan's hits need not be contiguous in the global index space (a filter's swap-and-pop deletion reorders the cloud, and gap-filled misses live above every stored return), so the per-scan readers present a scan's hits in their own local order. This maps each local position back to the global index used by :meth:`getHitXYZ` and friends. Stored returns come first, in stored order, followed by the scan's virtualized misses.
| scanID | Scan index |
| ValueError | If ``scanID`` is negative |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2804 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getScanHitXYZColumn | ( | self, | |
| int | scanID ) |
Read one scan's hit positions in a single pass.
Costs O(hits in the scan), not O(hits in the cloud): the scan's stored returns are located through an index built once and kept until the cloud changes, and its virtualized misses are walked in occupancy order rather than resolved one at a time. Prefer this to filtering :meth:`getHitXYZColumn` by scan.
| scanID | Scan index |
| ValueError | If ``scanID`` is negative |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2827 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanMaxReturns | ( | self, | |
| int | scanID ) |
Get the maximum returns per pulse used in single/limited-return mode (1 = single, N = N-return).
Definition at line 855 of file LiDARCloud.py.
| ScanMode pyhelios.LiDARCloud.LiDARCloud.getScanMode | ( | self, | |
| int | scanID ) |
Get the high-level acquisition mode of a scan as a :class:ScanMode.
STATIC_RASTER (fixed-origin grid), MOVING_RASTER (fan swept along a trajectory), SPINNING (continuously-rotating multi-channel sensor), or RISLEY_PRISM (Livox-style rosette).
Definition at line 782 of file LiDARCloud.py.
| vec3 pyhelios.LiDARCloud.LiDARCloud.getScanOrigin | ( | self, | |
| int | scanID ) |
Get origin of a specific scan.
Definition at line 703 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanPattern | ( | self, | |
| int | scanID ) |
Get the scan pattern for a scan.
Returns an integer: 0 = raster (uniform angular grid), 1 = spinning multibeam (rotating multi-channel sensor), 2 = Risley-prism (Livox-style rosette). Compare against ``ScanPattern.RASTER`` / ``ScanPattern.SPINNING_MULTIBEAM`` / ``ScanPattern.RISLEY_PRISM``.
Definition at line 763 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanPulseWidth | ( | self, | |
| int | scanID ) |
Get the pulse width / range resolution (meters) of a scan (0 = use syntheticScan argument).
Definition at line 897 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanRangeNoiseStdDev | ( | self, | |
| int | scanID ) |
Get the range (along-beam) measurement noise standard deviation for a scan (meters).
Returns the value supplied to addScan() as ``range_noise_stddev`` (0.0 if disabled).
Definition at line 725 of file LiDARCloud.py.
| ReturnMode pyhelios.LiDARCloud.LiDARCloud.getScanReturnMode | ( | self, | |
| int | scanID ) |
Get the return-reporting mode of a scan as a :class:ReturnMode (MULTI or SINGLE).
Definition at line 822 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanRevolutions | ( | self, | |
| int | scanID ) |
Get the number of revolutions the sensor head made (spinning scans; 0 otherwise).
Definition at line 800 of file LiDARCloud.py.
| List[RisleyPrism] pyhelios.LiDARCloud.LiDARCloud.getScanRisleyPrisms | ( | self, | |
| int | scanID ) |
Get the rotating wedge prisms of a Risley-prism scan as a list of :class:RisleyPrism.
Returns the prism stack in beam-traversal order (empty for non-Risley scans).
Definition at line 809 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanRisleyRefractiveIndexAir | ( | self, | |
| int | scanID ) |
Get the refractive index of the medium surrounding a Risley scan's prisms (1.0 for non-Risley).
Definition at line 816 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanRotationRate | ( | self, | |
| int | scanID ) |
Get the sensor-head rotation rate in revolutions/second (spinning scans; 0 otherwise).
Definition at line 794 of file LiDARCloud.py.
| SingleReturnSelection pyhelios.LiDARCloud.LiDARCloud.getScanSingleReturnSelection | ( | self, | |
| int | scanID ) |
Get the single/limited-return selection policy as a :class:SingleReturnSelection.
Definition at line 837 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanSizePhi | ( | self, | |
| int | scanID ) |
Get number of azimuthal scan points for a scan.
Definition at line 716 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanSizeTheta | ( | self, | |
| int | scanID ) |
Get number of zenith scan points for a scan.
Definition at line 710 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getScanStepsPerRev | ( | self, | |
| int | scanID ) |
Get the number of azimuth firing steps per revolution (spinning scans; 0 otherwise).
Definition at line 788 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanTiltPitch | ( | self, | |
| int | scanID ) |
Get the global scanner tilt pitch angle for a scan (radians; 0.0 if level).
Definition at line 746 of file LiDARCloud.py.
| float pyhelios.LiDARCloud.LiDARCloud.getScanTiltRoll | ( | self, | |
| int | scanID ) |
Get the global scanner tilt roll angle for a scan (radians; 0.0 if level).
Definition at line 740 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getSyntheticScanMemoryBudget | ( | self | ) |
Get the soft memory budget (bytes) for :meth:syntheticScan's transient buffers.
Returns the explicitly configured budget set via :meth:`setSyntheticScanMemoryBudget`, or 0 if using the automatic path-dependent default (8 GiB on a GPU build, 4 GiB otherwise).
Definition at line 893 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getTriangleCount | ( | self | ) |
Get number of triangles in the mesh.
.. warning::
Reports zero once a run's triangles have been streamed to a sink registered with
:meth:`setTriangulationSink` -- the mesh is released rather than stored. Clear the
sink before triangulating if you need the stored mesh.
Definition at line 1347 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.getTriangleVerticesAll | ( | self | ) |
Bulk-export every triangle's vertices and source scan in one call.
Returns (xyz_flat, scan_ids): xyz_flat is a (T*9,) float32 array laid out
[v0x,v0y,v0z, v1x,v1y,v1z, v2x,v2y,v2z] per triangle, scan_ids is a (T,)
int32 array. Avoids the Context round-trip and the per-triangle
getPrimitiveVertices loop.
.. warning::
Raises once a run's triangles have been streamed to a sink registered with
:meth:`setTriangulationSink` -- the mesh is released rather than stored, and the
native consumers refuse to operate on an empty mesh. Clear the sink before
triangulating if you need the stored mesh.
Definition at line 1379 of file LiDARCloud.py.
| dict pyhelios.LiDARCloud.LiDARCloud.getTriangulationStats | ( | self | ) |
Filter diagnostics from the most recent triangulateHitPoints() call.
Returns a dict::
{"candidates", "dropped_lmax", "dropped_aspect", "dropped_degenerate"}
Each dropped triangle is attributed to one primary reason (Lmax, then
aspect, then degenerate), so ``candidates == getTriangleCount() +
dropped_lmax + dropped_aspect + dropped_degenerate``. All zero if
triangulation has not been run. Use this to tell whether an empty or
sparse mesh is data-limited (few candidates) or filter-limited (many
candidates dropped by Lmax/aspect).
Definition at line 1363 of file LiDARCloud.py.
| int pyhelios.LiDARCloud.LiDARCloud.getVirtualMissCount | ( | self | ) |
Number of gap-filled misses currently held in virtualized form.
A miss synthesized by :meth:`gapfillMisses` is a pure function of its scan-grid cell, so it is stored implicitly rather than as an element of the hit array. Such points are counted by :meth:`getHitCount` and readable through every accessor, but occupy no per-point storage.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1812 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.hasMisses | ( | self | ) |
Return True if the cloud contains at least one miss.
:meth:`calculateLeafArea` requires misses and fails fast without them.
Definition at line 1254 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.hasVirtualMisses | ( | self | ) |
Whether any gap-filled miss is currently held in virtualized form.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1857 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.initializeCollisionDetection | ( | self, | |
| Context | context ) |
Initialize CollisionDetection plugin for ray tracing.
Required before performing synthetic scans.
| context | Helios Context instance containing geometry |
Definition at line 2363 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.is_available | ( | self | ) |
Check if LiDAR is available in current build.
Definition at line 3043 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.isGPUAccelerationEnabled | ( | self | ) |
Return True if GPU acceleration is currently enabled for collision-detection ray tracing.
Definition at line 2412 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.isGPUAvailable | ( | self | ) |
Return True if a CUDA-capable GPU is available for collision-detection ray tracing.
Reports capability (compiled with CUDA, a device present, and HELIOS_NO_GPU not set); use :meth:`isGPUAccelerationEnabled` to query whether GPU acceleration is currently toggled on.
Definition at line 2408 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.isHitMiss | ( | self, | |
| int | index ) |
Return True if a hit is a "miss" (a fired pulse that returned nothing).
Misses are the transmitted beams that form the denominator of the per-voxel transmission probability used by :meth:`calculateLeafArea`. They are produced by ``syntheticScan(..., record_misses=True)`` and by :meth:`gapfillMisses`.
Definition at line 1245 of file LiDARCloud.py.
| bool pyhelios.LiDARCloud.LiDARCloud.isMultiReturnData | ( | self | ) |
Return True if the cloud contains multi-return data.
Multi-return data is data in which a single laser pulse produced more than one recorded return (any hit with ``target_count`` greater than 1). This is a behavioral switch, not just a descriptive property: :meth:`triangulateHitPoints` branches on it, triangulating first returns only (with an adaptive separation filter) for multi-return data and treating every return as an independent single return otherwise. The two branches can differ substantially in reconstructed surface area, so a cloud assembled by hand (for example through :meth:`addHitPoints` or the native ASCII loader) can use this to confirm which one will run. Multi-return data must also carry the ``timestamp`` and ``target_index`` hit-data fields, which triangulation needs to group returns into beams and select first returns. If ``target_count > 1`` is found but either field is absent, this raises rather than reporting an answer the rest of the pipeline cannot act on. Requires helios-core v1.3.85 or newer.
| HeliosError | If multi-return data is present but ``timestamp`` or target_index is missing |
| RuntimeError | If the native library predates helios-core v1.3.85 |
Definition at line 1280 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.lastHitFilter | ( | self | ) |
Keep only last return hit points.
Definition at line 1433 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.loadXML | ( | self, | |
| str | filename ) |
Load scan metadata from XML file.
Definition at line 1476 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.materializeMisses | ( | self | ) |
Convert every virtualized gap-filled miss into a stored hit point.
Every observable is unchanged by this call -- it trades the memory saving for real storage. It happens automatically before any operation that renumbers the hit index space (adding or deleting a hit point, writing hit data or a grid cell), so calling it explicitly is only needed to pay that cost at a chosen moment.
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1871 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.reflectanceFilter | ( | self, | |
| float | minreflectance ) |
Filter hit points by minimum reflectance value.
Definition at line 1425 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.reserveHitPoints | ( | self, | |
| int | hit_count ) |
Reserve capacity for hit points and every scalar-data column at once.
Growing the hit-point array by repeated insertion reallocates geometrically, and during every reallocation the old and new buffers are both live. For a cloud of tens of millions of returns that transient is gigabytes on top of the steady-state cost, and on Windows it is charged against the system commit limit at allocation time so a load that would comfortably fit once settled can still fail while growing. Reserving the final size once removes the transient entirely. This only reserves capacity; it does not create hit points, and :meth:`getHitCount` is unchanged. Reserving less than the eventual total is harmless, as is reserving more.
| hit_count | Expected total number of hit points in the cloud |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 2009 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setCellGtheta | ( | self, | |
| float | Gtheta, | ||
| int | index ) |
Set G(theta) value for a grid cell.
Definition at line 1743 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.setExactPathLengths | ( | self, | |
| bool | exact ) |
Keep every beam path length exactly, instead of binning them.
The leaf-area inversion bins per-beam voxel path lengths once a voxel accumulates many samples, which bounds memory that would otherwise grow without limit with scan size. Binning recovers the extinction coefficient far inside the solver's tolerance, so this is an escape hatch for unusual geometry, or for confirming that binning is not responsible for a difference between two results.
| exact | True to keep every sample; False (the default) to bin above the threshold |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 2027 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setExternalTriangulation | ( | self, | |
| vertices, | |||
| scan_ids ) |
Replace the internal triangulation with an externally-supplied mesh.
Bypasses the internal Delaunay triangulation so a mesh produced elsewhere (a re-used Helios triangulation, or a per-scan open3d Ball-Pivot mesh) can drive leaf-area inversion without a recompute. After this call, ``calculateLeafArea()`` runs unchanged.
| vertices | Triangle vertices in world coordinates, accepted as a (T, 9) array laid out [v0x,v0y,v0z, v1x,v1y,v1z, v2x,v2y,v2z] per triangle, a (T, 3, 3) array, or a flat (T*9,) array – the same layout :meth:getTriangleVerticesAll exports, so a Helios mesh round-trips directly. |
| scan_ids | Source scan index for each triangle, shape (T,). Required; every entry must be a valid scan index (see :meth:addScan), since the leaf-angle G(theta) term needs each triangle's ray direction. A merged mesh with no scan association is not valid. |
A grid must already be defined (see :meth:addGrid).
Definition at line 1403 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.setMaxHitPoints | ( | self, | |
| int | max_hits ) |
Set the cap on stored hit points before loading fails with a diagnostic.
Exceeding the cap raises an error naming the projected point count and the limit, rather than throwing from inside the allocator where neither the scan responsible nor the size is visible. The default (:meth:`getDefaultMaxHitPoints`) is deliberately it guards against a mis-specified scan grid exhausting the machine, and is not a statement about machine capacity. Raise it when the machine genuinely has the memory.
| max_hits | Maximum stored hit points, or 0 to disable the check |
| RuntimeError | If the native library predates helios-core v1.3.84 |
Definition at line 1967 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setProgressCallback | ( | self, | |
| callback ) |
Register a progress callback fired with (progress_fraction, message) during :meth:syntheticScan.
``progress_fraction`` is a float in [0, 1]; ``message`` is a ``str`` describing the current phase. Pass ``None`` to clear the callback. The callback bridge is kept alive on this :class:`LiDARCloud` for as long as it is registered.
Definition at line 3019 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setScanDetectionThreshold | ( | self, | |
| int | scanID, | ||
| float | detection_threshold ) |
Set the detection threshold (energy fraction, noise floor) of a scan.
Definition at line 917 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setScanMaxReturns | ( | self, | |
| int | scanID, | ||
| int | max_returns ) |
Set the maximum returns per pulse used in single/limited-return mode (must be >= 1).
Definition at line 861 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setScanPulseWidth | ( | self, | |
| int | scanID, | ||
| float | pulse_width ) |
Set the pulse width / range resolution (meters) of a scan (0 = use syntheticScan argument).
Definition at line 903 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setScanReturnMode | ( | self, | |
| int | scanID, | ||
| Union[ReturnMode, int] | return_mode ) |
Set the return-reporting mode of a scan (ReturnMode.MULTI or ReturnMode.SINGLE).
Only affects analytic-waveform synthetic scans (more than one ray per pulse).
Definition at line 831 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setScanSingleReturnSelection | ( | self, | |
| int | scanID, | ||
| Union[SingleReturnSelection, int] | selection ) |
Set the single/limited-return selection policy (STRONGEST, FIRST, LAST, or STRONGEST_PLUS_LAST).
Used when the scan's return mode is SINGLE and a pulse resolves more returns than maxReturns. STRONGEST_PLUS_LAST is a dual-return mode that intrinsically yields 1 or 2 returns and ignores maxReturns.
Definition at line 849 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.setSyntheticScanHitSink | ( | self, | |
| callback ) |
Register a sink fired after each chunk of a :meth:syntheticScan lands in the cloud.
Without a sink, every chunk's returns accumulate in the cloud until the scan finishes,
so a very large scan holds every return before the caller can read any. With a sink,
``callback(first, count)`` is invoked after each chunk with the index of the first new
hit and the number of new hits. Inside the callback the new hits can be read (through
the per-scan column readers), written out, and then released with
:meth:`deleteHitPoints` -- they are always the tail of the cloud, so the cloud never
holds more than one chunk.
Chunk size is bounded by :meth:`setSyntheticScanMemoryBudget`. Pass ``None`` to clear.
.. note::
An exception raised inside ``callback`` cannot propagate through the native call
(a Python exception in a ctypes callback is swallowed and reported to C++ as
success, which would let the scan continue as though nothing failed). It is
captured and re-raised from the call that triggered it -- typically
:meth:`syntheticScan`.
| callback | Callable taking (first, count), or None to clear |
| TypeError | If ``callback`` is neither callable nor None |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2726 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setSyntheticScanMemoryBudget | ( | self, | |
| int | bytes ) |
Set the soft memory budget (bytes) for :meth:syntheticScan's transient buffers.
:meth:`syntheticScan` fans each pulse into ``rays_per_pulse`` sub-rays; for a large scan the simultaneously-traced sub-rays can demand many gigabytes if traced in one batch. This caps the live trace scratch buffers, so the per-scan beam fan-out is processed in chunks sized to stay near this budget regardless of scan resolution. It bounds only the transient buffers, not the output cloud. If never called, the budget is automatic and path-dependent (8 GiB on a GPU build, 4 GiB otherwise). Call this to override that with a fixed cap, typically to lower peak memory on a constrained host.
| bytes | Soft cap in bytes on the live ray-tracing scratch buffers. Must be > 0. |
Definition at line 883 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.setSyntheticScanProgressPointer | ( | self, | |
| ptr ) |
Register an external per-scan progress counter polled during :meth:syntheticScan.
``ptr`` is a ``ctypes.c_int`` into which syntheticScan writes the 0-based index of the scan currently being ray-traced (set to :meth:`getScanCount` when the batch finishes), letting a host thread poll progress while the blocking scan runs. The counter is owned by the caller and must outlive the scan. Pass ``None`` to clear.
Definition at line 2422 of file LiDARCloud.py.
| None pyhelios.LiDARCloud.LiDARCloud.setTriangulationSink | ( | self, | |
| callback ) |
Register a sink that receives each scan's triangles as :meth:triangulateHitPoints finishes it.
With a sink set, triangulation hands each scan's finished triangles to ``callback`` and
then releases them, keeping only the per-voxel leaf-angle sums the leaf-area inversion
needs. Retained memory becomes one scan's triangles at a time, and
:meth:`calculateLeafArea` still works and gives the same result.
``callback`` is called as ``callback(scanID, vertices, ids)`` where ``vertices`` is a
``(T, 9)`` float32 numpy array laid out ``[v0x,v0y,v0z, v1x,v1y,v1z, v2x,v2y,v2z]`` per
triangle and ``ids`` is a ``(T, 2)`` int32 array of ``[scanID, gridcell]``. Both are
copies owned by the caller. Pass ``None`` to clear the sink.
.. warning::
Once a run's triangles have been streamed, the mesh is not retained:
:meth:`getTriangleCount` reports zero and :meth:`getTriangleVerticesAll`,
:meth:`addTrianglesToContext`, :meth:`exportTriangleNormals` and
:meth:`exportTriangleAreas` raise rather than silently operating on an empty mesh.
Clear the sink before triangulating if you need the stored mesh.
.. note::
An exception raised inside ``callback`` cannot propagate through the native call
(a Python exception in a ctypes callback is swallowed and reported to C++ as
success). It is captured and re-raised from the call that triggered it --
typically :meth:`triangulateHitPoints`.
| callback | Callable taking (scanID, vertices, ids), or None to clear |
| TypeError | If ``callback`` is neither callable nor None |
| RuntimeError | If the native library predates helios-core v1.3.86 |
Definition at line 2663 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.syntheticScan | ( | self, | |
| Context | context, | ||
| Optional[int] | rays_per_pulse = None, | ||
| Optional[float] | pulse_distance_threshold = None, | ||
| bool | scan_grid_only = False, | ||
| bool | record_misses = True, | ||
| bool | append = False, | ||
| Optional[Union[ReturnMode, int]] | return_mode = None, | ||
| cancel_flag = None ) |
Perform synthetic LiDAR scan of geometry in Context.
Requires scan metadata to be defined first via addScan() or loadXML(). Uses ray tracing to simulate LiDAR instrument measurements.
| context | Helios Context containing geometry to scan |
| rays_per_pulse | Number of rays per pulse (None=discrete-return, typical: 100) |
| pulse_distance_threshold | Distance threshold for aggregating hits (meters, required for waveform) |
| scan_grid_only | If True, only scan within defined grid cells |
| record_misses | If True, record miss/sky points where rays don't hit geometry |
| append | If True, append to existing hits; if False, clear existing hits |
| return_mode | Optional :class:ReturnMode (MULTI or SINGLE) for analytic-waveform scans. Overrides each scan's stored return mode for this call only. Only valid when rays_per_pulse is set (waveform mode); raises ValueError otherwise. In SINGLE mode up to each scan's getScanMaxReturns() returns per pulse are reported, selected by the scan's single-return selection policy. |
| cancel_flag | Optional ctypes.c_int polled during the ray trace. Setting it non-zero from another thread aborts the scan mid-pass. It is cleared when the call returns, so a later scan on this cloud is not pre-cancelled. Example (Discrete-return):
>>> from pyhelios import Context, LiDARCloud
>>> from pyhelios.types import vec3
>>> with Context() as context:
... # Add geometry
... context.addPatch(center=vec3(0, 0, 0.5), size=vec2(1, 1))
|
| ... | ... with LiDARCloud() as lidar: ... # Define scan parameters ... scan_id = lidar.addScan( ... origin=vec3(0, 0, 2), ... Ntheta=100, theta_range=(0, 1.57), ... Nphi=100, phi_range=(0, 6.28), ... exit_diameter=0, beam_divergence=0 ... ) |
| ... | ... # Perform discrete-return scan ... lidar.syntheticScan(context) |
Example (Full-waveform): >>> lidar.syntheticScan( ... context, ... rays_per_pulse=100, ... pulse_distance_threshold=0.02, ... record_misses=True ... )
Definition at line 2086 of file LiDARCloud.py.
| pyhelios.LiDARCloud.LiDARCloud.triangulateHitPoints | ( | self, | |
| float | Lmax, | ||
| float | max_aspect_ratio = 4.0 ) |
Generate triangle mesh from hit points using Delaunay triangulation.
| Lmax | Maximum triangle edge length |
| max_aspect_ratio | Maximum triangle aspect ratio (default 4.0) |
Definition at line 1332 of file LiDARCloud.py.
|
protected |
Definition at line 2382 of file LiDARCloud.py.
|
protected |
Definition at line 193 of file LiDARCloud.py.
|
protected |
Definition at line 199 of file LiDARCloud.py.
|
protected |
Definition at line 207 of file LiDARCloud.py.
|
protected |
Definition at line 206 of file LiDARCloud.py.
|
protected |
Definition at line 205 of file LiDARCloud.py.
|
protected |
Definition at line 204 of file LiDARCloud.py.