API Reference

╔═══════════════════════════════════════════════════════════════════════╗ ║ ░▀█▀░█▀▀░█░░░█▀█░█▀█░░░█░█░█▀▀░▀█▀░█▀█░░░░░░░░░░░░░░░░░░░░░░░ ║ ║ ░░█░░█░█░█░░░█░█░█░█░░░█▄█░█▀▀░░█░░█▀█░░░░░░░░░░░░░░░░░░░░░░░ ║ ║ ░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░░░▀░▀░▀▀▀░░▀░░▀░▀░░░░░░░░░░░░░░░░░░░░░░░ ║ ║ ║ ║ Thermal model for wētā burrow heat exchange v0.1.0 ║ ║ ── model. fit. predict. science. ── ║ ╚═══════════════════════════════════════════════════════════════════════╝

A lumped-parameter heat conduction model for stone-shingle wētā burrows. Extends the IGLOO framework (Giraldo et al. 2019) to estimate active thermoregulation in ectothermic insects from field temperature recordings and photogrammetric burrow geometry.

Modules:

constants Physical constants and default configuration. ingest Data loading, validation, and cleaning. physics Thermal ODE, geometry, penetration depth. fitting Parameter estimation, null model, F-test. sensitivity Shell thickness sweep, allometric RMR. viz Publication figures: SVG, PNG, CSV export.

igloo_weta.constants

┌─────────────────────────────────────────────────────────────────────┐ │ CONSTANTS « the numbers that matter » │ └─────────────────────────────────────────────────────────────────────┘

Every assumption, physical constant, material property, species measurement, and default configuration in one file. When a reviewer asks “where did that number come from?” — point them here.

All values carry their source and plausible range so sensitivity analyses can sweep them systematically.

Import what you need:

from igloo_weta.constants import STONE, WOOD, SPECIES, SIM

Or grab a specific value:

from igloo_weta.constants import STONE
print(STONE.rho)          # 2650.0 kg/m³
print(STONE.rho_range)    # (2500.0, 2800.0)
class igloo_weta.constants.MaterialProperties(name, rho, rho_range, c, c_range, k_thermal, k_thermal_range, source)[source]

Thermophysical properties of a burrow wall material.

Parameters:
name

Human-readable material name.

rho

Density [kg/m³].

rho_range

Plausible density range [kg/m³].

c

Specific heat capacity [J/(kg·K)].

c_range

Plausible specific heat range [J/(kg·K)].

k_thermal

Thermal conductivity [W/(m·K)].

k_thermal_range

Plausible conductivity range [W/(m·K)].

source

Literature reference for these values.

property alpha: float

Thermal diffusivity α = k / (ρ·c) in m²/s.

igloo_weta.constants.STONE = MaterialProperties(name='Greywacke / schist (Otago)', rho=2650.0, rho_range=(2500.0, 2800.0), c=840.0, c_range=(780.0, 900.0), k_thermal=2.5, k_thermal_range=(1.5, 3.5), source='Greywacke typical values. Robertson (1988) Engineering Geology of the NZ Greywacke; Clauser & Huenges (1995) Thermal conductivity of rocks and minerals, AGU Ref Shelf 3.')

Properties of Otago greywacke/schist stone for rock burrows.

igloo_weta.constants.WOOD = MaterialProperties(name='Native hardwood (mahoe / ngaio / manuka)', rho=550.0, rho_range=(400.0, 700.0), c=1700.0, c_range=(1400.0, 2000.0), k_thermal=0.15, k_thermal_range=(0.1, 0.25), source='Wood handbook (Forest Products Lab, USDA 2010). NZ native hardwoods: mahoe (Melicytus ramiflorus) ~500 kg/m³, ngaio (Myoporum laetum) ~550 kg/m³, manuka (Leptospermum) ~600 kg/m³. Thermal conductivity across grain 0.10–0.25 W/(m·K).')

Properties of native NZ hardwood for tree gallery burrows.

class igloo_weta.constants.AirProperties(rho, c, source)[source]

Thermophysical properties of air at field-relevant temperatures.

Parameters:
rho

Density at ~15 °C [kg/m³].

c

Specific heat at constant pressure [J/(kg·K)].

source

Reference.

igloo_weta.constants.AIR = AirProperties(rho=1.225, c=1005.0, source='Standard atmosphere at 15 °C, 1 atm.')

Air properties at typical field temperature.

class igloo_weta.constants.SpeciesInfo(name, common_name, body_length_mm, body_length_range, body_width_mm, body_width_range, mass_g, mass_range_g, mass_n, burrow_type, gallery_entrance_mm, gallery_entrance_range, gallery_volume_cm3, gallery_volume_range, gallery_SA_cm2, gallery_SA_range, gallery_wall_mm, gallery_wall_range, gallery_source, wall_material, field_site, notes)[source]

