@@ -139,23 +139,27 @@ script:
139139 if (size_2_5 >= 18) {
140140
141141 float pm25 = sum_2_5 / (float)size_2_5;
142- if (pm25 < 12.0) {
143- aqi_2_5 = (50.0 - 0.0) / (12.0 - 0.0) * (pm25 - 0.0) + 0.0;
142+ pm25 = static_cast<int>(pm25 * 10) / 10.0; // pm25 is truncated to the nearest 0.1
143+
144+ // https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
145+ // 2024 EPA breakpoints: https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
146+ if (pm25 < 9.0) {
147+ aqi_2_5 = (50.0 - 0.0) / (9.0 - 0.0) * (pm25 - 0.0) + 0.0;
144148 } else if (pm25 < 35.4) {
145- aqi_2_5 = (100.0 - 51.0) / (35.4 - 12 .1) * (pm25 - 12 .1) + 51.0;
149+ aqi_2_5 = (100.0 - 51.0) / (35.4 - 9 .1) * (pm25 - 9 .1) + 51.0;
146150 } else if (pm25 < 55.4) {
147151 aqi_2_5 = (150.0 - 101.0) / (55.4 - 35.5) * (pm25 - 35.5) + 101.0;
148- } else if (pm25 < 150.4) {
149- aqi_2_5 = (200.0 - 151.0) / (150.4 - 55.5) * (pm25 - 55.5) + 151.0;
150- } else if (pm25 < 250.4) {
151- aqi_2_5 = (300.0 - 201.0) / (250.4 - 150.5) * (pm25 - 150.5) + 201.0;
152- } else if (pm25 < 350.4) {
153- aqi_2_5 = (400.0 - 301.0) / (350.4 - 250.5) * (pm25 - 250.5) + 301.0;
154- } else if (pm25 < 500.4) {
155- aqi_2_5 = (500.0 - 401.0) / (500.4 - 350.5) * (pm25 - 350.5) + 401.0;
152+ } else if (pm25 < 125.4) {
153+ aqi_2_5 = (200.0 - 151.0) / (125.4 - 55.5) * (pm25 - 55.5) + 151.0;
154+ } else if (pm25 < 225.4) {
155+ aqi_2_5 = (300.0 - 201.0) / (225.4 - 125.5) * (pm25 - 125.5) + 201.0;
156+ } else if (pm25 < 500.0) {
157+ aqi_2_5 = (500.0 - 301.0) / (500.0 - 225.5) * (pm25 - 225.5) + 301.0;
156158 } else {
157- aqi_2_5 = 500; // everything higher is just counted as 500
159+ // everything higher is just counted as 500
160+ aqi_2_5 = 500;
158161 }
162+
159163 }
160164
161165 int size_10_0 = 0;
@@ -172,6 +176,10 @@ script:
172176 if (size_10_0 >= 18) {
173177
174178 float pm10 = sum_10_0 / (float)size_10_0;
179+ pm10 = static_cast<int>(pm10); // pm10 is truncated to the nearest whole number
180+
181+ // https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
182+ // 2024 EPA breakpoints: https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
175183 if (pm10 < 54.0) {
176184 aqi_10_0 = (50.0 - 0.0) / (54.0 - 0.0) * (pm10 - 0.0) + 0.0;
177185 } else if (pm10 < 154.0) {
@@ -182,12 +190,11 @@ script:
182190 aqi_10_0 = (200.0 - 151.0) / (354.0 - 255.0) * (pm10 - 255.0) + 151.0;
183191 } else if (pm10 < 424.0) {
184192 aqi_10_0 = (300.0 - 201.0) / (424.0 - 355.0) * (pm10 - 355.0) + 201.0;
185- } else if (pm10 < 504.0) {
186- aqi_10_0 = (400.0 - 301.0) / (504.0 - 425.0) * (pm10 - 425.0) + 301.0;
187- } else if (pm10 < 604) {
188- aqi_10_0 = (500.0 - 401.0) / (604.0 - 505.0) * (pm10 - 505.0) + 401.0;
193+ } else if (pm10 < 500.0) {
194+ aqi_10_0 = (500.0 - 301.0) / (500.0 - 425.0) * (pm10 - 425.0) + 301.0;
189195 } else {
190- aqi_10_0 = 500; // everything higher is just counted as 500
196+ // everything higher is just counted as 500
197+ aqi_10_0 = 500.0;
191198 }
192199 }
193200
@@ -253,20 +260,19 @@ script:
253260 pm25 = static_cast<int>(pm25 * 10) / 10.0; // pm25 is truncated to the nearest 0.1
254261
255262 // https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
256- if (pm25 < 12.0) {
257- nowcast_2_5 = (50.0 - 0.0) / (12.0 - 0.0) * (pm25 - 0.0) + 0.0;
263+ // 2024 EPA breakpoints: https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
264+ if (pm25 < 9.0) {
265+ nowcast_2_5 = (50.0 - 0.0) / (9.0 - 0.0) * (pm25 - 0.0) + 0.0;
258266 } else if (pm25 < 35.4) {
259- nowcast_2_5 = (100.0 - 51.0) / (35.4 - 12 .1) * (pm25 - 12 .1) + 51.0;
267+ nowcast_2_5 = (100.0 - 51.0) / (35.4 - 9 .1) * (pm25 - 9 .1) + 51.0;
260268 } else if (pm25 < 55.4) {
261269 nowcast_2_5 = (150.0 - 101.0) / (55.4 - 35.5) * (pm25 - 35.5) + 101.0;
262- } else if (pm25 < 150.4) {
263- nowcast_2_5 = (200.0 - 151.0) / (150.4 - 55.5) * (pm25 - 55.5) + 151.0;
264- } else if (pm25 < 250.4) {
265- nowcast_2_5 = (300.0 - 201.0) / (250.4 - 150.5) * (pm25 - 150.5) + 201.0;
266- } else if (pm25 < 350.4) {
267- nowcast_2_5 = (400.0 - 301.0) / (350.4 - 250.5) * (pm25 - 250.5) + 301.0;
268- } else if (pm25 < 500.4) {
269- nowcast_2_5 = (500.0 - 401.0) / (500.4 - 350.5) * (pm25 - 350.5) + 401.0;
270+ } else if (pm25 < 125.4) {
271+ nowcast_2_5 = (200.0 - 151.0) / (125.4 - 55.5) * (pm25 - 55.5) + 151.0;
272+ } else if (pm25 < 225.4) {
273+ nowcast_2_5 = (300.0 - 201.0) / (225.4 - 125.5) * (pm25 - 125.5) + 201.0;
274+ } else if (pm25 < 500.0) {
275+ nowcast_2_5 = (500.0 - 301.0) / (500.0 - 225.5) * (pm25 - 225.5) + 301.0;
270276 } else {
271277 // everything higher is just counted as 500
272278 nowcast_2_5 = 500;
@@ -313,10 +319,12 @@ script:
313319 weight_sum += weight_pow;
314320 }
315321 }
322+
316323 float pm10 = pm_sum / weight_sum;
317324 pm10 = static_cast<int>(pm10); // pm10 is truncated to the nearest whole number
318325
319326 // https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
327+ // 2024 EPA breakpoints: https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
320328 if (pm10 < 54.0) {
321329 nowcast_10_0 = (50.0 - 0.0) / (54.0 - 0.0) * (pm10 - 0.0) + 0.0;
322330 } else if (pm10 < 154.0) {
@@ -327,10 +335,8 @@ script:
327335 nowcast_10_0 = (200.0 - 151.0) / (354.0 - 255.0) * (pm10 - 255.0) + 151.0;
328336 } else if (pm10 < 424.0) {
329337 nowcast_10_0 = (300.0 - 201.0) / (424.0 - 355.0) * (pm10 - 355.0) + 201.0;
330- } else if (pm10 < 504.0) {
331- nowcast_10_0 = (400.0 - 301.0) / (504.0 - 425.0) * (pm10 - 425.0) + 301.0;
332- } else if (pm10 < 604) {
333- nowcast_10_0 = (500.0 - 401.0) / (604.0 - 505.0) * (pm10 - 505.0) + 401.0;
338+ } else if (pm10 < 500.0) {
339+ nowcast_10_0 = (500.0 - 301.0) / (500.0 - 425.0) * (pm10 - 425.0) + 301.0;
334340 } else {
335341 // everything higher is just counted as 500
336342 nowcast_10_0 = 500.0;
0 commit comments