{ "cells": [ { "cell_type": "markdown", "id": "fda4c721", "metadata": {}, "source": [ "# Stand metrics and site enums" ] }, { "cell_type": "markdown", "id": "7fb27b941602401d91542211134fc71a", "metadata": {}, "source": [ "## Notebook Objectives\n", "- Walk through stand/site enum usage and how they feed site-index-ready stand setup.\n", "- Provide runnable, copy-safe snippets that work in the docs build environment.\n", "\n", "## Prerequisites\n", "- Python environment with `pyforestry` installed from this repository.\n", "- Execute cells in order; random components should use fixed seeds where shown.\n", "\n", "## Sources\n", "- Swedish site primitives and enums in `pyforestry.sweden.site`.\n" ] }, { "cell_type": "markdown", "id": "c3f9b0c5", "metadata": {}, "source": [ "This notebook shows how to work with circular plots, site enums, and site index models." ] }, { "cell_type": "code", "execution_count": null, "id": "d16d739a", "metadata": { "execution": { "iopub.execute_input": "2025-07-17T18:03:38.210740Z", "iopub.status.busy": "2025-07-17T18:03:38.210552Z", "iopub.status.idle": "2025-07-17T18:03:38.530469Z", "shell.execute_reply": "2025-07-17T18:03:38.530055Z" } }, "outputs": [ { "data": { "text/plain": [ "(12.75, 254.64790894703253)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pyforestry.base.helpers import CircularPlot, Stand, Tree, parse_tree_species\n", "\n", "plot1 = CircularPlot(\n", " id=1,\n", " radius_m=5.0,\n", " trees=[\n", " Tree(species=parse_tree_species(\"picea abies\"), diameter_cm=20),\n", " Tree(species=parse_tree_species(\"pinus sylvestris\"), diameter_cm=25),\n", " ],\n", ")\n", "plot2 = CircularPlot(\n", " id=2,\n", " radius_m=5.0,\n", " trees=[\n", " Tree(species=parse_tree_species(\"picea abies\"), diameter_cm=30),\n", " ],\n", ")\n", "stand = Stand(plots=[plot1, plot2])\n", "stand.BasalArea.TOTAL.value, stand.Stems.TOTAL.value" ] }, { "cell_type": "markdown", "id": "9ce79891", "metadata": {}, "source": [ "Site enums help provide structured parameters." ] }, { "cell_type": "code", "execution_count": 2, "id": "46f3f709", "metadata": { "execution": { "iopub.execute_input": "2025-07-17T18:03:38.533179Z", "iopub.status.busy": "2025-07-17T18:03:38.532452Z", "iopub.status.idle": "2025-07-17T18:03:38.544328Z", "shell.execute_reply": "2025-07-17T18:03:38.544013Z" } }, "outputs": [ { "data": { "text/plain": [ "(1, 16)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pyforestry.base.helpers import enum_code\n", "from pyforestry.sweden.site.enums import Sweden\n", "\n", "enum_code(Sweden.SoilMoistureEnum.DRY), enum_code(Sweden.County.UPPSALA)" ] }, { "cell_type": "code", "execution_count": 3, "id": "ebe4ef42", "metadata": { "execution": { "iopub.execute_input": "2025-07-17T18:03:38.545985Z", "iopub.status.busy": "2025-07-17T18:03:38.545672Z", "iopub.status.idle": "2025-07-17T18:03:38.554448Z", "shell.execute_reply": "2025-07-17T18:03:38.553959Z" } }, "outputs": [ { "data": { "text/plain": [ "26.672815668837686" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pyforestry.sweden.siteindex.sis.hagglund_lundmark_1977 import Hagglund_Lundmark_1977_SIS\n", "\n", "sis = Hagglund_Lundmark_1977_SIS(\n", " species=\"Picea abies\",\n", " latitude=60,\n", " altitude=100,\n", " soil_moisture=Sweden.SoilMoistureEnum.MESIC,\n", " ground_layer=Sweden.BottomLayer.FRESH_MOSS,\n", " vegetation=Sweden.FieldLayer.BILBERRY,\n", " soil_texture=Sweden.SoilTextureTill.SANDY,\n", " climate_code=Sweden.ClimateZone.K1,\n", " lateral_water=Sweden.SoilWater.SELDOM_NEVER,\n", " soil_depth=Sweden.SoilDepth.DEEP,\n", " incline_percent=5,\n", " aspect=0,\n", " nfi_adjustments=True,\n", " dlan=Sweden.County.UPPSALA,\n", " peat=False,\n", " gotland=False,\n", " coast=False,\n", " limes_norrlandicus=False,\n", ")\n", "float(sis)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate Site Categories From Requested SIS\n", "Use `predict_site_categories_county_tree` to get all categorical site inputs from\n", "`species`, requested `sis_hagglund_1979`, and county, then compare requested vs achieved SIS.\n" ], "id": "generated-site-cats" }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "from pyforestry.sweden.siteindex.sis.generated_site_category_trees import (\n", " predict_site_categories_county_tree,\n", ")\n", "\n", "requested_sis = 24.0\n", "species = \"Picea abies\"\n", "county = Sweden.County.UPPSALA\n", "\n", "predicted_categories = predict_site_categories_county_tree(\n", " sis_hagglund_1979=requested_sis,\n", " species=species,\n", " Direktlan=county,\n", ")\n", "\n", "achieved_sis = Hagglund_Lundmark_1977_SIS(\n", " species=species,\n", " latitude=60,\n", " altitude=100,\n", " soil_moisture=predicted_categories[\"soil_moisture\"],\n", " ground_layer=predicted_categories[\"bottom_layer\"],\n", " vegetation=predicted_categories[\"field_layer\"],\n", " soil_texture=predicted_categories[\"soil_texture\"],\n", " climate_code=Sweden.ClimateZone.K1,\n", " lateral_water=predicted_categories[\"soil_water\"],\n", " soil_depth=predicted_categories[\"soil_depth\"],\n", " incline_percent=5,\n", " aspect=0,\n", " nfi_adjustments=True,\n", " dlan=county,\n", " ditched=bool(predicted_categories[\"ditched\"]),\n", " peat=False,\n", " gotland=False,\n", " coast=False,\n", " limes_norrlandicus=False,\n", ")\n", "\n", "summary = pd.DataFrame(\n", " [\n", " {\n", " \"requested_sis\": requested_sis,\n", " \"achieved_sis\": float(achieved_sis),\n", " \"sis_abs_error\": abs(float(achieved_sis) - requested_sis),\n", " \"sis_rel_error_pct\": 100.0 * abs(float(achieved_sis) - requested_sis) / requested_sis,\n", " }\n", " ]\n", ")\n", "display(summary)\n", "predicted_categories\n" ], "id": "generated-site-closeness" }, { "cell_type": "markdown", "id": "371dc2e4", "metadata": {}, "source": [ "Geographic utilities and climate calculations." ] }, { "cell_type": "code", "execution_count": 4, "id": "bf113048", "metadata": { "execution": { "iopub.execute_input": "2025-07-17T18:03:38.556113Z", "iopub.status.busy": "2025-07-17T18:03:38.555948Z", "iopub.status.idle": "2025-07-17T18:03:38.693810Z", "shell.execute_reply": "2025-07-17T18:03:38.693242Z" } }, "outputs": [], "source": [ "from pyforestry.sweden.geo import Moren_Perttu_radiation_1994, RetrieveGeoCode\n", "\n", "RetrieveGeoCode.getDistanceToCoast(14.784528, 56.892405)\n", "RetrieveGeoCode.getClimateCode(14.784528, 56.892405)" ] }, { "cell_type": "code", "execution_count": 5, "id": "52f63767", "metadata": { "execution": { "iopub.execute_input": "2025-07-17T18:03:38.696289Z", "iopub.status.busy": "2025-07-17T18:03:38.696072Z", "iopub.status.idle": "2025-07-17T18:03:38.700315Z", "shell.execute_reply": "2025-07-17T18:03:38.699787Z" } }, "outputs": [ { "data": { "text/plain": [ "(1216.3800000000003, 1266.3800000000003)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "calc = Moren_Perttu_radiation_1994(latitude=60, altitude=100, july_avg_temp=17, jan_avg_temp=-8)\n", "(\n", " calc.calculate_temperature_sum_1000m(threshold_temperature=5),\n", " calc.get_corrected_temperature_sum(threshold_temperature=5),\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.12" } }, "nbformat": 4, "nbformat_minor": 5 }