Morphometric and ecological data for one wētā species.

Parameters:
name

Binomial species name.

common_name

Common name.

body_length_mm

Typical adult body length [mm].

body_length_range

Range of body lengths [mm].

body_width_mm

Typical adult body width [mm].

body_width_range

Range of body widths [mm].

mass_g

Mean adult body mass [g] (from our data).

mass_range_g

Range of masses in our dataset [g].

mass_n

Sample size for mass measurements.

burrow_type

"stone" or "wood".

gallery_entrance_mm

Gallery entrance diameter [mm].

gallery_entrance_range

Entrance diameter range [mm].

gallery_volume_cm3

Estimated single-occupant gallery volume [cm³].

gallery_volume_range

Volume range [cm³].

gallery_SA_cm2

Estimated inner surface area [cm²].

gallery_SA_range

Surface area range [cm²].

gallery_wall_mm

Estimated wall thickness [mm].

gallery_wall_range

Wall thickness range [mm].

gallery_source

Reference for gallery dimensions.

wall_material

Reference to material: STONE or WOOD.

field_site

Where the temperature data were collected.

notes

Additional ecological notes.

igloo_weta.constants.H_MAORI = SpeciesInfo(name='Hemideina maori', common_name='Mountain stone wētā', body_length_mm=45.0, body_length_range=(30.0, 55.0), body_width_mm=14.0, body_width_range=(10.0, 18.0), mass_g=6.27, mass_range_g=(3.09, 8.56), mass_n=17, burrow_type='stone', gallery_entrance_mm=20.0, gallery_entrance_range=(12.0, 30.0), gallery_volume_cm3=500.0, gallery_volume_range=(188.0, 3071.0), gallery_SA_cm2=1200.0, gallery_SA_range=(663.0, 2664.0), gallery_wall_mm=10.0, gallery_wall_range=(5.0, 30.0), gallery_source='Photogrammetric foam casts of Rock and Pillars stone burrows (this study). Volume and SA are the cavity dimensions. Wall thickness estimated as 1 cm stone shingle.', wall_material='stone', field_site='Rock and Pillars, Otago, NZ (~1428 m asl)', notes='Lives above the treeline in stone shingle crevices and cavities. Abandoned arboreal life millions of years ago. Rock burrows range from small single-animal crevices to large multi-chamber shingle piles.')

H. maori — the alpine species with stone burrows (this study).

igloo_weta.constants.H_THORACICA = SpeciesInfo(name='Hemideina thoracica', common_name='Auckland tree wētā', body_length_mm=40.0, body_length_range=(30.0, 45.0), body_width_mm=12.0, body_width_range=(9.0, 15.0), mass_g=3.32, mass_range_g=(2.16, 4.5), mass_n=9, burrow_type='wood', gallery_entrance_mm=15.0, gallery_entrance_range=(12.0, 18.0), gallery_volume_cm3=45.0, gallery_volume_range=(35.0, 55.0), gallery_SA_cm2=75.0, gallery_SA_range=(60.0, 90.0), gallery_wall_mm=12.0, gallery_wall_range=(10.0, 20.0), gallery_source='Measured from custom wētā motels used in this study (photo documentation with ruler). Two-chamber Forstner-routed design: cavity ~75×30×20 mm total (~45 cm³), wall ~10–12 mm sides, ~15 mm top/bottom. Back board ~15–20 mm. Entrance hole ~15 mm Ø. Mounted on native trees in bush. iButton DS1921/DS1922 loggers placed inside cavity (T_in) and on outer bark (T_out).', wall_material='wood', field_site='North Island, NZ (lowland–mid-elevation forest)', notes='Data collected from custom wētā motels, NOT natural galleries. Motel design: two-chamber cavity routed with Forstner bit, perspex viewing window, mounted on tree trunk. Readily occupied by wētā within weeks of deployment. Polygynandrous with harem formation. Natural galleries in trees bored by puriri moth (Aenetus virescens) and kanuka beetle (Ochrocydus huttoni) larvae would have different thermal properties.')

H. thoracica — lowland tree galleries, North Island.

