In This Series:
Preamble (download .pdf) Our Intent (download .pdf) How Can We Do It? (download .pdf) What Do We Expect From Our Selection Criteria? (download .pdf) Will We Find Any Significant Trend? (download .pdf) What's Under The Hood? (download .pdf) Which Stations Are We Sampling? (download .pdf)
Click the image above to order the Junkman's: Junk Science Judo: Self-defense Against Health Scares and Scams.
Quick Links
Top Ten 'Most Embarrassing Moments' of 2004!
Junk science? Junkman? Short Course Feedback E-mail List Archives & Links Reading List Fifth Anniversary
Contact JunkScience.com: Steve Milloy (Publisher) or Barry Hearn (Editor)
CSRwatch.com / SRIwatch.com
Support JunkScience.com Shop Amazon.com
Consumer Distorts DDT FAQ Malaria Clock Dioxin in Ben & Jerry's Capitol Radiation Our Swollen Future Ozone 'Depletion'
GreenSpin NumberWatch Living Issues Canada Free Press
|
What’s under the hood?
What, exactly, are we doing to derive a temperature?
Well, as we said, we’re using PEAR Services_Weather to request and parse information files hosted by NOAA, our script then sums the returned temperature data and divides the result by the number of returns received, inserting the temperature, number of reporting stations and time of execution completion into the database. During execution, any failure to gather the expected temperature results in the station identifier being inserted into a ‘failed’ table (so we can check for consistent shirkers and trace back if we need to in case of sudden anomalous temperature reports). Here’s the script executed each hour: Warning! Long, unformatted script listings follow!
<?php
// include class file include('Services/Weather.php');
// instantiate object for METAR decoding $metar = &Services_Weather::service("METAR", array("debug" => 0)); if (Services_Weather::isError($metar)) { die("Error: ".$metar->getMessage()."\n"); }
//Assign variable name to connection $Host = "localhost"; $User = ""; $Password = ""; $DBName = "ServicesWeatherDB"; $DB2Name = "GlobalMean"; $unitsFormat = "metric"; // The format the units are displayed in - // metric, standard or some customization. $i = 0; $j = 0; $CurrTemp = 0; $TotalTemp = 0; $MeanTemp = 0; $TargIcao = ""; $TargName = "";
//Connect to MySQL database
server using $dbcnx as connection name $dbcnx = mysql_connect ($Host, $User, $Password);
//Fail gracefully if required if (!$dbcnx) { echo( "Unable to connect to the database server at this time.\n\n" ); exit(); }
$result = mysql_query("SELECT * FROM $DB2Name.MetarUse");
if (!$result) { echo("Error performing query: " . mysql_error() . "\n\n"); exit(); }
$Terminated = date("l H:i:s"); print("Run began: ".$Terminated." GMT\n\n");
while ( $Row = mysql_fetch_array($result) ) { $TargIcao = $Row[0]; $TargName = $Row[1];
$j++; $data = $metar->getWeather($TargIcao, $unitsFormat);
if (Services_Weather::isError($data)) { print ("Error: ".$data->getMessage()."\n\n"); $Error = mysql_query("INSERT INTO $DB2Name.failed VALUES ('$TargIcao')"); } else { $i++; $CurrTemp = $data['temperature']; $TotalTemp += $CurrTemp; $MeanTemp = ($TotalTemp / $i);
print($TargIcao.": ".$TargName." = ".$CurrTemp." Earth's Mean Temp: ".number_format($MeanTemp, 2)."\n"); }
}
print("Number of stations attempted: ".$j."\nNumber of stations reporting: ".$i. "\n\nEstimated mean temperature: ".number_format($MeanTemp, 2)."\n\n"); $Terminated = date("Y-m-d H:i:s"); print("Run ended: ".$Terminated." GMT\n\n");
$result
= @mysql_query("INSERT INTO $DB2Name.MeanTemp VALUES ('$MeanTemp', '$i', '$Terminated')");
if (!$result) { echo("\n\nError performing query: " . mysql_error() . "\n\n"); exit(); } //Close Database connection - just to be tidy mysql_close ($dbcnx); ?> How did we decide which stations to sample? Firstly, we needed to know which stations were available so we simply went through the list of METAR airports and requested a temperature – where successful the identifier and name went into our ‘validated’ table, like this:
<?php
// include class file include('Services/Weather.php');
// instantiate object for METAR decoding $metar = &Services_Weather::service("METAR", array("debug" => 0)); if (Services_Weather::isError($metar)) { die("Error: ".$metar->getMessage()."\n"); }
//Assign variable name to connection $Host = "localhost"; $User = ""; $Password = ""; $DBName = "servicesweatherdb"; $DB2Name = "alternate";
$unitsFormat = "metric"; // The format the units are displayed in - // metric, standard or some customization. $TargIcao = ""; $TargName = "";
//Connect to MySQL database server using $dbcnx as connection name $dbcnx = mysql_connect ($Host, $User, $Password);
//Fail gracefully if required if (!$dbcnx) { echo(
"<p>Unable to connect to the database server at this time.</p>" ); exit(); } print("<p>Connected...</p>");
print("<p>Commencing data extract...</p>");
$Result = mysql_query("SELECT icao, name FROM $DBName.metarairports");
if (!$Result) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); }
print("<p>Beginning validation sequence...</p>");
while ($Row = mysql_fetch_array($Result)) { $TargIcao = $Row[0]; $TargName = $Row[1];
$data = $metar->getWeather($TargIcao, $unitsFormat);
if (Services_Weather::isError($data)) { print("<b>REJECTED:</b> ".$TargName."<br>"); } else { $CurrTemp = $data['temperature']; if ($CurrTemp){ $FoundOne = "INSERT INTO $DBName.validated VALUES ('$TargIcao', '$TargName')"; $Success = mysql_query($FoundOne); if (!$Success) { echo("<p>Insertion failed: " . mysql_error() . "</p>"); exit(); } print("<b>ADDED:</b> ".$TargName."<br>"); } } }
//free RAM mysql_free_result($Result);
//Close Database connection - just to be tidy mysql_close ($dbcnx);
?>
As previously mentioned we fudged a little to increase our Frigid Zone sampling and arbitrarily inserted islands, oil platforms and poorly
represented areas. Ideally, we wanted roughly 18% Frigid Zone although we are somewhat short on available candidates, something just short of 50% for our Temperate Regions and leaving a little under 1/3rd reporting from the Tropics. We calculated how many stations we had in each zone from our arbitrarily ‘protected’ groups, how many candidates were available in each zone from our validated set and then scripted a little harvesting routine that would collect every nth station for our table of locations to sample hourly. We plotted the results to our global map graphic while we tweaked the routine to reduce obvious clustering and omissions and ended up with 1,003 candidates, 158 Northern Frigid, 404 Northern Temperate, 321 Tropical, 116 Southern Temperate and our 4 lonely southern Frigid. This gives us ~16% Frigid, ~52% Temperate and ~32% Tropical. Given our constraints in the Polar Regions and Southern Hemisphere this is not too bad.
For those with a burning desire to see exactly what was done, here’s the script:
<?php
function isProtected($Lat, $Long){ if (($Lat >= 64) || ($Lat <= -45)){ return(true); // collect our polar and southern high latitude candidates } elseif ((($Lat < 64) && ($Lat >= 58)) && ($Long <= -165)) { return(true); // collect Chukchi Peninsula } elseif ((($Lat < 58) && ($Lat >= 10)) && ($Long <= -140)) { return(true); // collect Aleutian & Hawai'ian Islands } elseif ((($Lat < 8)
&& ($Lat > -45)) && ($Long <= -82)) { return(true); // collect Polynesian, Easter & Galapagos Islands } elseif ((($Lat < 64) && ($Lat >= 60)) && (($Long > -100) && ($Long <= 0))) { return(true); // collect Iceland, Southern Greenland and Norhtern Hudson } elseif ((($Lat < 60) && ($Lat > 55)) && (($Long > 0) && ($Long <= 5))) { return(true); // collect North Sea Rigs } elseif ((($Lat < 40) && ($Lat > 30)) && (($Long > -70) && ($Long <= -60))) { return(true); // collect Bermuda } elseif ((($Lat < 29) && ($Lat > 26)) && (($Long > -107) && ($Long < -103))) { return(true); // collect Chihuahua } elseif ((($Lat < 50) && ($Lat > 30)) && (($Long > -40) && ($Long <= -10))) { return(true); // collect Azores, Madeira } elseif ((($Lat < 8) && ($Lat > 0)) && (($Long > 15) && ($Long <= 25))) { return(true); // collect Central Africa } elseif ((($Lat < 9) && ($Lat > 0)) && (($Long > -70) && ($Long <= -40))) { return(true); // collect Venezuela, Nthrn Amazon } elseif ((($Lat < 0) && ($Lat > -5)) && (($Long > -75) && ($Long <= -50))) { return(true); // collect Wstrn Amazon } elseif ((($Lat < -8) && ($Lat > -13)) && (($Long >
-61) && ($Long <= -50))) { return(true); // collect Ctrl Amazon } elseif ((($Lat < 0) && ($Lat > -10)) && (($Long > -30) && ($Long <= 0))) { return(true); // collect Ascension Islands } elseif ((($Lat < 30) && ($Lat > 10)) && (($Long > -40) && ($Long <= 40))) { return(true); // collect Canary Islands, Sahara, Sahel } elseif ((($Lat < -8) && ($Lat > -35)) && (($Long < 20) && ($Long >= 10))) { return(true); // collect Angola, Skelleton Coast } elseif ((($Lat < 0) && ($Lat > -10)) && (($Long > 50) && ($Long <= 60))) { return(true); // collect Seychelles } elseif ((($Lat < -10) && ($Lat > -30)) && (($Long > 40) && ($Long <= 60))) { return(true); // collect Comoros, Madagascar, Mauritius } elseif ((($Lat < 23.3) && ($Lat > 10)) && (($Long > 50) && ($Long <= 60))) { return(true); // collect Socotra, Muscat } elseif ((($Lat < 0) && ($Lat > -45)) && (($Long > 40) && ($Long <= 180))) { return(true); // collect Indian Ocean, Oceania } elseif ((($Lat < 50) && ($Lat > 0)) && (($Long > 60) && ($Long <= 100))) { return(true); // collect Maldive, India, Central Asia } elseif ((($Lat < 50) && ($Lat > 10)) && (($Long > 100) &&
($Long <= 120))) { return(true); // collect China, SE Asia } elseif ((($Lat < 50) && ($Lat > 39)) && (($Long > 130) && ($Long <= 140))) { return(true); // collect Manchuria } elseif ((($Lat < 64) && ($Lat >= 50)) && (($Long > 30) && ($Long <= 180))) { return(true); // collect Russia/Siberia } elseif ((($Lat < 30) && ($Lat > 0)) && ($Long > 140)) { return(true); // collect Micronesia, Melanesia } elseif ((($Lat < 20) && ($Lat > 0)) && (($Long > 130) && ($Long <= 140))) { return(true); // collect Palau } else { return(false); } }
//Assign variable name to connection $Host = "localhost"; $User = ""; $Password = ""; $DBName = "servicesweatherdb"; $DB2Name = "GlobalMean";
//counter variables to control regional sampling $NHLE = 0; $NHLW = 0; $NMLE = 0; $NMLW = 0; $NTE = 0; $NTW = 0; $STE = 0; $STW = 0; $SMLE = 0; $SMLW = 0;
//Connect to MySQL database server using $dbcnx as connection name $dbcnx = mysql_connect ($Host, $User, $Password);
//Fail gracefully if required if (!$dbcnx) { echo( "<p>Unable to connect to the database server at this time.</p>" ); exit(); }
$Result = mysql_query("SELECT icao, name FROM $DBName.validated");
if (!$Result) { echo("<p>Error
performing query: " . mysql_error() . "</p>"); exit(); }
while ( $Row = mysql_fetch_array($Result) ) { $TargIcao = $Row[0]; $TargName = $Row[1];
$GetLat = mysql_query("SELECT latitude, longitude FROM $DBName.metarairports WHERE icao LIKE '$TargIcao'"); $NewLat = mysql_fetch_array ($GetLat); $Lat = $NewLat[0]; $Long = $NewLat[1];
if (isProtected($Lat, $Long)){ // gather isolated and underrepresented regions $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif (($Lat >= 45) && ($Lat < 64)){ if ($Long >= -20){ $NHLE++; if ($NHLE == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NHLE == 14){ $NHLE = 0; } } else { $NHLW++; if ($NHLW == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NHLW == 10){ $NHLW = 0; } } } elseif (($Lat >= 23.27) && ($Lat < 45)){ if ($Long >= -20){ $NMLE++; if
($NMLE == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NMLE == 10){ $NMLE = 0; } } else { $NMLW++; if ($NMLW == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NMLW == 21){ $NMLW = 0; } } } elseif (($Lat >= 0) && ($Lat < 23.27)){ if ($Long >= -20){ $NTE++; if ($NTE == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NTE == 5){ $NTE = 0; } } else { $NTW++; if (($NTW == 1) || ($NTW == 5)){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($NTW == 9){ $NTW = 0; } } } elseif (($Lat >= -23.27) && ($Lat < 0)){ if ($Long >= -20){ $STE++; if ($STE == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse
VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($STE == 5){ $STE = 0; } } else { $STW++; if ($STW == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($STW == 3){ $STW = 0; } } } elseif (($Lat >= -45) && ($Lat < -23.27)){ if ($Long >= -20){ $SMLE++; if (($SMLE == 1) || ($SMLE == 3) || ($SMLE == 5)){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } if ($SMLE == 5){ $SMLE = 0; } } } else { $SMLW++; if ($SMLW == 1){ $DoIt = mysql_query("INSERT INTO $DB2Name.metaruse VALUES ('$TargIcao', '$TargName')"); if (!$DoIt) { echo("<p>Error performing query: " . mysql_error() . "</p>"); exit(); } } elseif ($SMLW == 2){ $SMLW = 0; } } } }
mysql_free_result($Result);
//Close Database connection - just to be tidy mysql_close ($dbcnx);
?>
Preamble (.pdf) <> Our Intent (.pdf) <> How Can We Do It? (.pdf) <> What Do We Expect From Our Selection Criteria? (.pdf) <> Will We Find Any Significant Trend? (.pdf) <> What's Under The Hood? (.pdf) <> Which Stations Are We Sampling? (.pdf)
JunkScience.com
|