Weeknotes: 29th September 2025

Last Week

Yirgacheffe

Docs

With PROPL coming up soon, I'm still working towards trying to make Yirgacheffe more easy to pick up and use. A bunch of that has been trying to simplify APIs to make common tasks more easy, but there's also documentation and website work that's needed doing. So one thing I achieved this week was getting a very basic website and documentation set up on yirgacheffe.org. It needs work, but now it's easy to tweak, rather than being this big task I kept putting off.

Originally I has started trying to add documentation using Sphinx, which I think is by far the most popular and powerful docs system used in the Python ecosystem, but I just never really got on with it. In the end I switched over to mkdocs, which when combined with mkdocstring can generate documentation from code docstrings. I further combined this with mike, which takes your docs and makes a versioned snapshot of them, so I can publish not just the documentation as the code is today, but all versions I've ever published. I really like this as a feature of the documentation of other packages I use (e.g., numpy does this), so I really wanted this for Yirgacheffe also.

Other improvements

I did a bunch of small things code wise to Yirgacheffe too:

I fixed a regression I introduced a month ago with how Yirgacheffe tries to track the geospatial area (e.g., lat/lng bounds) of a polygon. If I have the information for it, I force polygon layers to be pixel aligned when you query for their bounds, as ultimately that's what is going to be detemining how they're rasterized. All of my newer code uses Yirgacheffe's newer 2.0 style APIs (which area available in later 1.x builds as I slowly turn the ship to its new course), but I'd missed that one of the older APIs still used the actual bounds of the polygon data and then errors were reported due to mismatched shapes (as it effectively had different bounds depending on how you asked the layer for that info). Tests we expanded to catch this and it is now fixed. Only really exciting as that old path is being used by the Area Of Habitat library use for our biodiversity metrics!

I added the ability to read the pixels directly from a lazy expression without having to first bounce the result to either a file or an in-memory raster. This, for example, was what topogmesh was having to do, and I think in part addresses a weak point of Yirgacheffe compared to say the R Terra package, which also provides a declarative interface but has ways of doing pixel level access.

Fixed type inference for expression results which was causing GeoTIFFs to end up saving float data into int files.

I started to take map projections more seriously - before projections were never checked, but now I validate them, and have started doing some work on converting between map projections for queries when I can. There's a lot more to do here, but it's good to at least very the projection information properly typed in Yirgacheffe rather than being just a string that was compared between layers.

LIFE and AOH bits

I updated the LIFE pipeline to use the updated AOH library that I talked about last week. The main thing was moving it from importing the AOH code as a git submodule and instead fetching it from pypi instead. A small thing, but I think a big step in trying to make it easier for non-developers to use the pipeline.

I did a small step forward on supporting the Dahal et al validation method for AOHs, by finally automating getting occurrence data from GBIF. I now need to do the final checking stage, which is part why I was fiddling with projection systems in Yirgacheffe earlier.

I did some more analysis on the hybrid habitat maps we'd been looking at, which showed that macroscopically they do seem to make sense compared with other data sources, for example Mapbiomass in Brazil. I still need to look into applying the Woodman et al approach to this map to see if it helps microscopically, where random distribution really makes the maps weaker.

Active Travel Hackday

I went to Active Travel Hackday at the weekend, which was fun. That's moved to a blog post of it's own that's half written, so there will be more on that shortly.

This week

Start on the presentation for PROPL

Look into apply Woodman et al to the hybrid habitat work

I'm on the critical path for too many LIFE related things, so I need to spend a little time working out how to enable others to do things that they need me for. This is always my intent, but then we have things to deliver and it's just always easier for me to do it. However, that's no longer true as I can't do all the things, so it's time to make sure things are in a good state for others.