{"id":1677,"date":"2014-01-13T20:04:46","date_gmt":"2014-01-14T01:04:46","guid":{"rendered":"http:\/\/lukemiller.org\/?p=1677"},"modified":"2015-11-30T16:00:40","modified_gmt":"2015-12-01T00:00:40","slug":"noaa-oisst-v2-high-resolution-daily-sea-surface-temperatures-with-r","status":"publish","type":"post","link":"https:\/\/lukemiller.org\/index.php\/2014\/01\/noaa-oisst-v2-high-resolution-daily-sea-surface-temperatures-with-r\/","title":{"rendered":"NOAA OISST v2 High Resolution daily sea surface temperatures with R"},"content":{"rendered":"<p><strong>Update, 2015-11-30<\/strong> <em>It appears that NOAA has gone through and upgraded all of the OISST files to the newer version of the NetCDF file format. As a result, the functions outlined in this post don&#8217;t work any longer. Instead, see the updated functions in my newer post, <a href=\"https:\/\/lukemiller.org\/index.php\/2014\/11\/extracting-noaa-sea-surface-temperatures-with-ncdf4\/\">https:\/\/lukemiller.org\/index.php\/2014\/11\/extracting-noaa-sea-surface-temperatures-with-ncdf4\/<\/a>. The concepts are the same as described here, but the newer functions use the ncdf4 package to access the newer NetCDF file format. <\/em><\/p>\n<p>The National Ocean and Atmospheric Administration generates freely-available world-wide estimates of mean daily sea surface temperature, and has been doing so back to 1981. The data are on a 0.25 x 0.25 degree grid, and provide an interpolated estimate of the sea surface temperature for each day of the year, based on a mix of satellite data and <em>in situ<\/em> sampling stations on ships and buoys. In <a href=\"https:\/\/lukemiller.org\/index.php\/2011\/03\/extracting-sea-surface-temperatures-from-noaas-oisstv2\/\">a post a while back<\/a> I outlined how to open and extract data from the lower-resolution weekly SST files that are provided on a 1&#215;1 degree grid. This post outlines functions to open and extract data from the higher resolution daily files using R and the <a href=\"http:\/\/cran.r-project.org\/web\/packages\/ncdf\/index.html\" target=\"_blank\">ncdf<\/a> package written by David Pierce, and the plotting function utilizes a function from the <a href=\"http:\/\/cran.r-project.org\/web\/packages\/oce\/index.html\" target=\"_blank\">fields<\/a> package written by Dan Kelley. <\/p>\n<p>The NOAA OISST v2 high resolution data are packaged into NetCDF files, and they come in two main versions, a yearly file that is around 740MB (the current year&#8217;s file is smaller), and 1-day files that are around 1MB each. The NetCDF files for these two versions are structured somewhat differently, so I&#8217;ve written two different functions to deal with the files. The functions can be loaded into your R session by downloading the script <a href=\"https:\/\/github.com\/millerlp\/Misc_R_scripts\/blob\/master\/NOAA_OISST_function.R\" target=\"_blank\">NOAA_OISST_function.R<\/a> from my GitHub repository, and calling<br \/>\n[code lang=&#8221;r&#8221;]<br \/>\nsource(&#8216;NOAA_OISST_function.R&#8217;)<br \/>\n[\/code]<br \/>\nto load the functions into memory. <\/p>\n<p>You&#8217;ll also need the ncdf and fields packages, which can be installed as follows:<br \/>\n[code lang=&#8221;r&#8221;]<br \/>\ninstall.packages(&quot;ncdf&quot;)<br \/>\ninstall.packages(&quot;fields&quot;)<br \/>\n[\/code]<\/p>\n<p>The homepage for the yearly datafiles is <a href=\"http:\/\/www.esrl.noaa.gov\/psd\/data\/gridded\/data.noaa.oisst.v2.highres.html\">http:\/\/www.esrl.noaa.gov\/psd\/data\/gridded\/data.noaa.oisst.v2.highres.html<\/a>. There you will find a description of the available data, and links to the FTP site <a href=\"ftp:\/\/ftp.cdc.noaa.gov\/Datasets\/noaa.oisst.v2.highres\/\" target=\"_blank\">ftp:\/\/ftp.cdc.noaa.gov\/Datasets\/noaa.oisst.v2.highres\/<\/a>. The files for mean daily SST are titled in the format <code>sst.day.mean.YEAR.v2.nc<\/code>. These files are uncompressed and ready to use. <\/p>\n<p>The homepage for the 1-day data files is <a href=\"http:\/\/www.ncdc.noaa.gov\/sst\/griddata.php\" target=\"_blank\">http:\/\/www.ncdc.noaa.gov\/sst\/griddata.php<\/a>, which leads you to the FTP site at <a href=\"ftp:\/\/eclipse.ncdc.noaa.gov\/pub\/OI-daily-v2\/NetCDF\/\" target=\"_blank\">ftp:\/\/eclipse.ncdc.noaa.gov\/pub\/OI-daily-v2\/NetCDF\/<\/a> where you&#8217;ll find sub-directories labeled AVHRR and AVHRR-ASMR. The AVHRR-ASMR files are no longer being produced, but you will find up to date files in the AVHRR subdirectories (these acronyms refer to the satellite instruments used in the data gathering). It&#8217;s important to note that the 1-day files come in a compressed .gz format, and you must first uncompress them with a separate software tool (like 7zip for Windows) before you try to use the function. <\/p>\n<p>For both functions to work, you also need one last file, the land-sea mask file. It can be directly downloaded from here: <a href=\"ftp:\/\/ftp.cdc.noaa.gov\/Datasets\/noaa.oisst.v2.highres\/lsmask.oisst.v2.nc\" target=\"_blank\">ftp:\/\/ftp.cdc.noaa.gov\/Datasets\/noaa.oisst.v2.highres\/lsmask.oisst.v2.nc<\/a>. <\/p>\n<p>The two main functions I&#8217;ve written are <code>extractOISST<\/code> and <code>extractOISST1day<\/code>. The former function only works with the yearly NetCDF files, and the latter function only works with the 1-day NetCDF files. <\/p>\n<p>Both functions take several arguments:<br \/>\n[code lang=&#8221;r&#8221;]<br \/>\ntest = extractOISST(fname, lsmask, lon1, lon2, lat1, lat2, date1, date2)<br \/>\ntest2 = extractOISST1day(fname, lsmask, lon1, lon2, lat1, lat2)<br \/>\n[\/code]<\/p>\n<p><code>fname<\/code> is the full path to the .nc data file.<br \/>\n<code>lsmask<\/code> is the full path to the land-sea mask file <code>lsmask.oisst.v2.nc<\/code><br \/>\n<code>lon1, lon2<\/code> are the two longitudes that bound the area you want to extract data for. They are given in degrees EAST of the prime meridian, so they range from 0.125 to 359.875. When you enter the arguments, <code>lon1<\/code> MUST be smaller (further west) than <code>lon2<\/code>. If you only want data for one longitude, you only need to enter a value for <code>lon1<\/code>.<br \/>\n<code>lat1, lat2<\/code> are the two latitudes that bound the area you want to extract data for. They are given in degrees NORTH, so that latitudes in the southern hemisphere all have negative values. The value for <code>lat1<\/code> must be less (further south) than the value of <code>lat2<\/code>. If you only want data for one latitude, you only need to enter a value for <code>lat1<\/code>.<br \/>\nSo for example, to get data near Lima, Peru, <code>lon1<\/code> would be 282.7, and <code>lat1<\/code> would be -12.1.<br \/>\nWhen using the yearly data file function, <code>date1, date2<\/code> should be provided as R Date objects or as character strings in the format <code>\"2013-12-29\"<\/code>. If only <code>date1<\/code> is provided, the output will only contain 1 day&#8217;s data, otherwise it will contain data for each day between the first and last dates provided (if they&#8217;re in the file). <\/p>\n<p>An example use:<br \/>\n[code lang=&#8221;r&#8221;]<br \/>\nfname = &quot;W:\/NOAA_OISST\/daily\/sst.day.mean.2013.v2.nc&quot;<br \/>\nlsmask = &quot;W:\/NOAA_OISST\/daily\/lsmask.oisst.v2.nc&quot;<br \/>\nsstout = extractOISST(fname,lsmask,lon1 = 230, lon2 = 250,<br \/>\n\t\tlat1 = 20, lat2 = 40,<br \/>\n\t\tdate1 = &quot;2013-01-01&quot;,date2 = &quot;2013-01-30&quot;)<br \/>\n[\/code]<\/p>\n<p>The output of the yearly file function is a 3-dimensional array, with the temperature data (degrees C) arranged so that latitudes are in rows, longitudes are in columns, and data from each grid cell on different days comprise the 3rd dimension. Missing data, including areas over land, are entered as <code>NA<\/code>. The 1st entry, <code>sstout[1,1,1]<\/code>, is the northernmost latitude and the westernmost longitude on the 1st date. Moving to the 2nd row of the array would put you at 0.25 degrees further south, and moving to the 2nd column of the array would put you 0.25 degrees further east. To see what latitude and longitude and date correspond to each location in the grid, you<br \/>\ncan extract the info from the <code>dimnames()<\/code> function. For example:<br \/>\n[code lang=&#8221;r&#8221;]<br \/>\nlats = as.numeric(dimnames(sstout)$Lat)<br \/>\nlongs = as.numeric(dimnames(sstout)$Long)<br \/>\ndates = as.Date(dimnames(sstout)$Date)<br \/>\n[\/code]<br \/>\nThe values that you get for latitude and longitude are the closest matches to your input values, and represent the center of each grid cell. <\/p>\n<p>I&#8217;ve also included a little function to plot the data, although there are certainly better plotting functions in packages like <code>fields<\/code>. I just provide this to check that you&#8217;re getting data from the region of the world you were hoping for. In the example here, I asked for data covering the west coast of North America including part of Baja California. The upper part of the Gulf of California should appear when the data are plotted.  <\/p>\n<p>[code lang=&#8221;r&#8221;]<br \/>\nplotOISST(sstout)<br \/>\n[\/code]<br \/>\n<figure id=\"attachment_1688\" aria-describedby=\"caption-attachment-1688\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2014\/01\/map11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2014\/01\/map11-300x300.png\" alt=\"A quick sanity check that the data are coming from the right part of the world.\" width=\"300\" height=\"300\" class=\"size-medium wp-image-1688\" srcset=\"https:\/\/lukemiller.org\/wp-content\/uploads\/2014\/01\/map11-300x300.png 300w, https:\/\/lukemiller.org\/wp-content\/uploads\/2014\/01\/map11-150x150.png 150w, https:\/\/lukemiller.org\/wp-content\/uploads\/2014\/01\/map11.png 672w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1688\" class=\"wp-caption-text\">A quick sanity check that the data are coming from the right part of the world.<\/figcaption><\/figure><\/p>\n<p>The 1-day function works in the same manner, but does not require any date arguments, because there is only 1 date in each file. The output from the 1-day function is a 2-dimensional matrix, with latitudes in rows and longitudes in columns (as above). The first entry [1,1], is the northernmost, westernmost grid cell in the range of lat\/long values you asked for. Moving down one row is 0.25 degrees further south, and moving to the right 1 column is 0.25 degrees further east. <\/p>\n<p>One issue I&#8217;ve wrestled with is how best to format the output arrays. When the data are first extracted inside the function, longitudes increase as you move down rows, and latitudes increase as you move right through columns, which might be counterintuitive to you. As a result, in the functions I flip the arrays around so that latitudes and longitudes are arrayed as you might expect, with northern values at the top, western values at the left. But this might not play nice with many plotting functions, so I&#8217;m open to suggestions about the &#8220;best&#8221; way to orient the output arrays. <\/p>\n<p>To cite your use of the data, NOAA suggests the following:<br \/>\n<em>&#8220;NOAA High Resolution SST data provided by the NOAA\/OAR\/ESRL PSD, Boulder, Colorado, USA, from their Web site at http:\/\/www.esrl.noaa.gov\/psd\/&#8221;<\/em><\/p>\n<p>or citing it as:<\/p>\n<p>Reynolds, Richard W., Thomas M. Smith, Chunying Liu, Dudley B. Chelton, Kenneth S. Casey, Michael G. Schlax, 2007: Daily High-Resolution-Blended Analyses for Sea Surface Temperature. J. Climate, 20, 5473-5496. Reynolds, Richard W., Thomas M. Smith, Chunying Liu, Dudley B. Chelton, Kenneth S. Casey, Michael G. Schlax, 2007: Daily High-Resolution-Blended Analyses for Sea Surface Temperature. J. Climate, 20, 5473-5496. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update, 2015-11-30 It appears that NOAA has gone through and upgraded all of the OISST files to the newer version of the NetCDF file format. As a result, the functions outlined in this post don&#8217;t work any longer. Instead, see the updated functions in my newer post, https:\/\/lukemiller.org\/index.php\/2014\/11\/extracting-noaa-sea-surface-temperatures-with-ncdf4\/. The concepts are the same as described [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[218],"tags":[75,64,77,7,73,177],"class_list":["post-1677","post","type-post","status-publish","format-standard","hentry","category-r-project","tag-netcdf","tag-noaa","tag-oisst","tag-r","tag-sea-surface-temperature","tag-sst"],"_links":{"self":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1677","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/comments?post=1677"}],"version-history":[{"count":13,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1677\/revisions"}],"predecessor-version":[{"id":2144,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/posts\/1677\/revisions\/2144"}],"wp:attachment":[{"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/media?parent=1677"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/categories?post=1677"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lukemiller.org\/index.php\/wp-json\/wp\/v2\/tags?post=1677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}