github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
github-actions[bot] edited this page May 28, 2026 · 47 revisions

SANDAG ESTIMATES PROGRAM

SANDAG has produced annual population and housing estimates since 1974. These estimates provide both internal and external customers with sub-jurisdiction-level information about population, housing, demographic, and household characteristics from a composite of data sources. They supplement the decennial census and American Community Survey (ACS) datasets for the San Diego region.

As new input data used to calculate the estimates—such as new releases from the Census Bureau, SANDAG’s Land Use and Dwelling Unit Inventory (LUDU), or the California Department of Finance (DOF)—are made available each year, we provide new editions of our estimates. It is a best practices to use the most recent release available.

Estimates are created for Master Geographic Reference Areas (MGRAs), SANDAG's atomic unit of geography, with results available at larger and more aggregate geographies, where data is more accurate and reliable. Find SANDAG’s estimates products on the Open Data Portal.

Modules

SANDAG's Estimates Program consists of multiple self-contained modules. Each module has clearly defined inputs/outputs and a deterministic pathway between them. This makes debugging easier and outputs consistent. The modular structure allows users to run specific parts of the program in order to generate specific data. Instructions for running the entirety or only part of the Estimates Program can be found in the README.md in the "Code" section of this repository.

The following table contains a high-level overview of each module, including the inputs, outputs, and a quick description. For more in-depth descriptions, including the actual algorithms used, follow the links to module specific pages under the Module column. Be aware that inputs to individual modules can be dependent on and created by previous modules, such as "Households in each MGRA" in the "Population by Type" module. Also, note that not included in the below table is the Utility module, which contains various helpful cross-module functionality

ModuleInput(s)Output(s)Description
StartupNoneMGRA cross reference. Special MGRAs.Create MGRA geography for subsequent modules. The MGRA geography and cross-reference output is a fundamental input to each module of the Estimates Program. As such, it is not listed in subsequent input(s) sections as it is always present.
Housing and HouseholdsPoint geometry housing stock by land use. Census tract occupancy rates by structure type. Juridiction total occupancy rate controls.Housing structures and households by structure type in each MGRA.Aggregate point geometry housing counts to the MGRA-level by structure type. Apply census tract-level occupancy rates by structure type to get households by structure type. Control overall occupancy rate to jurisdiction-level controls.
Population by TypeSpecial MGRAs. Point geometry group quarters by type. Jurisdiction population by type controls. Households in each MGRA. Census tract average household size. Jurisdiction household population controls.Population by structure type in each MGRA.Aggregate point group quarters to MGRAs. Control total group quarters to jurisdiction-level controls. Apply census tract-level average household size to households to get household population. Control household population to jurisdiction-level controls.
Population by Age/Sex/EthnicityTo create regional age/sex/ethnicity controls by housing type:
* Regional population by housing type
* Regional age/sex/ethnicity distributions for group quarters by type
Regional age/sex/ethnicity controls for total population.

To create census tract seed data:
* Census tract distributions of ethnicity, age, and age/ethnicity.

To create population by age/sex/ethnicity by housing type:
* Households in each MGRA
* Population by structure type in each MGRA
* Special MGRAs
* Regional age/sex/ethnicity controls by housing type
* Census tract seed data.
Population by Age/Sex/Ethnicity by housing type in each MGRA.Apply regional age/sex/ethnicity distributions for group quarters by type to regional group quarters population by type to get regional age/sex/ethnicity population for group quarters by type. Calculate regional age/sex/ethnicity household population as the remainder of regional age/sex/ethnicity controls for total population. This creates regional age/sex/ethnicity controls for population by housing type.

Take census tract 5-year ACS Detailed Tables providing age/sex/ethnicity information and use an iterative proportional fitting procedure to create age/sex/ethnicity distributions by census tract to be used as seed data in calculating age/sex/ethnicity at the MGRA-level.

Adjust census tract seed data applying age/sex restrictions for special MGRAs. Take the census tract seed data, regional age/sex/ethnicity controls for population by housing type, and MGRA-level population by housing type and use an iterative proportional fitting procedure to create MGRA-level age/sex/ethnicity population by housing type. Use the special MGRAs age/sex restriction and households in each MGRA to apply balancers ensuring restrictions and householder populations are respected within each MGRA.
Employment/JobsPoint geometry active duty military counts. Point geometry employment by ownership and industry. Census block employment by ownership and industry. Census block group self-employment counts. Population by age/sex/ethnicity in each MGRA. Regional employment controls by ownership and industry.Employment by ownership and industry in each MGRA.Aggregate active duty military to MGRAs. Allocate self-employment counts from census block groups to MGRAs using population by age/sex/ethnicity. Allocate employment counts from census blocks to MGRAs using point-level employment counts and scale to match regional controls within ownership and industry.
Household CharacteristicsHouseholds in each MGRA. Household population in each MGRA. Census tract household income distributions. Census tract households by size distributions.Households by income category and households by size category in each MGRA.Apply census tract households by income category to households in each MGRA.

Apply census tract households by size category to households in each MGRA. Balance households by size category such that the implied household population is in accordance with the household population in each MGRA.
StagingNoneNoneMarks the estimates run as completed in the production database.

In graph form, the web of dependencies is as follows:

graph TD;
Startup-->hs_hh[Housing and Households]; hs_hh-->pop[Population by Type];
pop-->pop_ase[Population by Age/Sex/Ethnicity];
hs_hh-->hh_char[Household Characteristics];
pop-->hh_char;
pop_ase-->emp[Employment/Jobs];
emp-->Staging
hh_char-->Staging;
Loading

Additionally, shared functionalities across modules are stored in the Utility module. This module contains software configurations specified in the config.toml, helper functions for rounding and integerization, as well as a handler allowing the program to use earlier ACS 5-year releases if the current year release is unavailable.

Clone this wiki locally