OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
modis_albedo.f90
Go to the documentation of this file.
2 
3 ! HI
4 !****************************************************************************
5  ! !F90
6  !
7  ! !Description:
8  ! This module contains the subroutines used to provide albedo and ecosystem
9  ! maps for processing a MOD06 granule.
10  ! There is only one callable routine, getAlbedoEco, which returns albedo
11  ! values and IGBP ecosystem classification for each pixel of the
12  ! MOD06 granule,
13  ! and for the wavelengths specified. Also returned are values of
14  ! snow albedos
15  ! by ecosystem class for the wavelengths specified.
16  !
17  ! !Callable routines:
18  ! getAlbedoEco()
19  !
20  ! !Revision History:
21  !
22  ! Revision 1.0 2003/12/18 12:43:43 EGMoody
23  ! Initial revision.
24  !
25  ! !Team-Unique Header:
26  ! Cloud Retrieval Group, NASA Goddard Space Flight Center
27  !
28  ! !References and Credits:
29  ! Written by
30  ! Eric Moody
31  ! Climate and Radiation Branch, Code 913
32  ! NASA/GSFC
33  ! Greenbelt MD 20771
34  ! Eric.Moody@gsfc.nasa.gov
35  !
36  ! !Design Notes:
37  !
38  ! !END
39  !*****************************************************************************
40 
41 
42  !Dependencies:
43  use generalauxtype
45  use core_arrays, only : cloudmask
48  implicit none
49 
50  private
51 
53 
54  integer, parameter :: MAX_VAR_DIMS = 10
55  integer :: lat_start, lat_end
56 
57  !local variables:
58  !counters:
59  integer (kind = integer_fourbyte) :: i,j,k,l,m,n
60 
61  !HDF variables:
62  integer (kind = integer_fourbyte) :: hdfstatus
63  integer (kind = integer_fourbyte ), &
64  dimension(MAX_VAR_DIMS) :: hdfstart, hdfstride, hdfedge
65  integer (kind = integer_fourbyte) :: sds_id, sds_index
66 
67  integer (kind = integer_fourbyte), parameter :: numsnowalbstatwaves = 10
68  integer (kind = integer_fourbyte), parameter :: numecosystems = 18
69  integer (kind = integer_fourbyte), parameter :: numsnowtypes = 2
70 
71  real :: snowalbedostats (1:numsnowalbstatwaves, 0:numecosystems-1, &
72  1:numsnowtypes)
73  real :: processsnowalbstats (1:set_albedo_bands, 0:numecosystems-1, &
74  1:numsnowtypes)
75 
76  integer (kind = integer_fourbyte), parameter :: numseaicealbwaves = 8
77  real (kind = single), dimension(NumSeaIceAlbWaves) :: meltseaicealbedos, &
78  dryseaicealbedos
79  real (kind = single), dimension(set_albedo_bands) :: &
80  processmeltseaicealbedos, processdryseaicealbedos, transitionalbedo, &
81  slope, intercept
82 
83  real (kind = single), parameter :: percentageofdry = 0.800d0
84  real :: wavelength(10)
85 
86 contains
87 
88 
89  subroutine init_snow_stats(SnowAlbedoFN, WavelengthText)
90 
91  character (len = *), intent(in ) :: snowalbedofn
92  character (len = *), dimension(:), intent(in ) :: wavelengthtext
93 
94  real (kind = single), dimension(NumSnowAlbStatWaves) :: possstatwavelengths
95  real (kind = single), dimension(NumSeaIceAlbWaves) :: possseaicewavelengths
96 
97  integer :: errorlevel, i, numalbwavesprocess
98  logical :: foundwave
99 
100  numalbwavesprocess = set_albedo_bands
101 
102  !*****************************************************************************
103  ! Read in the snow albedo statistics from the corresponding file:
104  !*****************************************************************************
105  call readsnowalbstats ( snowalbedofn, numsnowtypes, numsnowalbstatwaves, &
106  numecosystems, snowalbedostats, errorlevel )
107 
108  !*****************************************************************************
109  ! For each wavelength to be processed, store the albedo snow statistic in the
110  ! cooresponding index in a temp array. Note that 8-10 are broad band, and
111  ! not included.
112  !*****************************************************************************
113  !Load in the order of the statistical wavelengths from the file:
114  possstatwavelengths(1) = 0.470000
115  possstatwavelengths(2) = 0.555000
116  possstatwavelengths(3) = 0.659000
117  possstatwavelengths(4) = 0.858000
118  possstatwavelengths(5) = 1.240000
119  possstatwavelengths(6) = 1.640000
120  possstatwavelengths(7) = 2.130000
121  possstatwavelengths(8) = 0.0
122  possstatwavelengths(9) = 0.0
123  possstatwavelengths(10) = 0.0
124 
125  !Loop over the wavelengths to be processed, storing the cooresponding
126  ! data from the complete snowAlbedoStats array. Do not process 3.7,
127  ! the last index as there are no cooresponding values, instead compute
128  ! from the 2.1µm at the end:
129 
130  do i = 1, numalbwavesprocess
131  read( wavelengthtext(i), * ) wavelength(i)
132  end do
133 
134  processsnowalbstats= 0.
135  do i = 1, numalbwavesprocess-1
136  foundwave = .false.
137 
138  do j = 1, numsnowalbstatwaves-3
139  if ( mod(wavelength(i),possstatwavelengths(j)) < 0.05 ) then
140  processsnowalbstats(i,:,:) = snowalbedostats(j,:,:)
141  foundwave = .true.
142  goto 100
143  end if
144  end do
145  100 continue
146  if (.not. foundwave) then
147  return
148  end if
149  end do
150 
151  !compute the 3.7µm (assume 6 = 3.6 and 5 = 2.1µm):
152  processsnowalbstats(6,:,:) = processsnowalbstats(5,:,:) * 0.5000
153 
154  !*****************************************************************************
155  ! For each wavelength to be processed, store the albedo sea ica albedo in the
156  ! cooresponding index in a temp array.
157  !*****************************************************************************
158  !Load in the order of the statistical wavelengths from the file:
159  possseaicewavelengths(1) = 0.470000
160  possseaicewavelengths(2) = 0.555000
161  possseaicewavelengths(3) = 0.659000
162  possseaicewavelengths(4) = 0.858000
163  possseaicewavelengths(5) = 1.240000
164  possseaicewavelengths(6) = 1.640000
165  possseaicewavelengths(7) = 2.130000
166  possseaicewavelengths(8) = 3.700000
167 
168  ! Set the sea ice values to be equal to the dry perm snow/ice
169  ! values or percentage of them:
170  dryseaicealbedos(1:7) = snowalbedostats(1:7,15,1)
171  meltseaicealbedos(1:7) = snowalbedostats(1:7,15,1) * percentageofdry
172  !3.7 is half of 2.1:
173  dryseaicealbedos(8) = dryseaicealbedos(7) * 0.5000d0
174  meltseaicealbedos(8) = meltseaicealbedos(7) * 0.5000d0
175 
176  !Loop over the wavelengths to be processed, storing the cooresponding
177  ! data from the complete snowAlbedoStats array. Process 3.7µm for this
178  ! sea ice case
179  do i = 1, numalbwavesprocess
180  foundwave = .false.
181  do j = 1, numseaicealbwaves
182  if ( mod(wavelength(i),possseaicewavelengths(j)) < 0.05 ) then
183  processdryseaicealbedos(i) = dryseaicealbedos(j)
184  processmeltseaicealbedos(i) = meltseaicealbedos(j)
185  foundwave = .true.
186  goto 101
187  end if
188  end do
189  101 continue
190  if (.not. foundwave) then
191 ! status = 19
192 ! return
193  end if
194  end do
195 
196  end subroutine init_snow_stats
197 
198 ! --------------------------------------------------------------------------
199 ! --------------------------------------------------------------------------
200  subroutine getalbedoeco (Lat, Long, JulianDay, EcosystemFN, &
201  emissivity_name, Debug, WavelengthText, ProcessLandAlbedo, &
202  icec, Albedo, emissivity, Ecosystem, Status, sfc_info )
203 
204  ! WDR access c2_alt_snowice and albedo
206 
207  ! EM -- June 17, 2005
208  ! Apparently ncdump does not handle the metadata very well, and there
209  ! was some binary conversion
210  ! issue such that the metadata values are mixed up. If you use something
211  ! like HDFlook, they are fine.
212  ! Here is how ncdump prints them out:
213  ! byte IGBP_Land_Cover_Type(NumLatPoints, NumLongPoints) ;
214  ! IGBP_Land_Cover_Type:long_name = "IGBP Land Cover Classification Type" ;
215  ! IGBP_Land_Cover_Type:units = "class number" ;
216  ! IGBP_Land_Cover_Type:valid_range = '\0', '\376' ;
217  ! IGBP_Land_Cover_Type:_FillValue = '\377' ;
218  ! IGBP_Land_Cover_Type:water = '\0' ;
219  ! IGBP_Land_Cover_Type:evergreen needleleaf forest = '\1' ;
220  ! IGBP_Land_Cover_Type:evergreen broadleaf forest = '\2' ;
221  ! IGBP_Land_Cover_Type:deciduous needleleaf forest = '\3' ;
222  ! IGBP_Land_Cover_Type:deciduous broadleaf forest = '\4' ;
223  ! IGBP_Land_Cover_Type:mixed forests = '\5' ;
224  ! IGBP_Land_Cover_Type:closed shrubland = '\6' ;
225  ! IGBP_Land_Cover_Type:open shrublands = '\7' ;
226  ! IGBP_Land_Cover_Type:woody savannas = '\10' ;
227  ! IGBP_Land_Cover_Type:savannas = '\11' ;
228  ! IGBP_Land_Cover_Type:grasslands = '\12' ;
229  ! IGBP_Land_Cover_Type:permanent wetlands = '\13' ;
230  ! IGBP_Land_Cover_Type:croplands = '\14' ;
231  ! IGBP_Land_Cover_Type:urban and built-up = '\15' ;
232  ! IGBP_Land_Cover_Type:cropland/natural vegetation mosaic = '\16' ;
233  ! IGBP_Land_Cover_Type:snow and ice = '\17' ;
234  ! IGBP_Land_Cover_Type:barren or sparsely vegetated = '\20' ;
235  ! IGBP_Land_Cover_Type:unclassified = '\376' ;
236  ! If you notice it skips 7 and goes to 10 (open shrub to woody savanna)
237  ! and then 17 to 20 (snow/ice to barren).
238  !
239  ! Here is how my code actually assigns them:
240  !
241  !*****************************************************************************
242  ! Create the Ecosystem_Order array, used in HDF initialization:
243  !*****************************************************************************
244  ! Ecosystem_Order(0) = 'Ocean / Water'
245  ! Ecosystem_Order(1) = 'Evergreen Needle Forest'
246  ! Ecosystem_Order(2) = 'Evergreen Broad Forest'
247  ! Ecosystem_Order(3) = 'Deciduous Needle Forest'
248  ! Ecosystem_Order(4) = 'Deciduous Broad Forest'
249  ! Ecosystem_Order(5) = 'Mixed Forest'
250  ! Ecosystem_Order(6) = 'Closed Shrubs'
251  ! Ecosystem_Order(7) = 'Open / Shrubs'
252  ! Ecosystem_Order(8) = 'Woody Savanna'
253  ! Ecosystem_Order(9) = 'Savanna'
254  ! Ecosystem_Order(10) = 'Grassland'
255  ! Ecosystem_Order(11) = 'Wetland'
256  ! Ecosystem_Order(12) = 'Cropland'
257  ! Ecosystem_Order(13) = 'Urban'
258  ! Ecosystem_Order(14) = 'Crop Mosaic'
259  ! Ecosystem_Order(15) = 'Antarctic / Permanant Snow'
260  ! Ecosystem_Order(16) = 'Barren / Desert'
261  ! Ecosystem_Order(17) = 'Tundra'
262  !
263  !Ncdump is quite deficient in this respect and I get asked this all the time.
264  !But it is not a coding issue. -- E. Moody
265 
266  real (kind = single ), dimension(:,:), intent(in ) :: lat, long
267  character (len = *), intent(in ) :: ecosystemfn
268  character (len = *), intent(in ) :: emissivity_name
269  integer (kind = integer_fourbyte ), intent(in ) :: julianday
270  logical, intent(in ) :: debug
271  character (len = *), dimension(:), intent(in ) :: wavelengthtext
272  logical, dimension(:), intent(in ) :: processlandalbedo
273  real (kind = single), dimension(:,:), intent(in ) :: icec
274  real (kind = single ), dimension(:,:,:), intent(out) :: emissivity
275  integer*2, dimension(:,:,:), intent(out) :: albedo
276  integer*1, dimension(:,:), intent(out) :: ecosystem, sfc_info
277  integer (kind = integer_fourbyte), intent(out) :: status
278 
279  ! !Description:
280  ! This returns albedo values and IGBP ecosystem classification for each
281  ! pixel
282  ! of the MOD06 granule, and for the wavelengths specified. Also
283  ! returned are
284  ! values of snow albedos by ecosystem class for the wavelengths specified.
285  !
286  ! !Input Parameters:
287  ! Lat, Long : Latitude and Longitude arrays from granule.
288  ! WavelengthFN : The albedo filenames for each specified wavelength
289  ! to process.
290  ! EcosystemFN : The filename for the IGBP Ecosystem Classification map.
291  ! Julian Day : Julian Day
292  ! Debug : Logical Flag for printing during debugging.
293  ! WavelengthText : Text array of wavelengths to be processed.
294  !
295  ! !Output Parameters:
296  ! Wavelength : Real values of the Text array.
297  ! Albedo : 3D array containing the albedo values for each
298  ! lat/lon point
299  ! and for each wavelength specified.
300  ! SnowAlbedo : Snow albedos by ecosystem class for each
301  ! wavelength specified.
302  ! Ecosystem : IGBP ecosystem classification for each lat/lon point.
303  ! Status : Flag specifying if this routine worked correctly.
304  !
305  ! !Revision History:
306  ! See Module revision history at the beginning of the file.
307  !
308  ! !Team-Unique Header:
309  ! Cloud Retrieval Group, NASA Goddard Space Flight Center
310  !
311  ! !References and Credits:
312  ! Written by
313  ! Eric Moody
314  ! Climate and Radiation Branch, Code 913
315  ! NASA/GSFC
316  ! Greenbelt MD 20771
317  ! Eric.Moody@gsfc.nasa.gov
318  !
319  ! !Design Notes:
320  ! Albedos values for each lat/lon point are provided by finding
321  ! the nearest neighbor
322  ! from the ancillary albedo maps.
323  ! Wavelengths to be processed are specified through the WavelengthText
324  ! array and
325  ! corresponding WavelengthFN array.
326  ! There is no ancillary files for 3.7 micron, so this is assumed to be
327  ! half the 2.1 value.
328  ! The 3.7 micron always has to be last in the WavelengthText array and
329  ! WavelengthFN array,
330  ! however the WavelengthFN for 3.7 is not used, so it can be fill.
331  ! As the albedo ancillary data is for land only, water values are
332  ! assumed to be 5% for
333  ! all wavelengths.
334  ! Sea ice is approximated with perm snow/ice values for a winter time,
335  ! and a percentage
336  ! during a melt season. A transition period is approximated between
337  ! winter and melt.
338  !
339  ! The following status error values are used:
340  ! 1 = Array Sizes not valid
341  ! 2 = Invalid min/max long/lat
342  ! 3 = Invalid global map start/stop x/y
343  ! 4 = Could not gain access to Albedo HDF file
344  ! 5 = Could not gain access to Albedo SDS
345  ! 6 = Could not read Albedo SDS
346  ! 7 = Could not end access to Albedo SDS
347  ! 8 = Could not end access to Albedo HDF file
348  ! 9 = Could not gain access to Ecosystem HDF file
349  ! 10 = Could not gain access to Ecosystem SDS
350  ! 11 = Could not read Ecosystem SDS
351  ! 12 = Could not end access to Ecosystem SDS
352  ! 13 = Could not end access to Ecosystem HDF file
353  ! 14 = Trouble with Albedo Snow Statistics
354  ! 15 = Trouble with Reading NISE data
355  ! 16 = Pixel's computed global map index invalid
356  ! 17 = Pixel's geolocation invalid
357  ! 18 = Wavelengths do not match for snow statistics
358  ! 19 = Wavelengths do not match for sea ice values
359  !
360  !
361  ! !END
362 
363  !Local Variables
364 
365  !
366  !Size variables:
367  !
368  !Number of Albedo Wavelengths to be processed.
369  integer (kind = integer_fourbyte) :: numalbwavesprocess
370  !Number of Columns and Rows of the granule to be processed
371  integer (kind = integer_fourbyte) :: numberofcols, numberofrows
372 
373  !
374  !Min/Max Lat/Lon:
375  !
376  real (kind = single) :: minlat, maxlat, minlong, maxlong
377 
378  !
379  ! Albedo/Ecosystem map variables:
380  !
381  ! Global map dims and maximum number of albedo wavelengths:
382  integer (kind = integer_fourbyte) :: nummapcols, nummaprows
383  integer (kind = integer_fourbyte) :: nummapcols_alb, nummaprows_alb
384 
385  ! Stores the resolution (in degrees) of the global map
386  real (kind = single) :: map_resolution
387  real (kind = single) :: map_resolution_alb
388  ! Stores the upper right corner global map coords, used to compute rest
389  ! of map coords.
390  real (kind = single) :: westernmostlongitude, northernmostlatitude
391  real (kind = single) :: westernmostlongitude_alb, northernmostlatitude_alb
392  ! Indices for section of global map that is needed for supplying values
393  ! for granule:
394  integer (kind = integer_fourbyte) :: startx, stopx, starty, stopy, &
395  numberofxpoints, numberofypoints
396  integer (kind = integer_fourbyte) :: startx_alb, stopx_alb, &
397  starty_alb, stopy_alb
398  real (kind = single) :: startxval, stopxval, startyval, stopyval
399  ! Stores the real and integer values of the section of the global albedo map.
400  ! Used to scale the albedo values read in as integers from the HDF files.
401  real (kind = single ), parameter :: scalefactor = 0.00100
402  ! Store the NISE snow type:
403  INTEGER(integer_fourbyte), allocatable, DIMENSION(:,:) :: snowicetype
404  ! Store the section of the global ecosystem map needed for supplying
405  ! `values for granule:
406  integer (kind = integer_onebyte), allocatable, dimension(:,:) :: ecosystemmap
407  ! Dummy index variables:
408  integer (kind = integer_fourbyte) :: xindex, yindex
409  integer (kind = integer_fourbyte) :: xindex_alb, yindex_alb
410  ! HDF variables:
411  ! File IDs
412  integer (kind = integer_fourbyte) :: ecomapfid, albmapfid
413  ! SDS IDs
414  integer (kind = integer_fourbyte) :: ecomapsdsid, albmapsdsid
415  ! Stores the SDS name
416  character(len = MAX_SDS_NAME_LEN) :: sdsname
417 
418  ! Error handling:
419  INTEGER(integer_fourbyte) :: errorlevel
420 
421  ! Wavelength descriptions used in snow statistics:
422  !Variables used for sea ice albedos:
423  LOGICAL :: arcticmeltingseason, wintertomelttransition, melttowintertransition
424  integer (kind = integer_fourbyte), parameter :: transitiondays = 10, &
425  nhmeltbeg = 152, nhmeltend = 244, shmeltbeg = 334, shmeltend = 61
426 
427  !Water albedo values:
428  real (kind = single), parameter :: wateralbedo = 0.050000
429  real, dimension(:), allocatable :: albedo_real4
430  real, parameter :: emissivity_fill = 0.985 ! according to Wisconsin
431 
432  ! emissivity map variables
433  real, parameter :: emissivity_res = 0.05
434  integer, parameter :: num_emiss_cols = 7200
435  integer, parameter :: num_emiss_rows = 3600
436  real, dimension(:,:,:), allocatable :: emissivity_map
437  integer*2, dimension(:,:), allocatable :: emissivity_map_int
438  integer :: emiss_x, emiss_y
439  real :: emiss_west, emiss_north
440 
441  integer :: file_id, var_id, err_code, start(2), stride(2), edge(2)
442 
443  ! WDR definitions needed in replacing ftn hdf i/o package
444  integer c_sfstart
445  external c_sfstart
446  integer c_sfselect
447  external c_sfselect
448  integer c_sfn2index
449  external c_sfn2index
450  integer c_sfginfo
451  external c_sfginfo
452  integer c_sfrdata
453  external c_sfrdata
454  integer c_sfendacc
455  external c_sfendacc
456  integer c_sfend
457  external c_sfend
458  integer :: dfacc_read = 1
459  integer :: fail = -1
460 
461  ! WDR this will support the re-read only when lat, long range falls outside
462  ! the previous range of min, max (lat, lon)
463  real, dimension(2) :: min_geo_sav = (/ -9000., -9000. /), &
464  max_geo_sav = (/ -9000., -9000. /)
465  real :: geo_margin = 5. ! 5 degree extra margin to allocate for
466 
467  !*****************************************************************************
468  ! Determine the size of the arrays:
469  !*****************************************************************************
470  !Determine dimensions:
471  numberofcols = size( albedo(:,:,:), dim = 1 )
472  numberofrows = size( albedo(:,:,:), dim = 2 )
473  numalbwavesprocess = size( albedo(:,:,:), dim = 3 )
474 
475  if( .not. allocated( albedo_real4) ) &
476  allocate(albedo_real4(numalbwavesprocess))
477 
478  !print*,'c,R ',NumberOfCols,NumberOfRows
479  !Error checking:
480  if ( (numberofcols < 1) .or. &
481  (numberofrows < 1) .or. &
482  (numalbwavesprocess < 2) .or. &
483  (numecosystems < 1) ) then
484  status = error
485  call local_message_handler( &
486  'Problem with albedo array size, contact SDST',status,'getAlbedoEco')
487  return
488  end if
489 
490  !************************************************************************
491  ! Determine the min/max of lat/lon, which will be used to determine what
492  ! portion
493  ! of the albedo/eco maps need to be read in.
494  !************************************************************************
495  ! Determine min and max:
496  if (maxval(lat) == -999. .or. maxval(long) == -999.) then
497  ! there is no gelocation data in the scan.
498  albedo(:,:,:) = -999.
499  emissivity(:,:,:) = -999.
500  return
501  else
502  minlat = minval( lat, &
503  mask = ( (lat >= -90.0000 .and. lat <= 90.00000) ) )
504  maxlat = maxval( lat, &
505  mask = ( (lat >= -90.0000 .and. lat <= 90.00000) ) )
506  minlong = minval( long, &
507  mask = ( (long >= -180.000 .and. long <= 180.0000) ) )
508  maxlong = maxval( long, &
509  mask = ( (long >= -180.000 .and. long <= 180.0000) ) )
510  endif
511 
512  ! WDR see if we need to re-read the grids for geo bounds outside current
513  !PRINT*, 'Decide whether to read the albedo/emiss tables'
514  if( ( minlat < min_geo_sav(1) ) .or. ( maxlat > max_geo_sav(1) ) .or. &
515  ( minlong < min_geo_sav(2) ) .or. ( maxlong > max_geo_sav(2) ) ) then
516  !PRINT*, 'Reading albedo/emiss tables'
517  !PRINT*, 'minLat, maxLat, minLong, maxLong ', minLat, maxLat, minLong, maxLong
518  !PRINT*, 'min_geo_sav, max_geo_sav ', min_geo_sav, max_geo_sav
519 
520  ! set the new margin-enhanced range and re-read from files
521  minlat = minlat - geo_margin
522  maxlat = maxlat + geo_margin
523  minlong = minlong - geo_margin
524  maxlong = maxlong + geo_margin
525 
526  if( minlat < -90. ) minlat = -90.
527  if( maxlat > 90. ) maxlat = 90.
528  if( minlong < -180. ) minlong = -180.
529  if( maxlong > 180. ) maxlong = 180.
530 
531  min_geo_sav(1) = minlat
532  min_geo_sav(2) = minlong
533  max_geo_sav(1) = maxlat
534  max_geo_sav(2) = maxlong
535  !PRINT*, 'NEW min_geo_sav, max_geo_sav ', min_geo_sav, max_geo_sav
536 
537 
538  !**********************************************************************
539  ! Set up the global albedo/ecosystem map resolution and determine the
540  ! start/stop
541  ! points for the portion of the global map to be read in. This
542  ! is done by
543  ! computing the map indices from the min/max lat/lon values.
544  !**********************************************************************
545  ! 9-30-11 For Collection 4 (Moody) surface albedo and ecosystem maps
546  ! were identical resolution,
547  ! the resolution of the C5 SA dataset however is double C4, thus
548  ! appropriate modifications
549  ! have been made below to read the higher resolution Albedo map
550  ! data. - GTA
551 
552  nummapcols = 21600
553  nummaprows = 10800
554 
555  map_resolution = 360.000d0 / float(nummapcols)
556 
557  ! Compute the WesternMostLongitude and NothernMostLatitude of the maps:
558  westernmostlongitude = map_resolution / 2.0 - 180.0
559  northernmostlatitude = 90.0 - map_resolution / 2.0
560  !print*,'mapres=',Map_Resolution,westernMostLongitude,northernMostLatitude
561  !print*,'minLong=',minLong,maxLong,minLat,maxLat
562 
563  ! Because the albedo map res. is different than the ecosystem map,
564  ! save the albedo map
565  ! parameters for later determination surface albedo for each
566  ! granule pixel - GTA
567 
568  ! Compute the start/stop x/y indices based on min/max lat/lon values:
569  ! use anint so that it rounds to nearest index.
570  startx = anint( (minlong-westernmostlongitude) / (map_resolution) ) + 1
571  stopx = anint( (maxlong-westernmostlongitude) / (map_resolution) ) + 1
572  starty = anint( (northernmostlatitude-maxlat ) / (map_resolution) ) + 1
573  stopy = anint( (northernmostlatitude-minlat ) / (map_resolution) ) + 1
574 
575  ! Due to roundoff, geocoordinates of -90, 90, -180, 180 can result in
576  ! indices of one beyond the map bounds, so correct that here:
577  if (startx == 0) startx = 1
578  if (stopx == nummapcols+1 ) stopx = nummapcols
579  if (starty == 0) starty = 1
580  if (stopy == nummaprows+1 ) stopy = nummaprows
581 
582  ! Compute the number of points:
583  numberofxpoints = stopx - startx + 1
584  numberofypoints = stopy - starty + 1
585 
586  ! Error Checking:
587  if ( (startx < 1) .or. (stopx > nummapcols) .or. &
588  (starty < 1) .or. (stopy > nummaprows) .or. &
589  (startx > stopx) .or. (starty > stopy) ) then
590  ! status = error
591  ! call local_message_handler('Problem with loop index, contact SDST', &
592  ! status,'getAlbedoEco')
593  ! return
594  if (stopx > nummapcols) stopx = nummapcols
595  if (stopy > nummaprows) stopy = nummaprows
596  if (startx > stopx) startx = stopx-1
597  if (starty > stopy) starty = stopy-1
598  if (startx < 1) startx = 1
599  if (starty < 1) starty = 1
600 
601  end if
602 
603  !***********************************************************************
604  ! Allocate the global albedo and ecosytem map storage arrays based
605  ! upon these
606  ! start and stop values. Note that the arrays will be indexed using
607  ! start/stop
608  ! variables, instead of 1-NumberOfZPoints, for ease of selecting
609  ! the nearest
610  ! neighbor to the inputted lat/lon grid.
611  !************************************************************************
612  ! WDR re-allocate here
613  if( allocated(ecosystemmap) ) deallocate( ecosystemmap )
614  allocate( ecosystemmap(startx:stopx, starty:stopy ) )
615 
616  !*************************************************************************
617  ! Set up the HDF read variables, making note that HDF arrays start at 0
618  ! instead of F90's 1:
619  !************************************************************************
620  ! Define the starting point
621  hdfstart(:) = 0
622  hdfstart(1) = startx - 1
623  hdfstart(2) = starty - 1
624 
625  ! Define the stride = 1 so that it doesn't skip any data.
626  hdfstride(:) = 1
627 
628  ! Define the Number of Points to read:
629  hdfedge(:) = 1
630  hdfedge(1) = numberofxpoints
631  hdfedge(2) = numberofypoints
632 
633  !************************************************************************
634  ! Read in the portion of the ecosystem map from the corresponding file:
635  !***********************************************************************
636  ! Define the SDS Name:
637  sdsname = "IGBP_Land_Cover_Type"
638 
639  ! Open the HDF file for reading:
640  ecomapfid = c_sfstart(trim(ecosystemfn), dfacc_read)
641  if (ecomapfid == fail) then
642  status = failure
643  call local_message_handler('Problem detected ecosysyem file sfstart', &
644  status,'getAlbedoEco')
645  return
646  end if
647 
648  ! Obtain the data set ID's:
649  ecomapsdsid = c_sfselect(ecomapfid, c_sfn2index(ecomapfid, trim(sdsname)))
650  if (ecomapsdsid == fail) then
651  status = failure
652  call local_message_handler('Problem detected ecosystem file sfselect', &
653  status,'getAlbedoEco')
654  return
655  end if
656 
657  ! Read in the data:
658  hdfstatus = c_sfrdata(ecomapsdsid, hdfstart, hdfstride, hdfedge, &
659  ecosystemmap)
660  !Error checking:
661  if (hdfstatus == fail) then
662  status = failure
663  call local_message_handler('Problem detected ecosystem file sfrdata', &
664  status,'getAlbedoEco')
665  return
666  end if
667 
668  ! End Access to the datasets and files:
669  hdfstatus = c_sfendacc( ecomapsdsid )
670  if (hdfstatus == fail) then
671  status = failure
672  call local_message_handler('Problem detected ecosystem file sfendacc', &
673  status,'getAlbedoEco')
674  return
675  end if
676  hdfstatus = c_sfend( ecomapfid )
677  if (hdfstatus == fail) then
678  status = failure
679  call local_message_handler('Problem detected ecossystem file sfend', &
680  status,'getAlbedoEco')
681  return
682  end if
683  !************************************************************************
684  ! Read in the portion of the emissivity map from the corresponding file:
685  !***********************************************************************
686 
687  ! Compute the WesternMostLongitude and NothernMostLatitude of the maps:
688  emiss_west = emissivity_res / 2.0 - 180.0
689  emiss_north = 90.0 - emissivity_res / 2.0
690 
691  ! Compute the start/stop x/y indices based on min/max lat/lon values:
692  !use anint so that it rounds to nearest index.
693  startx = anint( (minlong-emiss_west) / (emissivity_res) ) + 1
694  stopx = anint( (maxlong-emiss_west) / (emissivity_res) ) + 1
695  starty = anint( (emiss_north-maxlat ) / (emissivity_res) ) + 1
696  stopy = anint( (emiss_north-minlat ) / (emissivity_res) ) + 1
697 
698  ! Due to roundoff, geocoordinates of -90, 90, -180, 180 can result in
699  ! indices of one beyond the map bounds, so correct that here:
700  if (startx == 0) startx = 1
701  if (stopx == num_emiss_cols+1 ) stopx = num_emiss_cols
702  if (starty == 0) starty = 1
703  if (stopy == num_emiss_rows+1 ) stopy = num_emiss_rows
704 
705  ! Compute the number of points:
706  numberofxpoints = stopx - startx + 1
707  numberofypoints = stopy - starty + 1
708 
709  ! Error Checking:
710  if ( (startx < 1) .or. (stopx > num_emiss_cols) .or. &
711  (starty < 1) .or. (stopy > num_emiss_rows) .or. &
712  (startx > stopx) .or. (starty > stopy) ) then
713 
714  if (stopx > nummapcols) stopx = nummapcols
715  if (stopy > nummaprows) stopy = nummaprows
716  if (startx > stopx) startx = stopx-1
717  if (starty > stopy) starty = stopy-1
718  if (startx < 1) startx = 1
719  if (starty < 1) starty = 1
720 
721  ! status = error
722  ! call local_message_handler('Problem with loop index, contact SDST', &
723  ! status,'getAlbedoEco')
724  ! return
725  end if
726 
727  ! Define the starting point
728  hdfstart(:) = 0
729  hdfstart(1) = startx - 1
730  hdfstart(2) = starty - 1
731 
732  ! Define the stride = 1 so that it doesn't skip any data.
733  hdfstride(:) = 1
734 
735  ! Define the Number of Points to read:
736  hdfedge(:) = 1
737  hdfedge(1) = numberofxpoints
738  hdfedge(2) = numberofypoints
739 
740  ! WDR re-allocate here instead
741  if( allocated( emissivity_map ) ) then
742  deallocate( emissivity_map )
743  end if
744  allocate( emissivity_map(startx:stopx, starty:stopy, 2) )
745  allocate( emissivity_map_int(startx:stopx, starty:stopy ) )
746 
747  ecomapfid = c_sfstart(trim(emissivity_name), dfacc_read)
748 
749  do i=1, 2
750 
751  if (i==1) sdsname = "emiss7"
752  if (i==2) sdsname = "emiss14"
753 
754  ecomapsdsid = c_sfselect(ecomapfid, c_sfn2index(ecomapfid, &
755  trim(sdsname)))
756 
757  hdfstatus = c_sfrdata(ecomapsdsid, hdfstart, hdfstride, hdfedge, &
758  emissivity_map_int)
759  emissivity_map(:,:,i) = emissivity_map_int * scalefactor
760 
761  hdfstatus = c_sfendacc(ecomapsdsid)
762 
763  end do
764 
765  hdfstatus = c_sfend(ecomapfid)
766 
767  deallocate(emissivity_map_int)
768  ! print*,'to snowalb'
769 
770  end if
771 
772  !*****************************************************************************
773  ! Read in the NISE snow type from the corresponding file:
774  !*****************************************************************************
775  allocate( snowicetype(1:numberofcols, 1:numberofrows ) )
776  snowicetype = 0 ! WDR-UIV
777 
778  if (errorlevel == fail) then
779  status = failure
780  call local_message_handler('Problem reported from GetNISEType', &
781  status,'getAlbedoEco')
782  return
783  end if
784 
785  ! print*,'tp latlon loop',NumberOfCols,NumberOfRows
786 
787  ! WDR we insert the l2 snow-ice array here
788  snowicetype = c2_alt_snowice
789  !*****************************************************************************
790  ! Loop over each pixel in the lat/lon grid, compute the global coordinates and
791  ! set the pixel's albedo and ecosystem values to the corresponding global
792  ! albedo and ecosystem map values. This is essentially a nearest neighbor
793  ! calculation.
794  !*****************************************************************************
795  do i = 1, numberofcols
796  do j = 1, numberofrows
797 
798  sfc_info(i,j) = 0
799  ! Check to see if the geolocation is valid, also check we have a cloud.
800  if ( (lat(i,j) >= -90.0000) .and. &
801  (lat(i,j) <= 90.0000) .and. &
802  (long(i,j) >= -180.000) .and. &
803  (long(i,j) <= 180.000) ) then
804 
805  ! put the emissivity values where they belong
806  emiss_x = anint( (long(i,j)-emiss_west) / (emissivity_res) ) + 1
807  emiss_y = anint( (emiss_north-lat(i,j)) / (emissivity_res) ) + 1
808 
809  if (emiss_x == 0) emiss_x = 1
810  if (emiss_x == num_emiss_cols+1 ) emiss_x = num_emiss_cols
811  if (emiss_y == 0) emiss_y = 1
812  if (emiss_y == num_emiss_rows+1 ) emiss_y = num_emiss_rows
813 
814 
815  emissivity(i,j, 1) = emissivity_map(emiss_x, emiss_y, 1)
816  emissivity(i,j, 2) = emissivity_map(emiss_x, emiss_y, 2)
817 
818  if (emissivity(i,j,1) < 0.) emissivity(i,j,1) = emissivity_fill
819  if (emissivity(i,j,2) < 0.) emissivity(i,j,2) = emissivity_fill
820 
821  ! end emissivity additions
822 
823  ! print*,'rows=',j,i,Map_Resolution,Long(i,j),westernMostLongitude, &
824  ! northernMostLatitude,Lat (i,j)
825 
826  ! Valid geolocation, so proceed.
827 
828  ! Compute the ecosystem map x,y indices from this pixel's lat/long values.
829  xindex = anint( (long(i,j)-westernmostlongitude) / (map_resolution) ) + 1
830  yindex = anint( (northernmostlatitude-lat(i,j)) / (map_resolution) ) + 1
831 
832  ! Due to roundoff, geocoordinates of -90, 90, -180, 180 can result in
833  ! indices of one beyond the map bounds, so correct that here:
834  if (xindex == 0) xindex = 1
835  if (xindex == nummapcols+1 ) xindex = nummapcols
836  if (yindex == 0) yindex = 1
837  if (yindex == nummaprows+1 ) yindex = nummaprows
838  ! print*,'xIndex, NumMapCols,yIndex, NumMapRows=',xIndex, &
839  ! NumMapCols,yIndex, NumMapRows
840  ! Checks to make sure indices are within bounds of the map:
841  if ( (xindex < 1) .or. (xindex > nummapcols) &
842  .or. (yindex < 1) .or. (yindex > nummaprows) ) then
843  status = error
844  call local_message_handler( &
845  'Problem detected, bad array indexes (main loop) ',status,'getAlbedoEco')
846  return
847  end if
848 
849  ! Implement Rich Frey (UWisc) interpolation scheme in which he
850  ! sets the map
851  ! to 200 if it should be set to snow/ice. For sea ice, he also
852  ! uses the icec data:
853 #ifndef GEOS5_SFC
854  if (lat(i,j) >= 40.0 .or. lat(i,j) <= -40.0) then
855  if (ecosystemmap(xindex,yindex) == 0) then
856  ! This is water, so check if the interpolation flagged as 200,
857  ! or the icec data
858  ! says this is ice, or the NISE has misidentified it as Perm Snow:
859  if ( (icec(i,j) > 0.5 .and. icec(i,j) <= 1.0) &
860  .or. (snowicetype(i,j) == 101) &
861  .or. (snowicetype(i,j) == 200) ) then
862  ! This is water, so this will be sea ice. Set snowIceType to 95%
863  ! so that the sea ice flag is triggered
864  snowicetype(i,j) = 95
865  end if
866  else
867  if ( (snowicetype(i,j) >= 1 .and. snowicetype(i,j) <= 100) &
868  .or. (snowicetype(i,j) == 200) ) then
869  ! This is snow covered land, so set to dry snow:
870  snowicetype(i,j) = 103
871  end if
872  end if
873  end if
874 #else
875  if (ecosystemmap(xindex,yindex) == 0) then
876  if ( snowicetype(i,j) >= 30 .and. snowicetype(i,j) <= 100) then
877  snowicetype(i,j) = snowicetype(i,j)
878  else
879  snowicetype(i,j) = 0
880  endif
881 #ifdef SSFR_INST
882  if ( icec(i,j) > 0. .and. icec(i,j) <= 1.0 ) &
883  snowicetype(i,j) = nint(icec(i,j)*100)
884 #else
885  if ( icec(i,j) > 0.5 .and. icec(i,j) <= 1.0 ) &
886  snowicetype(i,j) = nint(icec(i,j)*100)
887 #endif
888  endif
889 
890 #endif
891 
892  ! Store the ecosystem value:
893  ecosystem(i,j) = ecosystemmap(xindex,yindex)
894  ! print*,xIndex,yIndex,EcosystemMap(xIndex,yIndex)
895  ! WDR we use the sfc albedo from l2gen instead
896  albedo_real4(:) = c2_sfc_albedo( i, j, :)
897 
898  ! Set the albedo to either land values, water, or snow/ice, depending
899  ! on the scenario:
900  if ( (snowicetype(i,j) >= 1) &
901  .and. (snowicetype(i,j) <= 100) &
902  .and. (ecosystem(i,j) == 0) ) then
903 
904  ecosystem(i,j) = 15
905 
906  !This is sea ice, so set the either wet or dry scenario:
907 
908  sfc_info(i,j) = 1
909 
910  ! Determine arctic melting season and set albedo values:
911  if (lat(i,j) >= 0.0) then
912  ! Arctic melting season: June 1st (day 152) to September 1st (day 244):
913  SELECT CASE (julianday)
914  CASE ( (nhmeltbeg-transitiondays):nhmeltbeg-1)
915  ! transition period between winter and melt, so linear
916  ! fit between them
917  ! to get albedo value:
918  slope(:) = (processmeltseaicealbedos(:) - &
919  processdryseaicealbedos(:)) / real(transitiondays)
920  intercept(:) = processdryseaicealbedos(:) - slope(:) &
921  * real(nhmeltbeg-transitiondays)
922  transitionalbedo(:) = slope(:) * real(julianday) + intercept(:)
923  albedo_real4(:) = (transitionalbedo(:) * &
924  real(snowicetype(i,j))/100.000) &
925  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
926  CASE ( nhmeltbeg:nhmeltend )
927  ! Melt Sea Ice Values:
928  albedo_real4(:) = (processmeltseaicealbedos(:) * &
929  real(snowicetype(i,j))/100.000) &
930  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
931  CASE ( nhmeltend+1:(nhmeltend+transitiondays) )
932  ! transition period between melt and winter, so linear
933  ! fit between them
934  ! to get albedo value:
935  slope(:) = (processdryseaicealbedos(:)- &
936  processmeltseaicealbedos(:)) / real(transitiondays)
937  intercept(:) = processmeltseaicealbedos(:) - slope(:) &
938  * real(nhmeltend)
939  transitionalbedo(:) = slope(:) * real(julianday) + intercept(:)
940  albedo_real4(:) = (transitionalbedo(:) * &
941  real(snowicetype(i,j))/100.000) &
942  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
943  CASE DEFAULT
944  ! Dry Sea Ice values::
945  albedo_real4(:) = (processdryseaicealbedos(:) * &
946  real(snowicetype(i,j))/100.000) &
947  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
948  END SELECT
949 
950  else
951  ! Determine southern hemisphere melting season:
952  ! Antarctic melting season: December 1st (day 334) to
953  ! March 1st (day 61):
954  SELECT CASE (julianday)
955  CASE ( (shmeltbeg-transitiondays):shmeltbeg-1)
956  ! transition period between winter and melt, so linear
957  ! fit between them
958  ! to get albedo value:
959  slope(:) = (processmeltseaicealbedos(:)- &
960  processdryseaicealbedos(:)) &
961  / real(transitiondays)
962  intercept(:) = processdryseaicealbedos(:) - slope(:) &
963  * real(shmeltbeg-transitiondays)
964  transitionalbedo(:) = slope(:) * real(julianday) + intercept(:)
965  albedo_real4(:) = (transitionalbedo(:) * &
966  real(snowicetype(i,j))/100.000) &
967  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
968 
969  CASE ( shmeltbeg:366 )
970  ! Melt Sea Ice Values:
971  albedo_real4(:) = (processmeltseaicealbedos(:) * &
972  real(snowicetype(i,j))/100.000) &
973  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
974  CASE ( 1:shmeltend )
975  ! Melt Sea Ice Values:
976  albedo_real4(:) = (processmeltseaicealbedos(:) * &
977  real(snowicetype(i,j))/100.000) &
978  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
979  CASE (shmeltend+1:(shmeltend+transitiondays) )
980  ! transition period between melt and winter, so linear fit
981  ! between them
982  ! to get albedo value:
983  slope(:) = (processdryseaicealbedos(:)- &
984  processmeltseaicealbedos(:)) / real(transitiondays)
985  intercept(:) = processmeltseaicealbedos(:) - slope(:) * &
986  real(shmeltend)
987 
988  transitionalbedo(:) = slope(:) * real(julianday) + intercept(:)
989  albedo_real4(:) = (transitionalbedo(:) * &
990  real(snowicetype(i,j))/100.000) &
991  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
992 
993  CASE DEFAULT
994  ! Dry Sea Ice values::
995  albedo_real4(:) = (processdryseaicealbedos(:) * &
996  real(snowicetype(i,j))/100.000) &
997  + (wateralbedo * real(100-snowicetype(i,j))/100.000)
998  END SELECT
999 
1000  end if
1001 
1002  albedo(i,j,:) = nint(albedo_real4(:)*1000.)
1003 
1004  else if ( ecosystem(i,j) == 15 .or. snowicetype(i,j) == 101 ) then
1005  ! This is permanent snow/ice, so set to either map or stat value:
1006  ! WDR new logic with c2_sfc_albedo
1007  if ((ecosystem(i,j) == 15) .and. &
1008  ( c2_sfc_albedo(i,j,1) > 0 &
1009  .and. c2_sfc_albedo(i,j,1) < 1.) ) then
1010 
1011  ! This pixel is perm snow class and has a valid map value,
1012  ! so set to the map's value:
1013  albedo(i,j,:) = nint( (1.0 - emissivity(i,j,1))*1000.)
1014 
1015  sfc_info(i,j) = 3
1016 
1017  else
1018  ! This pixel isn't flag as perm ice eco, so set it to the
1019  ! statistical value for perm ice:
1020  ecosystem(i,j) = 15
1021  albedo(i,j,:) = nint(processsnowalbstats(:, ecosystem(i,j), 1)*1000.)
1022  albedo(i,j,6) = nint( (1.0 - emissivity(i,j,1))*1000.)
1023 
1024  sfc_info(i,j) = 3
1025  end if
1026 #ifndef GEOS5_SFC
1027  else if ( snowicetype(i,j) == 103 ) then
1028  !This is dry snow, so set the pixel to dry snow stats:
1029  ! if (Ecosystem(i,j) == 0) Ecosystem(i,j) = 15
1030  albedo(i,j,:) = nint( processsnowalbstats(:, ecosystem(i,j), 1) * 1000.)
1031  albedo(i,j,6) = nint( (1.0 - emissivity(i,j,1))*1000.)
1032  ecosystem(i,j)= 15
1033 
1034  sfc_info(i,j) = 3
1035 
1036 #else
1037  ! use the snow fraction as true fraction
1038  else if (snowicetype(i,j) >= 30 .and. snowicetype(i,j) <= 100 .and. &
1039  ecosystem(i,j) /= 0) then
1040  albedo(i,j,:) = nint( (c2_sfc_albedo(i,j,:)* &
1041  (1.-snowicetype(i,j)*0.01) + &
1042  snowicetype(i,j)*0.01* &
1043  processsnowalbstats(:, ecosystem(i,j), 1)) * 1000.)
1044  albedo(i,j,6) = nint( (1.0 - emissivity(i,j,1))*1000.)
1045  ecosystem(i,j)= 15
1046 
1047  sfc_info(i,j) = 3
1048 
1049 #endif
1050 
1051  else if ( snowicetype(i,j) == 104 ) then
1052  ! This is wet snow, so set the pixel to wet snow stats:
1053  ! if (Ecosystem(i,j) == 0) Ecosystem(i,j) = 15
1054  albedo(i,j,:) = nint(processsnowalbstats(:, ecosystem(i,j), 2) * 1000.)
1055  albedo(i,j,6) = nint((1.0 - emissivity(i,j,1))*1000.)
1056  ecosystem(i,j)= 15
1057 
1058  sfc_info(i,j) = 3
1059 
1060 
1061  else if (ecosystem(i,j) == 0) then
1062  ! Water, so set all wavelengths to the water albedo value, 5%:
1063  albedo(i,j,:) = nint(wateralbedo*1000.)
1064 
1065  sfc_info(i,j) = 0
1066  else
1067 
1068  ! This is a snow-free, ocean free, and not perm snow/ice pixel,
1069  ! so just store the value from the albedo map:
1070  albedo(i,j,:) = c2_sfc_albedo(i,j,:) * 1000.
1071  ! use the 1-emissivity for the 3.7um albedo map
1072  albedo(i,j,6) = nint((1.0 - emissivity(i,j,1))*1000.)
1073 
1074  sfc_info(i,j) = 2
1075  end if
1076 
1077  else
1078 
1079  ! Bad geolocation, so set albedos and emissivity to fill value
1080  albedo(i,j,:) = -999
1081  emissivity(i,j,:) = -999.
1082 
1083  end if
1084  end do
1085  end do
1086  !*****************************************************************************
1087  ! Deallocate arrays:
1088  !*****************************************************************************
1089  ! WDR we'll be keeping some of these arrays
1090  !WDRdeallocate( AlbedoMap )
1091  !WDRdeallocate( EcosystemMap )
1092  !WDRdeallocate( emissivity_map)
1093  deallocate( snowicetype )
1094  !WDRdeallocate(albedo_real4)
1095 
1096  if (status > 0 )then
1097  status = error
1098  call local_message_handler('Undetermined problem detected in getAlbedoEco',&
1099  status,'getAlbedoEco')
1100  endif
1101 
1102  end subroutine getalbedoeco
1103 
1104 end module modis_albedo
Definition: ch_xfr.f90:1
integer, dimension(:,:), allocatable c2_alt_snowice
Definition: ch_xfr.f90:25
subroutine, public init_snow_stats(SnowAlbedoFN, WavelengthText)
type(cloudmask_type), dimension(:,:), allocatable cloudmask
integer, parameter set_albedo_bands
real, dimension(:,:,:), allocatable c2_sfc_albedo
Definition: ch_xfr.f90:22
#define real
Definition: DbAlgOcean.cpp:26
integer, parameter single
subroutine, public getalbedoeco(Lat, Long, JulianDay, EcosystemFN, emissivity_name, Debug, WavelengthText, ProcessLandAlbedo, icec, Albedo, emissivity, Ecosystem, Status, sfc_info)
integer, public lat_start
string & trim(string &s, const string &delimiters)
Definition: EnvsatUtil.cpp:29
integer, public lat_end
subroutine local_message_handler(message, severity, functionname)
subroutine, public readsnowalbstats(StatsFN, NumSnowTypes, NumAlbBnds, numEco, AlbedoMean, errorLevel)