igloo_weta.constants.H_CRASSIDENS = SpeciesInfo(name='Hemideina crassidens', common_name='Wellington tree wētā', body_length_mm=65.0, body_length_range=(50.0, 75.0), body_width_mm=15.0, body_width_range=(12.0, 18.0), mass_g=4.89, mass_range_g=(3.85, 6.13), mass_n=8, burrow_type='wood', gallery_entrance_mm=15.0, gallery_entrance_range=(12.0, 18.0), gallery_volume_cm3=45.0, gallery_volume_range=(35.0, 55.0), gallery_SA_cm2=75.0, gallery_SA_range=(60.0, 90.0), gallery_wall_mm=12.0, gallery_wall_range=(10.0, 20.0), gallery_source='Measured from custom wētā motels used in this study (photo documentation with ruler). Same motel design as H. thoracica: two-chamber Forstner-routed cavity ~75×30×20 mm (~45 cm³), wall ~10–12 mm sides, ~15 mm top/bottom. Entrance ~15 mm Ø. iButton DS1921/DS1922 paired loggers: inside cavity + outer bark. Literature natural gallery reference: Kelly (2008) artificial galleries 53.8 cm³ for ~3 adults on Maud Island; entrance ~20 mm (Moller 1985).', wall_material='wood', field_site='Southern North Island / NW South Island, NZ', notes='Data collected from custom wētā motels (same design as H. thoracica motels). Largest tree wētā. Polygynous males guard females in galleries. Can also use rock refuges where trees unavailable. Gallery entrance kept clean; entered head-first, exited in reverse with tibial spines outward.')

H. crassidens — larger tree galleries, southern NI / NW SI.

igloo_weta.constants.SPECIES: dict[str, SpeciesInfo] = {'H. crassidens': SpeciesInfo(name='Hemideina crassidens', common_name='Wellington tree wētā', body_length_mm=65.0, body_length_range=(50.0, 75.0), body_width_mm=15.0, body_width_range=(12.0, 18.0), mass_g=4.89, mass_range_g=(3.85, 6.13), mass_n=8, burrow_type='wood', gallery_entrance_mm=15.0, gallery_entrance_range=(12.0, 18.0), gallery_volume_cm3=45.0, gallery_volume_range=(35.0, 55.0), gallery_SA_cm2=75.0, gallery_SA_range=(60.0, 90.0), gallery_wall_mm=12.0, gallery_wall_range=(10.0, 20.0), gallery_source='Measured from custom wētā motels used in this study (photo documentation with ruler). Same motel design as H. thoracica: two-chamber Forstner-routed cavity ~75×30×20 mm (~45 cm³), wall ~10–12 mm sides, ~15 mm top/bottom. Entrance ~15 mm Ø. iButton DS1921/DS1922 paired loggers: inside cavity + outer bark. Literature natural gallery reference: Kelly (2008) artificial galleries 53.8 cm³ for ~3 adults on Maud Island; entrance ~20 mm (Moller 1985).', wall_material='wood', field_site='Southern North Island / NW South Island, NZ', notes='Data collected from custom wētā motels (same design as H. thoracica motels). Largest tree wētā. Polygynous males guard females in galleries. Can also use rock refuges where trees unavailable. Gallery entrance kept clean; entered head-first, exited in reverse with tibial spines outward.'), 'H. maori': SpeciesInfo(name='Hemideina maori', common_name='Mountain stone wētā', body_length_mm=45.0, body_length_range=(30.0, 55.0), body_width_mm=14.0, body_width_range=(10.0, 18.0), mass_g=6.27, mass_range_g=(3.09, 8.56), mass_n=17, burrow_type='stone', gallery_entrance_mm=20.0, gallery_entrance_range=(12.0, 30.0), gallery_volume_cm3=500.0, gallery_volume_range=(188.0, 3071.0), gallery_SA_cm2=1200.0, gallery_SA_range=(663.0, 2664.0), gallery_wall_mm=10.0, gallery_wall_range=(5.0, 30.0), gallery_source='Photogrammetric foam casts of Rock and Pillars stone burrows (this study). Volume and SA are the cavity dimensions. Wall thickness estimated as 1 cm stone shingle.', wall_material='stone', field_site='Rock and Pillars, Otago, NZ (~1428 m asl)', notes='Lives above the treeline in stone shingle crevices and cavities. Abandoned arboreal life millions of years ago. Rock burrows range from small single-animal crevices to large multi-chamber shingle piles.'), 'H. thoracica': SpeciesInfo(name='Hemideina thoracica', common_name='Auckland tree wētā', body_length_mm=40.0, body_length_range=(30.0, 45.0), body_width_mm=12.0, body_width_range=(9.0, 15.0), mass_g=3.32, mass_range_g=(2.16, 4.5), mass_n=9, burrow_type='wood', gallery_entrance_mm=15.0, gallery_entrance_range=(12.0, 18.0), gallery_volume_cm3=45.0, gallery_volume_range=(35.0, 55.0), gallery_SA_cm2=75.0, gallery_SA_range=(60.0, 90.0), gallery_wall_mm=12.0, gallery_wall_range=(10.0, 20.0), gallery_source='Measured from custom wētā motels used in this study (photo documentation with ruler). Two-chamber Forstner-routed design: cavity ~75×30×20 mm total (~45 cm³), wall ~10–12 mm sides, ~15 mm top/bottom. Back board ~15–20 mm. Entrance hole ~15 mm Ø. Mounted on native trees in bush. iButton DS1921/DS1922 loggers placed inside cavity (T_in) and on outer bark (T_out).', wall_material='wood', field_site='North Island, NZ (lowland–mid-elevation forest)', notes='Data collected from custom wētā motels, NOT natural galleries. Motel design: two-chamber cavity routed with Forstner bit, perspex viewing window, mounted on tree trunk. Readily occupied by wētā within weeks of deployment. Polygynandrous with harem formation. Natural galleries in trees bored by puriri moth (Aenetus virescens) and kanuka beetle (Ochrocydus huttoni) larvae would have different thermal properties.')}

