TDM Calibration Reports
viewof globalCalibRun = {
const options = calib_runs_ojs;
if (options.length === 0) {
return Inputs.select([], {label: "Calibration Run:", disabled: true});
}
// Default to the run with the highest numeric ID (e.g. "C51" over "C50"),
// not just the last entry in `options` -- that list comes from a plain
// alphabetical sort (see list_available_runs in _validation_scripts.py),
// which only happens to match numeric order today because both IDs have
// the same digit count ("C9" would sort after "C50" alphabetically despite
// being numerically earlier).
const runNumber = id => {
const m = /(\d+)/.exec(id);
return m ? parseInt(m[1], 10) : -Infinity;
};
const latestRun = options.reduce((best, id) => runNumber(id) > runNumber(best) ? id : best, options[0]);
const stored = window.localStorage.getItem("tdmcalib:selectedRun");
const initial = options.includes(stored) ? stored : latestRun;
const input = Inputs.select(options, {label: "Calibration Run:", value: initial});
const selectEl = input.querySelector("select");
input.classList.add("calib-run-bar");
// Sidebar links for pages that don't have data for every run (currently
// just report/cvm-update.qmd, which is only ever generated for the model
// version's reference run -- not planned for every run the way the other
// report pages are) get greyed out -- rather than the run dropdown itself
// shrinking to that page's subset -- so the dropdown's options stay
// identical everywhere on the site. The link stays clickable. If the
// current page happens to be cvm-update.qmd itself, this also swaps its
// own #cvm-content/#cvm-empty-message visibility -- both elements are
// absent on every other page, so this is a no-op there.
function updateSidebarAvailability(run) {
const available = cvm_update_available_runs_ojs.includes(run);
const link = document.querySelector('#quarto-sidebar a[href$="cvm-update.html"]');
if (link) {
const item = link.closest(".sidebar-item") ?? link;
item.classList.toggle("sidebar-item-no-run-data", !available);
link.title = available ? "" : `No commercial-vehicle factoring data for ${run}`;
}
const content = document.getElementById("cvm-content");
const emptyMsg = document.getElementById("cvm-empty-message");
if (content) content.style.display = available ? "" : "none";
if (emptyMsg) emptyMsg.style.display = available ? "none" : "";
}
updateSidebarAvailability(initial);
input.addEventListener("input", () => {
window.localStorage.setItem("tdmcalib:selectedRun", input.value);
updateSidebarAvailability(input.value);
});
// Quarto's own OJS runtime places this cell's returned node into its
// normal in-page output slot right after this function returns -- moving
// it into the header/sidebar synchronously, before that happens, would
// just get undone a moment later. Deferring to the next tick runs this
// after that placement, so the move actually sticks.
setTimeout(() => {
const navbarBrand = document.querySelector("#quarto-header .navbar-brand-container");
if (navbarBrand) {
input.classList.remove("calib-run-bar");
input.classList.add("calib-run-navbar");
navbarBrand.appendChild(input);
return;
}
const sidebar = document.querySelector("#quarto-sidebar");
const menu = sidebar?.querySelector(".sidebar-menu-container");
if (!sidebar || !menu) return; // no navbar brand container or docked sidebar -- stays inline as a .calib-run-bar
// Inputs.select renders the label text and <select> on the same line by
// default -- force them onto separate lines to match the sidebar's
// stacked item style. Insert relative to the select's actual parent
// (not assumed to be the <label>, which varies by Inputs version) so
// this doesn't throw if they aren't nested.
selectEl?.parentNode.insertBefore(document.createElement("br"), selectEl);
input.classList.remove("calib-run-bar");
input.classList.add("calib-run-sidebar");
sidebar.insertBefore(input, menu);
}, 0);
return input;
}Calibration validation reports comparing modeled results against observed data (HTS, ACS, OBS, and count data). Each report covers every available calibration run — use the “Calibration Run” dropdown next to the title above to pick which run’s modeled results to view against observed data; your choice carries over as you move between pages.