![]() |
0.1.39
|
High-level interface for plant architecture modeling and procedural plant generation. More...
High-level interface for plant architecture modeling and procedural plant generation.
PlantArchitecture provides access to the comprehensive plant library with 25+ plant models including trees (almond, apple, olive, walnut), crops (bean, cowpea, maize, rice, soybean), and other plants. This class enables procedural plant generation, time-based growth simulation, and plant community modeling.
This class requires the native Helios library built with PlantArchitecture support. Use context managers for proper resource cleanup.
Definition at line 273 of file PlantArchitecture.py.
Public Member Functions | |
| __new__ (cls, context=None) | |
| Create PlantArchitecture instance. | |
| __init__ (self, Context context) | |
| Initialize PlantArchitecture with a Helios context. | |
| __enter__ (self) | |
| Context manager entry. | |
| __exit__ (self, exc_type, exc_val, exc_tb) | |
| Context manager exit - cleanup resources. | |
| __del__ (self) | |
| Destructor to ensure C++ resources freed even without 'with' statement. | |
| None | loadPlantModelFromLibrary (self, str plant_label) |
| Load a plant model from the built-in library. | |
| int | buildPlantInstanceFromLibrary (self, vec3 base_position, float age, Optional[dict] build_parameters=None) |
| Build a plant instance from the currently loaded library model. | |
| List[int] | buildPlantCanopyFromLibrary (self, vec3 canopy_center, vec2 plant_spacing, int2 plant_count, float age, float germination_rate=1.0, Optional[dict] build_parameters=None) |
| Build a canopy of regularly spaced plants from the currently loaded library model. | |
| None | advanceTime (self, float dt, Optional[int] plant_id=None, Optional[List[int]] plant_ids=None, Optional[int] years=None) |
| Advance time for plant growth and development. | |
| None | enableAttractionPoints (self, List[vec3] points, Optional[int] plant_id=None, Optional[float] view_half_angle_deg=None, float look_ahead_distance=0.1, float attraction_weight=0.6) |
| Steer shoot growth toward a set of target points. | |
| None | disableAttractionPoints (self, Optional[int] plant_id=None) |
| Stop steering growth toward attraction points. | |
| None | updateAttractionPoints (self, List[vec3] points, Optional[int] plant_id=None) |
| Replace the current attraction point set. | |
| None | appendAttractionPoints (self, List[vec3] points, Optional[int] plant_id=None) |
| Add to the current attraction point set. | |
| None | setAttractionParameters (self, float view_half_angle_deg, float look_ahead_distance, float attraction_weight, float obstacle_reduction_factor=0.75, Optional[int] plant_id=None) |
| Tune how strongly attraction points steer growth. | |
| setProgressCallback (self, callback) | |
| Set a callback to receive progress updates during long-running operations. | |
| setCancelFlag (self, cancel_flag) | |
| Register an external cancellation flag polled during long plant builds. | |
| getCurrentShootParameters (self, str shoot_type_label, bool return_typed=False) | |
| Get current shoot parameters for a shoot type. | |
| None | defineShootType (self, str shoot_type_label, Union[dict, ShootParameters] parameters) |
| Define a custom shoot type with specified parameters. | |
| getDefaultCarbohydrateParameters (self, bool return_typed=False) | |
| Get a default-constructed set of carbohydrate-model parameters. | |
| None | setPlantCarbohydrateParameters (self, int plant_id, Union[dict, CarbohydrateParameters] parameters) |
| Set carbohydrate-model parameters for a plant. | |
| getDefaultNitrogenParameters (self, bool return_typed=False) | |
| Get a default-constructed set of nitrogen-model parameters. | |
| None | setPlantNitrogenParameters (self, int plant_id, Union[dict, NitrogenParameters] parameters) |
| Set nitrogen-model parameters for a plant. | |
| List[str] | getAvailablePlantModels (self) |
| Get list of all available plant models in the library. | |
| List[str] | getPlantModelBuildParameterNames (self, str plant_model) |
| Get the names of the build parameters a library plant model accepts. | |
| List[str] | listShootTypeLabels (self, Optional[str] plant_model=None, Optional[int] plant_id=None) |
| Get the shoot type labels defined for a plant model. | |
| List[int] | getAllUUIDs (self) |
| Get UUIDs of every plant primitive in the model. | |
| List[int] | getAllLeafUUIDs (self) |
| Get UUIDs of every leaf primitive in the model. | |
| List[int] | getAllInternodeUUIDs (self) |
| Get UUIDs of every internode primitive in the model. | |
| List[int] | getAllPetioleUUIDs (self) |
| Get UUIDs of every petiole primitive in the model. | |
| List[int] | getAllPeduncleUUIDs (self) |
| Get UUIDs of every peduncle primitive in the model. | |
| List[int] | getAllFlowerUUIDs (self) |
| Get UUIDs of every flower primitive in the model. | |
| List[int] | getAllFruitUUIDs (self) |
| Get UUIDs of every fruit primitive in the model. | |
| List[int] | getAllObjectIDs (self) |
| Get object IDs of every plant compound object in the model. | |
| List[int] | getAllPlantIDs (self) |
| Get IDs of every plant instance in the model. | |
| List[int] | getAllPlantObjectIDs (self, int plant_id) |
| Get all object IDs for a specific plant. | |
| List[int] | getPlantLeafObjectIDs (self, int plant_id) |
| Get object IDs for all leaf objects on a specific plant. | |
| List[int] | getPlantPetioleObjectIDs (self, int plant_id) |
| Get object IDs for all petiole objects on a specific plant. | |
| List[int] | getPlantPeduncleObjectIDs (self, int plant_id) |
| Get object IDs for all peduncle objects on a specific plant. | |
| List[int] | getPlantFlowerObjectIDs (self, int plant_id) |
| Get object IDs for all flower (inflorescence) objects on a specific plant. | |
| List[int] | getPlantFruitObjectIDs (self, int plant_id) |
| Get object IDs for all fruit objects on a specific plant. | |
| List[vec3] | getPlantLeafBases (self, int plant_id) |
| Get the attachment base position of every leaf on a specific plant. | |
| List[int] | getAllPlantUUIDs (self, int plant_id, bool include_hidden=False) |
| Get all primitive UUIDs for a specific plant. | |
| List[int] | getAllShootIDs (self, int plant_id) |
| Get the IDs of all shoots belonging to a plant. | |
| Dict[str, Any] | getShoot (self, int plant_id, int shoot_id) |
| Get a read-only view of a shoot's topology. | |
| List[int] | getShootChildIDs (self, int plant_id, int shoot_id) |
| Get the child shoot IDs of a shoot (flattened across parent node indices). | |
| int | getParentShootID (self, int plant_id, int shoot_id) |
| Get the ID of the shoot a shoot grew from. | |
| int | getShootRank (self, int plant_id, int shoot_id) |
| Get the branching rank of a shoot. | |
| int | getShootDepth (self, int plant_id, int shoot_id) |
| Get the number of shoots between a shoot and the base stem shoot. | |
| bool | isShootPruned (self, int plant_id, int shoot_id) |
| Report whether a shoot has been pruned away entirely. | |
| List[int] | getPathToRoot (self, int plant_id, int shoot_id) |
| Get the chain of shoots connecting a shoot to the base stem shoot. | |
| List[int] | getChildShootIDs (self, int plant_id, int shoot_id) |
| Get the shoots that grew directly out of a shoot. | |
| List[int] | getAllDescendantShootIDs (self, int plant_id, int shoot_id) |
| Get every shoot descending from a shoot. | |
| Dict[int, List[int]] | getShootHierarchyMap (self, int plant_id) |
| Get the parent-to-children structure of a plant. | |
| List[tuple] | getShootInternodeVertices (self, int plant_id, int shoot_id) |
| Get the woody internode polyline vertices of a shoot as a list of (x, y, z) tuples. | |
| List[float] | getShootInternodeRadii (self, int plant_id, int shoot_id) |
| Get the per-vertex woody internode radii of a shoot. | |
| List[float] | getPlantLeafAreas (self, int plant_id) |
| Get the built one-sided surface area of every leaf on a plant. | |
| List[float] | getPlantInternodeLengths (self, int plant_id) |
| Get the built length of every internode on a plant. | |
| List[float] | getPlantLeafInclinations (self, int plant_id) |
| Get the inclination angle of every leaf on a plant. | |
| bool | isShootGeometryPrescribed (self, int plant_id, int shoot_id) |
| Report whether a shoot's existing geometry was prescribed by the caller rather than generated. | |
| float | getPlantAge (self, int plant_id) |
| Get the current age of a plant in days. | |
| float | getPlantMaxAge (self, int plant_id) |
| Get the maximum age of a plant, beyond which it stops growing. | |
| None | setPlantMaxAge (self, int plant_id, float max_age) |
| Set the maximum age of a plant, beyond which it stops growing. | |
| float | getPlantHeight (self, int plant_id) |
| Get the height of a plant in meters. | |
| float | getPlantLeafArea (self, int plant_id) |
| Get the total leaf area of a plant in m². | |
| None | optionalOutputObjectData (self, Union[str, List[str]] object_data_labels) |
| Enable optional output object data to be written to the Context. | |
| None | setPlantPhenologicalThresholds (self, int plant_id, float time_to_dormancy_break, float time_to_flower_initiation, float time_to_flower_opening, float time_to_fruit_set, float time_to_fruit_maturity, float time_to_dormancy, float max_leaf_lifespan=1e6, bool is_evergreen=False) |
| Set phenological timing thresholds for plant developmental stages. | |
| None | disablePlantPhenology (self, int plant_id) |
| Disable phenological progression for a plant. | |
| None | makePlantDormant (self, int plant_id) |
| Force a plant into a dormant state immediately. | |
| None | breakPlantDormancy (self, int plant_id) |
| Break dormancy for all shoots on a plant, returning it to an active state. | |
| bool | isPlantDormant (self, int plant_id) |
| Check whether a plant is dormant. | |
| None | pruneBranch (self, int plant_id, int shoot_id, int node_index) |
| Prune a shoot at a node, removing that node and everything distal to it. | |
| None | harvestPlant (self, int plant_id) |
| Harvest a plant by removing its flowers and fruit. | |
| None | removePlantLeaves (self, int plant_id) |
| Remove all leaves from every shoot on a plant. | |
| None | removeShootLeaves (self, int plant_id, int shoot_id) |
| Remove all leaves from a single shoot. | |
| None | removeShootVegetativeBuds (self, int plant_id, int shoot_id) |
| Mark every vegetative bud on a single shoot as dead. | |
| None | removeShootFloralBuds (self, int plant_id, int shoot_id) |
| Kill all floral buds on a single shoot. | |
| Dict[int, List[int]] | getShootIDsByRank (self, int plant_id) |
| Group a plant's shoot IDs by branching rank. | |
| List[int] | getTerminalShootIDs (self, int plant_id) |
| Get the plant's terminal shoots – those carrying no child shoots. | |
| List[int] | pruneShootsByRank (self, int plant_id, int min_rank) |
| Prune every shoot at or above a given branching rank. | |
| List[int] | pruneShootSubtree (self, int plant_id, int shoot_id, bool include_self=True) |
| Prune a shoot and everything growing off it. | |
| List[int] | pruneTerminalShoots (self, int plant_id, int stride=2) |
| Thin a plant by pruning every stride-th terminal shoot. | |
| None | enableSoftCollisionAvoidance (self, Optional[List[int]] target_object_UUIDs=None, Optional[List[int]] target_object_IDs=None, bool enable_petiole_collision=False, bool enable_fruit_collision=False) |
| Enable soft collision avoidance for procedural plant growth. | |
| None | enableGroundClipping (self, float ground_height=0.0) |
| Enable automatic removal of plant organs that fall below the ground plane. | |
| None | disableMessages (self) |
| Suppress standard output from the plantarchitecture plugin. | |
| None | enableMessages (self) |
| Re-enable standard output from the plantarchitecture plugin. | |
| None | disableCollisionDetection (self) |
| Disable collision detection for plant growth. | |
| None | setSoftCollisionAvoidanceParameters (self, float view_half_angle_deg=80.0, float look_ahead_distance=0.1, int sample_count=256, float inertia_weight=0.4) |
| Configure parameters for soft collision avoidance algorithm. | |
| None | setCollisionRelevantOrgans (self, bool include_internodes=False, bool include_leaves=True, bool include_petioles=False, bool include_flowers=False, bool include_fruit=False) |
| Specify which plant organs participate in collision detection. | |
| None | enableSolidObstacleAvoidance (self, List[int] obstacle_UUIDs, float avoidance_distance=0.5, bool enable_fruit_adjustment=False, bool enable_obstacle_pruning=False) |
| Enable hard obstacle avoidance for specified geometry. | |
| None | setStaticObstacles (self, List[int] target_UUIDs) |
| Mark geometry as static obstacles for collision detection optimization. | |
| List[int] | getPlantCollisionRelevantObjectIDs (self, int plant_id) |
| Get object IDs of collision-relevant geometry for a specific plant. | |
| None | writePlantMeshVertices (self, int plant_id, Union[str, Path] filename) |
| Write all plant mesh vertices to file for external processing. | |
| None | writePlantStructureXML (self, int plant_id, Union[str, Path] filename) |
| Save plant structure to XML file for later loading. | |
| None | writeQSMCylinderFile (self, int plant_id, Union[str, Path] filename) |
| Export plant structure in TreeQSM cylinder format. | |
| None | writePlantStructureUSD (self, int plant_id, Union[str, Path] filename, float elastic_modulus=5e9, float wood_density=800.0, *, float damping_time_constant=0.02, float static_friction=0.5, float dynamic_friction=0.3, float restitution=0.1, float organ_spring_stiffness=10.0, float organ_spring_damping=1.0, float leaf_mass_per_area=0.05, float fruit_mass=0.01, float flower_mass=0.002, int solver_position_iterations=32, float min_segment_length=0.001, float armature_stability_ratio=8.0, float physics_steps_per_second=60.0, Optional[float] damping_ratio=None) |
| Export plant structure as a USD articulated rigid body for NVIDIA IsaacSim physics. | |
| None | registerGrowthFrame (self, int plant_id, float min_segment_length=0.001) |
| Capture a snapshot of the plant's geometry as a growth animation frame. | |
| None | writePlantGrowthUSD (self, int plant_id, Union[str, Path] filename, float seconds_per_frame=1.0) |
| Export all registered growth frames as a time-sampled USD animation file. | |
| None | clearGrowthFrames (self, int plant_id) |
| Clear stored growth animation frames for a plant. | |
| int | getGrowthFrameCount (self, int plant_id) |
| Get the number of registered growth frames for a plant. | |
| List[int] | readPlantStructureXML (self, Union[str, Path] filename, bool quiet=False) |
| Load plant structure from XML file. | |
| int | addPlantInstance (self, vec3 base_position, float current_age) |
| Create an empty plant instance for custom plant building. | |
| None | deletePlantInstance (self, int plant_id) |
| Delete a plant instance and all associated geometry. | |
| int | addBaseStemShoot (self, int plant_id, int current_node_number, AxisRotation base_rotation, float internode_radius, float internode_length_max, float internode_length_scale_factor_fraction, float leaf_scale_factor_fraction, float radius_taper, str shoot_type_label) |
| Add a base stem shoot to a plant instance (main trunk/stem). | |
| int | appendShoot (self, int plant_id, int parent_shoot_id, int current_node_number, AxisRotation base_rotation, float internode_radius, float internode_length_max, float internode_length_scale_factor_fraction, float leaf_scale_factor_fraction, float radius_taper, str shoot_type_label) |
| Append a shoot to the end of an existing shoot. | |
| int | addChildShoot (self, int plant_id, int parent_shoot_id, int parent_node_index, int current_node_number, AxisRotation shoot_base_rotation, float internode_radius, float internode_length_max, float internode_length_scale_factor_fraction, float leaf_scale_factor_fraction, float radius_taper, str shoot_type_label, int petiole_index=0) |
| Add a child shoot at an axillary bud position on a parent shoot. | |
| int | addShootFromNodePositions (self, int plant_id, int parent_shoot_id, int parent_node_index, List[vec3] node_positions, List[float] node_radii, str shoot_type_label, Optional[str] growth_shoot_type_label=None, int petiole_index=0) |
| Add a shoot whose internode geometry is prescribed by measured node positions. | |
| None | setPetioleNodePositions (self, int plant_id, int shoot_id, int node_index, int petiole_index, List[vec3] node_positions, List[float] node_radii) |
| Prescribe the path of a petiole on an existing phytomer from measured node positions. | |
| None | setPetioleLeafGeometry (self, int plant_id, int shoot_id, int node_index, int petiole_index, List[vec3] leaf_bases, List[AxisRotation] leaf_rotations, List[float] leaf_sizes) |
| Prescribe the base position, orientation and size of every leaf on a petiole. | |
| None | setPetioleLeafCount (self, int plant_id, int shoot_id, int node_index, int petiole_index, int leaf_count) |
| Change the number of leaves (leaflets) on one petiole of an existing phytomer. | |
| None | setShootInternodeLengthMax (self, int plant_id, int shoot_id, float internode_length_max) |
| Set the target length of internodes grown at the apex of an existing shoot. | |
| None | terminateApicalBud (self, int plant_id, int shoot_id) |
| Stop a shoot's apex from adding any further phytomers. | |
| int | getShootVegetativeBudCount (self, int plant_id, int shoot_id, Optional[BudState] state=None) |
| Count a shoot's axillary vegetative buds, summed over all phytomers and petioles. | |
| int | getPlantLeafCount (self, int plant_id) |
| Get the number of leaf objects on a plant. | |
| None | enableLeafAngleDistributionTracking (self, plant_ids, float beta_mu_inclination, float beta_nu_inclination, float eccentricity, float ellipse_rotation_degrees, float lambda_degrees) |
| Steer leaf inclination and azimuth toward a prescribed distribution as the plant grows. | |
| None | enableLeafElevationAngleDistributionTracking (self, int plant_id, float beta_mu_inclination, float beta_nu_inclination, float lambda_degrees) |
| Steer leaf inclination toward a Beta distribution as the plant grows, leaving azimuth to the procedural model. | |
| None | enableLeafAzimuthAngleDistributionTracking (self, int plant_id, float eccentricity, float ellipse_rotation_degrees, float lambda_degrees) |
| Steer leaf azimuth toward an ellipsoidal distribution as the plant grows, leaving inclination to the procedural model. | |
| None | disableLeafAngleDistributionTracking (self, int plant_id) |
| Stop steering a plant's leaf angles toward a prescribed distribution. | |
| bool | isLeafAngleDistributionTrackingEnabled (self, int plant_id) |
| Whether a plant's leaf angles are being steered toward a prescribed distribution. | |
| float | getPetioleLength (self, int plant_id, int shoot_id, int node_index, Optional[int] petiole_index=None) |
| Current length of a phytomer's petioles, measured along the centerline. | |
| None | scalePetioleMaxLength (self, int plant_id, int shoot_id, int node_index, float scale_factor) |
| Scale the fully-elongated length every petiole on a phytomer is growing toward. | |
| None | setPetioleScaleFraction (self, int plant_id, int shoot_id, int node_index, int petiole_index, float petiole_scale_factor_fraction) |
| Set one petiole's current length as a fraction of its fully-elongated length, leaving the leaves it carries at the size they are. | |
| None | setPetioleAndLeafScaleFraction (self, int plant_id, int shoot_id, int node_index, int petiole_index, float petiole_scale_factor_fraction, float leaf_scale_factor_fraction) |
| Set a petiole's length and its leaves' size together, each as a fraction of its own fully-elongated value. | |
| None | scaleLeafSizeMax (self, int plant_id, int shoot_id, int node_index, float scale_factor) |
| Scale the size every leaf on a phytomer is expanding toward, leaving the blades where they are. | |
| None | setLeafNormal (self, int plant_id, int shoot_id, int node_index, int petiole_index, int leaf_index, vec3 target_normal) |
| Re-aim one leaf so its blade faces a given direction. | |
| None | bendPetioleUnderLeafWeight (self, int plant_id, int shoot_id, int node_index, int petiole_index, bool include_posed_leaves=False) |
| Bend one petiole, and the leaves it carries, under the weight of its leaflets. | |
| None | recordPetioleRestShape (self, int plant_id, int shoot_id, int node_index, int petiole_index) |
| Record one petiole's current centerline as its undeformed rest shape. | |
| None | setLeafAngleDistribution (self, plant_ids, float beta_mu_inclination, float beta_nu_inclination, Optional[float] eccentricity=None, float ellipse_rotation_degrees=0.0) |
| Re-aim every leaf of a finished plant so that its leaf angles follow a prescribed distribution. | |
| float | getPetioleFlexibility (self, int plant_id, int shoot_id, int node_index) |
| Bending flexibility of the petioles of one phytomer. | |
| None | setPetioleFlexibility (self, int plant_id, int shoot_id, int node_index, float flexibility) |
| Replace the bending flexibility of the petioles of one existing phytomer. | |
| None | setPhytomerCreationFunction (self, str shoot_type_label, Optional[Callable[[int, int, int, int, int, int, float], None]] callback) |
| Install a Python function that the plugin calls once for every new phytomer of a shoot type. | |
| None | setPhytomerCallbackFunction (self, str shoot_type_label, Optional[Callable[[int, int, int, float], None]] callback) |
| Install a Python function that the plugin calls for every phytomer of a shoot type on every time step. | |
| Optional[str] | getPhytomerCreationFunctionName (self, str shoot_type_label) |
| Get the name of the library creation function a shoot type carries. | |
| Optional[str] | getPhytomerCallbackFunctionName (self, str shoot_type_label) |
| Get the name of the library per-timestep callback function a shoot type carries. | |
| None | setInternodeMaxLength (self, int plant_id, int shoot_id, int node_index, float length) |
| Set the fully-elongated length of one existing internode. | |
| None | scaleInternodeMaxLength (self, int plant_id, int shoot_id, int node_index, float scale_factor) |
| Scale the fully-elongated length of one existing internode. | |
| None | scaleLeafPrototypeScale (self, int plant_id, int shoot_id, int node_index, float scale_factor, Optional[int] petiole_index=None) |
| Scale a phytomer's leaves now: both the blades' present size and the size they grow toward. | |
| None | setShootPhyllotacticAngle (self, int plant_id, int shoot_id, float mean_deg, Optional[float] sd_deg=None) |
| Set the phyllotactic angle that one shoot's next phytomers are created with. | |
| float | getPhytomerAge (self, int plant_id, int shoot_id, int node_index) |
| Age of one phytomer in days, counted from its creation. | |
| float | getInternodeLength (self, int plant_id, int shoot_id, int node_index) |
| Present length of one internode in meters, measured along its node positions. | |
| float | getInternodeRadius (self, int plant_id, int shoot_id, int node_index) |
| Radius in meters at the base of one internode. | |
| List[vec3] | getInternodeNodePositions (self, int plant_id, int shoot_id, int node_index) |
| Positions of one internode's nodes, from its base to its tip. | |
| vec3 | getInternodeAxisVector (self, int plant_id, int shoot_id, int node_index, float stem_fraction) |
| Unit direction of one internode at a fraction of its length. | |
| vec3 | getPetioleAxisVector (self, int plant_id, int shoot_id, int node_index, float stem_fraction, int petiole_index) |
| Unit direction of one petiole at a fraction of its length. | |
| List[vec3] | getPetioleVertices (self, int plant_id, int shoot_id, int node_index, int petiole_index) |
| Centerline vertices of one petiole, from its base at the node to its tip. | |
| List[float] | getPetioleRadii (self, int plant_id, int shoot_id, int node_index, int petiole_index) |
Radius in meters of one petiole at each of its centerline vertices (see :meth:getPetioleVertices). | |
| List[List[int]] | getPhytomerLeafObjectIDs (self, int plant_id, int shoot_id, int node_index) |
| Object IDs of one phytomer's leaves, grouped by petiole. | |
| vec3 | getLeafBasePosition (self, int plant_id, int shoot_id, int node_index, int petiole_index, int leaf_index) |
| Position where one leaf (leaflet) attaches to its petiole. | |
| tuple | getPlantModelLeafInclinationDistribution (self, str plant_model_name) |
Beta leaf inclination distribution (mu, nu) that a library plant model declares. | |
| None | setPlantModelLeafInclinationDistribution (self, str plant_model_name, float beta_mu, float beta_nu) |
| Set or clear the Beta leaf inclination distribution of a library plant model. | |
| bool | doesPlantModelDeclareLeafInclinationDistribution (self, str plant_model_name) |
| Whether a library plant model declares a leaf inclination distribution. | |
| float | getPlantAvailableNitrogen (self, int plant_id) |
| Nitrogen (g N) in a plant's available pool, awaiting allocation to its organs. | |
| float | getLeafBladeArea (self, int leaf_object_id) |
| One-sided blade area (m²) of a single leaf object. | |
| float | getShadowLightExposureAtPoint (self, int plant_id, vec3 position) |
| Local light exposure at a point from a plant's shadow-propagation grid. | |
| float | getSeasonPeakLightExposureAtPoint (self, int plant_id, vec3 position) |
| Local light exposure at a point under the plant's most recent seasonal peak canopy. | |
| Dict[str, float] | getPlantBuildParameters (self, int plant_id) |
| Get the build parameters a plant was built with. | |
| str | getPlantName (self, int plant_id) |
| Get the name of the plant model a plant was built from. | |
| str | determinePhenologyStage (self, int plant_id) |
| Determine the phenological stage of a plant. | |
| int | getShootNodeCount (self, int plant_id, int shoot_id) |
| Get the current number of nodes (phytomers) on one shoot. | |
| float | getPlantStemHeight (self, int plant_id) |
| Get the height of a plant's main stem in meters. | |
| Union[vec3, List[vec3]] | getPlantBasePosition (self, Union[int, List[int]] plant_ids) |
| Get the base position of one plant or of several plants. | |
| None | setPlantBasePosition (self, int plant_id, vec3 base_position) |
| Set the base position of a plant, moving the plant if it has already been built. | |
| List[int] | getPlantInternodeObjectIDs (self, int plant_id, Optional[str] shoot_type_label=None) |
| Get the object IDs of a plant's internode (tube) objects. | |
| List[float] | getPlantLeafInclinationAngleDistribution (self, Union[int, List[int]] plant_ids, int num_bins, bool normalize=True) |
| Get the leaf-area-weighted leaf inclination angle distribution of one or more plants. | |
| List[float] | getPlantLeafAzimuthAngleDistribution (self, Union[int, List[int]] plant_ids, int num_bins, bool normalize=True) |
| Get the leaf-area-weighted leaf azimuth angle distribution of one or more plants. | |
| Union[dict, PhytomerParameters] | resamplePhytomerParameters (self, Union[dict, PhytomerParameters] phytomer_parameters) |
| Draw one realization of a set of phytomer parameters. | |
| bool | is_available (self) |
| Check if PlantArchitecture is available in current build. | |
Static Public Member Functions | |
| List[str] | getLibraryPhytomerCreationFunctionNames () |
List the library phytomer creation functions that :meth:setPhytomerCreationFunction accepts by name. | |
| List[str] | getLibraryPhytomerCallbackFunctionNames () |
List the library per-timestep callback functions that :meth:setPhytomerCallbackFunction accepts by name. | |
Public Attributes | |
| context = context | |
Protected Member Functions | |
| _check_context_alive (self) | |
| Raise if the owning Context has been destroyed (see Context.check_context_alive). | |
| None | _validate_build_parameters (self, Optional[dict] build_parameters) |
| Validate build parameters against the names the loaded model declares natively. | |
| _shootScalarQuery (self, str wrapper_fn_name, int plant_id, int shoot_id, str description) | |
| Shared body for the per-shoot hierarchy accessors. | |
| List[float] | _plantFloatVector (self, str wrapper_fn_name, int plant_id, str description) |
| Shared body for the per-organ built-geometry queries. | |
| None | _removeShootOrgans (self, str wrapper_fn_name, int plant_id, int shoot_id, str organ_description) |
| Shared body for the three shoot-level organ removal methods. | |
| List[int] | _childShootIDsOrEmpty (self, int plant_id, int shoot_id) |
| Return a shoot's child IDs, or an empty list if it no longer resolves. | |
| List[int] | _liveChildShootIDs (self, int plant_id, int shoot_id) |
| Child shoot IDs that have not been pruned away, ascending. | |
| List[int] | _pruneShallowest (self, int plant_id, target_shoot_ids) |
| Prune every target that something shallower has not already removed. | |
| bool | _isPrunedOrGone (self, int plant_id, int shoot_id) |
| Whether a shoot has been pruned away or no longer resolves at all. | |
| None | _setLibraryPhytomerFunction (self, str shoot_type_label, str function_name, bool creation) |
| Optional[str] | _getLibraryPhytomerFunctionName (self, str shoot_type_label, bool creation) |
| _makePhytomerCallbackTrampoline (self, callback) | |
| Wrap callback so an exception is stored for re-raising instead of being lost inside ctypes. | |
| _makePhytomerCreationTrampoline (self, callback) | |
| Wrap callback so an exception is stored for re-raising instead of being lost inside ctypes. | |
| None | _reject_inside_phytomer_callback (self, str method_name) |
| Raise if called from a Python phytomer creation or callback function. | |
| None | _raise_pending_callback_error (self, Optional[BaseException] native_error=None) |
| Raise, and clear, an exception stored by a phytomer creation or callback function. | |
| _phytomerCall (self, str description, int plant_id, int shoot_id, int node_index, fn, *args) | |
| Call a per-phytomer wrapper, turning an out-of-range index into ValueError. | |
| List[float] | _plantAngleDistribution (self, str fn_name, plant_ids, num_bins, normalize, str what) |
| List[int] | _validatePlantIdList (cls, plant_ids) |
| Coerce a sequence of plant IDs, rejecting an empty or malformed one. | |
| int | _validatePetioleIndex (cls, petiole_index, str name="Petiole index") |
| Reject a non-int or negative petiole/leaf index. | |
Static Protected Member Functions | |
| None | _validate_attraction_points (points) |
| Reject point sets the native layer would misread or silently ignore. | |
| _validateNodesAndRadii (node_positions, node_radii, str positions_name, str radii_name) | |
| Validate a measured node path and return it as plain lists for the ctypes layer. | |
| None | _validateShootIdentifiers (int plant_id, int shoot_id) |
| Reject non-int and negative plant/shoot identifiers. | |
| BudState | _validateBudState (state) |
| Coerce a BudState (or its int value) and reject anything else. | |
| float | _validateStemFraction (stem_fraction) |
| None | _validatePlantModelName (plant_model_name) |
| int | _validatePlantIdentifier (plant_id) |
| Reject a non-int or negative plant ID, returning it as a plain int. | |
| int | _validateNodeIndex (node_index, str name="Node index") |
| Reject a non-int or negative phytomer index. | |
| float | _validateScaleFactor (scale_factor, str name="Scale factor") |
| Reject a non-numeric or non-positive scale factor. | |
Protected Attributes | |
| _plantarch_ptr = None | |
| _current_plant_model = None | |
| _progress_callback_ref = plantarch_wrapper.PROGRESS_CALLBACK(_c_callback) | |
| _pending_callback_error = None | |
| pyhelios.PlantArchitecture.PlantArchitecture.__init__ | ( | self, | |
| Context | context ) |
Initialize PlantArchitecture with a Helios context.
| context | Active Helios Context instance |
| PlantArchitectureError | If plugin not available in current build |
| RuntimeError | If plugin initialization fails |
Definition at line 292 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.__del__ | ( | self | ) |
Destructor to ensure C++ resources freed even without 'with' statement.
Definition at line 340 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.__enter__ | ( | self | ) |
Context manager entry.
Definition at line 330 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.__exit__ | ( | self, | |
| exc_type, | |||
| exc_val, | |||
| exc_tb ) |
Context manager exit - cleanup resources.
Definition at line 334 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.__new__ | ( | cls, | |
| context = None ) |
Create PlantArchitecture instance.
Explicit new to prevent ctypes contamination on Windows.
Definition at line 279 of file PlantArchitecture.py.
|
protected |
Raise if the owning Context has been destroyed (see Context.check_context_alive).
Definition at line 326 of file PlantArchitecture.py.
|
protected |
Return a shoot's child IDs, or an empty list if it no longer resolves.
Definition at line 2777 of file PlantArchitecture.py.
|
protected |
Definition at line 5417 of file PlantArchitecture.py.
|
protected |
Whether a shoot has been pruned away or no longer resolves at all.
Definition at line 2814 of file PlantArchitecture.py.
|
protected |
Child shoot IDs that have not been pruned away, ascending.
Definition at line 2786 of file PlantArchitecture.py.
|
protected |
Wrap callback so an exception is stored for re-raising instead of being lost inside ctypes.
Definition at line 5514 of file PlantArchitecture.py.
|
protected |
Wrap callback so an exception is stored for re-raising instead of being lost inside ctypes.
Definition at line 5536 of file PlantArchitecture.py.
|
protected |
Call a per-phytomer wrapper, turning an out-of-range index into ValueError.
Definition at line 5590 of file PlantArchitecture.py.
|
protected |
Definition at line 6357 of file PlantArchitecture.py.
|
protected |
Shared body for the per-organ built-geometry queries.
Definition at line 1878 of file PlantArchitecture.py.
|
protected |
Prune every target that something shallower has not already removed.
pruneBranch() recurses into child shoots, so cutting a shoot also empties every shoot descended from it. Targets are therefore visited in ascending shoot ID order -- a child shoot is always created after its parent and so always has the higher ID -- which puts each shoot after its ancestors. By the time a descendant of an already-cut shoot comes up it has nothing left on it and is skipped, so no shoot is cut twice and the returned list holds only the cuts that actually did something.
Definition at line 2802 of file PlantArchitecture.py.
|
protected |
Raise, and clear, an exception stored by a phytomer creation or callback function.
Definition at line 5576 of file PlantArchitecture.py.
|
protected |
Raise if called from a Python phytomer creation or callback function.
The native plugin skips these operations inside a callback and only prints a warning, which disableMessages() suppresses, so the call would otherwise appear to succeed.
Definition at line 5564 of file PlantArchitecture.py.
|
protected |
Shared body for the three shoot-level organ removal methods.
Definition at line 2579 of file PlantArchitecture.py.
|
protected |
Definition at line 5398 of file PlantArchitecture.py.
|
protected |
Shared body for the per-shoot hierarchy accessors.
Definition at line 1837 of file PlantArchitecture.py.
|
staticprotected |
Reject point sets the native layer would misread or silently ignore.
Definition at line 770 of file PlantArchitecture.py.
|
protected |
Validate build parameters against the names the loaded model declares natively.
Definition at line 387 of file PlantArchitecture.py.
|
staticprotected |
Coerce a BudState (or its int value) and reject anything else.
A bare int is accepted because BudState is an IntEnum, but it still has to name a real an out-of-range value would be cast onto the C++ enum, which is undefined behavior.
Definition at line 4545 of file PlantArchitecture.py.
|
staticprotected |
Reject a non-int or negative phytomer index.
Definition at line 6513 of file PlantArchitecture.py.
|
staticprotected |
Validate a measured node path and return it as plain lists for the ctypes layer.
Definition at line 4008 of file PlantArchitecture.py.
|
protected |
Reject a non-int or negative petiole/leaf index.
Definition at line 6525 of file PlantArchitecture.py.
|
staticprotected |
Reject a non-int or negative plant ID, returning it as a plain int.
Definition at line 6487 of file PlantArchitecture.py.
|
protected |
Coerce a sequence of plant IDs, rejecting an empty or malformed one.
Definition at line 6499 of file PlantArchitecture.py.
|
staticprotected |
Definition at line 6478 of file PlantArchitecture.py.
|
staticprotected |
Reject a non-numeric or non-positive scale factor.
Definition at line 6532 of file PlantArchitecture.py.
|
staticprotected |
Reject non-int and negative plant/shoot identifiers.
bool is excluded explicitly: it is an int subclass, so True would otherwise pass as shoot 1.
Definition at line 4528 of file PlantArchitecture.py.
|
staticprotected |
Definition at line 6471 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.addBaseStemShoot | ( | self, | |
| int | plant_id, | ||
| int | current_node_number, | ||
| AxisRotation | base_rotation, | ||
| float | internode_radius, | ||
| float | internode_length_max, | ||
| float | internode_length_scale_factor_fraction, | ||
| float | leaf_scale_factor_fraction, | ||
| float | radius_taper, | ||
| str | shoot_type_label ) |
Add a base stem shoot to a plant instance (main trunk/stem).
This method creates the primary shoot originating from the plant base. The base stem is typically the main trunk or primary stem from which all other shoots branch. Specify growth parameters to control the shoot's morphology and development. **IMPORTANT - Shoot Type Requirement**: Shoot types must be defined before use. The standard workflow is to load a plant model first using loadPlantModelFromLibrary(), which defines shoot types that can then be used for custom building. The shoot_type_label must match a shoot type defined in the loaded model.
| plant_id | ID of the plant instance |
| current_node_number | Starting node number for this shoot (typically 1) |
| base_rotation | Orientation as AxisRotation(pitch, yaw, roll) in radians (use math.radians() to convert) |
| internode_radius | Base radius of internodes in meters (must be > 0) |
| internode_length_max | Maximum internode length in meters (must be > 0) |
| internode_length_scale_factor_fraction | Scale factor for internode length (0-1 typically) |
| leaf_scale_factor_fraction | Scale factor for leaf size (0-1 typically) |
| radius_taper | Rate of radius decrease along shoot (0-1, where 1=no taper) |
| shoot_type_label | Label identifying shoot type - must match a type from loaded model |
| ValueError | If parameters are invalid (negative IDs, non-positive dimensions, empty label) |
| PlantArchitectureError | If shoot creation fails or shoot type doesn't exist |
Definition at line 3746 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.addChildShoot | ( | self, | |
| int | plant_id, | ||
| int | parent_shoot_id, | ||
| int | parent_node_index, | ||
| int | current_node_number, | ||
| AxisRotation | shoot_base_rotation, | ||
| float | internode_radius, | ||
| float | internode_length_max, | ||
| float | internode_length_scale_factor_fraction, | ||
| float | leaf_scale_factor_fraction, | ||
| float | radius_taper, | ||
| str | shoot_type_label, | ||
| int | petiole_index = 0 ) |
Add a child shoot at an axillary bud position on a parent shoot.
This method creates a lateral branch shoot emerging from a specific node on the parent shoot. Child shoots enable creation of branching architectures, with control over branch angle, size, and which petiole position the branch emerges from (for plants with multiple petioles per node). **IMPORTANT - Shoot Type Requirement**: The shoot_type_label must match a shoot type defined in a loaded plant model. Load a model with loadPlantModelFromLibrary() before calling this method.
| plant_id | ID of the plant instance |
| parent_shoot_id | ID of the parent shoot |
| parent_node_index | Index of the parent node where child emerges (0-based) |
| current_node_number | Starting node number for this child shoot |
| shoot_base_rotation | Orientation as AxisRotation(pitch, yaw, roll) in radians (use math.radians() to convert) |
| internode_radius | Base radius of child shoot internodes in meters (must be > 0) |
| internode_length_max | Maximum internode length in meters (must be > 0) |
| internode_length_scale_factor_fraction | Scale factor for internode length (0-1 typically) |
| leaf_scale_factor_fraction | Scale factor for leaf size (0-1 typically) |
| radius_taper | Rate of radius decrease along shoot (0-1, where 1=no taper) |
| shoot_type_label | Label identifying shoot type - must match loaded model |
| petiole_index | Which petiole at the node to branch from (default: 0) |
| ValueError | If parameters are invalid (negative values, non-positive dimensions, empty label) |
| PlantArchitectureError | If child shoot creation fails, parent doesn't exist, or shoot type not defined |
Definition at line 3946 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.addPlantInstance | ( | self, | |
| vec3 | base_position, | ||
| float | current_age ) |
Create an empty plant instance for custom plant building.
This method creates a new plant instance at the specified location without any shoots or organs. Use addBaseStemShoot(), appendShoot(), and addChildShoot() to manually construct the plant structure. This provides low-level control over plant architecture, enabling custom morphologies not available in the plant library.
| base_position | Cartesian (x,y,z) coordinates of plant base as vec3 |
| current_age | Current age of the plant in days (must be >= 0) |
| ValueError | If age is negative |
| PlantArchitectureError | If plant creation fails |
Definition at line 3635 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.addShootFromNodePositions | ( | self, | |
| int | plant_id, | ||
| int | parent_shoot_id, | ||
| int | parent_node_index, | ||
| List[vec3] | node_positions, | ||
| List[float] | node_radii, | ||
| str | shoot_type_label, | ||
| Optional[str] | growth_shoot_type_label = None, | ||
| int | petiole_index = 0 ) |
Add a shoot whose internode geometry is prescribed by measured node positions.
This builds a single shoot, rendered as one continuous internode tube, that follows a path given by the caller rather than one generated from the shoot type's curvature and tortuosity parameters. It is intended for reconstructing a plant from measured geometry such as a QSM, a digitized skeleton or photogrammetry. A shoot built through :meth:`addBaseStemShoot`, :meth:`appendShoot` or :meth:`addChildShoot` is an extrapolation from its base rotation and cannot follow a measured curve; approximating one by chaining many short shoots produces a separate tube object per link, which leaves visible gaps at every bend. The supplied positions are the phytomer endpoints: N+1 positions define N internodes and therefore N phytomers. The shoot type's ``internode.length_segments`` still controls how finely each internode is subdivided, with the intermediate nodes interpolated along the straight segment between the two prescribed endpoints. The caller controls internode length by choosing how many nodes to supply. The prescribed phytomers are created fully elongated and are therefore not re-scaled or re-curved by subsequent calls to :meth:`advanceTime`. New phytomers added at the shoot apex as the plant grows are generated normally, continuing from the direction of the final prescribed internode, and use the mean of the prescribed internode lengths as their target length. Prescribed radii act as a lower a shoot type with a non-zero ``girth_area_factor`` may thicken an internode during growth but never thins one, so a girth area factor of zero preserves the prescribed radii exactly. When ``parent_shoot_id`` is non-negative the base of the shoot is seated on the parent as :meth:`addChildShoot` does (offset from the attachment node to the surface of the parent internode) and the whole path is translated onto that point. All relative geometry is preserved; only the absolute position changes, and an error is raised if the discrepancy is large enough that the shoot would not be connected to its parent. **Separate growth type.** Building measured wood calls for curvature and tortuosity of zero so the measured path is not fought, a node cap at least as large as the longest measured branch, and often a girth area factor of zero so the measured radii are preserved. None of those describe how the plant should grow a shoot inheriting them extends perfectly straight and never reaches its node cap. Pass ``growth_shoot_type_label`` to take the node caps, the gravitropic curvature of phytomers added at the apex, and the type of the shoots this shoot's vegetative buds produce from a different shoot type. ``girth_area_factor`` and bud-break probability are deliberately still taken from the build type, and the build type remains the label reported by the shoot. A measured branch longer than the growth type's ``max_nodes`` is accepted and simply stops extending. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| parent_shoot_id | ID of the shoot to attach to, or -1 to create a base stem shoot at the start of a new plant |
| parent_node_index | Node of the parent shoot at which the new shoot is added. Ignored when parent_shoot_id is -1 |
| node_positions | Internode node positions in world coordinates, ordered from the base of the shoot to its tip. At least two are required, and no two consecutive positions may be coincident |
| node_radii | Radius of the shoot at each node, one per position. All must be > 0 |
| shoot_type_label | Shoot type whose parameters build the measured geometry. Must already be defined (by :meth:loadPlantModelFromLibrary or :meth:defineShootType) |
| growth_shoot_type_label | Optional shoot type whose parameters govern the shoot's future growth. None grows the shoot with shoot_type_label |
| petiole_index | Petiole within the parent node to attach to (default 0) |
| ValueError | If any ID is out of range, a position is not a vec3, a radius is not positive, fewer than two nodes are given, or the counts differ |
| PlantArchitectureError | If the native build fails (undefined shoot type, coincident consecutive nodes, base too far from the parent, ...) or the library predates v1.3.85 |
breakPlantDormancy before :meth:advanceTime if it is to grow.Definition at line 4123 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.advanceTime | ( | self, | |
| float | dt, | ||
| Optional[int] | plant_id = None, | ||
| Optional[List[int]] | plant_ids = None, | ||
| Optional[int] | years = None ) |
Advance time for plant growth and development.
Updates plants in the simulation, potentially adding new phytomers, growing existing organs, transitioning phenological stages, and updating plant geometry. By default every plant advances together. Pass plant_id or plant_ids to advance a subset, which is what staggered planting dates and mixed-age stands require.
| dt | Time step to advance in days (must be >= 0) |
| plant_id | Advance only this plant. Mutually exclusive with plant_ids. |
| plant_ids | Advance only these plants. Mutually exclusive with plant_id. |
| years | Advance this many whole years in addition to dt days. Applies to all plants and cannot be combined with plant_id or plant_ids. |
| ValueError | If dt or years is negative, or selectors are combined |
| PlantArchitectureError | If time advancement fails |
Definition at line 582 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.appendAttractionPoints | ( | self, | |
| List[vec3] | points, | ||
| Optional[int] | plant_id = None ) |
Add to the current attraction point set.
| points | Additional target locations as a list of vec3 |
| plant_id | Append for this plant only. Appends globally when None. |
| ValueError | If points is empty or contains a non-vec3, or plant_id is negative |
| PlantArchitectureError | If the operation fails |
Definition at line 721 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.appendShoot | ( | self, | |
| int | plant_id, | ||
| int | parent_shoot_id, | ||
| int | current_node_number, | ||
| AxisRotation | base_rotation, | ||
| float | internode_radius, | ||
| float | internode_length_max, | ||
| float | internode_length_scale_factor_fraction, | ||
| float | leaf_scale_factor_fraction, | ||
| float | radius_taper, | ||
| str | shoot_type_label ) |
Append a shoot to the end of an existing shoot.
This method extends an existing shoot by appending a new shoot at its terminal bud. Useful for creating multi-segmented shoots with varying properties along their length, such as shoots with different growth phases or developmental stages. **IMPORTANT - Shoot Type Requirement**: The shoot_type_label must match a shoot type defined in a loaded plant model. Load a model with loadPlantModelFromLibrary() before calling this method.
| plant_id | ID of the plant instance |
| parent_shoot_id | ID of the parent shoot to extend |
| current_node_number | Starting node number for this shoot |
| base_rotation | Orientation as AxisRotation(pitch, yaw, roll) in radians (use math.radians() to convert) |
| internode_radius | Base radius of internodes in meters (must be > 0) |
| internode_length_max | Maximum internode length in meters (must be > 0) |
| internode_length_scale_factor_fraction | Scale factor for internode length (0-1 typically) |
| leaf_scale_factor_fraction | Scale factor for leaf size (0-1 typically) |
| radius_taper | Rate of radius decrease along shoot (0-1, where 1=no taper) |
| shoot_type_label | Label identifying shoot type - must match loaded model |
| ValueError | If parameters are invalid (negative IDs, non-positive dimensions, empty label) |
| PlantArchitectureError | If shoot appending fails, parent doesn't exist, or shoot type not defined |
Definition at line 3839 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.bendPetioleUnderLeafWeight | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| bool | include_posed_leaves = False ) |
Bend one petiole, and the leaves it carries, under the weight of its leaflets.
The petiole is bent as a tapered cantilever clamped at its insertion, for the leaf's current size and the petiole's age. The bent shape is always computed from the recorded undeformed rest shape rather than the current shape, so repeated calls do not accumulate and creep the petiole downward. The insertion stays clamped, so the petiole keeps leaving the stem at its generated pitch and the droop appears beyond it as curvature along the length. This is normally driven by the growth model from ``PhytomerParameters.petiole.flexibility``; call it directly only to re-bend a petiole after changing its geometry or its flexibility (:meth:`setPetioleFlexibility`) yourself. It does nothing for a rigid petiole (flexibility left at zero), a petiole whose centerline was prescribed, one carrying a prescribed leaf, or when neither the load nor the compliance has changed since the last call. A leaf counts as prescribed once it has been posed by :meth:`setLeafNormal`, :meth:`setLeafAngleDistribution` or :meth:`setPetioleLeafGeometry`, so after any of those its petiole no longer bends. Pass ``include_posed_leaves=True`` to bend it anyway: the posed leaves are then carried along the petiole and turned with it, which moves them away from the orientation they were given.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer |
| include_posed_leaves | Also bend a petiole that carries posed leaves |
| ValueError | If any identifier is not a non-negative int, or include_posed_leaves is not a bool |
| PlantArchitectureError | If the plant, shoot, node or petiole does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 5016 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.breakPlantDormancy | ( | self, | |
| int | plant_id ) |
Break dormancy for all shoots on a plant, returning it to an active state.
This is the counterpart to :meth:`makePlantDormant`. Note that it only revives buds that are not dead, so a plant that was repeatedly made dormant may not recover every bud.
| plant_id | Identifier of the plant whose dormancy should be broken |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist or the call fails |
Definition at line 2350 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.buildPlantCanopyFromLibrary | ( | self, | |
| vec3 | canopy_center, | ||
| vec2 | plant_spacing, | ||
| int2 | plant_count, | ||
| float | age, | ||
| float | germination_rate = 1.0, | ||
| Optional[dict] | build_parameters = None ) |
Build a canopy of regularly spaced plants from the currently loaded library model.
| canopy_center | Cartesian (x,y,z) coordinates of canopy center as vec3 |
| plant_spacing | Spacing between plants in x- and y-directions (meters) as vec2 |
| plant_count | Number of plants in x- and y-directions as int2 |
| age | Age of all plants in days (must be >= 0) |
| germination_rate | Probability that each plant position will be occupied (0 to 1). A value of 1.0 means all positions are filled; 0.5 means roughly half the positions will have plants. Default is 1.0. |
| build_parameters | Optional dict of species-specific parameter overrides, applied to every plant in the canopy. Only some models accept them, and a key the model does not accept raises ValueError. See buildPlantInstanceFromLibrary() for the per-model list. |
| ValueError | If age is negative, germination_rate is not in [0, 1], plant count values are not positive, or build_parameters is invalid |
| PlantArchitectureError | If canopy building fails |
Definition at line 506 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.buildPlantInstanceFromLibrary | ( | self, | |
| vec3 | base_position, | ||
| float | age, | ||
| Optional[dict] | build_parameters = None ) |
Build a plant instance from the currently loaded library model.
| base_position | Cartesian (x,y,z) coordinates of plant base as vec3 |
| age | Age of the plant in days (must be >= 0) |
| build_parameters | Optional dict of species-specific parameter overrides, such as trellis dimensions, trunk height and scaffold count, grape cluster size, or sorghum tillers and panicle form. Only some models accept them, and a key the model does not accept raises ValueError:
|
| trunk_height | |
| num_scaffolds | |
| scaffold_angle |
|
| cluster_berry_count |
|
| catch_wire_height | |
| berry_diameter | |
| cluster_berry_count |
|
| ValueError | If age is negative or build_parameters is invalid |
| PlantArchitectureError | If plant building fails |
| RuntimeError | If no model has been loaded |
Definition at line 439 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.clearGrowthFrames | ( | self, | |
| int | plant_id ) |
Clear stored growth animation frames for a plant.
| plant_id | ID of the plant instance whose frames should be cleared |
| ValueError | If plant_id is negative |
Definition at line 3523 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.defineShootType | ( | self, | |
| str | shoot_type_label, | ||
| Union[dict, ShootParameters] | parameters ) |
Define a custom shoot type with specified parameters.
Allows creating new shoot types or modifying existing ones. Pass either a nested parameter ``dict`` (use :meth:`getCurrentShootParameters` as a template) or a typed :class:`pyhelios.plant_architecture_params.ShootParameters` object. Redefining an existing library shoot type preserves that species' built-in phytomer creation and callback functions, so species-specific organ behavior (such as maize forming ears rather than a tassel at every node) is retained.
| shoot_type_label | Unique name for this shoot type |
| parameters | A nested dict matching the ShootParameters structure, or a ShootParameters object. |
| ValueError | If shoot_type_label is empty, or parameters is not a dict or ShootParameters |
| PlantArchitectureError | If shoot type definition fails |
Definition at line 919 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.deletePlantInstance | ( | self, | |
| int | plant_id ) |
Delete a plant instance and all associated geometry.
This method removes a plant from the simulation, deleting all shoots, organs, and associated primitives from the context. The plant ID becomes invalid after deletion and should not be used in subsequent operations.
| plant_id | ID of the plant instance to delete |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If plant deletion fails or plant doesn't exist |
Definition at line 3678 of file PlantArchitecture.py.
| str pyhelios.PlantArchitecture.PlantArchitecture.determinePhenologyStage | ( | self, | |
| int | plant_id ) |
Determine the phenological stage of a plant.
The stage is decided in this order: ``"dormant"`` if every shoot is dormant; ``"reproductive"`` if the plant carries any flower or fruit; ``"senescent"`` if it is past 90% of the time from dormancy break to dormancy (only when a dormancy threshold is set, see :meth:`setPlantPhenologicalThresholds`); otherwise ``"vegetative"``.
| plant_id | ID of the plant instance |
"dormant", "vegetative", "reproductive" or "senescent"| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6185 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.disableAttractionPoints | ( | self, | |
| Optional[int] | plant_id = None ) |
Stop steering growth toward attraction points.
| plant_id | Disable for this plant only. Disables globally when None. |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the operation fails |
Definition at line 675 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.disableCollisionDetection | ( | self | ) |
Disable collision detection for plant growth.
This method turns off the collision detection system, allowing plants to grow without checking for obstacles. This improves performance but plants may grow through obstacles and other geometry.
| PlantArchitectureError | If disabling fails |
Definition at line 2954 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.disableLeafAngleDistributionTracking | ( | self, | |
| int | plant_id ) |
Stop steering a plant's leaf angles toward a prescribed distribution.
Leaves already steered keep the orientation they have reached; leaves emerging afterward are left where the procedural model puts them.
| plant_id | ID of the plant instance |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4693 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.disableMessages | ( | self | ) |
Suppress standard output from the plantarchitecture plugin.
This silences progress bars and informational messages the C++ plugin writes to stdout, including the "BVH not cached" warning emitted during the first growth steps of a collision-enabled canopy (before any plant geometry exists for the BVH to contain).
| PlantArchitectureError | If the call fails |
Definition at line 2918 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.disablePlantPhenology | ( | self, | |
| int | plant_id ) |
Disable phenological progression for a plant.
The plant continues to grow, but no phenological stage is ever scheduled: it does not enter dormancy, and flower and fruit stages are skipped. This is the explicit form of the state a plant is already in when :meth:`setPlantPhenologicalThresholds` has never been called on it, so it is mainly useful for turning phenology back off on a plant that had thresholds set earlier.
| plant_id | Identifier of the plant whose phenology is to be disabled |
advanceTime can compute a negative fruit scale factor. A plant that never had thresholds set is already in the no-phenology state and does not need it.| ValueError | If plant_id is negative |
| PlantArchitectureError | If disabling phenology fails |
Definition at line 2286 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.doesPlantModelDeclareLeafInclinationDistribution | ( | self, | |
| str | plant_model_name ) |
Whether a library plant model declares a leaf inclination distribution.
| ValueError | If ``plant_model_name`` is not a non-empty str |
| PlantArchitectureError | If the model is not in the library |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5960 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableAttractionPoints | ( | self, | |
| List[vec3] | points, | ||
| Optional[int] | plant_id = None, | ||
| Optional[float] | view_half_angle_deg = None, | ||
| float | look_ahead_distance = 0.1, | ||
| float | attraction_weight = 0.6 ) |
Steer shoot growth toward a set of target points.
Attraction points are the counterpart to collision avoidance: collision tells a plant what to grow around, attraction tells it what to grow toward. This is how trellis wires, espalier targets and greenhouse supports are modelled. Steering applies to growth that happens after this call, since the direction is chosen as each phytomer is constructed. Enable the points before advanceTime().
| points | Target locations as a list of vec3 |
| plant_id | Apply to this plant only. Applies to every plant when None. |
| view_half_angle_deg | Half-angle of the search cone in degrees. Defaults to 45 for the global form and 80 for the per-plant form, matching the native defaults, which differ between the two. |
| look_ahead_distance | How far ahead a shoot tip looks, in meters |
| attraction_weight | Strength of the steering, 0 to 1 |
| ValueError | If points is empty or contains a non-vec3, or plant_id is negative |
| PlantArchitectureError | If the operation fails |
Definition at line 643 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableGroundClipping | ( | self, | |
| float | ground_height = 0.0 ) |
Enable automatic removal of plant organs that fall below the ground plane.
Organ vertices below `ground_height` are clipped as plant geometry is built, which prevents drooping leaves and low branches from poking through a ground tile.
| ground_height | Height of the ground plane (default 0.0) |
| ValueError | If ground_height is not a number |
| PlantArchitectureError | If the call fails |
Definition at line 2892 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableLeafAngleDistributionTracking | ( | self, | |
| plant_ids, | |||
| float | beta_mu_inclination, | ||
| float | beta_nu_inclination, | ||
| float | eccentricity, | ||
| float | ellipse_rotation_degrees, | ||
| float | lambda_degrees ) |
Steer leaf inclination and azimuth toward a prescribed distribution as the plant grows.
Each leaf is given a target angle as it emerges and turns onto it while it expands, so a fully grown leaf never moves again: the plant matches the distribution at every stage without leaves shifting from one timestep to the next. Targets are not drawn independently per leaf, so the arrangement the model generated is preserved: each emerging leaf takes the bin that best trades closeness to the angle the model gave it against how far that bin is below its share of the plant's leaf area. Pass a list of plant IDs to realize the distribution over a canopy as a whole, in which case an individual plant need not follow the distribution on its own. Enabling tracking on an already-tracked plant replaces its target, so the target may be varied over the plant's life.
| plant_ids | A single plant ID, or a sequence of plant IDs to steer together |
| beta_mu_inclination | Mean parameter of the Beta inclination distribution |
| beta_nu_inclination | Shape parameter of the Beta inclination distribution |
| eccentricity | Eccentricity of the ellipse defining the azimuth distribution |
| ellipse_rotation_degrees | Rotation of that ellipse (degrees) |
| lambda_degrees | How strongly to favour filling the distribution over keeping each leaf near the angle the model gave it. Zero leaves the plant unchanged; values of order 180 match the distribution as closely as the growing plant allows. |
| ValueError | If any plant ID is not a non-negative int, or the list is empty |
| PlantArchitectureError | If a plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4590 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableLeafAzimuthAngleDistributionTracking | ( | self, | |
| int | plant_id, | ||
| float | eccentricity, | ||
| float | ellipse_rotation_degrees, | ||
| float | lambda_degrees ) |
Steer leaf azimuth toward an ellipsoidal distribution as the plant grows, leaving inclination to the procedural model.
The azimuth-only counterpart of :meth:enableLeafAngleDistributionTracking.
| plant_id | ID of the plant instance |
| eccentricity | Eccentricity of the ellipse defining the azimuth distribution |
| ellipse_rotation_degrees | Rotation of that ellipse (degrees) |
| lambda_degrees | How strongly to favour filling the distribution over keeping each leaf near the angle the model gave it |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4664 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableLeafElevationAngleDistributionTracking | ( | self, | |
| int | plant_id, | ||
| float | beta_mu_inclination, | ||
| float | beta_nu_inclination, | ||
| float | lambda_degrees ) |
Steer leaf inclination toward a Beta distribution as the plant grows, leaving azimuth to the procedural model.
The inclination-only counterpart of :meth:enableLeafAngleDistributionTracking.
| plant_id | ID of the plant instance |
| beta_mu_inclination | Mean parameter of the Beta inclination distribution |
| beta_nu_inclination | Shape parameter of the Beta inclination distribution |
| lambda_degrees | How strongly to favour filling the distribution over keeping each leaf near the angle the model gave it |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4630 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableMessages | ( | self | ) |
Re-enable standard output from the plantarchitecture plugin.
| PlantArchitectureError | If the call fails |
Definition at line 2934 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableSoftCollisionAvoidance | ( | self, | |
| Optional[List[int]] | target_object_UUIDs = None, | ||
| Optional[List[int]] | target_object_IDs = None, | ||
| bool | enable_petiole_collision = False, | ||
| bool | enable_fruit_collision = False ) |
Enable soft collision avoidance for procedural plant growth.
This method enables the collision detection system that guides plant growth away from obstacles and other plants. The system uses cone-based gap detection to find optimal growth directions that minimize collisions while maintaining natural plant architecture.
| target_object_UUIDs | List of primitive UUIDs to avoid collisions with. If empty, avoids all geometry in the context. |
| target_object_IDs | List of compound object IDs to avoid collisions with. |
| enable_petiole_collision | Enable collision detection for leaf petioles |
| enable_fruit_collision | Enable collision detection for fruit organs |
| PlantArchitectureError | If collision detection activation fails |
Definition at line 2856 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.enableSolidObstacleAvoidance | ( | self, | |
| List[int] | obstacle_UUIDs, | ||
| float | avoidance_distance = 0.5, | ||
| bool | enable_fruit_adjustment = False, | ||
| bool | enable_obstacle_pruning = False ) |
Enable hard obstacle avoidance for specified geometry.
This method configures solid obstacles that plants cannot grow through. Unlike soft collision avoidance (which guides growth), solid obstacles cause complete growth termination when encountered within the avoidance distance.
| obstacle_UUIDs | List of primitive UUIDs representing solid obstacles |
| avoidance_distance | Minimum distance to maintain from obstacles (meters). Growth stops if obstacles are closer. Default 0.5m. |
| enable_fruit_adjustment | Adjust fruit positions away from obstacles |
| enable_obstacle_pruning | Remove plant organs that penetrate obstacles |
| ValueError | If obstacle_UUIDs is empty or avoidance_distance is non-positive |
| PlantArchitectureError | If solid obstacle configuration fails |
Definition at line 3102 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllDescendantShootIDs | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get every shoot descending from a shoot.
Collected depth-first, so a shoot is always listed before its own descendants. The shoot itself is not included, and pruned shoots are omitted.
| plant_id | ID of the plant instance |
| shoot_id | Shoot whose descendants to collect |
Definition at line 1804 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllFlowerUUIDs | ( | self | ) |
Get UUIDs of every flower primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs. An empty list means no plant has reached the corresponding growth stage, which is a legitimate result rather than a failure.
| PlantArchitectureError | If retrieval fails |
Definition at line 1288 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllFruitUUIDs | ( | self | ) |
Get UUIDs of every fruit primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs. An empty list means no plant has reached the corresponding growth stage, which is a legitimate result rather than a failure.
| PlantArchitectureError | If retrieval fails |
Definition at line 1314 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllInternodeUUIDs | ( | self | ) |
Get UUIDs of every internode primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1213 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllLeafUUIDs | ( | self | ) |
Get UUIDs of every leaf primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1190 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllObjectIDs | ( | self | ) |
Get object IDs of every plant compound object in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1337 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllPeduncleUUIDs | ( | self | ) |
Get UUIDs of every peduncle primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs. An empty list means no plant has reached the corresponding growth stage, which is a legitimate result rather than a failure.
| PlantArchitectureError | If retrieval fails |
Definition at line 1262 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllPetioleUUIDs | ( | self | ) |
Get UUIDs of every petiole primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1236 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllPlantIDs | ( | self | ) |
Get IDs of every plant instance in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1360 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllPlantObjectIDs | ( | self, | |
| int | plant_id ) |
Get all object IDs for a specific plant.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1385 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllPlantUUIDs | ( | self, | |
| int | plant_id, | ||
| bool | include_hidden = False ) |
Get all primitive UUIDs for a specific plant.
| plant_id | ID of the plant instance |
| include_hidden | If True, also include UUIDs of hidden prototype primitives managed by this PlantArchitecture instance. |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1607 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllShootIDs | ( | self, | |
| int | plant_id ) |
Get the IDs of all shoots belonging to a plant.
Shoot IDs are contiguous 0-based indices into the plant's shoot tree, in creation order; shoot 0 is always the base stem. The returned IDs can be passed to :meth:`getShoot`, :meth:`getShootChildIDs`, etc.
| plant_id | ID of the plant instance |
Definition at line 1630 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getAllUUIDs | ( | self | ) |
Get UUIDs of every plant primitive in the model.
Spans every plant, unlike the per-plant getters, which is what canopy-wide work such as assigning optical properties or reading flux by organ type needs.
| PlantArchitectureError | If retrieval fails |
Definition at line 1167 of file PlantArchitecture.py.
| List[str] pyhelios.PlantArchitecture.PlantArchitecture.getAvailablePlantModels | ( | self | ) |
Get list of all available plant models in the library.
| PlantArchitectureError | If retrieval fails |
Definition at line 1060 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getChildShootIDs | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the shoots that grew directly out of a shoot.
Ordered by the node they attach to. This includes shoots created by :meth:`appendShoot`, which continue the parent's axis rather than branching from it; compare their :meth:`getShootRank` with the parent's to tell the two apart. Pruned shoots are not included.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
Definition at line 1784 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.getCurrentShootParameters | ( | self, | |
| str | shoot_type_label, | ||
| bool | return_typed = False ) |
Get current shoot parameters for a shoot type.
Returns the full nested shoot and phytomer parameter set, including the internode/petiole/leaf/peduncle/inflorescence sub-structures and the leaf prototype. Every numeric field is a RandomParameter spec with a 'distribution' and 'parameters'.
| shoot_type_label | Label for the shoot type. Labels are species-specific, e.g. "trifoliate" (bean), "trunk"/"scaffold" (almond). |
| return_typed | If True, return a typed :class:pyhelios.plant_architecture_params.ShootParameters object instead of a plain nested dict. |
dict (default) or a ShootParameters object containing:phytomer_parameters with nested internode/petiole/leaf/peduncle/ inflorescence parameters and the leaf prototype| ValueError | If shoot_type_label is empty |
| PlantArchitectureError | If parameter retrieval fails |
Definition at line 862 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.getDefaultCarbohydrateParameters | ( | self, | |
| bool | return_typed = False ) |
Get a default-constructed set of carbohydrate-model parameters.
The native API exposes no per-plant getter for carbohydrate parameters, so this returns the C++ defaults as a template to modify and apply via :meth:`setPlantCarbohydrateParameters`.
| return_typed | If True, return a typed :class:pyhelios.plant_architecture_params.CarbohydrateParameters. |
dict (default) or CarbohydrateParameters object. Definition at line 956 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.getDefaultNitrogenParameters | ( | self, | |
| bool | return_typed = False ) |
Get a default-constructed set of nitrogen-model parameters.
The native API exposes no per-plant getter for nitrogen parameters, so this returns the C++ defaults as a template to modify and apply via :meth:`setPlantNitrogenParameters`.
| return_typed | If True, return a typed :class:pyhelios.plant_architecture_params.NitrogenParameters. |
dict (default) or NitrogenParameters object. Definition at line 1004 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getGrowthFrameCount | ( | self, | |
| int | plant_id ) |
Get the number of registered growth frames for a plant.
| plant_id | ID of the plant instance to query |
registerGrowthFrame| ValueError | If plant_id is negative |
Definition at line 3545 of file PlantArchitecture.py.
| vec3 pyhelios.PlantArchitecture.PlantArchitecture.getInternodeAxisVector | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | stem_fraction ) |
Unit direction of one internode at a fraction of its length.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| stem_fraction | Position along the internode, 0 at its base and 1 at its tip |
| ValueError | If an identifier is invalid, ``stem_fraction`` is outside [0, 1], or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5802 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getInternodeLength | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Present length of one internode in meters, measured along its node positions.
| ValueError | If an identifier is invalid or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5751 of file PlantArchitecture.py.
| List[vec3] pyhelios.PlantArchitecture.PlantArchitecture.getInternodeNodePositions | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Positions of one internode's nodes, from its base to its tip.
The first position is the tip of the previous internode on the shoot.
| ValueError | If an identifier is invalid or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5781 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getInternodeRadius | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Radius in meters at the base of one internode.
| ValueError | If an identifier is invalid or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5765 of file PlantArchitecture.py.
| vec3 pyhelios.PlantArchitecture.PlantArchitecture.getLeafBasePosition | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| int | leaf_index ) |
Position where one leaf (leaflet) attaches to its petiole.
| ValueError | If an identifier is invalid or an index is out of range |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5890 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getLeafBladeArea | ( | self, | |
| int | leaf_object_id ) |
One-sided blade area (m²) of a single leaf object.
A leaf object can carry a petiolule -- the stalk joining a leaflet to its rachis (see :attr:`pyhelios.plant_architecture_params.LeafPrototype.build_petiolule`) -- whose primitives are labelled ``"petiolule"`` rather than ``"leaf"``. This reports the area of the object without them, which is what every leaf-area quantity of the plugin (:meth:`sumPlantLeafArea`, :meth:`getPlantLeafAreas`) means as of helios-core 1.3.89. ``Context.getObjectArea()`` on the same object includes the petiolule.
| leaf_object_id | Object ID of the leaf (e.g. from :meth:getPlantLeafObjectIDs) |
| ValueError | If ``leaf_object_id`` is not a non-negative int |
| PlantArchitectureError | If the object does not exist |
| RuntimeError | If the native library predates helios-core v1.3.89 |
Definition at line 6008 of file PlantArchitecture.py.
|
static |
List the library per-timestep callback functions that :meth:setPhytomerCallbackFunction accepts by name.
These are the functions the library plant models use, for example ``"AlmondSpurPhytomerCallbackFunction"`` (grows spurs on a model that defines a ``spur`` shoot type) or ``"GrapevinePhytomerCallbackFunction"`` (pulls fruit-zone leaves).
| RuntimeError | If the native library predates this function |
Definition at line 5508 of file PlantArchitecture.py.
|
static |
List the library phytomer creation functions that :meth:setPhytomerCreationFunction accepts by name.
These are the functions the library plant models use, for example ``"AlmondPhytomerCreationFunction"`` or ``"TomatoPhytomerCreationFunction"``.
| RuntimeError | If the native library predates this function |
Definition at line 5491 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getParentShootID | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the ID of the shoot a shoot grew from.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
Definition at line 1688 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPathToRoot | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the chain of shoots connecting a shoot to the base stem shoot.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
Definition at line 1766 of file PlantArchitecture.py.
| vec3 pyhelios.PlantArchitecture.PlantArchitecture.getPetioleAxisVector | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | stem_fraction, | ||
| int | petiole_index ) |
Unit direction of one petiole at a fraction of its length.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| stem_fraction | Position along the petiole, 0 at its base and 1 at its tip |
| petiole_index | Petiole within the phytomer |
| ValueError | If an identifier is invalid, ``stem_fraction`` is outside [0, 1], or an index is out of range (a phytomer whose leaf was shed has no petioles) |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5824 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPetioleFlexibility | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Bending flexibility of the petioles of one phytomer.
The value is drawn from ``PhytomerParameters.petiole.flexibility`` when the phytomer is created and held for its life. 0 is a rigid petiole.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| ValueError | If any identifier is not a non-negative int |
| PlantArchitectureError | If the plant, shoot or node does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 5160 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPetioleLength | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| Optional[int] | petiole_index = None ) |
Current length of a phytomer's petioles, measured along the centerline.
This is the length right now, not the mature length the petiole is growing toward, so it rises as the petiole elongates. Contrast the leaf readers, which report the size a leaf is expanding toward. The length is an arclength rather than a base-to-tip distance, so a petiole drooping under its leaves reports the same length as a rigid one of the same age. With ``petiole_index`` omitted, returns the mean over every petiole on the phytomer. Petioles at one node are parallel structures rather than segments in series, so their lengths are not additive and the mean is the meaningful summary. A phytomer with no petiole -- a leafless woody type, or one whose leaf has been shed reports 0.0.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer; None for the phytomer mean |
| ValueError | If any identifier is not a non-negative int |
| PlantArchitectureError | If the plant, shoot, node or petiole does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4760 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPetioleRadii | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index ) |
Radius in meters of one petiole at each of its centerline vertices (see :meth:getPetioleVertices).
| ValueError | If an identifier is invalid or an index is out of range |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5857 of file PlantArchitecture.py.
| List[vec3] pyhelios.PlantArchitecture.PlantArchitecture.getPetioleVertices | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index ) |
Centerline vertices of one petiole, from its base at the node to its tip.
| ValueError | If an identifier is invalid or an index is out of range |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5841 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPhytomerAge | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Age of one phytomer in days, counted from its creation.
| ValueError | If an identifier is invalid or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5738 of file PlantArchitecture.py.
| Optional[str] pyhelios.PlantArchitecture.PlantArchitecture.getPhytomerCallbackFunctionName | ( | self, | |
| str | shoot_type_label ) |
Get the name of the library per-timestep callback function a shoot type carries.
| shoot_type_label | An existing shoot type label |
None if the shoot type has no callback function or has a Python one| ValueError | If the label is not a non-empty str |
| PlantArchitectureError | If the shoot type does not exist |
| RuntimeError | If the native library predates this function |
Definition at line 5475 of file PlantArchitecture.py.
| Optional[str] pyhelios.PlantArchitecture.PlantArchitecture.getPhytomerCreationFunctionName | ( | self, | |
| str | shoot_type_label ) |
Get the name of the library creation function a shoot type carries.
Use it to carry a library model's creation function over to a new shoot type, which
:meth:`defineShootType` starts without::
params = plantarch.getCurrentShootParameters("proleptic")
plantarch.defineShootType("my_shoot", params)
name = plantarch.getPhytomerCreationFunctionName("proleptic")
if name:
plantarch.setPhytomerCreationFunction("my_shoot", name)
| shoot_type_label | An existing shoot type label |
None if the shoot type has no creation function or has a Python one| ValueError | If the label is not a non-empty str |
| PlantArchitectureError | If the shoot type does not exist |
| RuntimeError | If the native library predates this function |
Definition at line 5457 of file PlantArchitecture.py.
| List[List[int]] pyhelios.PlantArchitecture.PlantArchitecture.getPhytomerLeafObjectIDs | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Object IDs of one phytomer's leaves, grouped by petiole.
Returns one list per petiole with one object ID per leaf (leaflet) on that petiole, in the order :meth:`getLeafBasePosition` indexes them. A phytomer whose leaves were shed returns empty lists.
| ValueError | If an identifier is invalid or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5876 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantAge | ( | self, | |
| int | plant_id ) |
Get the current age of a plant in days.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 2021 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantAvailableNitrogen | ( | self, | |
| int | plant_id ) |
Nitrogen (g N) in a plant's available pool, awaiting allocation to its organs.
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5978 of file PlantArchitecture.py.
| Union[vec3, List[vec3]] pyhelios.PlantArchitecture.PlantArchitecture.getPlantBasePosition | ( | self, | |
| Union[int, List[int]] | plant_ids ) |
Get the base position of one plant or of several plants.
For a plant with no shoots yet, this is the position at which its first shoot will be placed.
| plant_ids | A single plant ID, or a sequence of plant IDs |
| ValueError | If a plant ID is not a non-negative int or the sequence is empty |
| PlantArchitectureError | If a plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6272 of file PlantArchitecture.py.
| Dict[str, float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantBuildParameters | ( | self, | |
| int | plant_id ) |
Get the build parameters a plant was built with.
These are the ``build_parameters`` given to :meth:`buildPlantInstanceFromLibrary` or :meth:`buildPlantCanopyFromLibrary`. A plant keeps them for its life (some, such as the sorghum ``tiller_count``, are read as it grows), and they are saved and restored by :meth:`writePlantStructureXML` / :meth:`readPlantStructureXML`. Parameters that were not given are absent and take the model's default where they are read.
| plant_id | ID of the plant |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.93 |
Definition at line 6118 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantCollisionRelevantObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs of collision-relevant geometry for a specific plant.
This method returns the subset of plant geometry that participates in collision detection, as filtered by setCollisionRelevantOrgans(). Useful for visualization and debugging collision detection behavior.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 3190 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantFlowerObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs for all flower (inflorescence) objects on a specific plant.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1508 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantFruitObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs for all fruit objects on a specific plant.
| plant_id | ID of the plant instance |
[].| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1540 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantHeight | ( | self, | |
| int | plant_id ) |
Get the height of a plant in meters.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 2110 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantInternodeLengths | ( | self, | |
| int | plant_id ) |
Get the built length of every internode on a plant.
Measured along the internode's node positions as they were built, so a shoot whose geometry was prescribed by :meth:`addShootFromNodePositions` reports its measured lengths and a grown shoot reports what growth produced. See :meth:`getPlantLeafAreas` for why this differs from reading the shoot type's ``internode_length_max``. Internodes are visited shoot by shoot and then phytomer by phytomer, so the result has one entry per phytomer on the plant. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the query fails or the library predates v1.3.85 |
Definition at line 1946 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantInternodeObjectIDs | ( | self, | |
| int | plant_id, | ||
| Optional[str] | shoot_type_label = None ) |
Get the object IDs of a plant's internode (tube) objects.
Each shoot is one tube object spanning all its internodes, so the list has one entry per shoot that has geometry. The structural counterpart to :meth:`getPlantLeafObjectIDs`.
| plant_id | ID of the plant instance |
| shoot_type_label | If given, only internodes of shoots of this type (e.g. "stem") are returned |
| ValueError | If ``plant_id`` is not a non-negative int or ``shoot_type_label`` is not a non-empty str |
| PlantArchitectureError | If the plant does not exist, or no shoot on it has the given shoot type label |
| RuntimeError | If the native library predates this binding |
Definition at line 6346 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafArea | ( | self, | |
| int | plant_id ) |
Get the total leaf area of a plant in m².
Leaf area is blade area: the petiolules (leaflet stalks) of compound leaves are excluded (helios-core 1.3.89+; earlier versions counted them as leaf).
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 2141 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafAreas | ( | self, | |
| int | plant_id ) |
Get the built one-sided surface area of every leaf on a plant.
Measured from the geometry that was actually built, rather than reported from the shoot type's parameters. The two answer different questions: the shoot type gives the distribution a parameter was drawn from, while this gives what the plant ended up with. This reports present area, so a leaf part-way through its growth is counted at its current size. Leaves are visited shoot by shoot and then phytomer by phytomer, the same order as :meth:`getPlantLeafObjectIDs`. Leaves whose geometry does not exist (removed, senesced, or never built) are omitted rather than reported as zero, so the result can be shorter than the list from :meth:`getPlantLeafObjectIDs`. Each area is blade area: a leaflet's petiolule belongs to its leaf object but is not counted (helios-core 1.3.89+). Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the query fails or the library predates v1.3.85 |
Definition at line 1919 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafAzimuthAngleDistribution | ( | self, | |
| Union[int, List[int]] | plant_ids, | ||
| int | num_bins, | ||
| bool | normalize = True ) |
Get the leaf-area-weighted leaf azimuth angle distribution of one or more plants.
Each leaf blade facet adds its area to the bin of its normal's azimuth (0-360 degrees). Petiolules are excluded. Several plants are pooled into one histogram.
| plant_ids | A single plant ID, or a sequence of plant IDs to pool |
| num_bins | Number of histogram bins, evenly spaced between 0 and 360 degrees |
| normalize | If True (default), the bins sum to 1; otherwise they hold leaf area (m^2). A plant with no leaves gives all-zero bins either way. |
num_bins values| ValueError | If a plant ID is invalid, the sequence is empty, ``num_bins`` is not a positive int, or normalize is not a bool |
| PlantArchitectureError | If a plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6424 of file PlantArchitecture.py.
| List[vec3] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafBases | ( | self, | |
| int | plant_id ) |
Get the attachment base position of every leaf on a specific plant.
The base is where the leaf attaches to its petiole, not the leaf centroid.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
getPlantLeafObjectIDs. The two are built by independent traversals of the shoot tree, so their index correspondence is not guaranteed by the native API.Definition at line 1575 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafCount | ( | self, | |
| int | plant_id ) |
Get the number of leaf objects on a plant.
Counts compound leaf objects, not primitives -- a leaf built from many triangles counts once, and a compound leaf contributes one per leaflet. Equivalent to ``len(getPlantLeafObjectIDs(plant_id))`` without materializing the ID list.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
Definition at line 4507 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafInclinationAngleDistribution | ( | self, | |
| Union[int, List[int]] | plant_ids, | ||
| int | num_bins, | ||
| bool | normalize = True ) |
Get the leaf-area-weighted leaf inclination angle distribution of one or more plants.
Each leaf blade facet adds its area to the bin of its inclination (the angle between the facet normal and vertical, folded into 0-90 degrees). Petiolules are excluded. Several plants are pooled into one histogram.
| plant_ids | A single plant ID, or a sequence of plant IDs to pool |
| num_bins | Number of histogram bins, evenly spaced between 0 and 90 degrees |
| normalize | If True (default), the bins sum to 1; otherwise they hold leaf area (m^2). A plant with no leaves gives all-zero bins either way. |
num_bins values| ValueError | If a plant ID is invalid, the sequence is empty, ``num_bins`` is not a positive int, or normalize is not a bool |
| PlantArchitectureError | If a plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6395 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafInclinations | ( | self, | |
| int | plant_id ) |
Get the inclination angle of every leaf on a plant.
The angle between each leaf blade and the horizontal, computed from its area-weighted normal so that a curved or folded blade is summarized by the direction it mostly faces. 0 degrees is a horizontal blade and 90 degrees a vertical one; because a blade is a surface, a normal pointing down describes the same inclination as its opposite pointing up, so the angle is folded about the horizontal and never exceeds 90 degrees. Ordering and the treatment of missing geometry match :meth:`getPlantLeafAreas`. A blade whose facet normals cancel exactly is additionally omitted, since it faces no single direction. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the query fails or the library predates v1.3.85 |
Definition at line 1975 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantLeafObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs for all leaf objects on a specific plant.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
getPlantLeafBases. The two are built by independent traversals of the shoot tree, so their index correspondence is not guaranteed by the native API.Definition at line 1417 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantMaxAge | ( | self, | |
| int | plant_id ) |
Get the maximum age of a plant, beyond which it stops growing.
| plant_id | ID of the plant instance |
setPlantMaxAge.| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 2048 of file PlantArchitecture.py.
| List[str] pyhelios.PlantArchitecture.PlantArchitecture.getPlantModelBuildParameterNames | ( | self, | |
| str | plant_model ) |
Get the names of the build parameters a library plant model accepts.
These are the keys that may be passed as ``build_parameters`` to :meth:`buildPlantInstanceFromLibrary` and :meth:`buildPlantCanopyFromLibrary` for the model; any other key is rejected. The model does not need to be loaded.
| plant_model | Name of the plant model (see :meth:getAvailablePlantModels) |
| ValueError | If ``plant_model`` is not a non-empty string |
| PlantArchitectureError | If the model does not exist in the library |
| RuntimeError | If the native library predates helios-core v1.3.93 |
Definition at line 1091 of file PlantArchitecture.py.
| tuple pyhelios.PlantArchitecture.PlantArchitecture.getPlantModelLeafInclinationDistribution | ( | self, | |
| str | plant_model_name ) |
Beta leaf inclination distribution (mu, nu) that a library plant model declares.
Plants built from a model that declares a distribution have their leaf inclinations steered toward it automatically. Returns ``(0.0, 0.0)`` when the model declares none.
| ValueError | If ``plant_model_name`` is not a non-empty str |
| PlantArchitectureError | If the model is not in the library |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5914 of file PlantArchitecture.py.
| str pyhelios.PlantArchitecture.PlantArchitecture.getPlantName | ( | self, | |
| int | plant_id ) |
Get the name of the plant model a plant was built from.
For a plant built with :meth:`buildPlantInstanceFromLibrary` this is the label passed to :meth:`loadPlantModelFromLibrary` (e.g. ``"bean"``). A plant assembled by hand with :meth:`addPlantInstance` reports whatever name the native library assigned to it.
| plant_id | ID of the plant instance |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6154 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantPeduncleObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs for all peduncle objects on a specific plant.
Peduncles are the stalks bearing flowers and fruit.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1478 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getPlantPetioleObjectIDs | ( | self, | |
| int | plant_id ) |
Get object IDs for all petiole objects on a specific plant.
Petioles are the stalks attaching leaves to the stem, so this is the structural counterpart to :meth:`getPlantLeafObjectIDs`.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If retrieval fails |
Definition at line 1447 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getPlantStemHeight | ( | self, | |
| int | plant_id ) |
Get the height of a plant's main stem in meters.
The vertical extent of the base stem shoot, extended by any shoot of the same rank appended to its tip. Unlike :meth:`getPlantHeight`, leaves, branches and inflorescences reaching above the stem are not counted.
| plant_id | ID of the plant instance |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist or has no stem geometry |
| RuntimeError | If the native library predates this binding |
Definition at line 6243 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getSeasonPeakLightExposureAtPoint | ( | self, | |
| int | plant_id, | ||
| vec3 | position ) |
Local light exposure at a point under the plant's most recent seasonal peak canopy.
Like :meth:`getShadowLightExposureAtPoint`, but read from the shadow grid captured when the plant's leaf area last reached its seasonal maximum rather than from the current canopy. Through dormancy, when a deciduous plant has no leaves and the current exposure is 1 everywhere, this still gives the light each point stood in over the past summer. The "apple" and "apple_fruitingwall" library models use it to decide how many flowers each bud forms.
| plant_id | ID of the plant |
| position | Query position in world coordinates |
| ValueError | If ``plant_id`` is not a non-negative int or ``position`` is not a vec3 |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.93 |
Definition at line 6078 of file PlantArchitecture.py.
| float pyhelios.PlantArchitecture.PlantArchitecture.getShadowLightExposureAtPoint | ( | self, | |
| int | plant_id, | ||
| vec3 | position ) |
Local light exposure at a point from a plant's shadow-propagation grid.
Exposure runs from 0 (fully shaded) to 1 (unshaded), and is the quantity that drives shade-based branch shedding at each dormancy boundary in parameter-based growth (after Palubicki et al. 2009): branches deep in the crown interior see a low exposure while branches on the crown surface do not. Returns 1 when the plant has no canopy yet, or when the shadow grid is disabled because the carbohydrate model is active. Intended for inspection and testing; it is a cheap surrogate for light interception, not a radiation calculation.
| plant_id | ID of the plant |
| position | Query position in world coordinates |
| ValueError | If ``plant_id`` is not a non-negative int or ``position`` is not a vec3 |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.89 |
Definition at line 6043 of file PlantArchitecture.py.
| Dict[str, Any] pyhelios.PlantArchitecture.PlantArchitecture.getShoot | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get a read-only view of a shoot's topology.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
rank, parent_shoot_id (-1 for the base stem), parent_node_index, and node_count. Definition at line 1650 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getShootChildIDs | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the child shoot IDs of a shoot (flattened across parent node indices).
Definition at line 1661 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getShootDepth | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the number of shoots between a shoot and the base stem shoot.
The base stem has depth 0, its children depth 1, and so on. Unlike :meth:`getShootRank` this counts every step in the shoot tree, including axis continuations created by :meth:`appendShoot`.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
Definition at line 1726 of file PlantArchitecture.py.
| Dict[int, List[int]] pyhelios.PlantArchitecture.PlantArchitecture.getShootHierarchyMap | ( | self, | |
| int | plant_id ) |
Get the parent-to-children structure of a plant.
Only shoots that actually have children appear as keys. Pruned shoots appear neither as keys nor among the children.
| plant_id | ID of the plant instance |
Definition at line 1824 of file PlantArchitecture.py.
| Dict[int, List[int]] pyhelios.PlantArchitecture.PlantArchitecture.getShootIDsByRank | ( | self, | |
| int | plant_id ) |
Group a plant's shoot IDs by branching rank.
Rank 0 is the base stem, rank 1 its direct branches, and so on. Shoots that have been pruned away are not included.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist |
Definition at line 2614 of file PlantArchitecture.py.
| List[float] pyhelios.PlantArchitecture.PlantArchitecture.getShootInternodeRadii | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the per-vertex woody internode radii of a shoot.
Definition at line 1861 of file PlantArchitecture.py.
| List[tuple] pyhelios.PlantArchitecture.PlantArchitecture.getShootInternodeVertices | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the woody internode polyline vertices of a shoot as a list of (x, y, z) tuples.
Definition at line 1850 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getShootNodeCount | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the current number of nodes (phytomers) on one shoot.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs; 0 is the base stem) |
| ValueError | If ``plant_id`` or ``shoot_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist or the shoot ID is out of range |
| RuntimeError | If the native library predates this binding |
Definition at line 6212 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getShootRank | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Get the branching rank of a shoot.
Rank is the botanical branching order: the base stem is rank 0, a branch off it is rank 1, and so on. A shoot created by :meth:`appendShoot` continues its parent's axis rather than branching from it, so it keeps the parent's rank. Rank is therefore not the same as :meth:`getShootDepth`.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
Definition at line 1709 of file PlantArchitecture.py.
| int pyhelios.PlantArchitecture.PlantArchitecture.getShootVegetativeBudCount | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| Optional[BudState] | state = None ) |
Count a shoot's axillary vegetative buds, summed over all phytomers and petioles.
Buds are never removed from a shoot -- only their state changes -- so the unfiltered count is stable over the shoot's life and makes a useful denominator.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| state | Count only buds in this :class:~pyhelios.BudState. None (the default) counts buds in every state. |
| ValueError | If an identifier is negative, or ``state`` is not a BudState |
| PlantArchitectureError | If the plant or shoot does not exist |
BudState.DEAD means "will produce nothing further", which covers both buds that were killed and buds that have already broken into a child shoot. A dead-bud count is therefore not a count of killed buds. To test whether a shoot can still grow, count the live states instead – for example the unfiltered total minus the dead count.Definition at line 4473 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.getTerminalShootIDs | ( | self, | |
| int | plant_id ) |
Get the plant's terminal shoots – those carrying no child shoots.
These are the tips of the shoot tree. Note that this is a topological test rather than a botanical one: a shoot whose axis is continued by :meth:`appendShoot` has that continuation as a child and so is not terminal. Pruned shoots are omitted.
| plant_id | ID of the plant instance |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist |
Definition at line 2648 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.harvestPlant | ( | self, | |
| int | plant_id ) |
Harvest a plant by removing its flowers and fruit.
Every non-dormant floral bud on the plant is killed, which deletes the associated flower, fruit and peduncle geometry from the Context. Vegetative structure is untouched and the plant continues to grow afterwards.
| plant_id | ID of the plant instance to harvest |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist or the call fails |
removePlantLeaves to defoliate.Definition at line 2466 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.is_available | ( | self | ) |
Check if PlantArchitecture is available in current build.
Definition at line 6546 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.isLeafAngleDistributionTrackingEnabled | ( | self, | |
| int | plant_id ) |
Whether a plant's leaf angles are being steered toward a prescribed distribution.
| plant_id | ID of the plant instance |
| ValueError | If ``plant_id`` is not a non-negative int |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4719 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.isPlantDormant | ( | self, | |
| int | plant_id ) |
Check whether a plant is dormant.
| plant_id | Identifier of the plant to check |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist or the query fails |
Definition at line 2379 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.isShootGeometryPrescribed | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Report whether a shoot's existing geometry was prescribed by the caller rather than generated.
True for a shoot built by :meth:`addShootFromNodePositions`, whose internode path follows measured node positions. Such a shoot's existing phytomers are exempt from the re-scaling and re-curving performed by :meth:`advanceTime`, so a caller reading geometry back can tell which parts of a plant are measurement and which are model output. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| ValueError | If either ID is negative |
| PlantArchitectureError | If the query fails or the library predates v1.3.85 |
Definition at line 2000 of file PlantArchitecture.py.
| bool pyhelios.PlantArchitecture.PlantArchitecture.isShootPruned | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Report whether a shoot has been pruned away entirely.
:meth:`pruneBranch` called with ``node_index=0`` removes all of a shoot's phytomers and geometry but keeps the shoot in the plant's tree so that shoot IDs stay stable. Such a shoot is still returned by :meth:`getAllShootIDs` but is inert it has zero nodes, contributes no leaf area, and cannot be queried for geometry. Use this to skip those shoots when walking :meth:`getAllShootIDs`.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
Definition at line 1749 of file PlantArchitecture.py.
| List[str] pyhelios.PlantArchitecture.PlantArchitecture.listShootTypeLabels | ( | self, | |
| Optional[str] | plant_model = None, | ||
| Optional[int] | plant_id = None ) |
Get the shoot type labels defined for a plant model.
Shoot type labels are species-specific strings such as "trunk" or "scaffold", and every shoot-parameter call takes one. Use this to discover the valid labels rather than guessing them.
| plant_model | Query this library model without changing the currently loaded one. Use getAvailablePlantModels() for valid names. Mutually exclusive with plant_id. |
| plant_id | Query the shoot types captured by this plant instance when it was created. Mutually exclusive with plant_model. |
With neither argument, queries the currently loaded model, which requires a prior call to loadPlantModelFromLibrary().
| ValueError | If both plant_model and plant_id are given, or plant_id is negative |
| PlantArchitectureError | If no model is loaded, or the model or plant is unknown |
Definition at line 1132 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.loadPlantModelFromLibrary | ( | self, | |
| str | plant_label ) |
Load a plant model from the built-in library.
| plant_label | Plant model identifier from library. Available models include: "almond", "apple", "bean", "bindweed", "butterlettuce", "capsicum", "cheeseweed", "cowpea", "easternredbud", "grapevine_VSP", "maize", "olive", "pistachio", "puncturevine", "rice", "sorghum", "soybean", "strawberry", "sugarbeet", "tomato", "cherrytomato", "walnut", "wheat" |
| ValueError | If plant_label is empty or invalid |
| PlantArchitectureError | If model loading fails |
Definition at line 367 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.makePlantDormant | ( | self, | |
| int | plant_id ) |
Force a plant into a dormant state immediately.
It is the counterpart to scheduling dormancy through this forces the state now, rather than waiting for a degree-day threshold to be crossed. Dormancy strips the plant's leaves and marks its non-dormant buds dormant, so a custom-built plant can be put into the same over-winter state that a library-built perennial reaches through phenology.
| plant_id | Identifier of the plant to make dormant |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist or the call fails |
Definition at line 2322 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.optionalOutputObjectData | ( | self, | |
| Union[str, List[str]] | object_data_labels ) |
Enable optional output object data to be written to the Context.
By default, the plant architecture model only writes a minimal set of object data. This method enables additional object data fields so that they are available on the Context's compound objects after building.
| object_data_labels | A single label or a list of labels to enable. Valid labels include: "age", "rank", "plantID", "plant_name", "plant_height", "plant_type", "phenology_stage", "leafID", "peduncleID", "closedflowerID", "openflowerID", "fruitID", "carbohydrate_concentration". The special label "all" enables every available field. |
| ValueError | If a label is empty or not a string |
| PlantArchitectureError | If an invalid label is supplied or the operation otherwise fails |
Definition at line 2177 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.pruneBranch | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index ) |
Prune a shoot at a node, removing that node and everything distal to it.
The phytomer at ``node_index`` is deleted along with every phytomer above it on the same shoot, and the cut recurses into every child shoot attached at or above that node. The shoot's woody internode tube is trimmed back to the cut and its apical bud is terminated, so the pruned axis will not resume growing. Pruning at ``node_index=0`` therefore removes the entire shoot and its whole branch system.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| node_index | Node on the shoot to cut at, in [0, node_count) |
| ValueError | If any identifier is negative |
| PlantArchitectureError | If the plant or shoot does not exist, if node_index is beyond the shoot's current node count, or if the native call fails |
getAllShootIDs with a node_count of 0 rather than disappearing. Do not rely on either behavior; traverse with :meth:getShoot and treat node_count == 0 as "nothing left here".Called from a phytomer creation or callback function (see :meth:setPhytomerCreationFunction, :meth:setPhytomerCallbackFunction), the arguments are checked immediately but the cut is deferred: it is applied at the end of the current time step of :meth:advanceTime, or before the build call that ran the function returns. Until then the shoot still looks uncut. Deferred cuts are applied in the order requested, and one whose shoot or node an earlier cut already removed does nothing.
Definition at line 2432 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.pruneShootsByRank | ( | self, | |
| int | plant_id, | ||
| int | min_rank ) |
Prune every shoot at or above a given branching rank.
This is the "remove higher-order branches" thinning operation: passing ``min_rank=3`` leaves the base stem and its first two orders of branching intact and cuts everything finer. Because :meth:`pruneBranch` already recurses into child shoots, only the shallowest shoot on each pruned axis is cut and the rest follow.
| plant_id | ID of the plant instance |
| min_rank | Lowest rank to prune. Must be at least 1 – rank 0 is the base stem, and pruning it would destroy the plant. |
| ValueError | If plant_id is negative or min_rank is less than 1 |
| PlantArchitectureError | If the plant does not exist |
deletePlantInstance; to cut the base stem itself call :meth:pruneBranch directly.Definition at line 2689 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.pruneShootSubtree | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| bool | include_self = True ) |
Prune a shoot and everything growing off it.
| plant_id | ID of the plant instance |
| shoot_id | Root of the branch system to remove |
| include_self | If True (default) the shoot itself is cut at node 0. If False the shoot is kept and only its child shoots are cut. |
| ValueError | If either identifier is negative |
| PlantArchitectureError | If the plant or shoot does not exist |
Definition at line 2727 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.pruneTerminalShoots | ( | self, | |
| int | plant_id, | ||
| int | stride = 2 ) |
Thin a plant by pruning every stride-th terminal shoot.
Terminal shoots are taken in ascending ID order and every ``stride``-th one starting from the first is cut, so ``stride=2`` removes about half the tips and ``stride=3`` about a third. The base stem is never cut.
| plant_id | ID of the plant instance |
| stride | Spacing between pruned tips. Must be at least 1; stride=1 prunes every terminal shoot. |
| ValueError | If plant_id is negative or stride is less than 1 |
| PlantArchitectureError | If the plant does not exist |
Definition at line 2759 of file PlantArchitecture.py.
| List[int] pyhelios.PlantArchitecture.PlantArchitecture.readPlantStructureXML | ( | self, | |
| Union[str, Path] | filename, | ||
| bool | quiet = False ) |
Load plant structure from XML file.
This method reads plant architecture data from an XML file previously saved with writePlantStructureXML(). The loaded plants are added to the current context and can be grown, modified, or analyzed like any other plants.
| filename | Path to XML file to load (absolute or relative to current working directory) |
| quiet | If True, suppress console output during loading (default: False) |
| ValueError | If filename is empty |
| PlantArchitectureError | If file doesn't exist, cannot be parsed, or loading fails |
Definition at line 3590 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.recordPetioleRestShape | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index ) |
Record one petiole's current centerline as its undeformed rest shape.
:meth:`bendPetioleUnderLeafWeight` always bends from the recorded rest shape, so a petiole whose centerline has been replaced wholesale -- by :meth:`setPetioleNodePositions`, for instance -- must have its new shape recorded before it will droop from it. This also marks the petiole as needing to be bent again, so the next bend is not skipped as redundant.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer |
| ValueError | If any identifier is not a non-negative int |
| PlantArchitectureError | If the plant, shoot, node or petiole does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 5056 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.registerGrowthFrame | ( | self, | |
| int | plant_id, | ||
| float | min_segment_length = 0.001 ) |
Capture a snapshot of the plant's geometry as a growth animation frame.
Call this after each :meth:`advanceTime` step to record the plant state for later animation export via :meth:`writePlantGrowthUSD`.
| plant_id | ID of the plant instance to capture |
| min_segment_length | Minimum segment length (m); shorter segments are skipped |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If plant doesn't exist |
Definition at line 3471 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.removePlantLeaves | ( | self, | |
| int | plant_id ) |
Remove all leaves from every shoot on a plant.
Leaf and petiole geometry is deleted from the Context. Buds are left alive, so the plant can produce new leaves as it continues to grow.
| plant_id | ID of the plant instance to defoliate |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the plant does not exist or the call fails |
Definition at line 2494 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.removeShootFloralBuds | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Kill all floral buds on a single shoot.
Existing flower, fruit and peduncle geometry on the shoot is deleted and no new flowers will form there.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| ValueError | If either identifier is negative |
| PlantArchitectureError | If the plant or shoot does not exist |
Definition at line 2573 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.removeShootLeaves | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Remove all leaves from a single shoot.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| ValueError | If either identifier is negative |
| PlantArchitectureError | If the plant or shoot does not exist |
Definition at line 2519 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.removeShootVegetativeBuds | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Mark every vegetative bud on a single shoot as dead.
Despite the name, nothing is removed: each axillary vegetative bud on the shoot is set to ``BudState.DEAD`` and the bud entries themselves stay in place, so :meth:`getShootVegetativeBudCount` still sees them and the unfiltered count is unchanged. Dead buds are skipped when dormancy breaks, so the shoot keeps its existing structure but produces no new lateral shoots -- the standard way to stop a trained axis from throwing new canes, and to stop the old wood of a reconstructed tree re-growing. This is exactly equivalent to setting every bud on the shoot to ``BudState.DEAD``; the shoot's own apex is unaffected, so pair it with :meth:`terminateApicalBud` to stop the shoot extending as well.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| ValueError | If either identifier is negative |
| PlantArchitectureError | If the plant or shoot does not exist |
:meth:`getShootVegetativeBudCount`, to confirm the buds are dead rather than
gone, and :meth:`terminateApicalBud`, for the shoot's apex.
Definition at line 2552 of file PlantArchitecture.py.
| Union[dict, PhytomerParameters] pyhelios.PlantArchitecture.PlantArchitecture.resamplePhytomerParameters | ( | self, | |
| Union[dict, PhytomerParameters] | phytomer_parameters ) |
Draw one realization of a set of phytomer parameters.
Mirrors the native ``PhytomerParameters::resample()``, which each phytomer calls once when it is created (helios-core 1.3.89+) to draw its own values of every distributed parameter. The draw uses the Context's random generator, so it follows ``Context.seedRandomGenerator()``. Every field with a distribution (uniform, normal, weibull, discrete values) comes back as a constant holding the value drawn for it; constant fields, and fields that are not random parameters, are returned unchanged and consume no random draws. The input is not modified.
| phytomer_parameters | A :class:pyhelios.plant_architecture_params.PhytomerParameters or its dict form (e.g. getCurrentShootParameters(label)["phytomer_parameters"]) |
| ValueError | If ``phytomer_parameters`` is not a dict or PhytomerParameters |
| PlantArchitectureError | If the parameters cannot be parsed natively |
| RuntimeError | If the native library predates helios-core v1.3.89 |
Definition at line 6452 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.scaleInternodeMaxLength | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | scale_factor ) |
Scale the fully-elongated length of one existing internode.
As :meth:`setInternodeMaxLength`, relative to the current target: a factor below one shortens an internode that is already longer than its new target, and a factor above one lets it grow further.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| scale_factor | Factor to scale the fully-elongated length by; must be positive |
| ValueError | If an identifier is invalid, ``scale_factor`` is not positive, or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5646 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.scaleLeafPrototypeScale | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | scale_factor, | ||
| Optional[int] | petiole_index = None ) |
Scale a phytomer's leaves now: both the blades' present size and the size they grow toward.
The leaves are rescaled about their bases immediately and keep their expansion fraction, so a half-expanded leaf stays half-expanded toward a proportionally larger or smaller mature size. This is what a C++ phytomer creation function does to size a new leaf by its position on the plant. Contrast :meth:`scaleLeafSizeMax`, which moves only the target and leaves the blades as they are.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| scale_factor | Factor to scale the leaves by; must be positive |
| petiole_index | Scale only the leaves of this petiole; None for every petiole |
| ValueError | If an identifier is invalid, ``scale_factor`` is not positive, or an index is out of range |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5674 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.scaleLeafSizeMax | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | scale_factor ) |
Scale the size every leaf on a phytomer is expanding toward, leaving the blades where they are.
The blade's present size is untouched and only its target changes, so the expansion fraction moves the other way: a fully-expanded leaf given a larger target becomes a partly-expanded leaf of the same size and goes on growing on the next :meth:advanceTime. This is what hands a leaf built from measured geometry back to the growth model still the size it was measured.
A factor small enough to put the target below the leaf's present size is the one case in which the blade does move: the leaf is taken down to the new target, and the leaflets of a compound leaf are then re-seated along the petiole, discarding a placement prescribed by :meth:setPetioleLeafGeometry.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| scale_factor | Factor to scale the mature leaf size by; must be positive |
| ValueError | If an identifier is invalid or ``scale_factor`` is not positive |
| PlantArchitectureError | If the plant, shoot or node does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4914 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.scalePetioleMaxLength | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | scale_factor ) |
Scale the fully-elongated length every petiole on a phytomer is growing toward.
The petiole counterpart of internode max-length scaling. The petiole's present length is left where it is and only its target changes, so a phytomer creation function can give a leaf born on a young plant a shorter final petiole without moving the petiole that is already there.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| scale_factor | Factor to scale the fully-elongated length by; must be positive |
| ValueError | If an identifier is invalid or ``scale_factor`` is not positive |
| PlantArchitectureError | If the plant, shoot or node does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4795 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setAttractionParameters | ( | self, | |
| float | view_half_angle_deg, | ||
| float | look_ahead_distance, | ||
| float | attraction_weight, | ||
| float | obstacle_reduction_factor = 0.75, | ||
| Optional[int] | plant_id = None ) |
Tune how strongly attraction points steer growth.
| view_half_angle_deg | Half-angle of the search cone in degrees |
| look_ahead_distance | How far ahead a shoot tip looks, in meters |
| attraction_weight | Strength of the steering, 0 to 1 |
| obstacle_reduction_factor | Scales attraction where an obstacle intervenes |
| plant_id | Apply to this plant only. Applies globally when None. |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If the operation fails |
Definition at line 748 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.setCancelFlag | ( | self, | |
| cancel_flag ) |
Register an external cancellation flag polled during long plant builds.
``cancel_flag`` is a ctypes.c_int that, when set non-zero from another thread, stops the canopy build loop and the advanceTime() growth loop between plants/timesteps — so a long generation can be aborted mid-build (returning whatever was built so far). Set it before the build call; pass None to clear. The flag is caller-owned and must outlive the build.
Definition at line 823 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setCollisionRelevantOrgans | ( | self, | |
| bool | include_internodes = False, | ||
| bool | include_leaves = True, | ||
| bool | include_petioles = False, | ||
| bool | include_flowers = False, | ||
| bool | include_fruit = False ) |
Specify which plant organs participate in collision detection.
This method allows filtering which organs are considered during collision detection, enabling optimization by excluding organs unlikely to cause problematic collisions.
| include_internodes | Include stem internodes in collision detection |
| include_leaves | Include leaf blades in collision detection |
| include_petioles | Include leaf petioles in collision detection |
| include_flowers | Include flowers in collision detection |
| include_fruit | Include fruit in collision detection |
| PlantArchitectureError | If organ filtering fails |
Definition at line 3053 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setInternodeMaxLength | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | length ) |
Set the fully-elongated length of one existing internode.
Only this phytomer's target changes; compare :meth:`setShootInternodeLengthMax`, which sets the target for internodes the shoot has yet to produce. A target below the internode's present length shortens it immediately; a larger target leaves the present length alone and the internode grows toward it on later :meth:`advanceTime` calls.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| length | Fully-elongated internode length in meters; must be positive and finite |
| ValueError | If an identifier is invalid, ``length`` is not positive and finite, or ``node_index`` is past the end of the shoot |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5619 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setLeafAngleDistribution | ( | self, | |
| plant_ids, | |||
| float | beta_mu_inclination, | ||
| float | beta_nu_inclination, | ||
| Optional[float] | eccentricity = None, | ||
| float | ellipse_rotation_degrees = 0.0 ) |
Re-aim every leaf of a finished plant so that its leaf angles follow a prescribed distribution.
Inclination is made to follow a Beta distribution. If ``eccentricity`` is given, azimuth is also made to follow an ellipsoidal distribution; otherwise each leaf keeps its azimuth. Angles are not sampled per leaf: leaves are ordered by their current angle, weighted by leaf area, and each takes the angle at its own position in the target distribution. The leaf arrangement of the plant is therefore kept, a leaf held steeper than its neighbour stays steeper, and the method can be called repeatedly with changing parameters (for example once per timestep) to move the canopy smoothly between distributions. This moves leaves that already exist. To steer leaves as they emerge on a growing plant, use :meth:`enableLeafAngleDistributionTracking`. Each leaf is re-aimed about its own base, so it stays attached to its petiole, and the angles are recorded on the phytomer so they survive an XML round trip.
| plant_ids | A single plant ID, or a sequence of plant IDs over which the distribution is realized as a whole |
| beta_mu_inclination | First parameter of the Beta inclination distribution; must be |
| positive | |
| beta_nu_inclination | Second parameter of the Beta inclination distribution; must be positive. The mean leaf inclination from horizontal is 90 * nu / (mu + nu) degrees, so raising nu relative to mu makes the leaves steeper. |
| eccentricity | Eccentricity of the ellipse defining the azimuth distribution, in [0, 1], where 0 is a uniform azimuth distribution. None (the default) leaves leaf azimuths as they are. |
| ellipse_rotation_degrees | Rotation of that ellipse (degrees); used only when eccentricity is given |
| ValueError | If a plant ID is not a non-negative int, the list is empty, a Beta parameter is not positive, or eccentricity is outside [0, 1] |
| PlantArchitectureError | If a plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 5111 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setLeafNormal | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| int | leaf_index, | ||
| vec3 | target_normal ) |
Re-aim one leaf so its blade faces a given direction.
The roll and pitch that carry the blade onto ``target_normal`` are applied as a single rotation about the leaf's own base, so the leaf stays attached to its petiole and keeps the azimuth of the petiole it hangs from. The angles are recorded on the phytomer, which is what makes the new orientation survive a :meth:`writePlantStructureXML` / :meth:`readPlantStructureXML` round trip -- rotating the leaf object directly through the Context changes the geometry without changing the record and is silently lost on reload.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer |
| leaf_index | Leaf within the petiole |
| target_normal | Direction the blade should face, in world coordinates. Need not be normalized. |
| ValueError | If an identifier is invalid, or ``target_normal`` is not a vec3 |
| PlantArchitectureError | If the leaf has no geometry, the blade's facet normals cancel, or the target cannot be reached by a roll-pitch pair |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4959 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleAndLeafScaleFraction | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| float | petiole_scale_factor_fraction, | ||
| float | leaf_scale_factor_fraction ) |
Set a petiole's length and its leaves' size together, each as a fraction of its own fully-elongated value.
The two fractions are applied in one pass, so the leaves are scaled, re-seated along the rescaled petiole and bent under their new weight once rather than twice. Use this rather than the two single-fraction calls when advancing both.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer |
| petiole_scale_factor_fraction | Fraction of the fully-elongated petiole length |
| leaf_scale_factor_fraction | Fraction of the fully-elongated leaf scale factor |
| ValueError | If any identifier is not a non-negative int |
| PlantArchitectureError | If the plant, shoot, node or petiole does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4870 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleFlexibility | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| float | flexibility ) |
Replace the bending flexibility of the petioles of one existing phytomer.
This changes how far the petioles droop under their leaflets' weight without rebuilding the plant. The geometry does not move until :meth:`bendPetioleUnderLeafWeight` is called for each petiole (or the plant next grows), which bends from the recorded rest shape, so raising and lowering the flexibility is reversible. If the leaves have been posed, for example by :meth:`setLeafAngleDistribution`, bend with ``include_posed_leaves=True``.
bendPetioleUnderLeafWeight does nothing at a flexibility of exactly zero, so a petiole that has been bent is returned to its rest shape with a small positive value rather than zero.| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| flexibility | Dimensionless petiole flexibility; must be finite and non-negative |
| ValueError | If an identifier is invalid or ``flexibility`` is not a finite non-negative number |
| PlantArchitectureError | If the plant, shoot or node does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 5203 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleLeafCount | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| int | leaf_count ) |
Change the number of leaves (leaflets) on one petiole of an existing phytomer.
The leaves are rebuilt procedurally. By default the count is set by the shoot type's ``leaf.leaves_per_petiole``; use this to match a measured compound leaf with a different number of leaflets before calling :meth:`setPetioleLeafGeometry`.
| plant_id | Plant identifier. |
| shoot_id | Shoot identifier. |
| node_index | Index of the phytomer along the shoot. |
| petiole_index | Index of the petiole on that phytomer. |
| leaf_count | Number of leaves to place on the petiole. Must be at least 1. |
| ValueError | If any index is negative or ``leaf_count`` is less than 1. |
| PlantArchitectureError | If the operation fails. |
setPetioleLeafGeometry for the same petiole, whose leaf_count must match the number of leaves on the petiole. Definition at line 4349 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleLeafGeometry | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| List[vec3] | leaf_bases, | ||
| List[AxisRotation] | leaf_rotations, | ||
| List[float] | leaf_sizes ) |
Prescribe the base position, orientation and size of every leaf on a petiole.
This is the leaf-level counterpart of :meth:`setPetioleNodePositions`, intended for the same reconstruction workflow. Every leaf on the petiole is prescribed in one for a compound leaf the leaflets are not independent, since a leaflet's roll and yaw signs and the prototype it is a copy of all follow from its position along the petiole. A species with one leaf per petiole passes one-element lists. Each leaf is rebuilt from its prototype and re-oriented through the same rotation chain used when a leaf is grown. The prescribed base, orientation and size are held exactly and are not changed by :meth:`advanceTime`; prescribed leaves are additionally exempt from the self-weight droop. **Rotation units and frame.** ``leaf_rotations`` are given in **radians**, as pitch, yaw and roll relative to the petiole and internode axes, not to world axes (the same convention as the native ``Phytomer::leaf_rotation``). The full chain that places a leaf includes the petiole's own azimuth and a size-dependent correction and is not invertible, so there is no exact conversion from a world-frame blade orientation; a caller fitting to measured data should iterate by forward evaluation, reading the resulting geometry back from the Context. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| shoot_id | ID of the shoot carrying the phytomer |
| node_index | Index of the phytomer within the shoot, counted from the base |
| petiole_index | Index of the petiole within the phytomer |
| leaf_bases | Base position of each leaf in world coordinates, one per leaf on the petiole, in the petiole's existing leaf order |
| leaf_rotations | AxisRotation(pitch, yaw, roll) of each leaf in radians |
| leaf_sizes | Fully elongated size of each leaf in meters. All must be > 0 |
| ValueError | If any index is negative, a base is not a vec3, a rotation is not an AxisRotation, a size is not positive, or the three lists differ in length |
| PlantArchitectureError | If the number of leaves does not match the petiole (the count is fixed when the phytomer is created), the native call fails, or the library predates v1.3.85 |
Definition at line 4276 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleNodePositions | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| List[vec3] | node_positions, | ||
| List[float] | node_radii ) |
Prescribe the path of a petiole on an existing phytomer from measured node positions.
This is the organ-level counterpart of :meth:`addShootFromNodePositions`. Where that method prescribes the internode skeleton of a shoot, this one prescribes the centerline of a single petiole hanging off it, so that a reconstruction from labelled measurements (a segmented point cloud, a digitized plant) can follow the measured petiole rather than the path the shoot type's petiole pitch and curvature would generate. The supplied positions are the nodes of the petiole tube, ordered from the base outward. Their number is free and need not match the shoot type's ``petiole.length_segments``; the petiole tube is rebuilt to match. The first position is snapped onto the tip of the internode the petiole grows from and the rest of the path is translated by the same amount, so all relative geometry is preserved exactly. An error is raised if that discrepancy is large enough that the petiole would not be attached to the stem. The prescribed petiole is not re-scaled by subsequent calls to :meth:`advanceTime`, and its radii are held as given. Requires helios-core v1.3.85 or newer.
| plant_id | ID of the plant instance |
| shoot_id | ID of the shoot carrying the phytomer |
| node_index | Index of the phytomer within the shoot, counted from the base |
| petiole_index | Index of the petiole within the phytomer |
| node_positions | Petiole node positions in world coordinates, base to tip. At least two are required, and no two consecutive positions may be coincident |
| node_radii | Radius of the petiole at each node, one per position. All must be > 0 |
| ValueError | If any index is negative, a position is not a vec3, a radius is not positive, fewer than two nodes are given, or the counts differ |
| PlantArchitectureError | If the native call fails or the library predates v1.3.85 |
setPetioleLeafGeometry for the same petiole, since leaf placement is oriented from the petiole axis. Definition at line 4206 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPetioleScaleFraction | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| int | node_index, | ||
| int | petiole_index, | ||
| float | petiole_scale_factor_fraction ) |
Set one petiole's current length as a fraction of its fully-elongated length, leaving the leaves it carries at the size they are.
A petiole is a stem segment rather than part of the blade and goes on extending after the blade has finished expanding, which is why its growth is driven by the shoot's internode rate rather than the leaf expansion rate. The leaves ride out along the petiole as it lengthens without changing size.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| node_index | Phytomer index within the shoot |
| petiole_index | Petiole within the phytomer |
| petiole_scale_factor_fraction | Fraction of the fully-elongated length (1.0 for a fully-elongated petiole) |
| ValueError | If any identifier is not a non-negative int |
| PlantArchitectureError | If the plant, shoot, node or petiole does not exist |
| RuntimeError | If the native library predates helios-core v1.3.87 |
Definition at line 4832 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPhytomerCallbackFunction | ( | self, | |
| str | shoot_type_label, | ||
| Optional[Callable[[int, int, int, float], None]] | callback ) |
Install a Python function that the plugin calls for every phytomer of a shoot type on every time step.
This is the Python counterpart of assigning
``phytomer_parameters.phytomer_callback_function`` in C++. Use it for per-phytomer logic that must
run as the plant develops rather than once at creation (for that, see
:meth:`setPhytomerCreationFunction`), for example adjusting growth targets with phytomer age.
The callback is called as::
callback(plant_id, shoot_id, node_index, phytomer_age)
once per phytomer per :meth:`advanceTime` sub-step, after the phytomer's age has been advanced, so
``(plant_id, shoot_id, node_index)`` addresses it through any per-phytomer method and
``phytomer_age`` (days) equals :meth:`getPhytomerAge` at that moment. ``advanceTime`` divides its
interval into sub-steps of at most the shortest phyllochron (and at most 1 day for intervals shorter
than that), so the number of calls per phytomer is the number of sub-steps, not the number of days. It
also runs inside :meth:`buildPlantInstanceFromLibrary` and :meth:`buildPlantCanopyFromLibrary` when
they grow a plant to its starting age. The return value is ignored.
Performance the cost scales with (phytomers x sub-steps), so keep the callback's own work light,
especially for large populations that change slowly, such as a dormant tree over many days.
If the callback raises, the exception propagates out of the call that advanced time with its original
type, and no further callbacks run during that call; the plant is left partly advanced.
Which phytomers are affected:
- The function is copied into each phytomer when the phytomer is created, so phytomers created
before this call do not call a newly installed function. Install it before building the plant.
- Phytomers created while a Python callback is installed look it up by label on each call, so
replacing the callback or clearing it with ``None`` also takes effect for them.
- ``None`` restores the function the shoot type had before a Python callback was first
installed on it, usually the library one. Clearing a callback that was never installed
changes nothing.
- As with :meth:`setPhytomerCreationFunction`, redefining an existing label with
:meth:`defineShootType` keeps the function, but a new label defined from another type's parameter
dict starts with none.
| shoot_type_label | An existing shoot type label |
| callback | A callable taking the four arguments above; the name of a library callback function (see :meth:getLibraryPhytomerCallbackFunctionNames), which installs that native function in place of whatever the type had; or None to restore the function the type had before a Python callback was installed |
| ValueError | If the label is not a non-empty str, the callback is neither callable, a str nor None, or the name is empty |
| PlantArchitectureError | If the shoot type does not exist or the name is not a library callback function |
| RuntimeError | If the native library predates this function |
Definition at line 5370 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPhytomerCreationFunction | ( | self, | |
| str | shoot_type_label, | ||
| Optional[Callable[[int, int, int, int, int, int, float], None]] | callback ) |
Install a Python function that the plugin calls once for every new phytomer of a shoot type.
This is the Python counterpart of assigning
``phytomer_parameters.phytomer_creation_function`` in C++. It is how a model varies a
phytomer's growth targets with its position on the plant -- for example scaling leaf and
petiole size with node rank -- using the per-phytomer methods such as
:meth:`scaleLeafPrototypeScale`, :meth:`scalePetioleMaxLength` and
:meth:`scaleInternodeMaxLength`.
The callback is called as::
callback(plant_id, shoot_id, node_index, shoot_node_index,
parent_shoot_node_index, shoot_max_nodes, plant_age)
after the plugin has attached the new phytomer to its shoot, so
``(plant_id, shoot_id, node_index)`` addresses it through any per-phytomer method.
``node_index`` is the phytomer's index on its shoot. ``shoot_node_index`` is the value the
plugin passes to a C++ creation function, kept for porting C++ models: during growth it
equals ``node_index``, but while a shoot's initial phytomers are built by
:meth:`addBaseStemShoot`, :meth:`appendShoot` or :meth:`addChildShoot` it is the shoot's
initial node count (a one-node base stem passes 1 for phytomer 0).
``parent_shoot_node_index`` is the node of the parent shoot this shoot grows from,
``shoot_max_nodes`` the shoot's node limit and ``plant_age`` the plant's age in days.
The return value is ignored.
The callback fires for phytomers created while building shoots as well as during
:meth:`advanceTime`. If it raises, the exception propagates out of the call that created
the phytomer (``advanceTime``, ``addBaseStemShoot``, ...) with its original type, and no
further callbacks run during that call; the plant is left as it was when the exception was
raised, partly grown. Changes the callback makes to the length of an internode prescribed
by :meth:`addShootFromNodePositions` are undone by the plugin.
Which shoots are affected:
- The function is stored on the shoot type, and each shoot copies its type's parameters
when it is created, so shoots created before this call keep whatever function they had.
- Shoots created while a Python callback is installed look it up by label each time, so
replacing the callback or clearing it with ``None`` also takes effect for them.
- ``None`` restores the function the shoot type had before a Python callback was first
installed on it, usually the library one (for example the library ``tomato`` model's
``mainstem`` function, which rescales every new phytomer's leaves and internode by plant
age). To build without a library function, define a new shoot type from the parameters
(see below), which carries none.
- Redefining an existing label with :meth:`defineShootType` keeps its creation function.
A new label defined from another type's parameters (for example
``defineShootType("my_stem", getCurrentShootParameters("mainstem"))``) starts with
none, because the parameter dict carries no functions: it inherits neither a Python
callback nor a library function.
| shoot_type_label | An existing shoot type label |
| callback | A callable taking the seven arguments above; the name of a library creation function (see :meth:getLibraryPhytomerCreationFunctionNames), which installs that native function in place of whatever the type had; or None to restore the function the type had before a Python callback was installed |
| ValueError | If the label is not a non-empty str, the callback is neither callable, a str nor None, or the name is empty |
| PlantArchitectureError | If the shoot type does not exist or the name is not a library creation function |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5289 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantBasePosition | ( | self, | |
| int | plant_id, | ||
| vec3 | base_position ) |
Set the base position of a plant, moving the plant if it has already been built.
For a plant with no shoots, this only stores the position, and the first shoot added with :meth:`addBaseStemShoot` is placed there. For a plant that already has shoots, the whole plant is translated by the difference between the new and old base position -- its geometry, stored organ positions, per-plant attraction points and cached shading state and later growth continues from the moved position.
Context.translateObject), or the plant will be moved twice. This cannot be called from inside a phytomer creation or callback function.| plant_id | ID of the plant instance |
| base_position | New base position (vec3) |
| ValueError | If ``plant_id`` is not a non-negative int or ``base_position`` is not a vec3 |
| PlantArchitectureError | If the plant does not exist |
| RuntimeError | If the native library predates this binding |
Definition at line 6310 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantCarbohydrateParameters | ( | self, | |
| int | plant_id, | ||
| Union[dict, CarbohydrateParameters] | parameters ) |
Set carbohydrate-model parameters for a plant.
| plant_id | Target plant instance ID |
| parameters | A flat dict or a CarbohydrateParameters object. |
| ValueError | If parameters is not a dict or CarbohydrateParameters |
| PlantArchitectureError | If the operation fails |
Definition at line 976 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantMaxAge | ( | self, | |
| int | plant_id, | ||
| float | max_age ) |
Set the maximum age of a plant, beyond which it stops growing.
Once a plant's age reaches this value, :meth:`advanceTime` stops advancing it and its geometry becomes static. The default is 999 days. Every plant model in the library sets its own value as part of its builder (an apple tree, for example, uses 1460 days), but a plant assembled manually with :meth:`addPlantInstance` keeps the default and so silently stops growing after 999 days. Setting a maximum age below the plant's current age is permitted, and freezes the plant at its current form.
| plant_id | ID of the plant instance |
| max_age | Maximum age of the plant in days. Must be non-negative. |
| ValueError | If plant_id is negative or max_age is negative |
| PlantArchitectureError | If the plant does not exist |
Definition at line 2081 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantModelLeafInclinationDistribution | ( | self, | |
| str | plant_model_name, | ||
| float | beta_mu, | ||
| float | beta_nu ) |
Set or clear the Beta leaf inclination distribution of a library plant model.
Plants built from the model afterwards are steered toward the distribution. Two positive values set it; ``(0, 0)`` clears it, restoring the model's unsteered leaf angles.
| ValueError | If the name is not a non-empty str, or the Beta parameters are not both positive or both zero |
| PlantArchitectureError | If the model is not in the library |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5934 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantNitrogenParameters | ( | self, | |
| int | plant_id, | ||
| Union[dict, NitrogenParameters] | parameters ) |
Set nitrogen-model parameters for a plant.
| plant_id | Target plant instance ID |
| parameters | A flat dict or a NitrogenParameters object. |
| ValueError | If parameters is not a dict or NitrogenParameters, or the dict contains a key that is not a nitrogen parameter |
| PlantArchitectureError | If the operation fails |
Definition at line 1025 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setPlantPhenologicalThresholds | ( | self, | |
| int | plant_id, | ||
| float | time_to_dormancy_break, | ||
| float | time_to_flower_initiation, | ||
| float | time_to_flower_opening, | ||
| float | time_to_fruit_set, | ||
| float | time_to_fruit_maturity, | ||
| float | time_to_dormancy, | ||
| float | max_leaf_lifespan = 1e6, | ||
| bool | is_evergreen = False ) |
Set phenological timing thresholds for plant developmental stages.
Controls the timing of key phenological events based on thermal time or calendar time depending on the plant model.
| plant_id | ID of the plant instance |
| time_to_dormancy_break | Degree-days or days until dormancy ends |
| time_to_flower_initiation | Time until flower buds are initiated |
| time_to_flower_opening | Time until flowers open |
| time_to_fruit_set | Time until fruit begins developing |
| time_to_fruit_maturity | Time until fruit reaches maturity |
| time_to_dormancy | Time until plant enters dormancy |
| max_leaf_lifespan | Maximum leaf lifespan in days (default: 1e6) |
| is_evergreen | If True, the plant retains leaves through dormancy instead of shedding them at senescence (default: False) |
| ValueError | If plant_id is negative |
| PlantArchitectureError | If phenology setting fails |
Definition at line 2228 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.setProgressCallback | ( | self, | |
| callback ) |
Set a callback to receive progress updates during long-running operations.
The callback fires during advanceTime() and adjustFruitForObstacleCollision() as the underlying ProgressBar updates.
| callback | A callable(progress: float, message: str) where progress is in [0, 1], or None to clear the callback. |
| ValueError | If callback is not callable and not None. |
Definition at line 795 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setShootInternodeLengthMax | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| float | internode_length_max ) |
Set the target length of internodes grown at the apex of an existing shoot.
A shoot built by :meth:`addShootFromNodePositions` otherwise grows toward the mean of its prescribed internode lengths; use this to give newly grown internodes a different target length.
| plant_id | Plant identifier. |
| shoot_id | Shoot identifier. |
| internode_length_max | Target internode length in meters. Must be positive. |
| ValueError | If an identifier is negative or the length is not positive. |
| PlantArchitectureError | If the operation fails. |
writePlantStructureXML, so it must be set again after :meth:readPlantStructureXML. Definition at line 4388 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setShootPhyllotacticAngle | ( | self, | |
| int | plant_id, | ||
| int | shoot_id, | ||
| float | mean_deg, | ||
| Optional[float] | sd_deg = None ) |
Set the phyllotactic angle that one shoot's next phytomers are created with.
Each new phytomer draws its angle from its shoot's own copy of the shoot parameters, so calling this before a time step sets the angle of the phytomers produced during that step without touching any phytomer already built, any other shoot, or the shoot type. Calling it before every step drives a node-by-node angle sequence. With ``sd_deg`` omitted the angle is the constant ``mean_deg``. With ``sd_deg`` given the angle is drawn from a normal distribution, which draws from the Context random generator for every new phytomer even when ``sd_deg`` is 0 -- matching a C++ caller of ``phyllotactic_angle.normalDistribution(mean, sd)``, which matters when reproducing a C++ run draw for draw.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant |
| mean_deg | Phyllotactic angle, or its mean, in degrees |
| sd_deg | Standard deviation in degrees (non-negative), or None for a constant |
| ValueError | If an identifier is invalid or an angle is not finite, or ``sd_deg`` is negative |
| PlantArchitectureError | If the plant or shoot does not exist |
| RuntimeError | If the native library predates helios-core v1.3.88 |
Definition at line 5709 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setSoftCollisionAvoidanceParameters | ( | self, | |
| float | view_half_angle_deg = 80.0, | ||
| float | look_ahead_distance = 0.1, | ||
| int | sample_count = 256, | ||
| float | inertia_weight = 0.4 ) |
Configure parameters for soft collision avoidance algorithm.
These parameters control the cone-based gap detection algorithm that guides plant growth away from obstacles. Adjusting these values allows fine-tuning the balance between collision avoidance and natural growth patterns.
| view_half_angle_deg | Half-angle of detection cone in degrees (0-180). Default 80° provides wide field of view. |
| look_ahead_distance | Distance to look ahead for collisions in meters. Larger values detect distant obstacles. Default 0.1m. |
| sample_count | Number of ray samples within cone. More samples improve accuracy but reduce performance. Default 256. |
| inertia_weight | Weight for previous growth direction (0-1). Higher values make growth smoother but less responsive. Default 0.4. |
| ValueError | If parameters are outside valid ranges |
| PlantArchitectureError | If parameter setting fails |
Definition at line 2994 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.setStaticObstacles | ( | self, | |
| List[int] | target_UUIDs ) |
Mark geometry as static obstacles for collision detection optimization.
This method tells the collision detection system that certain geometry will not move during the simulation. The system can then build an optimized Bounding Volume Hierarchy (BVH) for these obstacles, significantly improving collision detection performance in scenes with many static obstacles.
| target_UUIDs | List of primitive UUIDs representing static obstacles |
| ValueError | If target_UUIDs is empty |
| PlantArchitectureError | If static obstacle configuration fails |
Definition at line 3153 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.terminateApicalBud | ( | self, | |
| int | plant_id, | ||
| int | shoot_id ) |
Stop a shoot's apex from adding any further phytomers.
The shoot keeps everything it already has, and its vegetative buds keep whatever state they are in -- this kills only the apical meristem. The shoot therefore stops extending at its tip but can still throw laterals; to stop those as well, pair this with :meth:`removeShootVegetativeBuds`. This is the standard way to freeze the old wood of a reconstructed tree before growing it forward with :meth:`advanceTime`.
| plant_id | ID of the plant instance |
| shoot_id | Shoot index within the plant (see :meth:getAllShootIDs) |
| ValueError | If either identifier is not a non-negative int |
| PlantArchitectureError | If the plant or shoot does not exist |
Definition at line 4430 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.updateAttractionPoints | ( | self, | |
| List[vec3] | points, | ||
| Optional[int] | plant_id = None ) |
Replace the current attraction point set.
| points | Replacement target locations as a list of vec3 |
| plant_id | Update this plant only. Updates globally when None. |
| ValueError | If points is empty or contains a non-vec3, or plant_id is negative |
| PlantArchitectureError | If the operation fails |
Definition at line 697 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.writePlantGrowthUSD | ( | self, | |
| int | plant_id, | ||
| Union[str, Path] | filename, | ||
| float | seconds_per_frame = 1.0 ) |
Export all registered growth frames as a time-sampled USD animation file.
The resulting file can be imported directly into Blender. This is a visual-only export — no physics prims, joints, or collision shapes are written.
| plant_id | ID of the plant instance to export |
| filename | Output file path (should have .usda extension) |
| seconds_per_frame | Duration in seconds each growth frame occupies (default: 1.0) |
| ValueError | If plant_id is negative or filename is empty |
| PlantArchitectureError | If plant doesn't exist or file cannot be written |
Definition at line 3496 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.writePlantMeshVertices | ( | self, | |
| int | plant_id, | ||
| Union[str, Path] | filename ) |
Write all plant mesh vertices to file for external processing.
This method exports all vertex coordinates (x,y,z) for every primitive in the plant, writing one vertex per line. Useful for external processing such as computing bounding volumes, convex hulls, or performing custom geometric analysis.
| plant_id | ID of the plant instance to export |
| filename | Path to output file (absolute or relative to current working directory) |
| ValueError | If plant_id is negative or filename is empty |
| PlantArchitectureError | If plant doesn't exist or file cannot be written |
Definition at line 3226 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.writePlantStructureUSD | ( | self, | |
| int | plant_id, | ||
| Union[str, Path] | filename, | ||
| float | elastic_modulus = 5e9, | ||
| float | wood_density = 800.0, | ||
| * | , | ||
| float | damping_time_constant = 0.02, | ||
| float | static_friction = 0.5, | ||
| float | dynamic_friction = 0.3, | ||
| float | restitution = 0.1, | ||
| float | organ_spring_stiffness = 10.0, | ||
| float | organ_spring_damping = 1.0, | ||
| float | leaf_mass_per_area = 0.05, | ||
| float | fruit_mass = 0.01, | ||
| float | flower_mass = 0.002, | ||
| int | solver_position_iterations = 32, | ||
| float | min_segment_length = 0.001, | ||
| float | armature_stability_ratio = 8.0, | ||
| float | physics_steps_per_second = 60.0, | ||
| Optional[float] | damping_ratio = None ) |
Export plant structure as a USD articulated rigid body for NVIDIA IsaacSim physics.
Each tube segment becomes a capsule-shaped rigid link connected to its parent by a joint that locks translation, limits bending to +/-60 degrees and carries a spring on each rotation axis, with stiffness derived from beam bending stiffness (E*I/L). Leaves, fruits, and flowers are represented as mass bodies attached by spring links. Beam stiffness on a short, light segment is stiffer than a physics solver can integrate at a typical step rate, so each joint is given armature (an artificial inertia) that caps its natural frequency at armature_stability_ratio * physics_steps_per_second. Armature adds no weight, so deflection under gravity is unchanged. If the simulation runs at a coarser step than physics_steps_per_second, set that parameter to match or the plant may be unstable.
| plant_id | ID of the plant instance to export |
| filename | Output file path (should have .usda extension) |
| elastic_modulus | Young's modulus (Pa) for joint stiffness, K = E*I/L |
| wood_density | Wood density (kg/m^3) used to compute mass from capsule volume |
| damping_time_constant | Damping time constant (s) of the joints between stem, petiole and peduncle segments; joint damping is this value times the joint stiffness. Must be non-negative. |
| static_friction | Static friction coefficient for collision material |
| dynamic_friction | Dynamic friction coefficient for collision material |
| restitution | Restitution (bounciness) for collision material |
| organ_spring_stiffness | Spring stiffness (N*m/rad) for organ attachment joints |
| organ_spring_damping | Damping (N*m*s/rad) for organ attachment joints |
| leaf_mass_per_area | Leaf mass per unit area (kg/m^2) |
| fruit_mass | Mass per fruit (kg) |
| flower_mass | Mass per flower (kg) |
| solver_position_iterations | PhysX articulation solver position iteration count |
| min_segment_length | Minimum segment length (m); shorter segments are skipped |
| armature_stability_ratio | Cap on each joint's own natural frequency, as a multiple of the physics step rate. Lower is more stable. Must be positive. |
| physics_steps_per_second | Physics step rate (Hz) the simulation is expected to run at, used to size the joint armature. Must be positive. |
| damping_ratio | Removed; raises ValueError if given. See the note below. |
| ValueError | If plant_id is negative, filename is empty, a damping or armature parameter is out of range, or the removed damping_ratio parameter is given |
| PlantArchitectureError | If plant doesn't exist or file cannot be written |
damping_ratio was removed in helios-core 1.3.90, where joint damping became proportional to stiffness. Use damping_time_constant (seconds) instead; the two are not interchangeable.Definition at line 3399 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.writePlantStructureXML | ( | self, | |
| int | plant_id, | ||
| Union[str, Path] | filename ) |
Save plant structure to XML file for later loading.
This method exports the complete plant architecture to an XML file, including all shoots, phytomers, organs, and their properties. The saved plant can be reloaded later using readPlantStructureXML().
| plant_id | ID of the plant instance to save |
| filename | Path to output XML file (absolute or relative to current working directory) |
| ValueError | If plant_id is negative or filename is empty |
| PlantArchitectureError | If plant doesn't exist or file cannot be written |
Definition at line 3274 of file PlantArchitecture.py.
| None pyhelios.PlantArchitecture.PlantArchitecture.writeQSMCylinderFile | ( | self, | |
| int | plant_id, | ||
| Union[str, Path] | filename ) |
Export plant structure in TreeQSM cylinder format.
This method writes the plant structure as a series of cylinders following the TreeQSM format (Raumonen et al., 2013). Each row represents one cylinder with columns for radius, length, start position, axis direction, branch topology, and other structural properties. Useful for biomechanical analysis and quantitative structure modeling.
| plant_id | ID of the plant instance to export |
| filename | Path to output file (absolute or relative, typically .txt extension) |
| ValueError | If plant_id is negative or filename is empty |
| PlantArchitectureError | If plant doesn't exist or file cannot be written |
Definition at line 3330 of file PlantArchitecture.py.
|
protected |
Definition at line 314 of file PlantArchitecture.py.
|
protected |
Definition at line 5580 of file PlantArchitecture.py.
|
protected |
Definition at line 311 of file PlantArchitecture.py.
|
protected |
Definition at line 807 of file PlantArchitecture.py.
| pyhelios.PlantArchitecture.PlantArchitecture.context = context |
Definition at line 310 of file PlantArchitecture.py.