All species in a lookup dict keyed by binomial name.

class igloo_weta.constants.AllometryParams(a, b, Q10, T_ref_C, a_range, b_range, Q10_range, source)[source]

Parameters for insect resting metabolic rate allometry.

The standard model:

RMR_25 = a · M^b   (mW, grams)
RMR_T  = RMR_25 / Q10^((25 − T) / 10)
Parameters:
a

Pre-factor [mW / g^b].

b

Mass scaling exponent.

Q10

Temperature coefficient.

T_ref_C

Reference temperature [°C].

a_range

Plausible range for a.

b_range

Plausible range for b.

Q10_range

Plausible range for Q10.

source

Literature reference.

igloo_weta.constants.ALLOMETRY = AllometryParams(a=10.5, b=0.75, Q10=2.5, T_ref_C=25.0, a_range=(8.0, 14.0), b_range=(0.67, 0.82), Q10_range=(2.0, 3.0), source="Lighton (2008) Measuring Metabolic Rates, OUP. Insect RMR compilation. Q10 range from Chown & Nicolson (2004) Insect Physiological Ecology, OUP. Exponent 0.75: Kleiber's law; range 0.67–0.82 from Glazier (2005) Biol Rev 80:611.")

Allometric metabolic rate parameters with literature ranges.

class igloo_weta.constants.SimulationConfig(n_cycles, substeps, k_fit_bounds, shell_thickness_m, shell_sweep_cm, wood_wall_sweep_cm)[source]

Default parameters for the ODE integration and fitting.

Parameters:
n_cycles

Warm-up cycles before steady state.

substeps

Euler sub-steps per hour.

k_fit_bounds

Bounds on k during optimisation (1/h).

shell_thickness_m

Default stone shell thickness [m].

shell_sweep_cm

Thicknesses for sensitivity sweep [cm].

wood_wall_sweep_cm

Wall thicknesses for wood gallery sweep [cm].

igloo_weta.constants.SIM = SimulationConfig(n_cycles=25, substeps=20, k_fit_bounds=(0.005, 10.0), shell_thickness_m=0.01, shell_sweep_cm=(0.5, 1.0, 1.5, 2.0, 3.0, 5.0), wood_wall_sweep_cm=(1.0, 1.5, 2.0, 2.5, 3.0, 5.0))

Default simulation and fitting configuration.

class igloo_weta.constants.VizConfig(dpi, svg_font_family, species_colors)[source]

Plot styling defaults.

Parameters:
dpi

Raster resolution for PNG.

svg_font_family

Font family for editable SVG text.

species_colors

Colour per species for consistent plots.

igloo_weta.constants.VIZ = VizConfig(dpi=200, svg_font_family='sans-serif', species_colors={'H. maori': '#d62728', 'H. thoracica': '#ff7f0e', 'H. crassidens': '#2ca02c'})

Visualisation defaults.

igloo_weta.constants.EXCLUDE_ROCK_IDS: list[int] = [22]

Rock IDs excluded from species-level pooling.

Rock 22 is excluded because its humidity was at saturation (~100%), indicating potential evaporative cooling artefacts that confound the thermal model.

igloo_weta.ingest

┌─────────────────────────────────────────────────────────────────────┐ │ INGEST « loading the raw signal » │ └─────────────────────────────────────────────────────────────────────┘

Data loading, validation, and cleaning for field temperature recordings, photogrammetric burrow geometry, and wētā morphometrics.

All loaders return pandas DataFrames with consistent column names. Paths default to the data/ directory adjacent to the package root.

Example:

from igloo_weta.ingest import load_all
ds = load_all("/path/to/data")
print(ds.hourly_24h.columns)
class igloo_weta.ingest.DataBundle(hourly_24h, incubator, overall, daily, rock_phys, weta_morph)[source]

