Skip to content

Commit

Permalink
MOVES4.0.1 with movesdb20240104
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbizercox committed Jan 17, 2024
2 parents e3d994c + bd714a5 commit eef9da4
Show file tree
Hide file tree
Showing 40 changed files with 893 additions and 145 deletions.
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ identifiers:
value: "Office of Transportation and Air Quality. US Environmental Protection Agency. Ann Arbor, MI."
description: "Publisher"
url: "https://www.epa.gov/moves"
version: 4.0.0
date-released: 2023-08-30
version: 4.0.1
date-released: 2024-01-18
2 changes: 1 addition & 1 deletion MOVESConfiguration.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defaultServerName = localhost
defaultDatabaseName = movesdb20230615
defaultDatabaseName = movesdb20240104
executionServerName = localhost
executionDatabaseName = MOVESExecution
outputServerName = 127.0.0.1
Expand Down
Binary file modified amazon/movesamazon.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@
<echo message=" to this file in -Dinput. Use -Doutput= to specify the output" />
<echo message=" file path; file types can be .xls(x), .txt, or .csv. For help," />
<echo message=" see database\NEIQA\NEIQAInstructions.pdf" />
<echo message=" ant onroadNEIQA -Dinput=&quot;cXXXXXyYYYY_in,cZZZZZyYYYY_in&quot; -Doutput=PSC_QA_Report.xlsx" />
<echo message=" ant onroadNEIQA -Dinput=db_list.txt -Doutput=PSC_QA_Report.xlsx" />
<echo message=" ant onroadNEIQA -Dinput=&quot;cXXXXXyYYYY_ZZZZZZZZ,cAAAAAyYYYY_ZZZZZZZZ&quot; -Doutput=QA_Report.xlsx" />
<echo message=" ant onroadNEIQA -Dinput=db_list.txt -Doutput=QA_Report.xlsx" />
<echo message="nonroadNEIQA - run the nonroad NEI QA scripts. Usage has the same arguments" />
<echo message=" as the onroadNEIQA command. " />
<echo message="-------------------------------------------------------------------------------"/>
Expand Down
7 changes: 7 additions & 0 deletions database/AgeDistributionImporter.sql
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,10 @@ select concat('ERROR: Source ',sourceTypeID,', year ',yearID,' ageFraction sum i
from tempNotUnity;

drop table if exists tempNotUnity;

-- Complain about any null values
insert into importTempMessages (message)
SELECT concat('ERROR: Found a NULL ageFraction value for sourceTypeID: ', sourceTypeID)
from SourceTypeAgeDistribution
where ageFraction IS NULL
LIMIT 1;
7 changes: 7 additions & 0 deletions database/AverageSpeedDistributionImporter.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ select concat('ERROR: Source ',sourceTypeID,', road ',roadTypeID,', hour/day ',h
from tempNotUnity;

drop table if exists tempNotUnity;

-- Complain about any null values
insert into importTempMessages (message)
SELECT concat('ERROR: Found a NULL avgSpeedFraction value for sourceTypeID: ', sourceTypeID)
from avgSpeedDistribution
where avgSpeedFraction IS NULL
LIMIT 1;
Binary file modified database/NEIQA/NEIQAInstructions.pdf
Binary file not shown.
79 changes: 70 additions & 9 deletions database/NEIQA/onroadCDBchecks.sql
Original file line number Diff line number Diff line change
Expand Up @@ -602,11 +602,6 @@ Update CDB_Checks as a, tempb as b set a.count = b.table_rows Where a.tableName

-- Present tables
Update CDB_Checks set testDescription = 'Present' where `count` is not null;

Update CDB_Checks set testDescription = 'Table likely to be overwritten',
`status` = 'Warning'
where `count` > 0
and tableName in ('emissionratebyage', 'fuelsupply', 'fuelformulation', 'zonemonthhour');

Update CDB_Checks set testDescription = 'Table no longer used as user input',
`status` = 'Error'
Expand Down Expand Up @@ -1623,6 +1618,7 @@ Drop table if exists tempA;
-- source type, fuel type, and model year are valid (i.e., no diesel motorcycles).
-- So this table checks for completeness vs. samplevehiclepopulation, which contains this definition
-- Also, only check for the existence of modelyearids that will appear in the run (according to the year table)
-- Also, insert a different message if the entire table is empty, so that it can be flagged as a warning instead
INSERT INTO QA_Checks_Log values ( 1507, 'OK', @hVersion, curDate(), curTime() );
Insert into CDB_Checks
( tableName,
Expand All @@ -1639,7 +1635,25 @@ INSERT INTO QA_Checks_Log values ( 1507, 'OK', @hVersion, curDate(), curTime() )
join `year`
where modelYearID between yearID-30 and yearID) as t1
left join avft using (sourceTypeID, fuelTypeID, modelYearID)
where fuelEngFraction is NULL
join (select count(*) as n from avft) as t2
where fuelEngFraction is NULL and n > 0
ORDER BY sourceTypeID, fuelTypeID, modelYearID LIMIT 1;

Insert into CDB_Checks
( tableName,
checkNumber,
testDescription
)
Select 'avft' as tableName,
1507 as checkNumber,
'Table is empty' as testDescription
from (select distinct sourceTypeID, fuelTypeID, modelYearID
from ##defaultdb##.samplevehiclepopulation
join `year`
where modelYearID between yearID-30 and yearID) as t1
left join avft using (sourceTypeID, fuelTypeID, modelYearID)
join (select count(*) as n from avft) as t2
where fuelEngFraction is NULL and n = 0
ORDER BY sourceTypeID, fuelTypeID, modelYearID LIMIT 1;

-- check no. 1508: check column type definitions for input db mismatches with default db
Expand Down Expand Up @@ -2445,6 +2459,18 @@ join (select column_name, column_type, is_nullable, column_key from information_
where table_schema = '##defaultdb##' and table_name = 'emissionratebyage') t2 using (column_name)
where t1.column_type <> t2.column_type or t1.is_nullable <> t2.is_nullable or t1.column_key <> t2.column_key;

-- check no. 1905: warn that any user-supplied emissionRateByAge table is likely to be overwritten
INSERT INTO QA_Checks_Log values ( 1905, 'OK', @hVersion, curDate(), curTime() );
Insert into CDB_Checks
( TableName,
CheckNumber,
TestDescription )
Select "emissionRateByAge" as tableName,
1905,
'Table likely to be overwritten' as testDescription
from emissionRateByAge
having count(*) > 0;

-- Checks for fuelformulation
Insert into CDB_Checks (CheckNumber, TableName, TestDescription) values (2000, "fuelFormulation", "Table Check:");

Expand Down Expand Up @@ -2836,6 +2862,18 @@ join (select column_name, column_type, is_nullable, column_key from information_
where table_schema = '##defaultdb##' and table_name = 'fuelformulation') t2 using (column_name)
where t1.column_type <> t2.column_type or t1.is_nullable <> t2.is_nullable or t1.column_key <> t2.column_key;

-- check no. 2015: warn that any user-supplied fuelformulation table is likely to be overwritten
INSERT INTO QA_Checks_Log values ( 2015, 'OK', @hVersion, curDate(), curTime() );
Insert into CDB_Checks
( TableName,
CheckNumber,
TestDescription )
Select "fuelFormulation" as tableName,
2015,
'Table likely to be overwritten' as testDescription
from fuelFormulation
having count(*) > 0;

-- fuelsupply checks
Insert into CDB_Checks (CheckNumber, TableName, TestDescription) values (2100, "fuelSupply", "Table Check:");

Expand Down Expand Up @@ -2961,6 +2999,17 @@ join (select column_name, column_type, is_nullable, column_key from information_
where table_schema = '##defaultdb##' and table_name = 'fuelsupply') t2 using (column_name)
where t1.column_type <> t2.column_type or t1.is_nullable <> t2.is_nullable or t1.column_key <> t2.column_key;

-- check no. 2106: warn that any user-supplied fuelSupply table is likely to be overwritten
INSERT INTO QA_Checks_Log values ( 2106, 'OK', @hVersion, curDate(), curTime() );
Insert into CDB_Checks
( TableName,
CheckNumber,
TestDescription )
Select "fuelSupply" as tableName,
2106,
'Table likely to be overwritten' as testDescription
from fuelSupply
having count(*) > 0;

-- fuelusagefraction
Insert into CDB_Checks (CheckNumber, TableName, TestDescription) values (2200, "fuelUsageFraction", "Table Check:");
Expand Down Expand Up @@ -8040,6 +8089,17 @@ join (select column_name, column_type, is_nullable, column_key from information_
where table_schema = '##defaultdb##' and table_name = 'zonemonthhour') t2 using (column_name)
where t1.column_type <> t2.column_type or t1.is_nullable <> t2.is_nullable or t1.column_key <> t2.column_key;

-- check no. 5008: warn that any user-supplied zoneMonthHour table is likely to be overwritten
INSERT INTO QA_Checks_Log values ( 5008, 'OK', @hVersion, curDate(), curTime() );
Insert into CDB_Checks
( TableName,
CheckNumber,
TestDescription )
Select "zoneMonthHour" as tableName,
5008,
'Table likely to be overwritten' as testDescription
from zoneMonthHour
having count(*) > 0;

-- zoneRoadType
Insert into CDB_Checks (CheckNumber, TableName, TestDescription) values (5100, "zoneRoadType", "Table Check:");
Expand Down Expand Up @@ -8192,9 +8252,10 @@ Update CDB_Checks set status = 'Error' where checkNumber is not null an
-- set Status to 'Warning' for select checks (these are typically distribution checks, as well as tables that give warnings
-- if you supply them: fuelformulation, fuelsupply, and zonemonthhour)
Update CDB_Checks set status = 'Warning' where checkNumber in
(1608,1609,1610,1611,1807,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2101,
2102,2103,2104,2406,2507,2508,2808,2809,3605,3804,3805,3906,4506,5001,5002,5003,5004,5005,
5006);
(1608,1609,1610,1611,1806,1807,1905,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,
2012,2015,2101,2102,2103,2104,2106,2406,2507,2508,2808,2809,3605,3804,3805,3906,4506,5001,
5002,5003,5004,5005,5006,5008);
Update CDB_Checks set status = 'Warning' where checkNumber = 1507 and testDescription = 'Table is empty';

-- special cases for VMT/starts checks --
-- mark all VMT row count checks as 'complete' regardless of results
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
-- Nonroad Post Processing Script (updated 1/2/2024):
-- Emission factors in grams per operating hour by SCC and Model Year
--
-- MOVES-Nonroad Output Guidance:
-- SCC and Model Year must be selected and present in the results.
-- This script will run faster if engine tech and HP class
-- are not selected, and if there is only one sector, year,
-- month, and day in the output.
--
-- When prompted to save, specify one of the following file types: .xlsx, .xls, or .txt
-- The raw output of this script is also stored in the output database in a table called:
-- EmissionFactors_per_operatinghour_by_SCC_and_ModelYear
--
-- WARNING:
-- This script may take a long time to complete depending on
-- the size of the output database. A confirmation notice will
-- alert you when this action has completed.

flush tables;

-- Set up indexing for setting NULL values to 0
set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index_state');
set @sqlstmt := if( @exist > 0, 'select ''INFO: index_state already exists.''', 'create index index_state on movesoutput ( stateID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index_state');
set @sqlstmt := if( @exist > 0, 'select ''INFO: index_state already exists.''', 'create index index_state on movesactivityoutput ( stateID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index_county');
set @sqlstmt := if( @exist > 0, 'select ''INFO: index_county already exists.''', 'create index index_county on movesoutput ( countyID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index_county');
set @sqlstmt := if( @exist > 0, 'select ''INFO: index_county already exists.''', 'create index index_county on movesactivityoutput ( countyID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

-- Convert NULLs to 0 to improve joins
UPDATE movesoutput SET stateID = 0 WHERE stateID IS NULL;
UPDATE movesoutput SET countyID = 0 WHERE countyID IS NULL;
UPDATE movesactivityoutput SET stateID = 0 WHERE stateID IS NULL;
UPDATE movesactivityoutput SET countyID = 0 WHERE countyID IS NULL;

-- Set up indexing for everything else
set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index1');
set @sqlstmt := if( @exist > 0, 'select ''INFO: Index already exists.''', 'create index index1 on movesoutput ( MOVESRunID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index104');
set @sqlstmt := if( @exist > 0, 'select ''INFO: Index already exists.''', 'create index index104 on movesoutput ( MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID,pollutantID,processID )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index10');
set @sqlstmt := if( @exist > 0, 'select ''INFO: Index already exists.''', 'create index index10 on movesactivityoutput ( activitytypeid )');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

-- Get time units
set @timeUnits := (select timeUnits from movesrun limit 1);

-- Get hours of activity
drop table if exists hours;
create table hours
select
MOVESRunID,
yearID,
monthID,
dayID,
stateID,
countyID,
SCC,
fuelTypeID,
modelYearID,
engTechID,
hpID,
activity as hours
from movesactivityoutput
where activitytypeid = 2;

create index index1 on hours (MOVESRunID,yearID,monthID,dayID,stateID,countyID,SCC,modelYearID);


-- Set up unit conversions table
drop table if exists units;
create table units (fromUnit char(5), factor double, description text);
insert into units values
('ton', 907185, 'From U.S. tons to grams'),
('lb', 453.592, 'From lbm to grams'),
('kg', 1000, 'From kg to grams'),
('g', 1, 'From grams to grams');


-- Get inventories by SCC
drop table if exists temp1;
create table temp1
select
MOVESRunID,
yearID,
monthID,
dayID,
stateID,
countyID,
scc,
modelYearID,
pollutantID,
processID,
units.factor * sum(emissionQuant) as emissionQuant
from movesoutput m
left join movesrun using (movesrunid)
left join units on (movesrun.massUnits = units.fromUnit)
group by MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID,pollutantID,processID;

create index index1 on temp1 (MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID);
create index index2 on temp1 (scc);


-- Get hours by SCC and ModelYearID
drop table if exists temp2;
create table temp2
select
MOVESRunID,
yearID,
monthID,
dayID,
stateID,
countyID,
scc,
modelYearID,
sum(hours) as hours
from hours
group by MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID;

create index index1 on temp2 (MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID);


-- Join temp1 and temp2 and calculate the emission rate for the resulting output table
drop table if exists EmissionFactors_per_operatinghour_by_SCC_and_ModelYear;
create table EmissionFactors_per_operatinghour_by_SCC_and_ModelYear
select
b1.MOVESRunID,
b1.yearID,
b1.monthID,
b1.dayID,
b1.stateID,
b1.countyID,
b1.scc,
s.description as sccDescription,
s.fuelTypeID,
b1.modelYearID,
b1.pollutantID,
b1.processID,
b1.emissionQuant,
b2.hours,
IF(b2.hours != 0, b1.emissionQuant / b2.hours, NULL) as emissionRate,
'g/hr' as emissionRateUnits
from temp1 b1
inner join temp2 b2 USING (MOVESRunID,yearID,monthID,dayID,stateID,countyID,scc,modelYearID)
left join ##defaultdb##.nrscc s on (b1.scc=s.scc);

-- Drop intermediate tables and the primary indexes
drop table if exists hours;
drop table if exists temp1;
drop table if exists temp2;
drop table if exists units;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index1');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index1 does not exist.''', 'drop index index1 on movesoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index104');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index104 does not exist.''', 'drop index index104 on movesoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index10');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index10 does not exist.''', 'drop index index10 on movesactivityoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

-- Revert 0s to NULLs
UPDATE movesoutput SET stateID = NULL WHERE stateID = 0;
UPDATE movesoutput SET countyID = NULL WHERE countyID = 0;
UPDATE movesactivityoutput SET stateID = NULL WHERE stateID = 0;
UPDATE movesactivityoutput SET countyID = NULL WHERE countyID = 0;

-- drop the rest of the indexes
set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index_state');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index_state does not exist.''', 'drop index index_state on movesoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index_state');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index_state does not exist.''', 'drop index index_state on movesactivityoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesoutput' and index_name = 'index_county');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index_county does not exist.''', 'drop index index_county on movesoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;

set @exist := (select count(*) from information_schema.statistics where table_schema = DATABASE() and table_name = 'movesactivityoutput' and index_name = 'index_county');
set @sqlstmt := if( @exist = 0, 'select ''INFO: index_county does not exist.''', 'drop index index_county on movesactivityoutput');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
Loading

0 comments on commit eef9da4

Please sign in to comment.