PROGRAM ANLYxyz c This program is a modified and improved version of the "analysis.for" c FORTRAN sample program included with the World Ocean Atlas. c c This program will read in any World Ocean Atlas 1-degree file, c "quarter degree" file, or the ~1994 Mixed-Layer Depth files. c These are all essentially data files of the 360x180 1-degree WOA grids c (and also the 5-degree and/or 1/4-degree files). c c This program writes the data out to a file in the form of c "latitude longitude value", with a user option of using either a c space (" ") or a comma (",") to separate the columns. c c c For problems, questions, or suggestions, please contact c ( OCLhelp@noaa.gov ). c c----------------------------------------------------------------------------- c VERSION-SPECIFICATIONS: c parameter (rVERSION = 5.2) c c----------------------------------------------------------------------------- c c c c Parameter descriptions c c . idim = longitude c . jdim = latitude c . kdim = standard depth levels c c 33 Standard level depths (in meters): c c 0,10,20,30,50,75,100,125,150,200,250,300,400,500,600,700,800,900,1000, c 1100,1200,1300,1400,1500,1750,2000,2500,3000,3500,4000,4500,5000,5500 c c NOTE: c c See the World Ocean Atlas 2005 documentation for variable depth c . range and units. c c Land, missing, or "no value" = -99.9999 for f8.4 read files c . = -100. for f8.0 read files c c------------------------------------------------------------------------------ parameter (idim=1440, jdim=720, kdim=33) parameter (iFIDi=11, iFIDo=66) character*1 yesno character*70 filename !- name of file to process character*4 form1 !- extension labelling data form1 /".000"/ real data(idim,jdim) !- array to hold the data 501 format(3x,"Contact/Questions: OCLhelp@noaa.gov",14x, * "--> VERSION ",f3.1," <--") write(6,'(80("-"))') write(6,*)' ' write(6,*) * ' AAA N N L Y Y ', * ' A A NN N L Y Y ', * ' AAAAA N N N L Y x x y y zzz ', * ' A A N NN L Y x y y z ', * ' A A N N LLLLL Y x x yy zzz ', * ' y ', * ' y ' write(6,*)' ' write(6,501)rVERSION write(6,'(80("-"))') write(6,*)' ' write(6,*)' ' write(6,*) * 'Please enter a WOA file name to process (e.g. t00an1):' do ilp = 1,70 filename(ilp:ilp)= " " enddo read(5,'(a70)')filename iGZIP = 0 do ilp = 1,70 if (filename(ilp:ilp) .ne. " ") ilast = ilp if (filename(ilp:ilp+2) .eq. ".gz") iGZIP = 1 if (filename(ilp:ilp+2) .eq. ".GZ") iGZIP = 1 enddo c WAS THIE FILE STILL COMPRESS (*.gz)? if (iGZIP .gt. 0) then write(6,*)' ' write(6,*)'------------------------------------------------' write(6,*)' ' write(6,*)' This data file still has a ".gz" extension,' write(6,*)' which means that it is still compressed.' write(6,*)' ' write(6,*)' Please uncompress the file to use this program.' write(6,*)' ' write(6,*)'------------------------------------------------' write(6,*)' ' stop endif write(6,*)' ' write(6,*)'-------------------------------------- ' write(6,*)' ' write(6,*)'Enter file type: ' write(6,*)' ' write(6,*)' 0: analyzed field (an1,_obj)' write(6,*) * ' 1: points within radius of influence field (gp1,_pts)' write(6,*)' 2: data distribution (dd1,dd5)' write(6,*)' 3: raw (unanalyzed) mean fields (mn1,mn5)' write(6,*)' 4: standard deviation field (sd1,sd5)' write(6,*)' 5: standard error of the mean field (se1,se5)' write(6,*)' 6: minus annual field (ma1)' write(6,*)' 7: observed minus annual field (oa1)' write(6,*)' 8: basin mask or landsea mask (msk)' write(6,*)' 9: * Mixed Layer Depth * files (f7.3 format)' write(6,*)' ' read(5,*)ifield c Fields 2, 3, 4 & 5 can be one-degree or five-degree files c Fields 1, 2 & 8 values are stored as f8.0, land=-100. (if applicable) c Fields 0,3,4,5,6, & 7 are stored as f8.4, land=-99.9999 c Field 9 is 1-degree, f7.3, one depth level (MLD files) if ( ifield .le. 5) then write(6,*)' ' write(6,*)'-------------------------------------- ' write(6,*)' ' write(6,*)' Pick a Grid size: ' write(6,*)' ' write(6,*)' (1) for one-degree gridded data ' if (ifield .ge. 2) then write(6,*) * ' (5) for five-degree gridded data ' else write(6,*) * ' (25) for quarter-degree gridded data' endif write(6,*)' ' read(5,*) ispace else ispace=1 endif c FIVE DEGREE or ONE-DEGREE or QUARTER-DEGREE if ( ispace .eq. 5 ) then idimx=idim/20 jdimx=jdim/20 space=5. elseif ( ispace .eq. 25 ) then idimx=idim jdimx=jdim space=0.25 else !- assume "ispace = 1" idimx=idim/4 jdimx=jdim/4 space=1. endif if ( ifield .eq. 1 .or. ifield .eq. 2 * .or. ifield .eq. 8 ) then itype=0 elseif (ifield .eq. 9) then itype=2 else itype=1 endif if (itype .ne. 2) then write(6,*)' ' write(6,*)'-------------------------------------- ' write(6,*)' ' write(6,*)' Enter the depth level (1-33) you wish to extract' write(6,*)' or enter -1 to extract all depth levels.' write(6,*)' ' read(5,*) kx else !- MLD (only one level) kx = 1 endif if (kx .gt. 0 .and. kx .lt. 34) then iONElev = kx else iONElev = -1 kx = 33 endif write(6,*)' ' write(6,*)'-------------------------------------- ' write(6,*)' ' write(6,*) * 'The output format from this program consists of three' write(6,*) * ' fixed-width, ten-character-wide columns. Do you ' write(6,*) * ' want to separate the columns with a comma (",")?' write(6,*)' ' write(6,*) * '---> Enter "y" for this format (comma-separated):' write(6,*)' ' c . 123456789012345678901234567890, write(6,*)' latitude, longtude, WOA_value,' write(6,*)' 35.5, -120.5, 134.345,' write(6,*)' 35.5, -120.5, 134.345,' write(6,*)' 35.5, -120.5, 134.345,' write(6,*)' ' write(6,*) * '---> Enter "n" for this format (space-separated):' write(6,*)' ' c . 123456789012345678901234567890, write(6,*)' latitude longtude WOA_value ' write(6,*)' 35.5 -120.5 134.345 ' write(6,*)' 35.5 -120.5 134.345 ' write(6,*)' 35.5 -120.5 134.345 ' write(6,*)' ' iCOMMA = 0 read(5,'(a1)')yesno if (yesno .eq. "y" .or. yesno .eq. "Y") iCOMMA = 1 c Read in data open(iFIDi,file=filename,status='old',form='formatted') c NOTE: IF YOU ARE UNABLE TO OPEN CD-ROM DATA, c . INCLUDE 'readonly' IN THE ABOVE OPEN STATEMENT write(6,'(/)') write(6,*)'Reading in data file [',filename(1:ilast),'] ...' 100 format(10f8.4) 101 format(10f7.3) 200 format(10f8.0) do 15 k=1,kx !- For each depth loop if (itype .eq. 1)then read(iFIDi,100,end=15) ((data(i,j),i=1,idimx),j=1,jdimx) elseif (itype .eq. 2)then read(iFIDi,101,end=15) ((data(i,j),i=1,idimx),j=1,jdimx) else read(iFIDi,200,end=15) ((data(i,j),i=1,idimx),j=1,jdimx) endif c . Build the file extension (based on depth = .001, .002, .003, ...) if (k .lt. 10) then write(form1(4:4),'(i1)')k else write(form1(3:4),'(i2)')k endif if ( * (iONElev .gt. 0 .and. k .eq. iONElev) .or. !- only one level * (iONElev .lt. 0) !- all levels * ) then write(6,*)' ' write(6,*)'Writing data to file "',filename(1:ilast), * form1(1:4),'" ...' open(iFIDo,file=filename(1:ilast)//form1(1:4), * status='unknown') if (iCOMMA .gt. 0) then write(iFIDo,'(a31)')' LATITUDE, LONGTUDE, WOA_VALUE,' else write(iFIDo,'(a30)')' LATITUDE LONGTUDE WOA_VALUE' endif c rCENTER centers lat/lon point in center of the grid (space) c 1-deg : space / 2. = 1. / 2. = 0.5 c 5-deg : space / 2. = 5. / 2. = 2.5 c 1/4-deg: space / 2. = 0.25 / 2. = 0.125 rCENTER = space / 2. c iHALF is the grid halfway point c 1-deg : 180 / 1 = 180 (360 total) c 5-deg : 180 / 5 = 36 (72 total) c 1/4-deg: 180 / 0.25 = 720 (1440 total) iHALF = int ( 180. / space ) c do ilpx = 1,idimx !- LONGITUDE LOOP (0 to 180 to -180 to -0) do ilpy = 1,jdimx !- LATITUDE LOOP (-90 + 90) c LATITUDE: Gridding goes 1-180 (first 90 = South, later 90 = North) rLAT = (float(ilpy) * space) - (90. + rCENTER) c LON (1-360): STARTS at Greenwich (1-180 = E, 181-360 = W). if (ilpx .le. iHALF) then rLON = ( float(ilpx) * space ) - rCENTER else rLON = -1 * (360+rCENTER - (float(ilpx) * space)) endif c . Screen Formatting Cleanup (-99.9999 --> -99.9990) if (data(ilpx,ilpy) .lt. -99.) * data(ilpx,ilpy) = -99.9990 if (iCOMMA .gt. 0) then if ( ispace .ne. 25 ) then write(iFIDo,'(f9.1,",",f9.1,",",f9.3,",")')rLAT,rLON, * data(ilpx,ilpy) else write(iFIDo,'(f9.3,",",f9.3,",",f9.3,",")')rLAT,rLON, * data(ilpx,ilpy) endif else if ( ispace .ne. 25 ) then write(iFIDo,'(f9.1," ",f9.1," ",f9.3)')rLAT,rLON, * data(ilpx,ilpy) else write(iFIDo,'(f9.3," ",f9.3," ",f9.3)')rLAT,rLON, * data(ilpx,ilpy) endif endif enddo enddo endif 15 continue !- for each depth loop close(2) stop end c--------------------------------------------------------------------- c--------------------------------------------------------------------- c--------------------------------------------------------------------- SUBROUTINE GRID(rlat,rlon,lat,lon,space) C CALCULATES GRID NUMBERS FROM INPUT LATITUDE AND LONGITUDE c************************************************************ c c Passed Variables: c c rlat,rlon - actual latitude and longitude c lat,lon - calculated grid box numbers c space - grid spacing (1.0 is a 1 degree latitude c by one degree longitude grid box) c c*********************************************************** c********************************************************** c c Calculate latitude grid number: c c 1. add 90 to actual latitude, since actual latitudes c run from -90 to 90, and grid numbers run from c 1 to 180. c c 2. Divide by spacing. The additional 1E-6 is to c insure that any latitude right on the line between c two grid boxes will be included in the smaller c number grid box. c c 3. Add one, since a grid number for actual latitude c -90 would be 0 otherwise. c c********************************************************** lat=int((rlat+90.)/(space+1.E-7))+1 c********************************************************** c c Calculate longitude grid number c c 1. Longitude grid numbers run from 1 to 360 while c actual longitudes run from -180 to 180. The difference c from latitude is that negative values are converted c to the larger end of longitude grid numbers. c They are converted to the values 181 to 360. c c********************************************************** if (rlon.le.0) then lon=int((rlon+360.)/(space+1.E-7))+1 else lon=int(rlon/(space+1.E-7))+1 endif return end