Container for all experimental datasets.

Parameters:
hourly_24h

Mean 24-h diurnal cycle per rock (hourly bins).

incubator

Full-duration hourly aggregates from incubator control.

overall

Per-rock summary statistics across all days.

daily

Day-by-day averages per rock.

rock_phys

Photogrammetric cavity geometry (foam cast measurements).

weta_morph

Wētā morphometrics and species assignments.

igloo_weta.ingest.load_hourly_24h(data_dir=None)[source]

Load the 24-hour hourly average temperatures per rock.

Parameters:

data_dir (Optional[str]) – Path to data directory. None uses the default.

Return type:

DataFrame

Returns:

DataFrame with columns including Hour, rock, inside_mean, outside_mean, diff_mean, etc.

igloo_weta.ingest.load_incubator(data_dir=None)[source]

Load the incubator passive-control hourly time series.

Parameters:

data_dir (Optional[str]) – Path to data directory.

Return type:

DataFrame

Returns:

DataFrame indexed by elapsed_hour with inside/outside temperature means, SEMs, and confidence intervals.

igloo_weta.ingest.load_overall(data_dir=None)[source]

Load per-rock overall summary statistics.

Parameters:

data_dir (Optional[str]) – Path to data directory.

Returns:

mean temperatures, confidence intervals, humidity.

Return type:

DataFrame with one row per rock

igloo_weta.ingest.load_daily(data_dir=None)[source]

Load day-by-day temperature averages per rock.

Parameters:

data_dir (Optional[str]) – Path to data directory.

Return type:

DataFrame

Returns:

DataFrame with day, rock, and temperature columns.

igloo_weta.ingest.load_rock_physics(data_dir=None)[source]

Load photogrammetric burrow geometry from foam casts.

The Total Volume and Total Surface area columns describe the air cavity (foam imprint), not the stone. Stone shell properties are computed downstream in igloo_weta.physics.

Parameters:

data_dir (Optional[str]) – Path to data directory.

Return type:

DataFrame

Returns:

DataFrame with Rock number, Total Volume (cm3), Total Surface area (cm2), and chunk data.

igloo_weta.ingest.load_weta_morphometrics(data_dir=None)[source]

Load wētā body measurements and assign species from ID prefixes.

Species are inferred from the Weta number prefix: HMH. maori, HthoraH. thoracica, HcrassH. crassidens.

Parameters:

data_dir (Optional[str]) – Path to data directory.

Return type:

DataFrame

Returns:

DataFrame with added species column.

igloo_weta.ingest.summarise_species(morph_df)[source]

Compute per-species weight statistics from morphometric data.

Parameters:

morph_df (DataFrame) – Output of load_weta_morphometrics().

Return type:

dict

Returns:

Dict keyed by species name, each containing n, mean, std, min, max, median, and weights (array).

igloo_weta.ingest.load_all(data_dir=None)[source]

Load every dataset and return a single DataBundle.

Parameters:

data_dir (Optional[str]) – Override for the data directory path.

Return type:

DataBundle

Returns:

Populated DataBundle ready for analysis.

igloo_weta.physics

┌─────────────────────────────────────────────────────────────────────┐ │ PHYSICS « the laws of thermodynamics » │ └─────────────────────────────────────────────────────────────────────┘

Lumped-parameter thermal model for stone-shingle wētā burrows.

The governing ODE:

C_eff · dT_in/dt  =  U · (T_out(t) − T_in(t))  +  Q_weta

where C_eff is the effective heat capacity of the burrow (stone shell + enclosed air), U is the overall thermal conductance, and Q_weta is the metabolic heat production of the wētā.

Defining k = U / C_eff (thermal rate constant, 1/s):

dT_in/dt  =  k · (T_out − T_in)  +  Q_weta / C_eff

The null model sets Q_weta = 0. Any systematic positive residual (T_in_observed > T_in_null) implies active heating by the wētā.

Analogous to the IGLOO model (Giraldo et al. 2019, Sci Rep 9:3974), which used the same heat conduction framework for Drosophila body temperature in thermal gradients.

class igloo_weta.physics.BurrowPhysics(C_eff, C_stone, C_air, V_cavity_m3, SA_m2, M_stone_kg, V_shell_m3, shell_m)[source]

Physical properties of a stone-shingle burrow cavity.

All quantities in SI units unless noted.

Parameters:
C_eff

Effective heat capacity [J/K].

C_stone

Stone shell heat capacity [J/K].

C_air

Enclosed air heat capacity [J/K].

V_cavity_m3

Air cavity volume [m³].

SA_m2

Inner wall surface area [m²].

M_stone_kg

Stone shell mass [kg].

