Quickstart Guide
This guide will get you up and running with CNit in minutes.
Installation
Requirements
Python 3.9 or later
pip (Python package installer)
For developers: conda or mamba (recommended)
For Users
If you just want to use CNit:
pip install cnit
For Developers
To set up a development environment for this project, follow these steps:
Create a new conda environment (replace
cnitwith your preferred name if desired):conda create --name cnit python=3.9
Activate your environment:
conda activate cnit
Clone the repository (if you haven’t already):
git clone https://github.com/gangtang-au/cnit.git cd cnit
Install all dependencies and set up the package:
make envThis will install all required dependencies (including notebook, docs, and testing tools) and install the package in editable mode.
Note
The Makefile will check that you are not in the base environment and will refuse
to run if you are.
TL;DR for developers:
conda create --name cnit python=3.9
conda activate cnit
git clone https://github.com/gangtang-au/cnit.git
cd cnit
make env
Alternative: Using venv
If you prefer not to use conda:
# Create a new virtual environment
python -m venv cnit-env
# Activate it
# On macOS/Linux:
source cnit-env/bin/activate
# On Windows:
cnit-env\Scripts\activate
# Install in development mode
pip install -e ".[notebook,docs,tests]"
Verify Installation
Check that CNit is installed correctly:
pip show cnit
This will display the package information including version, location, and dependencies.
You can also verify by importing the package in Python:
import cnit
print("CNit installed successfully!")
If the import succeeds without errors, CNit is ready to use!
Basic Usage
Import the main classes:
from cnit import CNModel, CNModelConfig, CNExpConfig
Note
Import Aliases: For convenience, CNit provides short aliases:
CNModel=CarbonNitrogenCycleModelCNModelConfig=CarbonNitrogenCycleModelConfigCNExpConfig=CarbonNitrogenCycleExperimentConfig
Both names work identically. Use whichever you prefer!
Your First Simulation
Here’s a minimal example to run CNit:
import numpy as np
from cnit import CNitModel, CNitModelConfig
from cnit import Q # Local pint.quantity class for units handling
# Create model with default parameters
config = CNitModelConfig()
model = CNitModel.from_config(config)
# Set up time axis and forcing
time_axis = Q(np.arange(1850, 2101), "yr")
n_steps = len(time_axis)
# Simple forcing (constant values for illustration)
dT_s = Q(np.linspace(0, 2, n_steps), "K") # 2°C warming
CO2_s = Q(np.linspace(280, 560, n_steps), "ppm") # CO2 doubling
# Land use emissions (zero for simplicity)
CemsLUnet_s = Q(np.zeros(n_steps), "GtC/yr")
CemsLUgrs_s = Q(np.zeros(n_steps), "GtC/yr")
# Nitrogen inputs
NflxAD_s = Q(np.linspace(0.05, 0.15, n_steps), "GtN/yr") # Increasing deposition
NflxFT_s = Q(np.linspace(0, 0.1, n_steps), "GtN/yr") # Increasing fertilizer
# Nitrogen land use emissions
NemsLUnet_s = Q(np.zeros(n_steps), "GtN/yr")
NemsLUgrs_s = Q(np.zeros(n_steps), "GtN/yr")
NemsLUmin_s = Q(np.zeros(n_steps), "GtN/yr")
# Run the model
res = model.run(
time_axis=time_axis,
dT_s=dT_s,
CO2_s=CO2_s,
CemsLUnet_s=CemsLUnet_s,
CemsLUgrs_s=CemsLUgrs_s,
NflxAD_s=NflxAD_s,
NflxFT_s=NflxFT_s,
NemsLUnet_s=NemsLUnet_s,
NemsLUgrs_s=NemsLUgrs_s,
NemsLUmin_s=NemsLUmin_s,
)
# Access results
cveg, cveg_unit = res["CplsP"].data, re["CplsP"].units
nveg, nveg_unit = res["NplsP"].data, res["NplsP"].units
npp, npp_unit = res["CflxNPP"].data, res["CflxNPP"].units
print(f"Final plant carbon: {cveg[-1]} {cveg_unit}")
print(f"Final plant nitrogen: {nveg[-1]} {nveg_unit}")
print(f"NPP change: {npp[0]} → {npp[-1]} {npp_unit}")
Visualizing Results
Plot the carbon pools over time:
import matplotlib.pyplot as plt
# Set default plotting properties
plt.rcParams.update(
{
"font.size": 6, # Default font size for all text
"axes.titlesize": 6, # Axes title
"axes.labelsize": 6, # Axes labels
"xtick.labelsize": 6, # X-axis tick labels
"ytick.labelsize": 6, # Y-axis tick labels
"legend.fontsize": 6, # Legend text
"figure.titlesize": 6, # Figure title
"lines.linewidth": 0.5, # Default line width
"figure.figsize": (9 / 2.54, 6 / 2.54), # Default figure size in cm
"figure.dpi": 150, # Default DPI for figures
"figure.constrained_layout.use": True, # Use constrained layout by default
"xtick.major.size": 1, # X-axis major tick length
"ytick.major.size": 1, # Y-axis major tick length
}
)
fig, (axs1, axs2) = plt.subplots(2, 4, figsize=(12 / 2.54, 6 / 2.54))
time = time_axis.m
# Carbon pools
axs1[0].plot(time, res["CplsP"])
axs1[1].plot(time, res["CplsL"])
axs1[2].plot(time, res["CplsS"])
axs1[3].axis("off")
axs1[0].set_ylabel("Carbon Pool (GtC)")
axs1[0].set_title("Plant")
axs1[1].set_title("Litter")
axs1[2].set_title("Soil")
# Nitrogen pools
axs2[0].plot(time, res["NplsP"])
axs2[1].plot(time, res["NplsL"])
axs2[2].plot(time, res["NplsS"])
axs2[3].plot(time, res["NplsM"])
axs2[0].set_ylabel("Nitrogen Pool (GtN)")
axs2[0].set_title("Plant")
axs2[1].set_title("Litter")
axs2[2].set_title("Soil")
axs2[3].set_title("Mineral")
plt.show()
Understanding the Results
The results Dataset contains:
Carbon Variables:
CplsP,CplsL,CplsS: Plant, litter, and soil carbon pool sizes [GtC]CflxNPP,CflxLPR: Net primary production and litter production respiration [GtC/yr]CflxRH: Heterotrophic respiration [GtC/yr]CflxNetPLS: Net terrestrial carbon flux (net biome production) [GtC/yr]
Nitrogen Variables:
NplsP,NplsL,NplsS,NplsM: Plant, litter, soil, and mineral nitrogen pool sizes [GtN]NflxPU,NflxBNF: Nitrogen plant uptake and biological nitrogen fixation [GtN/yr]NflxNetMIN: Net mineralization [GtN/yr]NflxPUdef: Nitrogen deficit for plant uptake [GtN/yr]
Next Steps
Read CNit Model Overview to understand the model structure
Browse CNit Physics API for detailed API documentation
Check Example for realistic forcing data