V_shell_m3

Stone shell volume [m³].

shell_m

Shell thickness used [m].

igloo_weta.physics.compute_burrow_physics(volume_cm3, surface_area_cm2, shell_m=0.01)[source]

Compute thermal properties from foam-cast photogrammetry.

The photogrammetry scans measure the foam cast of the cavity, so volume_cm3 is the air space and surface_area_cm2 is the inner wall area. The stone shell of thickness shell_m surrounds this cavity.

Parameters:
  • volume_cm3 (float) – Cavity volume from foam cast in cm³.

  • surface_area_cm2 (float) – Inner surface area from foam cast in cm².

  • shell_m (float) – Stone shell thickness in metres.

Return type:

BurrowPhysics

Returns:

Populated BurrowPhysics instance.

igloo_weta.physics.thermal_penetration_depth(time_s)[source]

Compute thermal penetration depth into stone.

Uses the standard diffusion scaling δ = √(α·t) where α is the thermal diffusivity of stone.

Parameters:

time_s (float) – Time horizon in seconds.

Return type:

float

Returns:

Penetration depth in metres.

igloo_weta.physics.simulate_burrow_temperature(k, T_out_series, T_in_initial, Q_norm=0.0, dt=1.0)[source]

Simulate burrow interior temperature using forward Euler.

Integrates:

T_in[i+1] = T_in[i] + k·(T_out[i] − T_in[i])·dt + Q_norm·dt
Parameters:
  • k (float) – Thermal rate constant [1/hour].

  • T_out_series (ndarray) – Outside temperature time series [°C].

  • T_in_initial (float) – Initial inside temperature [°C].

  • Q_norm (float) – Normalised heat input Q_weta/C_eff [°C/hour].

  • dt (float) – Timestep in hours.

Return type:

ndarray

Returns:

Array of simulated inside temperatures, same length as T_out_series.

igloo_weta.physics.simulate_24h_steady_state(k, T_out_24h, Q_norm=0.0, n_cycles=25, substeps=20)[source]

Run the 24-h cycle to steady-state oscillation.

Uses sub-hour Euler steps for accuracy, then samples at hourly resolution.

Parameters:
  • k (float) – Thermal rate constant [1/hour].

  • T_out_24h (ndarray) – Mean outside temperature for each hour (length 24).

  • Q_norm (float) – Normalised heat input [°C/hour].

  • n_cycles (int) – Warm-up cycles before recording.

  • substeps (int) – Euler sub-steps per hour.

Return type:

ndarray

Returns:

Steady-state inside temperature array of length 24.

igloo_weta.physics.compute_phase_lag(T_in, T_out)[source]

Compute phase lag via circular cross-correlation.

Parameters:
  • T_in (ndarray) – Inside temperature array (length 24).

  • T_out (ndarray) – Outside temperature array (length 24).

Return type:

tuple[int, float]

Returns:

Tuple of (lag_hours, max_correlation). Positive lag means T_in lags behind T_out.

igloo_weta.physics.compute_amplitude_ratio(T_in, T_out)[source]

Ratio of diurnal temperature amplitudes (inside / outside).

Parameters:
  • T_in (ndarray) – Inside temperature array.

  • T_out (ndarray) – Outside temperature array.

Return type:

float

Returns:

Amplitude ratio. Values < 1 indicate damping by thermal mass.

igloo_weta.fitting

┌─────────────────────────────────────────────────────────────────────┐ │ FITTING « dialling in the numbers » │ └─────────────────────────────────────────────────────────────────────┘

Parameter estimation for the burrow thermal model. Fits the thermal rate constant k and normalised heat input q from 24-h diurnal temperature recordings, then converts to physical units using burrow geometry.

Two models are fitted per rock:

  1. Null model (passive thermal lag, Q_weta = 0): dT_in/dt = k · (T_out T_in)

  2. Full model (lag + wētā heat): dT_in/dt = k · (T_out T_in) + q

An F-test determines whether the wētā heat term significantly improves the fit.

class igloo_weta.fitting.RockResult(rock, has_phys, T_in_obs, T_out_obs, T_in_ci_lo, T_in_ci_hi, mean_dT_obs, phase_lag_obs, amp_ratio_obs, k_null, r2_null, T_pred_null, phase_null, amp_null, k_fit, q_fit, r2_full, T_pred_full, F_stat, p_value, residual_null, mean_residual, tau_hours, phys, U_fit_W_K, Q_weta_W, T_cross_raw, T_cross_corr, slope_corr, intercept_corr)[source]

Full analysis result for a single rock burrow.

Parameters:
rock

Rock identifier number.

has_phys

Whether photogrammetric geometry is available.

T_in_obs

Observed inside temperature (24 h).

T_out_obs

Observed outside temperature (24 h).

T_in_ci_lo

Lower 95 % CI on inside temperature.

T_in_ci_hi

Upper 95 % CI on inside temperature.

mean_dT_obs

Mean observed ΔT = T_in − T_out (°C).

phase_lag_obs

Observed phase lag (hours).

amp_ratio_obs

Observed amplitude ratio.

k_null

Fitted k from null model (1/h).

r2_null

R² of null model.

T_pred_null

Predicted T_in from null model (24 h).

phase_null

Phase lag of null prediction.

amp_null

Amplitude ratio of null prediction.

k_fit

Fitted k from full model (1/h).

q_fit

Fitted normalised heat q (°C/h).

r2_full

R² of full model.

T_pred_full

Predicted T_in from full model (24 h).

F_stat

F-statistic for model comparison.

p_value

p-value of F-test.

residual_null

Lag-corrected residual = T_obs − T_null.

mean_residual

Mean of residual_null.

tau_hours

Thermal time constant 1/k (hours).

phys

BurrowPhysics or None.

U_fit_W_K

Thermal conductance U (W/K) or None.

Q_weta_W

Metabolic heat output (W) or None.

T_cross_raw

Raw crossover temperature (°C).

T_cross_corr

Lag-corrected crossover temperature (°C).

slope_corr

Slope of corrected ΔT vs T_out regression.

intercept_corr

Intercept of corrected regression.

class igloo_weta.fitting.IncubatorResult(k_wood, T_pred, T_in, T_out, hours, r2)[source]

Result from fitting the passive incubator control experiment.

Parameters:
k_wood

Fitted thermal rate constant for wood burrow (1/h).

T_pred

Predicted inside temperature series.

T_in

Observed inside temperature series.

T_out

Observed outside temperature series.

hours

Elapsed hour array.

r2

Coefficient of determination.

igloo_weta.fitting.fit_incubator(incubator_df)[source]

Fit thermal rate constant from the passive incubator experiment.

No wētā were present — validates the modelling framework on wood burrows where Q_weta is known to be zero.

Parameters:

incubator_df (DataFrame) – Output of load_incubator().

Return type:

IncubatorResult

Returns:

IncubatorResult with fitted k, predictions, and R².

igloo_weta.fitting.fit_single_rock(rock_id, hourly_24h, rock_phys_df, shell_m=0.01)[source]

Fit thermal model for a single rock burrow.

Fits both the null (passive) and full (passive + wētā) models, performs an F-test, computes lag-corrected residuals and crossover temperatures.

Parameters:
  • rock_id (int) – Numeric rock identifier.

  • hourly_24h (DataFrame) – Full 24-h hourly average DataFrame (all rocks).

  • rock_phys_df (DataFrame) – Photogrammetric geometry DataFrame.

  • shell_m (float) – Stone shell thickness in metres.

Return type:

Optional[RockResult]

Returns:

RockResult or None if insufficient data.

igloo_weta.fitting.fit_all_rocks(hourly_24h, rock_phys_df, shell_m=0.01)[source]

Fit thermal models for every rock in the dataset.

Parameters:
  • hourly_24h (DataFrame) – 24-h hourly averages (all rocks).

  • rock_phys_df (DataFrame) – Photogrammetric geometry.

  • shell_m (float) – Stone shell thickness in metres.

Return type:

list[RockResult]

Returns:

List of RockResult, one per rock with sufficient data.

igloo_weta.fitting.compute_species_crossover(results, exclude=None)[source]

Compute the species-level crossover temperature.

Pools lag-corrected residuals across rocks (excluding specified IDs) and fits a linear regression of ΔT_corrected vs T_out.

Parameters:
Return type:

dict

Returns:

Dict with keys T_cross_raw, T_cross_corr, slope_raw, slope_corr, intercept_raw, intercept_corr.

igloo_weta.sensitivity

┌─────────────────────────────────────────────────────────────────────┐ │ SENSITIVITY « wiggling the knobs » │ └─────────────────────────────────────────────────────────────────────┘

Shell thickness sensitivity analysis and allometric metabolic rate estimation for wētā species.

Key insight: the fitted parameters k and q (in °C/h) are determined entirely from the temperature dynamics and do not depend on shell thickness. Only the conversion to physical units (Watts, mW/K) scales linearly with the assumed shell thickness. The crossover temperature is also thickness-independent.

igloo_weta.sensitivity.rmr_at_temperature(mass_g, temp_c)[source]

Estimate resting metabolic rate at a given temperature.

Uses standard insect allometric scaling:

RMR_25 = a · M^b    (mW, grams)

corrected to temp_c via Q₁₀:

RMR_T = RMR_25 / Q10^((25 − T) / 10)
Parameters:
  • mass_g (float) – Body mass in grams.

  • temp_c (float) – Ambient temperature in °C.

Return type:

float

Returns:

Estimated RMR in milliwatts.

class igloo_weta.sensitivity.SpeciesRMR(species, mass_g, rmr_5, rmr_10, rmr_15, rmr_25, color)[source]

Metabolic rate estimates for one wētā species.

Parameters:
species

Species name.

mass_g

Mean body mass (g).

rmr_5

RMR at 5 °C (mW).

rmr_10

RMR at 10 °C (mW).

rmr_15

RMR at 15 °C (mW).

rmr_25

RMR at 25 °C (mW).

color

Default plot colour.

igloo_weta.sensitivity.compute_species_rmr(species_stats)[source]

Compute RMR estimates for each wētā species.

Parameters:

species_stats (dict) – Output of summarise_species().

Return type:

dict[str, SpeciesRMR]

Returns:

Dict keyed by species name, values are SpeciesRMR.

class igloo_weta.sensitivity.ThicknessPoint(thickness_cm, C_eff, U_mW_K, Q_mW, M_stone_g)[source]

Q and U estimates at one shell thickness for one rock.

Parameters:
thickness_cm

Shell thickness in cm.

C_eff

Effective heat capacity (J/K).

U_mW_K

Thermal conductance (mW/K).

Q_mW

Metabolic heat estimate (mW).

M_stone_g

Stone shell mass (g).

igloo_weta.sensitivity.sweep_shell_thickness(result, thicknesses_cm=None)[source]

Compute Q_weta and U at multiple shell thicknesses for one rock.

Because k and q are thickness-independent, Q = q · C_eff / 3600 scales linearly. No re-fitting is needed.

Parameters:
  • result (RockResult) – RockResult from fit_single_rock().

  • thicknesses_cm (Optional[list[float]]) – List of thicknesses to evaluate (default from constants).

Return type:

list[ThicknessPoint]

Returns:

List of ThicknessPoint, one per thickness.

igloo_weta.sensitivity.sweep_all_rocks(results, thicknesses_cm=None)[source]

Run shell thickness sweep for every rock with geometry.

Parameters:
Return type:

dict[int, list[ThicknessPoint]]

Returns:

Dict keyed by rock ID, values are lists of ThicknessPoint.

igloo_weta.viz

┌─────────────────────────────────────────────────────────────────────┐ │ VIZ « painting the picture » │ └─────────────────────────────────────────────────────────────────────┘

Publication-quality figure generation for the wētā burrow thermal model. Every figure is exported as SVG (editable text), PNG, and accompanying CSV data tables.

SVG output uses editable fonts — open in Inkscape or Illustrator to tweak labels without re-running the pipeline.

igloo_weta.viz.plot_incubator(inc, output_dir)[source]

Plot incubator passive control: observed vs predicted.

Parameters:
  • inc (IncubatorResult) – IncubatorResult.

  • output_dir (str) – Output directory for files.

Return type:

list[str]

Returns:

List of written file paths (SVG, PNG, CSV).

igloo_weta.viz.plot_per_rock_fits(results, output_dir)[source]

Plot 24-h model fits for each rock (null + full model).

Parameters:
  • results (list[RockResult]) – List of RockResult.

  • output_dir (str) – Output directory.

Return type:

list[str]

Returns:

Written file paths.

igloo_weta.viz.plot_residuals(results, output_dir)[source]

Plot lag-corrected residuals (T_obs − T_null) per rock.

Parameters:
  • results (list[RockResult]) – List of RockResult.

  • output_dir (str) – Output directory.

Return type:

list[str]

Returns:

Written file paths.

igloo_weta.viz.plot_crossover(results, species_cross, output_dir)[source]

Plot the heating–cooling crossover analysis (4 panels).

Parameters:
  • results (list[RockResult]) – List of RockResult.

  • species_cross (dict) – Output of compute_species_crossover().

  • output_dir (str) – Output directory.

Return type:

list[str]

Returns:

Written file paths.

igloo_weta.viz.plot_species_sensitivity(results, sweep_data, species_rmr, output_dir)[source]

Plot shell thickness sensitivity with species RMR bands.

Top row: Q vs thickness. Bottom row: Q/RMR ratio (log scale). One column per species.

Parameters:
Return type:

list[str]

Returns:

Written file paths.

igloo_weta.viz.export_results_csv(results, output_dir)[source]

Export per-rock results as a CSV table.

Parameters:
  • results (list[RockResult]) – List of RockResult.

  • output_dir (str) – Output directory.

Return type:

str

Returns:

Path to the written CSV.