diff --git a/BRAMS/Template/RAMSIN b/BRAMS/Template/RAMSIN index 0e9b47465..d326c8527 100644 --- a/BRAMS/Template/RAMSIN +++ b/BRAMS/Template/RAMSIN @@ -1545,14 +1545,17 @@ $MODEL_OPTIONS ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. ! ! For regional runs, it is wise to use options 1 or 2, especially for ! ! long runs. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is 0. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, ! + ! use flat bedrock, otherwise assume free drainage. This option is ! + ! morerelevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Zero flux from the bottom of the bottommost layer. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of ! ! the bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction ! ! is controlled by variable SLDRAIN. In the future options 0, 1, and ! ! 2 may be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! ! is always at saturation. ! !------------------------------------------------------------------------------------! ISOILBC = 1, @@ -2033,7 +2036,7 @@ $ED2_INFO ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -2041,6 +2044,10 @@ $ED2_INFO ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! IED_INIT_MODE = 5, !---------------------------------------------------------------------------------------! @@ -2347,13 +2354,19 @@ $ED2_INFO ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! IALLOM = 3, !---------------------------------------------------------------------------------------! @@ -2425,10 +2438,25 @@ $ED2_INFO ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! IPHEN_SCHEME = 2, !---------------------------------------------------------------------------------------! diff --git a/BRAMS/run/RAMSIN b/BRAMS/run/RAMSIN index dd87f6b44..415e1fcb2 100644 --- a/BRAMS/run/RAMSIN +++ b/BRAMS/run/RAMSIN @@ -1552,14 +1552,17 @@ $MODEL_OPTIONS ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. ! ! For regional runs, it is wise to use options 1 or 2, especially for ! ! long runs. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is 0. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, ! + ! use flat bedrock, otherwise assume free drainage. This option is ! + ! morerelevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Zero flux from the bottom of the bottommost layer. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of ! ! the bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction ! ! is controlled by variable SLDRAIN. In the future options 0, 1, and ! ! 2 may be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom ! ! is always at saturation. ! !------------------------------------------------------------------------------------! ISOILBC = 1, @@ -2050,7 +2053,7 @@ $ED2_INFO ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -2058,6 +2061,10 @@ $ED2_INFO ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! IED_INIT_MODE = 5, !---------------------------------------------------------------------------------------! @@ -2365,13 +2372,19 @@ $ED2_INFO ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! IALLOM = 3, !---------------------------------------------------------------------------------------! @@ -2443,10 +2456,25 @@ $ED2_INFO ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! IPHEN_SCHEME = 2, !---------------------------------------------------------------------------------------! diff --git a/BRAMS/src/core/local_proc.F90 b/BRAMS/src/core/local_proc.F90 index e538cb55a..f01819257 100644 --- a/BRAMS/src/core/local_proc.F90 +++ b/BRAMS/src/core/local_proc.F90 @@ -325,6 +325,9 @@ subroutine master_putdxt(master_num) use rpara, only : & nmachs, & ! INTENT(IN) machnum ! INTENT(IN) +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -333,10 +336,6 @@ subroutine master_putdxt(master_num) real :: dxtmax(maxgrds) integer :: master_num,ierr -#if defined(RAMS_MPI) - include 'mpif.h' -#endif - ! Calculating DXTMAX do ifm = 1,ngrids nn2 = nnxp(ifm) @@ -367,10 +366,10 @@ subroutine master_putcflmax(master_num) nmachs, & ! INTENT(IN) machnum, & ! INTENT(IN) mainnum ! intent(in) - #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none integer :: master_num,ierr #if defined(RAMS_MPI) @@ -387,11 +386,11 @@ subroutine node_getdxt(dxtmax_local) use io_params, only : & maxgrds ! INTENT(IN) use node_mod, only: master_num - implicit none - #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none + real, intent(out) :: dxtmax_local(maxgrds) integer :: ierr #if defined(RAMS_MPI) @@ -413,12 +412,12 @@ subroutine node_getcflmax() cflxy, & ! INTENT(OUT) cflz ! INTENT(OUT) use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none -#if defined(RAMS_MPI) - include 'mpif.h' -#endif integer :: ierr #if defined(RAMS_MPI) diff --git a/BRAMS/src/core/model.F90 b/BRAMS/src/core/model.F90 index b7e7f2bac..f61570550 100644 --- a/BRAMS/src/core/model.F90 +++ b/BRAMS/src/core/model.F90 @@ -265,6 +265,9 @@ subroutine par_model(master_num) ptimes ! INTENT(IN) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none ! +------------------------------------------------------------------ @@ -284,9 +287,6 @@ subroutine par_model(master_num) !MLO integer :: ierr, master_num -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !ALF real :: dxtmax_local(maxgrds) diff --git a/BRAMS/src/core/rammain.F90 b/BRAMS/src/core/rammain.F90 index fd6c98910..fe4a86f4c 100644 --- a/BRAMS/src/core/rammain.F90 +++ b/BRAMS/src/core/rammain.F90 @@ -16,6 +16,9 @@ program main ! invoking master/slave processes or full model process ! destroy processes ! +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -65,7 +68,6 @@ program main ! For MPI interface integer :: ierr #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif ! Get input arguments (required by C interface of MPI_Init) diff --git a/BRAMS/src/core/rams_master.F90 b/BRAMS/src/core/rams_master.F90 index 8eba33de1..1722160e0 100644 --- a/BRAMS/src/core/rams_master.F90 +++ b/BRAMS/src/core/rams_master.F90 @@ -38,6 +38,9 @@ subroutine rams_master(ipara, nslaves, master_num, name_name) use mem_radiate, only: ISWRTYP, ILWRTYP ! Intent(in) use mem_leaf, only : isfcl ! Intent(in) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -63,7 +66,6 @@ subroutine rams_master(ipara, nslaves, master_num, name_name) integer :: ierr #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !MLO] diff --git a/BRAMS/src/core/rnode.F90 b/BRAMS/src/core/rnode.F90 index 6604df513..c00c9c903 100644 --- a/BRAMS/src/core/rnode.F90 +++ b/BRAMS/src/core/rnode.F90 @@ -78,13 +78,16 @@ subroutine rams_node() use mem_leaf, only: isfcl ! intent(in) use dtset, only: dtset_new ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif + implicit none ! Local Variables: #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: isendflg,isendlite,isendmean,isendboth,nt,npass,icm,ifm,nfeed real :: wstart,totcpu,t1,w1,t6,w6 @@ -385,13 +388,15 @@ subroutine init_params(init) use mem_oda use mem_radiate, only: ISWRTYP, ILWRTYP ! Intent(in) use mem_leaf , only: isfcl ! Intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer, intent(in) :: init #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif integer :: ierr @@ -438,6 +443,9 @@ subroutine init_fields(init) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims , only : ndim_types +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -473,7 +481,6 @@ subroutine init_fields(init) !----- Include modules. ----------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! diff --git a/BRAMS/src/ed2/edcp_driver.F90 b/BRAMS/src/ed2/edcp_driver.F90 index ffa40b50d..8c8c6dee8 100644 --- a/BRAMS/src/ed2/edcp_driver.F90 +++ b/BRAMS/src/ed2/edcp_driver.F90 @@ -11,6 +11,7 @@ subroutine ed_coup_driver() , edgrid_g ! ! subroutine use ed_init , only : read_obstime ! ! subroutine use ed_misc_coms , only : fast_diagnostics & ! intent(in) + , current_time & ! intent(in) , iyeara & ! intent(in) , imontha & ! intent(in) , idatea & ! intent(in) @@ -47,6 +48,9 @@ subroutine ed_coup_driver() use budget_utils , only : ed_init_budget ! ! sub-routine use ed_type_init , only : ed_init_viable ! ! sub-routine use soil_respiration , only : zero_litter_inputs ! ! sub-routine +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Local variables. ----------------------------------------------------------------! @@ -63,17 +67,14 @@ subroutine ed_coup_driver() integer :: jd2 integer :: ierr integer :: igr - integer :: ping + integer :: ping + logical :: new_day real :: wtime1 real :: wtime2 real :: wtime_start ! wall time real :: cputime1 !----- External function. --------------------------------------------------------------! real , external :: walltime ! wall time - !----- MPI header. ---------------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/BRAMS/src/ed2/edcp_init.F90 b/BRAMS/src/ed2/edcp_init.F90 index c5dc646ad..d87e7ad34 100644 --- a/BRAMS/src/ed2/edcp_init.F90 +++ b/BRAMS/src/ed2/edcp_init.F90 @@ -20,11 +20,11 @@ subroutine master_ed_init(iparallel) , allocate_edglobals & ! subroutine , allocate_edtype & ! subroutine , edgrid_g ! ! intent(inout) - implicit none - !------Included variables. -------------------------------------------------------------! + !------MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: iparallel !----- Local variables. ----------------------------------------------------------------! @@ -108,11 +108,11 @@ subroutine node_ed_init , allocate_edglobals & ! sub-routine , allocate_edtype & ! sub-routine , edgrid_g ! ! structure - implicit none - !------Included variables. -------------------------------------------------------------! + !------MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! integer :: ifm integer :: ierr @@ -181,12 +181,11 @@ subroutine copy_in_bramsmpi(master_num_b,mchnum_b,mynum_b,nmachs_b,machs_b,ipara use grid_coms , only : ngrids & ! intent(out) , nnxp & ! intent(out) , nnyp ! ! intent(out) - - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + + implicit none !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: master_num_b integer , intent(in) :: mchnum_b @@ -267,11 +266,11 @@ subroutine init_master_work(ipara) , allocate_edglobals & ! sub-routine , allocate_edtype ! ! sub-routine use mem_polygons , only : maxsite ! ! intent(in) - implicit none - !----- Included variables. -------------------------------------------------------------! + !----- MPI variables and procedures. ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: ipara !----- Local variables. ----------------------------------------------------------------! @@ -510,11 +509,10 @@ subroutine init_node_work() , allocate_edglobals & ! sub-routine , allocate_edtype ! ! sub-routine use mem_polygons , only : maxsite ! ! sub-routine - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! integer :: ifm integer :: nm diff --git a/BRAMS/src/ed2/edcp_load_namelist.f90 b/BRAMS/src/ed2/edcp_load_namelist.f90 index 1275b834a..d4dc405d1 100644 --- a/BRAMS/src/ed2/edcp_load_namelist.f90 +++ b/BRAMS/src/ed2/edcp_load_namelist.f90 @@ -114,7 +114,7 @@ subroutine read_ednl(iunit,filename) , sl_felling_s_ltharv & ! intent(out) , cl_fseeds_harvest & ! intent(out) , cl_fstorage_harvest & ! intent(out) - , cl_fleaf_harvest ! ! intent(out) + , cl_fleaf_harvest & ! intent(out) , lu_database & ! intent(out) , plantation_file & ! intent(out) , lu_rescale_file & ! intent(out) diff --git a/BRAMS/src/ed2/edcp_mpiutils.F90 b/BRAMS/src/ed2/edcp_mpiutils.F90 index 2ee522ff8..9a4ee4fc4 100644 --- a/BRAMS/src/ed2/edcp_mpiutils.F90 +++ b/BRAMS/src/ed2/edcp_mpiutils.F90 @@ -234,11 +234,10 @@ subroutine masterput_ednl(mainnum) , idetailed & ! intent(in) , patch_keep ! ! intent(in) use fusion_fission_coms , only : ifusion ! ! intent(in) - implicit none - !----- Standard common blocks. ---------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: mainnum !----- Local variables. ----------------------------------------------------------------! @@ -760,11 +759,10 @@ subroutine nodeget_ednl(master_num) , idetailed & ! intent(out) , patch_keep ! ! intent(out) use fusion_fission_coms , only : ifusion ! ! intent(out) - implicit none - !----- Standard common blocks. ---------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Arguments. ----------------------------------------------------------------------! integer, intent(in) :: master_num !----- Local variables. ----------------------------------------------------------------! diff --git a/BRAMS/src/io/error_mess.F90 b/BRAMS/src/io/error_mess.F90 index 1e868e3b2..276496f8c 100644 --- a/BRAMS/src/io/error_mess.F90 +++ b/BRAMS/src/io/error_mess.F90 @@ -6,11 +6,11 @@ subroutine abort_run(reason,subr,file) ! being frozen. ! !------------------------------------------------------------------------------------------! use node_mod, only: nmachs,mynum - implicit none - character(len=*), intent(in) :: reason,subr,file #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none + character(len=*), intent(in) :: reason,subr,file write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' write(unit=*,fmt='(a)') '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' @@ -49,12 +49,12 @@ subroutine opspec_mess(reason,opssub) ! This is just a first warning to be given in the standard output. Since the namelist ! ! may have more than one error, I list all the problems, then the model will stop. ! !------------------------------------------------------------------------------------------! +#if defined(RAMS_MPI) + use mpi +#endif implicit none character(len=*), intent(in) :: reason,opssub -#if defined(RAMS_MPI) - include 'mpif.h' -#endif write (unit=*,fmt='(a)') ' ' write (unit=*,fmt='(a)') '----------------------------------------------------------------------------' write (unit=*,fmt='(3(a,1x))') '>>>> ',trim(opssub),' error! in your namelist!' diff --git a/BRAMS/src/mpi/mpass_advec.F90 b/BRAMS/src/mpi/mpass_advec.F90 index 540945520..111187a2f 100644 --- a/BRAMS/src/mpi/mpass_advec.F90 +++ b/BRAMS/src/mpi/mpass_advec.F90 @@ -36,6 +36,9 @@ subroutine node_sendadv(iaflag) use mem_cuparm , only : nclouds ! ! intent(in) use grid_dims , only : maxgrds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -59,7 +62,6 @@ subroutine node_sendadv(iaflag) !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -220,12 +222,14 @@ subroutine node_getadv(iaflag) use mem_scratch use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: iaflag diff --git a/BRAMS/src/mpi/mpass_cyclic.F90 b/BRAMS/src/mpi/mpass_cyclic.F90 index a9e5cea5e..71a9628b7 100644 --- a/BRAMS/src/mpi/mpass_cyclic.F90 +++ b/BRAMS/src/mpi/mpass_cyclic.F90 @@ -49,10 +49,10 @@ subroutine node_cycinit(nzp,nxp,nyp,npvar,nmachs,ibnd,jbnd,mynum) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims, only : ndim_types - implicit none #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none integer :: nmachs,mynum,icypts,nzp,nxp,nyp,icycpts,iadd,mdn,msn,ndn,nsn & ,ibnd,jbnd,nm,maxijrecv_cyc integer, dimension(ndim_types) :: npvar @@ -282,12 +282,14 @@ subroutine node_sendcyclic(isflag) use grid_dims use mem_cuparm, only: nclouds use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Included variables --------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: isflag @@ -479,13 +481,13 @@ subroutine node_getcyclic(isflag) use grid_dims use mem_cuparm, only : nclouds use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Included variables --------------------------------------------------------------! include 'interface.h' -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: isflag !----- Local variables -----------------------------------------------------------------! diff --git a/BRAMS/src/mpi/mpass_dtl.F90 b/BRAMS/src/mpi/mpass_dtl.F90 index d4236305b..c929f11f1 100644 --- a/BRAMS/src/mpi/mpass_dtl.F90 +++ b/BRAMS/src/mpi/mpass_dtl.F90 @@ -23,12 +23,12 @@ subroutine master_getcflcpu() use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none include 'interface.h' -#if defined(RAMS_MPI) -include 'mpif.h' -#endif integer :: ngr,nm,k real, save, allocatable :: buff1(:),buff2(:) integer, save :: ncall=0 @@ -69,12 +69,14 @@ subroutine node_putcflcpu(totcpu,totwall) use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif real :: totcpu,totwall integer :: ierr @@ -94,12 +96,12 @@ subroutine master_putdtsched(isendflg,isendlite,isendmean & ,isendboth,ntsend) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none -#if defined(RAMS_MPI) -include 'mpif.h' -#endif integer :: ierr integer :: isendflg,isendlite,isendmean,isendboth,ntsend @@ -135,13 +137,15 @@ subroutine node_getdtsched(isendflg,isendlite,isendmean,isendboth) use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer :: isendflg,isendlite,isendmean,isendboth,ntsend #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr diff --git a/BRAMS/src/mpi/mpass_feed.F90 b/BRAMS/src/mpi/mpass_feed.F90 index 8b318aa7a..a9462ebee 100644 --- a/BRAMS/src/mpi/mpass_feed.F90 +++ b/BRAMS/src/mpi/mpass_feed.F90 @@ -56,13 +56,15 @@ subroutine node_sendfeed(ngr) use grid_dims , only: & maxgrds ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none integer :: ngr #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr,ipos @@ -255,12 +257,14 @@ subroutine node_getfeed(icm,ifm) nypmax, & ! intent(in) nzpmax, & ! intent(in) maxgrds ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' -include 'mpif.h' #endif integer :: ierr,ipos diff --git a/BRAMS/src/mpi/mpass_full.F90 b/BRAMS/src/mpi/mpass_full.F90 index 166db5138..54a01a54f 100644 --- a/BRAMS/src/mpi/mpass_full.F90 +++ b/BRAMS/src/mpi/mpass_full.F90 @@ -32,12 +32,14 @@ subroutine master_sendinit() use io_params use rpara use mem_aerad, only: nwave +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants. ----------------------------------------------------------------! @@ -194,12 +196,14 @@ subroutine node_getinit() use mem_grid use io_params use mem_aerad, only: nwave +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants. ----------------------------------------------------------------! @@ -407,11 +411,13 @@ subroutine node_sendall() use grid_dims use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants -----------------------------------------------------------------! @@ -534,11 +540,13 @@ subroutine master_getall() use mem_cuparm , only: nclouds ! ! intent(in) use mem_aerad , only: nwave ! ! intent(in) use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Local constants -----------------------------------------------------------------! diff --git a/BRAMS/src/mpi/mpass_init.F90 b/BRAMS/src/mpi/mpass_init.F90 index bb809fe5e..76e524e79 100644 --- a/BRAMS/src/mpi/mpass_init.F90 +++ b/BRAMS/src/mpi/mpass_init.F90 @@ -21,12 +21,14 @@ subroutine masterput_processid(nproc,taskids,master_num) use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, dimension(*), intent(in) :: taskids @@ -165,11 +167,13 @@ subroutine masterput_nl(master_num) , ribmax & ! intent(in) , leaf_maxwhc & ! intent(in) , min_patch_area ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -498,12 +502,14 @@ subroutine masterput_gridinit(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if (RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -550,11 +556,13 @@ subroutine masterput_grid_dimens(master_num) use mem_grid use cyclic_mod use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' include 'interface.h' #endif !----- Arguments -----------------------------------------------------------------------! @@ -640,12 +648,14 @@ subroutine masterput_gridset(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -702,13 +712,15 @@ subroutine masterput_misc(master_num) use rpara use mem_cuparm use ref_sounding +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: master_num @@ -777,12 +789,14 @@ subroutine masterput_cofnest(master_num) use mem_grid use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -841,12 +855,14 @@ subroutine masterput_micphys(master_num) use micphys use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: master_num @@ -900,12 +916,14 @@ subroutine nodeget_processid(init) use grid_dims use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: init @@ -1033,11 +1051,13 @@ subroutine nodeget_nl , ribmax & ! intent(out) , leaf_maxwhc & ! intent(out) , min_patch_area ! ! intent(out) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm,ierr @@ -1363,12 +1383,14 @@ subroutine nodeget_gridinit use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm,ierr @@ -1413,12 +1435,14 @@ subroutine nodeget_grid_dimens() use mem_grid use node_mod use cyclic_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: nm @@ -1525,12 +1549,14 @@ subroutine nodeget_gridset use mem_grid use node_mod +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1586,12 +1612,14 @@ subroutine nodeget_misc use mem_cuparm use ref_sounding use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1659,12 +1687,14 @@ subroutine nodeget_cofnest use mem_grid use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr @@ -1722,12 +1752,14 @@ subroutine nodeget_micphys use micphys use node_mod, only : master_num +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables -----------------------------------------------------------------! integer :: ierr diff --git a/BRAMS/src/mpi/mpass_lbc.F90 b/BRAMS/src/mpi/mpass_lbc.F90 index 177b1f712..d39cc79d0 100644 --- a/BRAMS/src/mpi/mpass_lbc.F90 +++ b/BRAMS/src/mpi/mpass_lbc.F90 @@ -36,6 +36,9 @@ subroutine node_sendlbc() use mem_cuparm , only : nclouds ! ! intent(in) use grid_dims , only : maxgrds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Local variables. ----------------------------------------------------------------! @@ -56,7 +59,6 @@ subroutine node_sendlbc() !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -168,12 +170,14 @@ subroutine node_getlbc() use mem_scratch use mem_cuparm , only : nclouds ! ! intent(in) use mem_aerad , only : nwave ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Local variables. ----------------------------------------------------------------! #if defined(RAMS_MPI) diff --git a/BRAMS/src/mpi/mpass_nest.F90 b/BRAMS/src/mpi/mpass_nest.F90 index f4f323dda..6951b21bf 100644 --- a/BRAMS/src/mpi/mpass_nest.F90 +++ b/BRAMS/src/mpi/mpass_nest.F90 @@ -27,10 +27,12 @@ subroutine node_sendnbc(ifm,icm) use var_tables use mem_basic use grid_dims, only: maxgrds +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr,ipos integer :: nm,i1,i2,j1,j2,k1,k2,ng,itype,mtp,iptr,nv @@ -249,11 +251,13 @@ subroutine node_getnbc(ifm,icm) use mem_scratch use mem_basic use mem_nestb +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr,ipos #if defined(RAMS_MPI) diff --git a/BRAMS/src/mpi/mpass_oda.F90 b/BRAMS/src/mpi/mpass_oda.F90 index f03f1c892..f204789ba 100644 --- a/BRAMS/src/mpi/mpass_oda.F90 +++ b/BRAMS/src/mpi/mpass_oda.F90 @@ -24,6 +24,9 @@ subroutine masterput_oda(master_num) use grid_dims use mem_oda use rpara +#if defined(RAMS_MPI) + use mpi +#endif implicit none @@ -33,7 +36,6 @@ subroutine masterput_oda(master_num) ! +------------------------------------------------------------------ #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ns integer :: master_num @@ -137,11 +139,13 @@ subroutine nodeget_oda() use node_mod use mem_oda +#if defined(RAMS_MPI) + use mpi +#endif implicit none #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif integer :: ierr integer :: ns diff --git a/BRAMS/src/mpi/mpass_st.F90 b/BRAMS/src/mpi/mpass_st.F90 index 92a54c5cc..129061c4b 100644 --- a/BRAMS/src/mpi/mpass_st.F90 +++ b/BRAMS/src/mpi/mpass_st.F90 @@ -35,13 +35,15 @@ subroutine node_sendst(isflag) use mem_scratch use mem_basic +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer, intent(in) :: isflag @@ -215,12 +217,14 @@ subroutine node_getst(isflag) use node_mod use mem_scratch use mem_basic +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Module variables. ---------------------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: isflag diff --git a/BRAMS/src/mpi/paral.F90 b/BRAMS/src/mpi/paral.F90 index 3a3e5b351..88c91be62 100644 --- a/BRAMS/src/mpi/paral.F90 +++ b/BRAMS/src/mpi/paral.F90 @@ -25,13 +25,15 @@ subroutine node_sendanl(vtype) use var_tables use mem_scratch use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! character(len=*) , intent(in) :: vtype @@ -120,12 +122,14 @@ subroutine master_getanl(vtype) use mem_cuparm, only : nclouds use mem_aerad , only : nwave use grid_dims +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- External variable declaration ---------------------------------------------------! #if defined(RAMS_MPI) include 'interface.h' - include 'mpif.h' #endif !----- Arguments -----------------------------------------------------------------------! character(len=*) , intent(in) :: vtype diff --git a/ED/Template/Template/ED2IN b/ED/Template/Template/ED2IN index 63504ddd5..a13c645ba 100644 --- a/ED/Template/Template/ED2IN +++ b/ED/Template/Template/ED2IN @@ -414,7 +414,7 @@ $ED_NL ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -422,6 +422,10 @@ $ED_NL ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! NL%IED_INIT_MODE = myinitmode !---------------------------------------------------------------------------------------! @@ -715,14 +719,17 @@ $ED_NL !---------------------------------------------------------------------------------------! ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. Choose ! ! the option according to the site characteristics. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, use ! + ! flat bedrock, otherwise assume free drainage. This option is more ! + ! relevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! ! bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction is ! ! controlled by variable SLDRAIN. In the future options 0, 1, and 2 may ! ! be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! ! always at saturation. ! !---------------------------------------------------------------------------------------! NL%ISOILBC = mysoilbc @@ -882,13 +889,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = myallom !---------------------------------------------------------------------------------------! @@ -959,10 +972,25 @@ $ED_NL ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = myiphen !---------------------------------------------------------------------------------------! diff --git a/ED/Template/Template/emptyepost.sh b/ED/Template/Template/emptyepost.sh deleted file mode 100755 index 44654274e..000000000 --- a/ED/Template/Template/emptyepost.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -rm -fvr epost -mkdir epost diff --git a/ED/Template/Template/gen_obstimes.r b/ED/Template/Template/gen_obstimes.r new file mode 100644 index 000000000..40df2d2b1 --- /dev/null +++ b/ED/Template/Template/gen_obstimes.r @@ -0,0 +1,194 @@ +#----- This should be called before anything else, don't define stuff before this line. ---# +rm(list=ls()) +graphics.off() +#------------------------------------------------------------------------------------------# + + +#----- The user-defined variable section. -------------------------------------------------# +main = "pathhere" +histomain = "pathhere" +srcdir = "thisrscpath" +polyg = "thispoly" +queue = "thisqueue" +yeara = thisyeara +montha = thismontha +datea = thisdatea +timea = thistimea +yearz = thisyearz +monthz = thismonthz +datez = thisdatez +timez = thistimez +lon = thislon +lat = thislat +#------------------------------------------------------------------------------------------# + + +#----- List periods. ----------------------------------------------------------------------# +n = 0 +period = list() +n = n + 1 +period[[n]] = list( todaya = "01/01/2003" + , todayz = "12/31/2010" + , times = c("01:30:00","13:30:00") + )#end list +n = n + 1 +period[[n]] = list( todaya = "01/01/2011" + , todayz = "12/31/2018" + , times = c("06:00:00","18:00:00") + )#end list +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +# No need to change anything beyond this point unless you are developing the script. # +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric years. # +#------------------------------------------------------------------------------------------# +numyears <<- function(when){ + yrs = years(when) + lyrs = levels(yrs) + yrout = as.numeric(lyrs[match(yrs,lyrs)]) + return(yrout) +}#end function +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric months. # +#------------------------------------------------------------------------------------------# +nummonths <<- function(when){ + mos = months(when) + lmos = levels(mos) + moout = match(mos,lmos) + return(moout) +}#end function +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that converts a chron object to numeric days. # +#------------------------------------------------------------------------------------------# +numdays <<- function(when){ + dys = days(when) + ldys = levels(dys) + dyout = match(dys,ldys) + return(dyout) +} #end function +#==========================================================================================# +#==========================================================================================# + + +#----- Output path. -----------------------------------------------------------------------# +output = file.path(main,polyg) +#------------------------------------------------------------------------------------------# + + +#----- Load some useful scripts and packages. ---------------------------------------------# +isok = require(chron) +isok = require(data.table) +#------------------------------------------------------------------------------------------# + + + +#----- Find the standard output files. ----------------------------------------------------# +whena = chron(paste(montha,datea,yeara,sep="/")) +whenz = chron(paste(monthz,datez,yearz,sep="/")) +#------------------------------------------------------------------------------------------# + + +#----- Find the time offset, and round it to the nearest half-hour. -----------------------# +offutc = round( 2. * lon / 15.) / 2. +#------------------------------------------------------------------------------------------# + + +#----- Find number of periods. ------------------------------------------------------------# +nperiod = length(period) +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Expand the times for all days. # +#------------------------------------------------------------------------------------------# +when = NULL +for (p in sequence(nperiod)){ + #----- Current period. -----------------------------------------------------------------# + todaya = chron(period[[p]]$todaya) + todayz = chron(period[[p]]$todayz) + times = period[[p]]$times + #---------------------------------------------------------------------------------------# + + + #------ List of dates and times. -------------------------------------------------------# + today = chron(seq(from=as.numeric(todaya),to=as.numeric(todayz),by=1)) + ntoday = length(today) + ntimes = length(times) + #---------------------------------------------------------------------------------------# + + + #------- Append times from this period. ------------------------------------------------# + when.now = chron(rep(today,each=ntimes),rep(times,times=ntoday)) + offutc / 24 + when.now = when.now[(when.now >= whena) & (when.now <= whenz)] + #---------------------------------------------------------------------------------------# + + #------ Append time. -------------------------------------------------------------------# + when = chron(c(when,when.now)) + #---------------------------------------------------------------------------------------# +}#end for (p in sequence(nperiod)) +#------------------------------------------------------------------------------------------# + + + + +#----- Write the data sets. ---------------------------------------------------------------# +datum = data.table( Year = sprintf("%4.4i",numyears (when)) + , Month = sprintf("%2.2i",nummonths(when)) + , Date = sprintf("%2.2i",numdays (when)) + , Hour = sprintf("%2.2i",hours (when)) + , Minute = sprintf("%2.2i",minutes (when)) + , Second = sprintf("%2.2i",seconds (when)) + , stringsAsFactors = FALSE + )#end data.table +#------------------------------------------------------------------------------------------# + + + + +#----- Write observation times. -----------------------------------------------------------# +obstab = file.path(main,polyg,paste0(polyg,"_obstimes.txt")) +dummy = write.table( x = format(datum) + , file = obstab + , append = FALSE + , quote = FALSE + , row.names = FALSE + , col.names = TRUE + )#end write.table +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/mled b/ED/Template/Template/mled deleted file mode 100755 index b80a599a1..000000000 Binary files a/ED/Template/Template/mled and /dev/null differ diff --git a/ED/Template/Template/monthly_ascii.r b/ED/Template/Template/monthly_ascii.r new file mode 100644 index 000000000..2756cca1a --- /dev/null +++ b/ED/Template/Template/monthly_ascii.r @@ -0,0 +1,456 @@ + +#----- Paths. -----------------------------------------------------------------------------# +here = "thispath" # Current directory. +there = "thatpath" # Directory where analyses/history are +srcdir = "thisrscpath" # Source directory. +outroot = "thisoutroot" # Directory for figures +#------------------------------------------------------------------------------------------# + + +#----- Time options. ----------------------------------------------------------------------# +monthbeg = thismontha # First month to use +yearbeg = thisyeara # First year to consider +yearend = thisyearz # Maximum year to consider +reload.data = TRUE # Should I reload partially loaded data? +sasmonth.short = c(2,5,8,11) # Months for SAS plots (short runs) +sasmonth.long = 5 # Months for SAS plots (long runs) +nyears.long = 15 # Runs longer than this are considered long runs. +#------------------------------------------------------------------------------------------# + + + +#----- Name of the simulations. -----------------------------------------------------------# +myplaces = c("thispoly") +#------------------------------------------------------------------------------------------# + + + +#----- Plot options. ----------------------------------------------------------------------# +outform = thisoutform # Formats for output file. Supported formats are: + # - "X11" - for printing on screen + # - "quartz" - for printing on Mac OS screen + # - "eps" - for postscript printing + # - "png" - for PNG printing + # - "tif" - for TIFF printing + # - "pdf" - for PDF printing +depth = 96 # PNG resolution, in pixels per inch +paper = "letter" # Paper size, to define the plot shape +ptsz = 16 # Font size. +lwidth = 2.5 # Line width +plotgrid = TRUE # Should I plot the grid in the background? +sasfixlimits = FALSE # Use a fixed scale for size and age-structure + # plots? (FALSE will set a suitable scale for + # each plot) +fcgrid = TRUE # Include a grid on the filled contour plots? +ncolshov = 200 # Target number of colours for Hovmoller diagrams. +hovgrid = TRUE # Include a grid on the Hovmoller plots? +legwhere = "topleft" # Where should I place the legend? +inset = 0.01 # Inset between legend and edge of plot region. +scalleg = 0.40 # Expand y limits by this relative amount to fit + # the legend +cex.main = 0.8 # Scale coefficient for the title +theta = 315. # Azimuth for perspective projection +phi = 30. # Vertical angle for perspective projection +ltheta = -210. # Azimuth angle for light +shade = 0.125 # Shade intensity +expz = 0.5 # Expansion factor for Z axis +cexmin = 0.5 # Minimum "head" size of the lollipop +cexmax = 3.0 # Maximum "head" size of the lollipop +ylnudge = 0.05 # Nudging factor for ylimit +ptype = "l" # Type of plot +ptyped = "p" # Type of plot +ptypeb = "o" # Type of plot +drought.mark = mydroughtmark # Put a background to highlight droughts? +drought.yeara = mydroughtyeara # First year that has drought +drought.yearz = mydroughtyearz # Last year that has drought +months.drought = mymonthsdrought # Months with drought +ibackground = mybackground # Background settings (check load_everything.r) +#------------------------------------------------------------------------------------------# + + + +#------ Miscellaneous settings. -----------------------------------------------------------# +slz.min = -5.0 # The deepest depth that trees access water. +idbh.type = myidbhtype # Type of DBH class + # 1 -- Every 10 cm until 100cm; > 100cm + # 2 -- 0-10; 10-20; 20-35; 35-50; 50-70; > 70 (cm) + # 3 -- 0-10; 10-35; 35-55; > 55 (cm) +klight = myklight # Weighting factor for maximum carbon balance +corr.growth.storage = mycorrection # Correction factor to be applied to growth and + # storage respiration +iallom = myallom # Allometry to use +isoil.hydro = myslhydro # Soil hydrology method +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# NO NEED TO CHANGE ANYTHING BEYOND THIS POINT UNLESS YOU ARE DEVELOPING THE CODE... # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + + +#----- Load some packages and scripts. ----------------------------------------------------# +source(file.path(srcdir,"load.everything.r")) +#------------------------------------------------------------------------------------------# + + +#----- Set how many formats we must output. -----------------------------------------------# +outform = tolower(outform) +nout = length (outform) +#------------------------------------------------------------------------------------------# + + +#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# +options(locatorBell=FALSE) +#------------------------------------------------------------------------------------------# + + +#----- Load observations. -----------------------------------------------------------------# +obsrfile = file.path(srcdir,"LBA_MIP.v9.RData") +load(file=obsrfile) + +#----- Define plot window size ------------------------------------------------------------# +size = plotsize(proje=FALSE,paper=paper) +#------------------------------------------------------------------------------------------# + + + +#---- Create the main output directory in case there is none. -----------------------------# +if (! file.exists(outroot)) dir.create(outroot) +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Big place loop starts here... # +#------------------------------------------------------------------------------------------# +for (place in myplaces){ + + #----- Retrieve default information about this place and set up some variables. --------# + thispoi = locations(where=place,here=there,yearbeg=yearbeg,yearend=yearend + ,monthbeg=monthbeg) + inpref = thispoi$pathin + outmain = file.path(outroot,place) + outcsv = file.path(outmain,"csv_month") + lieu = thispoi$lieu + iata = thispoi$iata + suffix = thispoi$iata + yeara = thispoi$yeara + yearz = thispoi$yearz + meszz = thispoi$monz + + #---------------------------------------------------------------------------------------# + # Make sure we only deal with full years. # + #---------------------------------------------------------------------------------------# + if (monthbeg > 1) yeara = yeara + 1 + if (meszz < 12) yearz = yearz - 1 + monthbeg = 1 + meszz = 12 + if (yeara > yearz){ + cat(" - Yeara: ",yeara,"\n") + cat(" - Yearz: ",yearz,"\n") + cat(" - Prefix: ",inpref,"\n") + cat(" - Invalid years, will not process data...","\n") + q("no") + }#end if + #---------------------------------------------------------------------------------------# + + + #----- Create the directories in case they don't exist. --------------------------------# + if (! file.exists(outmain)) dir.create(outmain) + if (! file.exists(outcsv )) dir.create(outcsv ) + #---------------------------------------------------------------------------------------# + + + + #----- Decide how frequently the cohort-level variables should be saved. ---------------# + if ((yearend - yearbeg + 1) <= nyears.long){ + sasmonth = sasmonth.short + plot.ycomp = TRUE + }else{ + sasmonth = sasmonth.long + plot.ycomp = FALSE + }#end if + #---------------------------------------------------------------------------------------# + + + + + #----- Print a banner to entretain the user. -------------------------------------------# + cat(" + Post-processing output from ",lieu,"...","\n") + + + #---------------------------------------------------------------------------------------# + # Flush all variables that will hold the data. # + #---------------------------------------------------------------------------------------# + ntimes = (yearz-yeara-1)*12+meszz+(12-monthbeg+1) + nyears = yearz-yeara+1 + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Make the RData file name, then we check whether we must read the files again # + # or use the stored RData. Notice that the path is the same for plot_ycomp.r and # + # plot_monthly, so you don't need to read in the data twice. # + #---------------------------------------------------------------------------------------# + path.data = file.path(here,place,"rdata_month") + if (! file.exists(path.data)) dir.create(path.data) + ed22.rdata = file.path(path.data,paste(place,"RData",sep=".")) + ed22.status = file.path(path.data,paste("status_",place,".txt",sep="")) + if (reload.data && file.exists(ed22.rdata)){ + #----- Load the modelled dataset. ---------------------------------------------------# + cat(" - Loading previous session...","\n") + load(ed22.rdata) + tresume = datum$ntimes + 1 + if (ntimes > datum$ntimes){ + datum = update.monthly( new.ntimes = ntimes + , old.datum = datum + , montha = monthbeg + , yeara = yeara + , inpref = inpref + , slz.min = slz.min + )#end update.monthly + }#end if + #------------------------------------------------------------------------------------# + }else{ + cat(" - Starting new session...","\n") + tresume = 1 + datum = create.monthly( ntimes = ntimes + , montha = monthbeg + , yeara = yeara + , inpref = inpref + , slz.min = slz.min + )#end create.monthly + }#end if + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check whether we have anything to update. # + #---------------------------------------------------------------------------------------# + complete = tresume > ntimes + #---------------------------------------------------------------------------------------# + + + + #----- Copy some dimensions to scalars. ------------------------------------------------# + nzg = datum$nzg + nzs = datum$nzs + ndcycle = datum$ndcycle + isoilflg = datum$isoilflg + slz = datum$slz + slxsand = datum$slxsand + slxclay = datum$slxclay + ntext = datum$ntext + soil.prop = datum$soil.prop + dslz = datum$dslz + soil.depth = datum$soil.depth + soil.dry = datum$soil.dry + soil.poro = datum$soil.poro + ka = datum$ka + kz = datum$kz + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Loop over all times in case there is anything new to be read. # + #---------------------------------------------------------------------------------------# + if (! complete){ + + #------------------------------------------------------------------------------------# + # This function will read the files. # + #------------------------------------------------------------------------------------# + datum = read.q.files(datum=datum,ntimes=ntimes,tresume=tresume,sasmonth=sasmonth) + #------------------------------------------------------------------------------------# + + + #------ Save the data to the R object. ----------------------------------------------# + cat(" + Saving data to ",basename(ed22.rdata),"...","\n") + save(datum,file=ed22.rdata) + #------------------------------------------------------------------------------------# + }#end if (! complete) + #---------------------------------------------------------------------------------------# + + + #----- Update status file with latest data converted into R. ---------------------------# + latest = paste(datum$year[ntimes],datum$month[ntimes],sep=" ") + dummy = write(x=latest,file=ed22.status,append=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #----- Make some shorter versions of some variables. -----------------------------------# + mfac = datum$month + yfac = datum$year + emean = datum$emean + emsqu = datum$emsqu + qmean = datum$qmean + qmsqu = datum$qmsqu + szpft = datum$szpft + lu = datum$lu + patch = datum$patch + cohort = datum$cohort + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Remove all elements of the DBH/PFT class that do not have a single valid cohort # + # at any given time. # + #---------------------------------------------------------------------------------------# + empty = is.na(szpft$nplant) | szpft$nplant == 0 + for (vname in names(szpft)) szpft[[vname]][empty] = NA + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Convert mortality and recruitment so it is scaled between 0 and 100%. # + #---------------------------------------------------------------------------------------# + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) + #---------------------------------------------------------------------------------------# + + + #----- Find which PFTs, land uses and transitions we need to consider ------------------# + pftave = apply( X = szpft$agb[,ndbh+1,] + , MARGIN = 2 + , FUN = mean + , na.rm = TRUE + )#end apply + luave = apply( X = lu$agb + , MARGIN = 2 + , FUN = mean + , na.rm = TRUE + )#end apply + distave = apply(X=lu$dist,MARGIN=c(2,3),FUN=mean) + selpft = is.finite(pftave ) & pftave > 0. + sellu = is.finite(luave ) & luave > 0. + seldist = is.finite(distave) & distave > 0. + n.selpft = sum(selpft ) + n.sellu = sum(sellu ) + n.seldist = sum(seldist) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Create data frame with yearly averages. # + #---------------------------------------------------------------------------------------# + cat0(" + Create data frame with monthly averages.") + mglob = data.table( year = datum$year + , month = datum$month + , numdays = daymax(datum$month,datum$year) + , atm.prss = emean$atm.prss * 100. + , atm.temp = emean$atm.temp + t00 + , atm.shv = emean$atm.shv * 0.001 + , atm.vels = emean$atm.vels + , precip = emean$rain/daymax(datum$month,datum$year)/day.sec + , rshort.in = emean$rshort + , rlong.in = emean$rlong + , agb = emean$agb + , lai = emean$lai + , wai = emean$wai + , rshort.out = emean$rshort + , rlong.out = emean$rlong + , cas.height = emean$can.depth + , cas.prss = emean$can.prss * 100. + , cas.temp = emean$can.temp + t00 + , cas.shv = emean$can.shv * 0.001 + , gnd.temp = emean$gnd.temp + t00 + , leaf.temp = emean$leaf.temp + t00 + , wood.temp = emean$wood.temp + t00 + , soil.temp = emean$soil.temp.top + t00 + , soil.water = emean$soil.water.top + , soil.rmoist = emean$soil.wetness.top + , sfcw.temp = emean$sfcw.temp + t00 + , sfcw.fliq = emean$sfcw.fliq + , sfcw.mass = emean$sfcw.mass + , sfcw.depth = emean$sfcw.depth + , sfcw.cover = emean$sfcw.cover + , runoff = emean$runoff / day.sec + , leaf.water = emean$leaf.water + , wood.water = 0. * emean$leaf.water + , hflxca = emean$hflxca + , wflxca = emean$wflxca / day.sec + , hflxgc = emean$hflxgc + , wflxgc = emean$wflxgc / day.sec + , hflxlc = emean$hflxlc + , wflxlc = emean$wflxlc / day.sec + , hflxwc = emean$hflxwc + , wflxwc = emean$wflxwc / day.sec + , transp = emean$transp / day.sec + )#end data.frame + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # Write csv files with the output. # + #---------------------------------------------------------------------------------------# + cat0(" + Write output files.") + csv.emean = file.path(outcsv,paste0(place,"_emean.csv" )) + dummy = write.table(x=mglob ,file=csv.emean,quote=FALSE,sep=",",row.names=FALSE) + #---------------------------------------------------------------------------------------# + +}#end for (place in myplaces) +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/mrun.sh b/ED/Template/Template/mrun.sh deleted file mode 100755 index 29a0e5435..000000000 --- a/ED/Template/Template/mrun.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -#-----Change your settings here ----------------------------------------------------------# -here=`pwd` # Folder to start the run -queue='thisqueue' # Queue name -#------------------------------------------------------------------------------------------# - -if [ 'z'${1} = 'z' ] -then - echo 'Which m-file do you want to run (needs to be in current dir include .m)?' - read filenameIN -else - filenameIN=${1} -fi - -if [ 'z'${2} = 'z' ] -then - echo 'What run name do you want to use?' - read jobname -else - jobname=${2} -fi - - -joberrname=${jobname}'_err.out' - -module load math/matlab-R2009a 1>/dev/null 2>/dev/null - -#----- Submitting the job, we use a shell script so we can track the run on the fly -------# -bsub -q ${queue} -o ${joberrname} -J ${jobname} "matlab -nodesktop -nojvm -nosplash < ${filenameIN} > ${jobname}.out" - -echo " - Running ${filenameIN} under job name ${jobname}" diff --git a/ED/Template/Template/plot_eval_ed.r b/ED/Template/Template/plot_eval_ed.r index a70cf1d6c..0ac9e88e7 100644 --- a/ED/Template/Template/plot_eval_ed.r +++ b/ED/Template/Template/plot_eval_ed.r @@ -1080,7 +1080,7 @@ for (place in myplaces){ #----- Find and plot the distribution function for this hour. -----------# sd.obser = sd(this.obser[sel],na.rm=TRUE) - if (sd.obser %>% 1.0e-6){ + if (sd.obser %gt% 1.0e-6){ #----- Find the residuals. -------------------------------------------# this.resid = this.obser - this.model comp$residuals[sel] = this.resid[sel] diff --git a/ED/Template/Template/plot_monthly.r b/ED/Template/Template/plot_monthly.r index 41127c33a..81efb3fce 100644 --- a/ED/Template/Template/plot_monthly.r +++ b/ED/Template/Template/plot_monthly.r @@ -591,21 +591,57 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# - # Replace the mortality and recruitment exponential rates by the "interests" rates. # + # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# @@ -732,10 +768,10 @@ for (place in myplaces){ , na.rm = TRUE )#end apply distave = apply(X=lu$dist,MARGIN=c(2,3),FUN=mean) - selpftl = pftave %>% 0. - selpfts = pftave %>% 0. & (! (pft$key %in% "ALL") ) - sellu = luave %>% 0. - seldist = distave %>% 0. + selpftl = pftave %gt% 0. + selpfts = pftave %gt% 0. & (! (pft$key %in% "ALL") ) + sellu = luave %gt% 0. + seldist = distave %gt% 0. n.selpftl = sum(selpftl) n.selpfts = sum(selpfts) n.sellu = sum(sellu ) @@ -798,7 +834,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]][,ndbh+1,] if (plog){ #----- Eliminate non-positive values in case it is a log plot. -------------# - badlog = (! (thisvar %>% 0) ) & (! stackit) + badlog = (! (thisvar %gt% 0) ) & (! stackit) thisvar[badlog] = NA_real_ }#end if }else{ @@ -817,6 +853,7 @@ for (place in myplaces){ bottom = rep(0.,times=ntimes) }#end if + thisvar = ifelse(test=is.finite(thisvar),yes=thisvar,no=0.) thisvar = cbind(bottom,thisvar[,sequence(npft),drop=FALSE]) thisvar = t(apply(X=thisvar,MARGIN=1,FUN=cumsum)) }#end if (stackit) @@ -992,7 +1029,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]] if (plog){ xylog = "y" - badlog = ( ! (thisvar %>% 0) ) & (! stackit) + badlog = ( ! (thisvar %gt% 0) ) & (! stackit) thisvar[badlog] = NA_real_ }else{ xylog = "" @@ -1061,6 +1098,7 @@ for (place in myplaces){ bottom = rep(0.,times=ntimes) }#end if thisdbh = thisvar[,,p] + thisdbh = ifelse(test=is.finite(thisdbh),yes=thisdbh,no=0.) thisdbh = cbind(bottom,thisdbh[,sequence(ndbh),drop=FALSE]) thisdbh = t(apply(X=thisdbh,MARGIN=1,FUN=cumsum)) }else{ @@ -1912,7 +1950,7 @@ for (place in myplaces){ thisvar = lu[[vnam]] if (plog){ xylog = "y" - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }else{ xylog = "" @@ -2183,7 +2221,8 @@ for (place in myplaces){ legpos = themenow$legpos plotit = themenow$emean ylimit.fix = themenow$emean.lim - + thstack = themenow$stack + if (plotit){ #---------------------------------------------------------------------------------# @@ -2191,7 +2230,9 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# outdir = file.path(outpref,"theme_emean") if (! file.exists(outdir)) dir.create(outdir) - cat0(" + ",group," time series for several variables.") + cat0(" ~ ",group," time series for several variables.") + #---------------------------------------------------------------------------------# + #----- Define the number of layers. ----------------------------------------------# @@ -2199,6 +2240,43 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + ndat = length(emean[[vnames[1]]]) + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=0,nrow=ndat,ncol=nlayers+1) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,l] = ytheme[,l-1] + emean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=NA_real_,nrow=ndat,ncol=nlayers ) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,l] = emean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------# # Find the limit, make some room for the legend, and in case the field is a # @@ -2206,9 +2284,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# xlimit = pretty.xylim(u=as.numeric(datum$tomonth),fracexp=0.0,is.log=FALSE) if (any(! is.finite(ylimit.fix))){ - ylimit = NULL - for (l in 1:nlayers) ylimit = c(ylimit,emean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=plog) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=plog) }else{ ylimit = ylimit.fix }#end if @@ -2264,15 +2340,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , ncol = min(3,pretty.box(nlayers)$ncol) - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }else{ + #----- Line legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2298,12 +2392,33 @@ for (place in myplaces){ if (plotgrid){ abline(v=whenplot8$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ------------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = emean[[vnames[l]]] - points(x=datum$tomonth,y=thisvar,col=lcolours[l],lwd=llwd[l],type=ltype - ,pch=16,cex=0.8) - }#end for + #----- Plot data. -------------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ------------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(datum$tomonth,rev(datum$tomonth)) + , y = c(ytheme[,l] ,rev(ytheme [,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }else{ + #----- Plot lines. ---------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = datum$tomonth + , y = ytheme [,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2340,6 +2455,7 @@ for (place in myplaces){ legpos = themenow$legpos plotit = themenow$mmean ylimit.fix = themenow$mmean.lim + thstack = themenow$stack if (plotit){ @@ -2348,7 +2464,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# outdir = file.path(outpref,"theme_mmean") if (! file.exists(outdir)) dir.create(outdir) - cat0(" + ",group," time series for several variables.") + cat0(" ~ ",group," time series for several variables.") #----- Define the number of layers. ----------------------------------------------# @@ -2356,6 +2472,43 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + ndat = length(mmean[[vnames[1]]]) + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=0,nrow=ndat,ncol=nlayers+1) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,l] = ytheme[,l-1] + mmean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = matrix(data=NA_real_,nrow=ndat,ncol=nlayers ) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,l] = mmean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------# # Find the limit, make some room for the legend, and in case the field is a # @@ -2363,9 +2516,7 @@ for (place in myplaces){ #---------------------------------------------------------------------------------# xlimit = pretty.xylim(u=montmont,fracexp=0.0,is.log=plog) if (any (! is.finite(ylimit.fix))){ - ylimit = NULL - for (l in 1:nlayers) ylimit = c(ylimit,mmean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=plog) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=plog) }else{ ylimit = ylimit.fix }#end if @@ -2421,17 +2572,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , pch = 16 - , ncol = min(3,pretty.box(nlayers)$ncol) - , cex = 0.9*cex.ptsz - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }else{ + #----- Line legend. --------------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2457,12 +2624,33 @@ for (place in myplaces){ if (plotgrid){ abline(v=mplot$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ------------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = mmean[[vnames[l]]] - points(x=montmont,y=thisvar,col=lcolours[l],lwd=llwd[l],type=ltype - ,pch=16,cex=0.8) - }#end for + #----- Plot data. -------------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ------------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(montmont ,rev(montmont)) + , y = c(ytheme[,l],rev(ytheme [,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }else{ + #----- Plot lines. ---------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = montmont + , y = ytheme [,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #---------------------------------------------------------------------------# + }#end if (thstack) #------------------------------------------------------------------------------# @@ -2498,6 +2686,7 @@ for (place in myplaces){ unit = themenow$unit legpos = themenow$legpos plotit = themenow$qmean + thstack = themenow$stack if (plog){ xylog = "y" }else{ @@ -2514,18 +2703,66 @@ for (place in myplaces){ if (! file.exists(outdir)) dir.create(outdir) outtheme = file.path(outdir,prefix) if (! file.exists(outtheme)) dir.create(outtheme) - cat0(" + ",group," diurnal cycle for several variables.") + cat0(" ~ ",group," diurnal cycle for several variables.") #----- Define the number of layers. ----------------------------------------------# nlayers = length(vnames) - xlimit = range(thisday) - ylimit = NULL - for (l in sequence(nlayers)) ylimit = c(ylimit,umean[[vnames[l]]]) - ylimit = pretty.xylim(u=ylimit,fracexp=0.0,is.log=FALSE) #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # Create a matrix with all the layers. # + #---------------------------------------------------------------------------------# + if (thstack){ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = array(data=0,dim=c(dim(umean[[vnames[1]]]),nlayers+1)) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + layer.loop = sequence(nlayers+1)[-1] + for (l in layer.loop){ + #----- Layers are added as a stack. ----------------------------------------# + v.vnow = vnames[l-1] + ytheme[,,l] = ytheme[,,l-1] + umean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }else{ + #----- Initialise the data with all layers. -----------------------------------# + ytheme = array(data=0,dim=c(dim(umean[[vnames[1]]]),nlayers)) + #------------------------------------------------------------------------------# + + + #----- Add layers. ------------------------------------------------------------# + for (l in sequence(nlayers)){ + #----- Layers are added as they are in the original values. ----------------# + v.vnow = vnames[l] + ytheme[,,l] = umean[[v.vnow]] + #---------------------------------------------------------------------------# + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------------# + }#end if (thstack) + #---------------------------------------------------------------------------------# + + + + #----- Append the first hour of the day at the end. ------------------------------# + ytheme = abind(ytheme,ytheme[,1,,drop=FALSE],along=2) + #---------------------------------------------------------------------------------# + + + + #------ Find limits. -------------------------------------------------------------# + xlimit = range(thisday) + ylimit = pretty.xylim(u=c(ytheme),fracexp=0.0,is.log=FALSE) + #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# # Loop over all months. # #---------------------------------------------------------------------------------# @@ -2574,15 +2811,33 @@ for (place in myplaces){ par(mar=c(0.1,4.6,0.1,2.1)) plot.new() plot.window(xlim=c(0,1),ylim=c(0,1)) - legend( x = "bottom" - , inset = 0.0 - , legend = description - , col = lcolours - , lwd = llwd - , ncol = min(3,pretty.box(nlayers)$ncol) - , xpd = TRUE - , bty = "n" - )#end legend + if (thstack){ + #----- Fill legend. -----------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = rev(description) + , fill = rev(lcolours ) + , border = "transparent" + , density = -1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #------------------------------------------------------------------------# + }else{ + #----- Line legend. -----------------------------------------------------# + legend( x = "bottom" + , inset = 0.0 + , legend = description + , col = lcolours + , lwd = llwd + , ncol = 1 + , xpd = TRUE + , cex = 0.75 + , bty = "n" + )#end legend + #------------------------------------------------------------------------# + }#end if (thstack) #---------------------------------------------------------------------------# @@ -2608,16 +2863,37 @@ for (place in myplaces){ if (plotgrid){ abline(v=uplot$levels,h=axTicks(side=2),col=grid.colour,lty="solid") }#end if - #----- Plot lines. ---------------------------------------------------------# - for (l in sequence(nlayers)){ - thisvar = umean[[vnames[l]]] - thisvar = cbind(thisvar[,ndcycle],thisvar) - points(x=thisday,y=thisvar[pmon,],col=lcolours[l] - ,lwd=llwd[l],type=ltype,pch=16) - }#end for + #----- Plot data. ----------------------------------------------------------# + if (thstack){ + #----- Plot polygons. ---------------------------------------------------# + for (l in sequence(nlayers)){ + polygon( x = c(thisday ,rev(thisday )) + , y = c(ytheme[pmon,,l],rev(ytheme[pmon,,l+1])) + , col = lcolours[l] + , border = "transparent" + , density = -1 + , lty = "solid" + )#end points + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------# + }else{ + #----- Plot lines. ------------------------------------------------------# + for (l in sequence(nlayers)){ + points( x = thisday + , y = ytheme [pmon,,l] + , col = lcolours[ l] + , lwd = llwd [ l] + , type = ltype + , pch = 16 + , cex = 0.8 + )#end points + }#end for (l in sequence(nlayers)) + #------------------------------------------------------------------------# + }#end if (thstack) #---------------------------------------------------------------------------# + #----- Close the device. ---------------------------------------------------# dummy = close.plot(outform=outform[o]) #---------------------------------------------------------------------------# diff --git a/ED/Template/Template/plot_yearly.r b/ED/Template/Template/plot_yearly.r index 5b588afe9..ae1122ee8 100644 --- a/ED/Template/Template/plot_yearly.r +++ b/ED/Template/Template/plot_yearly.r @@ -428,18 +428,53 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# @@ -544,7 +579,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]][,ndbh+1,] if (plog){ #----- Eliminate non-positive values in case it is a log plot. -------------# - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }#end if }else{ @@ -683,7 +718,7 @@ for (place in myplaces){ thisvar = szpft[[vnam]] if (plog){ xylog = "y" - badlog = thisvar %<=% 0 + badlog = thisvar %le% 0 thisvar[badlog] = NA }else{ xylog = "" @@ -1055,7 +1090,7 @@ for (place in myplaces){ thisvar = lu[[vnam]] if (plog){ xylog = "y" - badlog = ! (thisvar %>% 0) + badlog = ! (thisvar %gt% 0) thisvar[badlog] = NA }else{ xylog = "" @@ -1949,7 +1984,7 @@ for (place in myplaces){ #------------------------------------------------------------------------------# # Discard cohorts that are near-recruit size. # #------------------------------------------------------------------------------# - keepww = popww %>% 0. + keepww = popww %gt% 0. ageww = ageww[keepww] dbhww = dbhww[keepww] pftww = pftww[keepww] diff --git a/ED/Template/Template/purge.sh b/ED/Template/Template/purge.sh deleted file mode 100755 index e8e920edd..000000000 --- a/ED/Template/Template/purge.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -rm -fvr analy -rm -fvr histo -rm -fvr output -rm -fvr rdata_* -mkdir analy -mkdir histo -mkdir output -rm -fv core.* fort.* *_out.out *_lsf.out *_out.err -rm -fv budget_* thermo_state_* photo_state_* diff --git a/ED/Template/Template/srun.sh b/ED/Template/Template/srun.sh deleted file mode 100755 index b65e514bb..000000000 --- a/ED/Template/Template/srun.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -#--------------------------------- Change settings here -----------------------------------# -here="pathhere/thispoly" # Folder to start the run -queue="thisqueue" # Queue name -joblog="${here}/serial_lsf.out" # Name of the job output -jobname="thisdesc-thispoly" # Job name -callserial="${here}/callserial.sh" # Name of executable -initrc="myinitrc" # Script to load before doing anything -thisnum=myorder # No longer used -sbatch=$(which sbatch) # SLURM command to submit job. -memory=thismemory # Requested memory (per CPU) -runtime=thistime # Requested time -#------------------------------------------------------------------------------------------# - - -#----- Source script. ---------------------------------------------------------------------# -. ${initrc} -#------------------------------------------------------------------------------------------# - - -#----- Erase old logfiles and joblogs -----------------------------------------------------# -if [ -s ${joblog} ] -then - rm -fv ${joblog} -fi -#------------------------------------------------------------------------------------------# - - - -#----- Submit the job, we use a shell script so we can track the run on the fly -----------# -${sbatch} -p ${queue} --mem-per-cpu=${memory} -t ${runtime} -o ${joblog} -J ${jobname} \ - -n 1 --wrap="${callserial} zzzzzzzz" -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/Template/whichrun.r b/ED/Template/Template/whichrun.r index b89fe317a..1677dc3d8 100644 --- a/ED/Template/Template/whichrun.r +++ b/ED/Template/Template/whichrun.r @@ -53,6 +53,7 @@ endrun = file.path(main,polyg,"serial_lsf.out" ) hasrun = file.path(main,polyg,"serial_out.out" ) haserr = file.path(main,polyg,"serial_out.err" ) hascrashed = file.path(main,polyg,"crashed_out.out") +hashydfail = file.path(main,polyg,"hydfail_out.out") hassigsegv = file.path(main,polyg,"sigsegv_out.out") hasbad.met = file.path(main,polyg,"bad_met_out.out") hasmetmiss = file.path(main,polyg,"metmiss_out.out") @@ -85,13 +86,15 @@ if (file.exists(hasrun) && ! sigsegv){ metmiss = ( length(grep("Cannot open met driver input file",simout)) > 0 | length(grep("Specify ED_MET_DRIVER_DB properly",simout)) > 0 ) crashed = length(grep("IFLAG1 problem." ,simout)) > 0 + hydfail = length(grep("Plant Hydrodynamics is off-track." ,simout)) > 0 bad.met = length(grep("Meteorological forcing has issues" ,simout)) > 0 stopped = length(grep("FATAL ERROR" ,simout)) > 0 finished = length(grep("ED-2\\.2 execution ends" ,simout)) > 0 - running = ! (metmiss || crashed || stopped || finished) + running = ! (metmiss || crashed || hydfail || stopped || finished) }else if (file.exists(hasrun) && sigsegv){ metmiss = FALSE crashed = FALSE + hydfail = FALSE bad.met = FALSE stopped = FALSE finished = FALSE @@ -100,6 +103,7 @@ if (file.exists(hasrun) && ! sigsegv){ metmiss = file.exists(hasmetmiss) bad.met = file.exists(hasbad.met) crashed = file.exists(hascrashed) + hydfail = file.exists(hashydfail) stopped = file.exists(hasstopped) sigsegv = file.exists(hassigsegv) finished = FALSE @@ -153,7 +157,7 @@ if (nhisto > 0){ dummy = file.remove(tryhisto) if (finished){ finished = FALSE - running = ! (metmiss || crashed || stopped || finished) + running = ! (metmiss || crashed || hydfail || stopped || finished) }#end if }else{ hasoutput = TRUE @@ -351,6 +355,8 @@ if (running && hasoutput){ status = paste(polyg,yyyy,mm,dd,hhhh,"SIGSEGV",agb,bsa,lai,scb,npa,sep=" ") }else if(crashed){ status = paste(polyg,yyyy,mm,dd,hhhh,"CRASHED",agb,bsa,lai,scb,npa,sep=" ") +}else if(hydfail){ + status = paste(polyg,yyyy,mm,dd,hhhh,"HYDFAIL",agb,bsa,lai,scb,npa,sep=" ") }else if(bad.met){ status = paste(polyg,yyyy,mm,dd,hhhh,"BAD_MET",agb,bsa,lai,scb,npa,sep=" ") }else if (metmiss){ diff --git a/ED/Template/Template/yearly_ascii.r b/ED/Template/Template/yearly_ascii.r index 63047156e..7b8df3af6 100644 --- a/ED/Template/Template/yearly_ascii.r +++ b/ED/Template/Template/yearly_ascii.r @@ -414,21 +414,58 @@ for (place in myplaces){ #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Convert mortality and recruitment so it is scaled between 0 and 100%. # #---------------------------------------------------------------------------------------# - szpft$mort = 100. * (1.0 - exp(- szpft$mort ) ) - szpft$dimort = 100. * (1.0 - exp(- szpft$dimort ) ) - szpft$ncbmort = 100. * (1.0 - exp(- szpft$ncbmort ) ) - szpft$recrpft = 100. * ( exp( szpft$recr ) - 1.0) - szpft$agb.mort = 100. * (1.0 - exp(- szpft$agb.mort ) ) - szpft$agb.dimort = 100. * (1.0 - exp(- szpft$agb.dimort ) ) - szpft$agb.ncbmort = 100. * (1.0 - exp(- szpft$agb.ncbmort ) ) - szpft$agb.recrpft = 100. * ( exp( szpft$agb.recr ) - 1.0) - szpft$bsa.mort = 100. * (1.0 - exp(- szpft$bsa.mort ) ) - szpft$bsa.dimort = 100. * (1.0 - exp(- szpft$bsa.dimort ) ) - szpft$bsa.ncbmort = 100. * (1.0 - exp(- szpft$bsa.ncbmort ) ) - szpft$bsa.recrpft = 100. * ( exp( szpft$bsa.recr ) - 1.0) + struct = c("szpft","emean","mmean","ymean") + struct = struct[struct %in% ls()] + nstruct = length(struct) + mort.list = c( "mort", "dimort", "ncbmort", "hydmort","fire.lethal" + ,"agb.mort","agb.dimort","agb.ncbmort","agb.hydmort" + ,"bsa.mort","bsa.dimort","bsa.ncbmort","bsa.hydmort" + )#end c + recr.list = c( "recr","agb.recr","bsa.recr") + for (s in sequence(nstruct)){ + #----- Copy structure to a temporary variable. --------------------------------------# + stnow = struct[s] + xmean = get(struct[s]) + #------------------------------------------------------------------------------------# + + + #----- Select mortality and recruitment variables to update. ------------------------# + mort.check = mort.list[mort.list %in% names(xmean)] + nmort.check = length(mort.check) + recr.check = recr.list[recr.list %in% names(xmean)] + nrecr.check = length(recr.check) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through mortality variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (m in sequence(nmort.check)){ + mort.now = mort.check[m] + xmean[[mort.now]] = 100. * ( 1.0 - exp( - xmean[[mort.now]]) ) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Loop through recruitment variables, make them "interest rates". # + #------------------------------------------------------------------------------------# + for (r in sequence(nrecr.check)){ + recr.now = recr.check[r] + xmean[[recr.now]] = 100. * ( exp( + xmean[[recr.now]] ) - 1.0) + }#end for (m in sequence(nmort.check)) + #------------------------------------------------------------------------------------# + + + #------ Update structure. -----------------------------------------------------------# + dummy = assign(x=stnow,value=xmean) + #------------------------------------------------------------------------------------# + }#end for (s in seq_along(struct)) #---------------------------------------------------------------------------------------# diff --git a/ED/Template/bring_scripts.sh b/ED/Template/bring_scripts.sh index f4d20a56d..5bc552f2b 100755 --- a/ED/Template/bring_scripts.sh +++ b/ED/Template/bring_scripts.sh @@ -11,18 +11,28 @@ then #------ No platform provided. Try to guess, and if failed, then prompts the user. -----# host=$(hostname -s) case ${host} in - rclogin*|holy*|moorcroft*|rcnx*) platform="SLURM" ;; - au*|ha*) platform="PBS" ;; - sdumont*) platform="SLURM" ;; - sun-master|cmm*) platform="sun-lncc" ;; + rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + #----- Use SLURM scripts. --------------------------------------------------------# + platform="SLURM" + #---------------------------------------------------------------------------------# + ;; + au*|ha*|sun-master|cmm*) + #----- Use PBS scripts. ----------------------------------------------------------# + platform="PBS" + #---------------------------------------------------------------------------------# + ;; *) + #----- Host name is not one of the known ones. -----------------------------------# echo -n "Failed guessing platform from node name. Please type the name: " read platform + #---------------------------------------------------------------------------------# ;; esac - + #---------------------------------------------------------------------------------------# else + #------ Platform is provided as argument. ----------------------------------------------# platform=${1} + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# @@ -62,4 +72,5 @@ fi #----- Copy all scripts from the script pool. ---------------------------------------------# /bin/cp -v ./scripts/${platform}/*.sh . +/bin/cp -v ./scripts/COMMON/*.sh . #------------------------------------------------------------------------------------------# diff --git a/ED/Template/compare_equilibrium.r b/ED/Template/compare_equilibrium.r index 23715e718..9444b608f 100644 --- a/ED/Template/compare_equilibrium.r +++ b/ED/Template/compare_equilibrium.r @@ -306,7 +306,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "agb" , desc = "Above-ground biomass" , unit = untab$kgcom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -320,7 +320,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "bsa" , desc = "Basal area" , unit = untab$m2om2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -334,7 +334,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "lai" , desc = "Leaf area index" , unit = untab$m2lom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -348,7 +348,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tai" , desc = "Tree area index" , unit = untab$m2lom2 - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , szpftvar = TRUE @@ -610,8 +610,8 @@ for (p in sequence(nsites)){ #---------------------------------------------------------------------------------# # Eliminate cohorts that are too small for AGB and basal area estimates. # #---------------------------------------------------------------------------------# - agbco = ifelse(dbhco %>=% this$dbh.min, agbco, 0.) - bsaco = ifelse(dbhco %>=% this$dbh.min, bsaco, 0.) + agbco = ifelse(dbhco %ge% this$dbh.min, agbco, 0.) + bsaco = ifelse(dbhco %ge% this$dbh.min, bsaco, 0.) #---------------------------------------------------------------------------------# diff --git a/ED/Template/compare_hourly.r b/ED/Template/compare_hourly.r index 5b10b79c2..65de2af89 100644 --- a/ED/Template/compare_hourly.r +++ b/ED/Template/compare_hourly.r @@ -333,7 +333,7 @@ compvar[[ n]] = list( vnam = "ustar" , symbol = "u^symbol(\"\\052\")" , desc = "Friction velocity" , unit = untab$mos - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#3B24B3" @@ -347,7 +347,7 @@ compvar[[ n]] = list( vnam = "cflxca" , symbol = "dot(C)[a*e]" , desc = "Carbon dioxide flux" , unit = untab$umolcom2os - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#AB8C3D" @@ -361,7 +361,7 @@ compvar[[ n]] = list( vnam = "cflxst" , symbol = "dot(C)[s*t*o*r]" , desc = "Carbon dioxide storage" , unit = untab$umolcom2os - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "orangered" , hue.high = "blue" , col = "#7D6E93" @@ -375,7 +375,7 @@ compvar[[ n]] = list( vnam = "nee" , symbol = "N*E*E" , desc = "Net ecosystem exchange" , unit = untab$umolcom2os - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#A3CC52" @@ -389,7 +389,7 @@ compvar[[ n]] = list( vnam = "nep" , symbol = "N*E*P" , desc = "Net ecosystem productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , col = "#A3CC52" @@ -403,7 +403,7 @@ compvar[[ n]] = list( vnam = "reco" , symbol = "dot(R)[E*c*o]" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#AB8C3D" @@ -417,7 +417,7 @@ compvar[[ n]] = list( vnam = "gpp" , symbol = "G*P*P" , desc = "Gross primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "clife" + , cscheme.mean = "prgn" , hue.low = "purple" , hue.high = "green" , col = "#306614" @@ -431,7 +431,7 @@ compvar[[ n]] = list( vnam = "parup" , symbol = "dot(Q)[P*A*R]^symbol(\"\\335\")" , desc = "Outgoing PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#143305" @@ -445,7 +445,7 @@ compvar[[ n]] = list( vnam = "rshortup" , symbol = "dot(Q)[S*W]^symbol(\"\\335\")" , desc = "Outgoing shortwave radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#2996CC" @@ -459,7 +459,7 @@ compvar[[ n]] = list( vnam = "rlongup" , symbol = "dot(Q)[L*W]^symbol(\"\\335\")" , desc = "Outgoing longwave radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#E65C17" @@ -473,7 +473,7 @@ compvar[[ n]] = list( vnam = "hflxca" , symbol = "dot(Q)[a*e]" , desc = "Sensible heat flux" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#990F0F" @@ -487,7 +487,7 @@ compvar[[ n]] = list( vnam = "wflxca" , symbol = "dot(W)[a*e]" , desc = "Water vapour flux" , unit = untab$kgwom2oday - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0A4766" @@ -501,7 +501,7 @@ compvar[[ n]] = list( vnam = "can.temp" , symbol = "T[a]" , desc = "CAS Temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#4D0404" @@ -515,7 +515,7 @@ compvar[[ n]] = list( vnam = "can.shv" , symbol = "w[a]" , desc = "CAS specific humidity" , unit = untab$gwokg - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#160959" @@ -529,7 +529,7 @@ compvar[[ n]] = list( vnam = "can.co2" , symbol = "c[a]" , desc = "CAS CO2 mix. ratio" , unit = untab$umolcomol - , cscheme.mean = "iclife" + , cscheme.mean = "iprgn" , hue.low = "green" , hue.high = "purple" , col = "#4B6614" @@ -543,7 +543,7 @@ compvar[[ n]] = list( vnam = "soil.temp" , symbol = "T[s*o*i*l]" , desc = "Soil temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#7D6E93" @@ -557,7 +557,7 @@ compvar[[ n]] = list( vnam = "soil.water" , symbol = "vartheta[s*o*i*l]" , desc = "Soil moisture" , unit = untab$m3wom3 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#00AAAF" @@ -571,7 +571,7 @@ compvar[[ n]] = list( vnam = "soil.wetness" , symbol = "hat(w)[s*o*i*l]" , desc = "Soil wetness" , unit = untab$pc - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#00F3FB" @@ -595,7 +595,7 @@ control[[n]] = list( vnam = "rshort" , symbol = "S*W^symbol(\"\\337\")" , desc = "Incoming shortwave radiation" , unit = untab$wom2 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#FF5700" @@ -608,7 +608,7 @@ control[[n]] = list( vnam = "par" , symbol = "P*A*R^symbol(\"\\337\")" , desc = "Incoming PAR" , unit = untab$umolom2os - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -621,7 +621,7 @@ control[[n]] = list( vnam = "rlong" , symbol = "L*W^symbol(\"\\337\")" , desc = "Incoming longwave radiation" , unit = untab$wom2 - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#A00014" @@ -634,7 +634,7 @@ control[[n]] = list( vnam = "atm.prss" , symbol = "p(e*f*t)" , desc = "Air pressure" , unit = untab$hpa - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#520485" @@ -647,7 +647,7 @@ control[[n]] = list( vnam = "atm.temp" , symbol = "T(e*f*t)" , desc = "Air temperature" , unit = untab$degC - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#FF5700" @@ -660,7 +660,7 @@ control[[n]] = list( vnam = "atm.shv" , symbol = "w(e*f*t)" , desc = "Air specific humidity" , unit = untab$gwokg - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -673,7 +673,7 @@ control[[n]] = list( vnam = "atm.vels" , symbol = "u(e*f*t)" , desc = "Wind speed" , unit = untab$mos - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#520485" @@ -686,7 +686,7 @@ control[[n]] = list( vnam = "rain" , symbol = "dot(W)(e*f*t)" , desc = "Precipitation rate" , unit = untab$kgwom2oday - , cscheme.mean = "ipanoply" + , cscheme.mean = "rdbu" , hue.low = "orangered" , hue.high = "blue" , col = "#0742C3" @@ -699,7 +699,7 @@ control[[n]] = list( vnam = "atm.vpdef" , symbol = "e(e*f*t)" , desc = "Vapour pressure deficit" , unit = untab$hpa - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , col = "#FF5700" @@ -1534,7 +1534,7 @@ for (p in loop.sites){ #----- Create a quick filter for different u*. --------------------------------------# ustar.eco = ifelse(obser$measured.ustar & measured.co2,obser$ustar,NA) - ust.measured.eco = outer(ustar.eco,obser$ust.filter,FUN='%>=%') + ust.measured.eco = outer(ustar.eco,obser$ust.filter,FUN='%ge%') #------------------------------------------------------------------------------------# }#end if #---------------------------------------------------------------------------------------# @@ -8997,7 +8997,7 @@ if (plot.skill.taylor){ #------------------------------------------------------------------------------# comp = res[[iata]]$sim[[simul.key[1]]][[this.vnam]] sdev.obs.now = sqrt(comp$obs.moment[cc,d,nseason,2]) - sel = sel & sdev.obs.now %>% 0 + sel = sel & sdev.obs.now %gt% 0 n.sel = sum(sel) #------------------------------------------------------------------------------# @@ -9537,7 +9537,7 @@ if (plot.skill.taylor){ #----- Select fortnightly averages. ----------------------------------------# sel = is.finite(obs[[this.fnmean]][,cc]) sdev.obs.now = sd(obs[[this.fnmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.fnmean]][sel,cc] this.mod = mod[[this.fnmean]][sel,cc] percent.skill[p,d] = sum(sel) @@ -9545,7 +9545,7 @@ if (plot.skill.taylor){ #----- Select daily averages. ----------------------------------------------# sel = is.finite(obs[[this.dmean]][,cc]) sdev.obs.now = sd(obs[[this.dmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.dmean]][sel,cc] this.mod = mod[[this.dmean]][sel,cc] percent.skill[p,d] = sum(sel) @@ -9558,7 +9558,7 @@ if (plot.skill.taylor){ sel = d.sel & s.sel & o.sel sel = ifelse(is.na(sel),FALSE,sel) sdev.obs.now = sd(obs[[this.vnam]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.vnam]][sel,cc] this.mod = mod[[this.vnam]][sel,cc] if (sum(d.sel & s.sel) > 0){ @@ -9777,7 +9777,7 @@ if (plot.skill.taylor){ for (p in sequence(nsites)){ iata = sites$iata[p] this.diel = diel.key[d] - if (percent.skill[p,d] %>% 0){ + if (percent.skill[p,d] %gt% 0){ pair.now = list.skill[[iata]][[this.diel]] }else{ pair.now = list(obs=c(NA,NA,NA),mod=c(NA,NA,NA)) @@ -10278,7 +10278,7 @@ if (plot.skill.taylor){ sel = ( is.finite(obs[[this.fnmean]][,cc]) & this.vnam %in% v.inc ) sdev.obs.now = sd(obs[[this.fnmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.fnmean]][sel,cc] this.mod = mod[[this.fnmean]][sel,cc] percent.skill[v,p] = sum(sel) @@ -10287,7 +10287,7 @@ if (plot.skill.taylor){ sel = ( is.finite(obs[[this.dmean]][,cc]) & this.vnam %in% v.inc ) sdev.obs.now = sd(obs[[this.dmean]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.dmean]][sel,cc] this.mod = mod[[this.dmean]][sel,cc] percent.skill[v,p] = sum(sel) @@ -10300,7 +10300,7 @@ if (plot.skill.taylor){ sel = d.sel & s.sel & o.sel sel = ifelse(is.na(sel),FALSE,sel) sdev.obs.now = sd(obs[[this.vnam]][sel,cc],na.rm=TRUE) - sel = sel & sdev.obs.now %>% 0. + sel = sel & sdev.obs.now %gt% 0. this.obs = obs[[this.vnam]][sel,cc] this.mod = mod[[this.vnam]][sel,cc] if (sum(d.sel & s.sel) > 0){ @@ -11048,7 +11048,7 @@ if (plot.soil.skill.taylor){ comp = res[[iata]]$sim[[simul.key[1]]][[this.vnam]] sdev.obs.now = sqrt(comp$obs.moment[cc,d,nseason,2]) sdev.mod.now = sqrt(comp$mod.moment[cc,d,nseason,2]) - sel = sel & sdev.obs.now %>% 0 + sel = sel & sdev.obs.now %gt% 0 n.sel = sum(sel) #------------------------------------------------------------------------# @@ -12117,7 +12117,7 @@ if (make.summ.table){ #------ Aggregate data to the total. ------------------------------------------# - if (df.now %>% 0 & o.sdev.now %>% 0){ + if (df.now %gt% 0 & o.sdev.now %gt% 0){ s.table$n [v] = s.table$n [v] + n.now s.table$df [v] = s.table$df [v] + df.now s.table$bias [v] = s.table$bias [v] + n.now * bias.now diff --git a/ED/Template/compare_longterm.r b/ED/Template/compare_longterm.r index ab20899ac..6f325f883 100644 --- a/ED/Template/compare_longterm.r +++ b/ED/Template/compare_longterm.r @@ -14,7 +14,7 @@ graphics.off() # Here is the user defined variable section. # #------------------------------------------------------------------------------------------# here = getwd() # Current directory -srcdir = "/n/home00/mlongo/util/Rsc" # Script directory +srcdir = "/n/home00/mlongo/Util/Rsc" # Script directory ibackground = 0 # Make figures compatible to background # 0 -- white # 1 -- black @@ -236,7 +236,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "agb" , desc = "Above-ground biomass" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -249,7 +249,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ba" , desc = "Basal area" , unit = untab$m2om2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -262,7 +262,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "lai" , desc = "Leaf area index" , unit = untab$m2lom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -275,7 +275,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "gpp" , desc = "Gross primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -288,7 +288,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "npp" , desc = "Net primary productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -301,7 +301,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -314,7 +314,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "cba" , desc = "Carbon balance" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -327,7 +327,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -340,7 +340,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "nep" , desc = "Net Ecosystem Productivity" , unit = untab$kgcom2oyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -353,7 +353,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -366,7 +366,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wflxca" , desc = "Water vapour flux" , unit = untab$kgwom2oday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -379,7 +379,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "transp" , desc = "Transpiration" , unit = untab$kgwom2oday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -392,7 +392,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "bowen" , desc = "Bowen ratio" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -405,7 +405,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tratio" , desc = "Transpiration ratio" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -418,7 +418,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ustar" , desc = "Friction velocity" , unit = untab$mos - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -431,7 +431,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshortup" , desc = "Upward SW radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -444,7 +444,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "albedo" , desc = "Albedo" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -457,7 +457,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rlongup" , desc = "Upward LW radiation" , unit = untab$wom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -470,7 +470,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "parup" , desc = "Upward PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -483,7 +483,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.gnd" , desc = "Ground absorption - PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -496,7 +496,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshort.gnd" , desc = "Ground absorption - SW" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -509,7 +509,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gpp" , desc = "Leaf GPP" , unit = untab$kgcom2loyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -522,7 +522,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = untab$kgwom2loday - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -535,7 +535,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.temp" , desc = "Leaf temperature" , unit = untab$degC - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -548,7 +548,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.vpd" , desc = "Leaf VPD" , unit = untab$hpa - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -561,7 +561,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf" , desc = "Leaf Absorption - PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -574,7 +574,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.beam" , desc = "Leaf Absorption - Direct PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -587,7 +587,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.diff" , desc = "Leaf Absorption - Diffuse PAR" , unit = untab$umolom2os - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -600,7 +600,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par" , desc = "Norm. Leaf Absorption - PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -613,7 +613,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.beam" , desc = "Norm. Leaf Absorption - Direct PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -626,7 +626,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.diff" , desc = "Norm. Leaf Absorption - Diffuse PAR" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -639,7 +639,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.light" , desc = "Light-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -652,7 +652,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.rubp" , desc = "RuBP-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -665,7 +665,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.co2" , desc = "CO2-limited Assimilation" , unit = untab$umolom2los - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -678,7 +678,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "fast.soil.c" , desc = "Fast soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -691,7 +691,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "struct.soil.c" , desc = "Structural soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -704,7 +704,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "slow.soil.c" , desc = "Slow soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -717,7 +717,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "tot.soil.c" , desc = "Soil carbon" , unit = untab$kgcom2 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -730,7 +730,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "can.depth" , desc = "Mean canopy height" , unit = untab$m - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -743,7 +743,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "can.area" , desc = "Mean canopy area" , unit = untab$empty - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -756,7 +756,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wood.dens" , desc = "Mean wood density" , unit = untab$gocm3 - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = FALSE @@ -769,7 +769,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "firemort" , desc = "Fire mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -782,7 +782,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "ncbmort" , desc = "Density-dependent mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -795,7 +795,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "dimort" , desc = "Density independent mortality" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -808,7 +808,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "mort" , desc = "Mortality rate" , unit = untab$pcpopoyr - , cscheme.mean = "panoply" + , cscheme.mean = "irdbu" , hue.low = "blue" , hue.high = "orangered" , szpftvar = TRUE @@ -1454,12 +1454,12 @@ if (reload.range && file.exists(rdata.range)){ #------ Bowen ratio: use the patch-level variable. ----------------------# hflxca = datum$patch$hflxca [[stamp]] qwflxca = datum$patch$qwflxca[[stamp]] - vnow = ifelse(qwflxca %!=% 0, hflxca/qwflxca, NA) + vnow = ifelse(qwflxca %ne% 0, hflxca/qwflxca, NA) }else if(this.vnam %in% "tratio"){ #------ Bowen ratio: use the patch-level variable. ----------------------# transp = datum$patch$transp[[stamp]] wflxca = datum$patch$wflxca[[stamp]] - vnow = ifelse(wflxca %!=% 0, transp/wflxca, NA) + vnow = ifelse(wflxca %ne% 0, transp/wflxca, NA) }else if(this.patchvar){ #------ Use patch-level info if available... ----------------------------# vnow = datum$patch [[this.vnam]][[stamp]] @@ -1663,20 +1663,20 @@ for (p in loop.sites){ szpft = NULL patch = NULL }else if (this.vnam %in% "bowen"){ - emean = with(datum$emean,ifelse(qwflxca %!=% 0,hflxca/qwflxca,NA)) + emean = with(datum$emean,ifelse(qwflxca %ne% 0,hflxca/qwflxca,NA)) szpft = NULL patch = with( data = datum$patch - , expr = mapply( FUN = function(h,qw) ifelse(qw%!=%0,h/qw,NA) + , expr = mapply( FUN = function(h,qw) ifelse(qw%ne%0,h/qw,NA) , h = hflxca , qw = qwflxca , SIMPLIFY = FALSE )#end mapply )#end with }else if (this.vnam %in% "tratio"){ - emean = with(datum$emean,ifelse(wflxca %!=% 0,transp/wflxca,NA)) + emean = with(datum$emean,ifelse(wflxca %ne% 0,transp/wflxca,NA)) szpft = NULL patch = with( data = datum$patch - , expr = mapply( FUN = function(tp,w) ifelse(w%!=%0,tp/w,NA) + , expr = mapply( FUN = function(tp,w) ifelse(w%ne%0,tp/w,NA) , tp = transp , w = wflxca , SIMPLIFY = FALSE @@ -4115,7 +4115,7 @@ if (plot.ym.patch){ # Update range. # #---------------------------------------------------------------------------# if (zlog){ - ym.patch = ifelse(ym.patch %>% 0.0,ym.patch,NA) + ym.patch = ifelse(ym.patch %gt% 0.0,ym.patch,NA) yrange[,p,s] = range(c(yrange[,p,s],ym.patch),finite=TRUE) }else if (this.vnam %in% "bowen"){ ym.patch = pmax(bmn,pmin(bmx,ym.patch)) @@ -4560,7 +4560,7 @@ if (plot.zm.patch){ zm.patch = model[[this.vnam]]$zm.age }#end if if (zlog){ - zm.patch = ifelse(zm.patch %>% 0.0,zm.patch,NA) + zm.patch = ifelse(zm.patch %gt% 0.0,zm.patch,NA) }else if (this.vnam %in% "bowen"){ zm.patch = pmax(bmn,pmin(bmx,zm.patch)) + 0. * zm.patch }else if (this.vnam %in% "tratio"){ @@ -5056,7 +5056,7 @@ if (plot.xyz.patch){ # Update range. # #---------------------------------------------------------------------------# if (zlog){ - mm.patch = ifelse(mm.patch %>% 0.0,mm.patch,NA) + mm.patch = ifelse(mm.patch %gt% 0.0,mm.patch,NA) }else if (this.vnam %in% "bowen"){ mm.patch = pmax(bmn,pmin(bmx,mm.patch)) + 0. * mm.patch }else if (this.vnam %in% "tratio"){ diff --git a/ED/Template/compare_patch.r b/ED/Template/compare_patch.r index 9c55a3d1b..fdcf3e9b9 100644 --- a/ED/Template/compare_patch.r +++ b/ED/Template/compare_patch.r @@ -145,7 +145,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zupr.gpp" , desc = "GPP - Upper canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -156,7 +156,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zmid.gpp" , desc = "GPP - Mid-canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -167,7 +167,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "zlwr.gpp" , desc = "GPP - Lower canopy" , unit = "kgwom2oday" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -178,7 +178,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "gpp" , desc = "Gross primary productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "gpp" , clcum = "nplant" @@ -189,7 +189,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "npp" , desc = "Net primary productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "npp" , clcum = "nplant" @@ -200,7 +200,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = "kgcom2oyr" - , cscheme = "iatlas" + , cscheme = "ibrbg" , qmean = TRUE , clprof = "plant.resp" , clcum = "nplant" @@ -211,7 +211,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "cba" , desc = "Carbon balance" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = FALSE , clprof = "cba" , clcum = NA_character_ @@ -222,7 +222,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = "kgcom2oyr" - , cscheme = "iatlas" + , cscheme = "ibrbg" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -233,7 +233,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "nep" , desc = "Net Ecosystem Productivity" , unit = "kgcom2oyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -244,7 +244,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -255,7 +255,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "wflxca" , desc = "Water vapour flux" , unit = "kgwom2oday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -266,7 +266,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "transp" , desc = "Transpiration" , unit = "kgwom2oday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = "transp" , clcum = "nplant" @@ -277,7 +277,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshortup" , desc = "Upward SW radiation" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -288,7 +288,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rlongup" , desc = "Upward LW radiation" , unit = "wom2" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -299,7 +299,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "parup" , desc = "Upward PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -310,7 +310,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.gnd" , desc = "Ground absorption - PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -321,7 +321,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "rshort.gnd" , desc = "Ground absorption - SW" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -332,7 +332,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "sm.stress" , desc = "Soil moisture stress" , unit = "empty" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = NA_character_ , clcum = NA_character_ @@ -343,7 +343,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gpp" , desc = "Leaf GPP" , unit = "kgcom2loyr" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "leaf.gpp" , clcum = NA_character_ @@ -354,7 +354,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.temp" , desc = "Mean Leaf Temperature" , unit = "degC" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.temp" , clcum = NA_character_ @@ -365,7 +365,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.vpd" , desc = "Mean Leaf VPD" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.vpd" , clcum = NA_character_ @@ -376,7 +376,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = "kgwom2loday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = TRUE , clprof = "leaf.gsw" , clcum = NA_character_ @@ -387,7 +387,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf" , desc = "Leaf Absorption - PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par" , clcum = "lai" @@ -398,7 +398,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.beam" , desc = "Leaf Absorption - Direct PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.beam" , clcum = "lai" @@ -409,7 +409,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "par.leaf.diff" , desc = "Leaf Absorption - Diffuse PAR" , unit = "umolom2os" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.diff" , clcum = "lai" @@ -420,7 +420,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par" , desc = "Norm. Leaf Absorption - PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par" , clcum = NA_character_ @@ -431,7 +431,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.beam" , desc = "Norm. Leaf Absorption - Direct PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.beam" , clcum = NA_character_ @@ -442,7 +442,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "leaf.par.diff" , desc = "Norm. Leaf Absorption - Diffuse PAR" , unit = "umolom2los" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = TRUE , clprof = "leaf.par.diff" , clcum = NA_character_ @@ -453,7 +453,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.light" , desc = "Light-limited Assimilation" , unit = "umolom2los" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "assim.light" , clcum = NA_character_ @@ -464,7 +464,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "assim.rubp" , desc = "RuBP-limited Assimilation" , unit = "umolom2los" - , cscheme = "atlas" + , cscheme = "brbg" , qmean = TRUE , clprof = "assim.rubp" , clcum = NA_character_ @@ -475,7 +475,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lpar" , desc = "Daytime PAR absorportion by leaves" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -486,7 +486,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lvpd" , desc = "Daytime Leaf VPD" , unit = "hpa" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -497,7 +497,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.ltemp" , desc = "Daytime Leaf Temperature" , unit = "degC" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -508,7 +508,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.sms" , desc = "Daytime soil moisture stress" , unit = "empty" - , cscheme = "panoply" + , cscheme = "irdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -519,7 +519,7 @@ n = n + 1 compvar[[ n]] = list( vnam = "phap.lgsw" , desc = "Daytime stomatal conductance" , unit = "kgwom2loday" - , cscheme = "ipanoply" + , cscheme = "rdbu" , qmean = FALSE , clprof = NA_character_ , clcum = NA_character_ @@ -713,8 +713,8 @@ msize = plotsize(proje=FALSE,paper=mpaper,extendfc="lon",extfactor=f.ext/2) # Define some utility functions to determine derived patch variables. # #------------------------------------------------------------------------------------------# sum.soil.c.fun = function(fast,slow,struct) fast + slow + struct -bowen.fun = function(h,qw) ifelse(test = qw %!=% 0., yes = h/qw, no = NA) -tratio.fun = function(tp,w) ifelse(test = w %!=% 0., yes = tp/w, no = NA) +bowen.fun = function(h,qw) ifelse(test = qw %ne% 0., yes = h/qw, no = NA) +tratio.fun = function(tp,w) ifelse(test = w %ne% 0., yes = tp/w, no = NA) discard.fun = function(x) x * NA #------------------------------------------------------------------------------------------# @@ -741,7 +741,7 @@ layer.gpp.one.fun = function(dat,top,bot){ #------ We can't process empty data frames. --------------------------------------------# if (nrow(dat) > 0){ #----- Discard empty layers. --------------------------------------------------------# - dat = dat[dat$lai %>% 0,,drop=FALSE] + dat = dat[dat$lai %gt% 0,,drop=FALSE] #------------------------------------------------------------------------------------# }#end if (nrow(dat) > 0) #---------------------------------------------------------------------------------------# @@ -800,7 +800,7 @@ layer.gpp.one.fun = function(dat,top,bot){ #------ We can't process empty data frames. --------------------------------------------# if (nrow(dat) > 0){ #----- Discard empty layers. --------------------------------------------------------# - dat = dat[dat$lai %>% 0,,drop=FALSE] + dat = dat[dat$lai %gt% 0,,drop=FALSE] #------------------------------------------------------------------------------------# }#end if (nrow(dat) > 0) #---------------------------------------------------------------------------------------# diff --git a/ED/Template/compare_profiles.r b/ED/Template/compare_profiles.r index 79015524d..7219f4329 100644 --- a/ED/Template/compare_profiles.r +++ b/ED/Template/compare_profiles.r @@ -1810,7 +1810,7 @@ if (plot.site){ # for relative components, to avoid weird results. # #------------------------------------------------------------------------------# sel.day = tapply(X=model$diel[mn],INDEX=model$hour[mn],FUN=commonest) - sel.day = sel.day %==% 2 + sel.day = sel.day %eq% 2 #------------------------------------------------------------------------------# diff --git a/ED/Template/make_joborder.r b/ED/Template/make_joborder.r index 584a54388..3370fbbb2 100644 --- a/ED/Template/make_joborder.r +++ b/ED/Template/make_joborder.r @@ -29,6 +29,9 @@ lonlat = NULL # NULL - define runs local # (varrun/varlabel) #lonlat = file.path(here,"lonlat_input.txt") # Not NULL - read lon/lat from file, # and finish up settings below +add.coord = TRUE # Add coordinates to names +varalways = "ifire" # Variables to always appear in the + # jobname #------------------------------------------------------------------------------------------# @@ -132,128 +135,129 @@ if (! defjob && is.null(lonlat)){ #------------------------------------------------------------------------------------------# # Default properties. # #------------------------------------------------------------------------------------------# -default = list( run = "unnamed" - , iata = "xxx" - , lon = 0.00 - , lat = 0.00 - , yeara = "1967" - , montha = "01" - , daya = "01" - , timea = "0000" - , yearz = "2013" - , monthz = "01" - , dayz = "01" - , timez = "0000" - , init.mode = 6 - , iscenario = "default" - , isizepft = 0 - , iage = 30 - , imaxcohort = 50 - , isoilflg = 1 - , istext = 1 - , sand = -1.0 - , clay = -1.0 - , slsoc = 0.0266 - , slph = 4.7 - , slcec = 0.124 - , sldbd = 1192. - , depth = "F" - , isoil.hydro = 2 - , isoilbc = 1 - , sldrain = 90. - , scolour = 16 - , slzres = 0 - , queue = "linux.q" - , met.driver = "tower" - , dtlsm = 600. - , month.yrstep = 1 - , iphysiol = 3 - , vmfact.c3 = 1.00 - , vmfact.c4 = 1.00 - , mphoto.trc3 = 8.0 - , mphoto.tec3 = 7.2 - , mphoto.c4 = 4.0 - , bphoto.blc3 = 10000. - , bphoto.nlc3 = 1000. - , bphoto.c4 = 10000. - , kw.grass = 25. - , kw.tree = 20. - , gamma.c3 = 0.015 - , gamma.c4 = 0.025 - , d0.grass = 0.016 - , d0.tree = 0.016 - , alpha.c3 = 0.080 - , alpha.c4 = 0.040 - , klowco2 = round(0.7/39 * 1.e6) - , decomp.scheme = 5 - , rrffact = 1.000 - , growthresp = 0.300 - , lwidth.grass = 0.05 - , lwidth.bltree = 0.05 - , lwidth.nltree = 0.05 - , q10.c3 = 2.21 - , q10.c4 = 2.21 - , h2o.limit = 5 - , imort.scheme = 1 - , ddmort.const = 0.8 - , cbr.scheme = 0 - , isfclyrm = 4 - , icanturb = 0 - , ubmin = 1.00 - , ugbmin = 0.40 - , ustmin = 0.10 - , gamm = 13.0 - , gamh = 13.0 - , tprandtl = 1.00 - , ribmax = 0.50 - , atmco2 = 400. - , thcrit = -1.20 - , sm.fire = -1.40 - , ifire = 0 - , fire.parm = 0.5 - , ipercol = 0 - , runoff.time = 3600. - , imetrad = 5 - , ibranch = 1 - , icanrad = 2 - , ihrzrad = 0 - , crown.mod = 0 - , ltrans.vis = 0.05 - , lreflect.vis = 0.10 - , ltrans.nir = 0.200 - , lreflect.nir = 0.400 - , orient.tree = +0.100 - , orient.grass = -0.300 - , clump.tree = 0.80 - , clump.grass = 0.80 - , igoutput = 0 - , ivegtdyn = 1 - , ihydro = 0 - , istemresp = 1 - , istomata = 0 - , iplastic = 2 - , icarbonmort = 2 - , ihydromort = 0 - , igndvap = 0 - , iphen = -1 - , iallom = 3 - , ieconomics = 1 - , igrass = 1 - , ibigleaf = 0 - , integ.scheme = 1 - , nsub.euler = 50 - , irepro = 3 - , treefall = 0.0100 - , ianth.disturb = 0 - , ianth.dataset = "glu-331" - , sl.scale = 0 - , sl.yr.first = 1992 - , sl.nyrs = 50. - , biomass.harv = 0. - , skid.area = 1.0 - , skid.small = 0.60 - , skid.large = 1.00 - , felling.small = 0.35 +default = list( run = "unnamed" + , iata = "xxx" + , lon = 0.00 + , lat = 0.00 + , yeara = "1967" + , montha = "01" + , daya = "01" + , timea = "0000" + , yearz = "2013" + , monthz = "01" + , dayz = "01" + , timez = "0000" + , init.mode = 6 + , iscenario = "default" + , isizepft = 0 + , iage = 30 + , imaxcohort = 50 + , isoilflg = 1 + , istext = 1 + , sand = -1.0 + , clay = -1.0 + , slsoc = 0.0266 + , slph = 4.7 + , slcec = 0.124 + , sldbd = 1192. + , depth = "F" + , isoil.hydro = 2 + , isoilbc = 1 + , sldrain = 90. + , scolour = 16 + , slzres = 0 + , queue = "linux.q" + , met.driver = "tower" + , dtlsm = 600. + , month.yrstep = 1 + , iphysiol = 3 + , vmfact.c3 = 1.00 + , vmfact.c4 = 1.00 + , mphoto.trc3 = 8.0 + , mphoto.tec3 = 7.2 + , mphoto.c4 = 4.0 + , bphoto.blc3 = 10000. + , bphoto.nlc3 = 1000. + , bphoto.c4 = 10000. + , kw.grass = 25. + , kw.tree = 20. + , gamma.c3 = 0.015 + , gamma.c4 = 0.025 + , d0.grass = 0.016 + , d0.tree = 0.016 + , alpha.c3 = 0.080 + , alpha.c4 = 0.040 + , klowco2 = round(0.7/39 * 1.e6) + , decomp.scheme = 5 + , rrffact = 1.000 + , growthresp = 0.300 + , lwidth.grass = 0.05 + , lwidth.bltree = 0.05 + , lwidth.nltree = 0.05 + , q10.c3 = 2.21 + , q10.c4 = 2.21 + , h2o.limit = 5 + , imort.scheme = 1 + , ddmort.const = 0.8 + , cbr.scheme = 0 + , isfclyrm = 3 + , icanturb = 0 + , ubmin = 1.00 + , ugbmin = 0.40 + , ustmin = 0.10 + , gamm = 13.0 + , gamh = 13.0 + , tprandtl = 1.00 + , ribmax = 0.50 + , atmco2 = 400. + , thcrit = -1.20 + , sm.fire = -1.40 + , ifire = 0 + , fire.parm = 0.5 + , ipercol = 0 + , runoff.time = 3600. + , imetrad = 5 + , ibranch = 1 + , icanrad = 2 + , ihrzrad = 0 + , crown.mod = 0 + , ltrans.vis = 0.05 + , lreflect.vis = 0.10 + , ltrans.nir = 0.200 + , lreflect.nir = 0.400 + , orient.tree = +0.100 + , orient.grass = -0.300 + , clump.tree = 0.80 + , clump.grass = 0.80 + , igoutput = 0 + , ivegtdyn = 1 + , ihydro = 0 + , istemresp = 1 + , istomata = 0 + , iplastic = 2 + , icarbonmort = 2 + , ihydromort = 0 + , igndvap = 0 + , iphen = -1 + , iallom = 3 + , ieconomics = 1 + , igrass = 1 + , ibigleaf = 0 + , integ.scheme = 1 + , nsub.euler = 50 + , irepro = 3 + , treefall = 0.0100 + , ianth.disturb = 0 + , ianth.dataset = "glu-331" + , sl.scale = 0 + , sl.yr.first = 1992 + , sl.nyrs = 50. + , biomass.harv = 0. + , skid.area = 1.0 + , skid.dbh.thresh = 30. + , skid.small = 0.60 + , skid.large = 1.00 + , felling.small = 0.35 ) #end list #------------------------------------------------------------------------------------------# @@ -302,17 +306,17 @@ for (n in sequence(nvars)){ joborder$felling.small = sapply(myruns$sl.type,FUN=switch,ril=0.35,cvl=0.10,NA) }else if (name.now %in% "ihydrodyn"){ idx = myruns$ihydrodyn + 1 - joborder$ihydro = c(0,0,1)[idx] - joborder$istemresp = c(0,1,1)[idx] - joborder$istomata = c(0,0,1)[idx] - joborder$growthresp = c(0.30,0.45,0.45)[idx] - joborder$iphen = c(3,3,4)[idx] - joborder$iplastic = c(2,3,3)[idx] - joborder$icarbonmort = c(1,2,2)[idx] - joborder$ihydromort = c(0,0,1)[idx] - joborder$iallom = c(3,4,4)[idx] - joborder$h2o.limit = c(5,5,4)[idx] - joborder$igrass = c(1,1,0)[idx] + joborder$ihydro = c( 0, 1, 1, 1, 1, 1)[idx] + joborder$istemresp = c( 0, 0, 1, 1, 0, 0)[idx] + joborder$istomata = c( 0, 1, 1, 1, 1, 1)[idx] + joborder$growthresp = c(0.30,0.45,0.45,0.40,0.40,0.40)[idx] + joborder$iphen = c( 2, 2, 4, 4, 3, 5)[idx] + joborder$iplastic = c( 2, 2, 3, 3, 2, 2)[idx] + joborder$icarbonmort = c( 1, 1, 2, 2, 1, 1)[idx] + joborder$ihydromort = c( 0, 0, 1, 1, 0, 0)[idx] + joborder$iallom = c( 3, 3, 4, 3, 3, 5)[idx] + joborder$h2o.limit = c( 5, 3, 4, 3, 3, 3)[idx] + joborder$igrass = c( 1, 0, 0, 0, 0, 0)[idx] }else if (name.now %in% names(joborder)){ joborder[[name.now]] = myruns[[name.now]] }else{ @@ -344,6 +348,11 @@ if ( "biomass.harv" %in% names(varrun)){ )#end redundant forbidden = forbidden | redundant }#end if ("biomass.harv" %in% names(varrun)) +if ( all(c("ifire","sm.fire") %in% names(varrun))){ + smf.min = min(varrun$sm.fire) + redundant = joborder$ifire == 0 & joborder$sm.fire != smf.min + forbidden = forbidden | redundant +}#end if ( "ifire" %in% names(varrun)) joborder = joborder[! forbidden,] myruns = myruns[! forbidden,] nruns = nrow(myruns) @@ -421,6 +430,18 @@ if (is.null(lonlat)){ #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case coordinates are sought, add them right after iata. # + #---------------------------------------------------------------------------------------# + if (add.coord){ + idx = match(varrun$iata,poilist$iata) + lonlab = sprintf("lon%+06.2f",poilist$lon[idx]) + latlab = sprintf("lat%+06.2f",poilist$lat[idx]) + varlabel$iata = paste(varlabel$iata,lonlab,latlab,sep="_") + }#end if + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Build the name of the simulations. The polygon name always stays, even if the run # @@ -430,7 +451,7 @@ if (is.null(lonlat)){ runname = defname[! forbidden] metname = "" }else{ - stay = which(names(varlabel) %in% c("iata")) + stay = which(names(varlabel) %in% c("iata",varalways)) bye = which(sapply(X=varlabel,FUN=length) == 1) bye = bye[! bye %in% stay] if (length(bye) > 0) for (b in sort(bye,decreasing=TRUE)) varlabel[[b]] = NULL @@ -452,11 +473,10 @@ if (is.null(lonlat)){ #---------------------------------------------------------------------------------------# # Job name by appending longitude and latitude. # #---------------------------------------------------------------------------------------# - joborder$run = paste( joborder$iata - , "_lon",sprintf("%+06.2f",joborder$lon) - , "_lat",sprintf("%+06.2f",joborder$lat) - , sep = "" - )#end paste + joborder$run = paste0( joborder$iata + , "_lon",sprintf("%+06.2f",joborder$lon) + , "_lat",sprintf("%+06.2f",joborder$lat) + )#end paste0 #---------------------------------------------------------------------------------------# }#end if #------------------------------------------------------------------------------------------# diff --git a/ED/Template/plot_vulnerable.r b/ED/Template/plot_vulnerable.r index 25eb83397..b57e54ad2 100644 --- a/ED/Template/plot_vulnerable.r +++ b/ED/Template/plot_vulnerable.r @@ -101,7 +101,7 @@ ed22var[[ 1]] = list( vname = "et" , plog = FALSE , min = 600 , max = 1600 - , cscheme = "ipanoply" + , cscheme = "rdbu" )#end list ed22var[[ 2]] = list( vname = "transp" , desc = "Transpiration" @@ -109,7 +109,7 @@ ed22var[[ 2]] = list( vname = "transp" , plog = FALSE , min = 400 , max = 1000 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 3]] = list( vname = "gpp" , desc = "Gross Primary Productivity" @@ -117,7 +117,7 @@ ed22var[[ 3]] = list( vname = "gpp" , plog = FALSE , min = 1.5 , max = 3.5 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 4]] = list( vname = "npp" , desc = "Net Primary Productivity" @@ -125,7 +125,7 @@ ed22var[[ 4]] = list( vname = "npp" , plog = FALSE , min = 1.2 , max = 3.0 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 5]] = list( vname = "rshort" , desc = "Incoming SW Radiation" @@ -133,7 +133,7 @@ ed22var[[ 5]] = list( vname = "rshort" , plog = FALSE , min = 170 , max = 230 - , cscheme = "icloudy" + , cscheme = "ibugy" )#end list ed22var[[ 6]] = list( vname = "atm.temp" , desc = "Air temperature" @@ -141,7 +141,7 @@ ed22var[[ 6]] = list( vname = "atm.temp" , plog = FALSE , min = 15 , max = 27 - , cscheme = "panoply" + , cscheme = "irdbu" )#end list ed22var[[ 7]] = list( vname = "atm.vpd" , desc = "Air VPD" @@ -149,7 +149,7 @@ ed22var[[ 7]] = list( vname = "atm.vpd" , plog = FALSE , min = 5 , max = 21 - , cscheme = "panoply" + , cscheme = "irdbu" )#end list ed22var[[ 8]] = list( vname = "agb" , desc = "Above-ground biomass" @@ -157,7 +157,7 @@ ed22var[[ 8]] = list( vname = "agb" , plog = FALSE , min = 0 , max = 22 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[ 9]] = list( vname = "bsa" , desc = "Basal Area" @@ -165,7 +165,7 @@ ed22var[[ 9]] = list( vname = "bsa" , plog = FALSE , min = 0 , max = 32 - , cscheme = "clife" + , cscheme = "prgn" )#end list ed22var[[10]] = list( vname = "lai" , desc = "Leaf area index" @@ -173,7 +173,7 @@ ed22var[[10]] = list( vname = "lai" , plog = FALSE , min = 1.5 , max = 4.5 - , cscheme = "clife" + , cscheme = "prgn" )#end list #------------------------------------------------------------------------------------------# @@ -183,7 +183,7 @@ ed22var[[10]] = list( vname = "lai" statvar = list() statvar[[ 1]] = list( vname = "location" , desc = "Location Parameter" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "mmoyr" , min = 900 , max = 3500 @@ -191,7 +191,7 @@ statvar[[ 1]] = list( vname = "location" )#end list statvar[[ 2]] = list( vname = "scale" , desc = "Scale Parameter" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "mmoyr" , min = 100 , max = 1000 @@ -199,7 +199,7 @@ statvar[[ 2]] = list( vname = "scale" )#end list statvar[[ 3]] = list( vname = "shape" , desc = "Shape Parameter" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "empty" , min = -5 , max = +5 @@ -207,7 +207,7 @@ statvar[[ 3]] = list( vname = "shape" )#end list statvar[[ 4]] = list( vname = "dlocation.rel" , desc = "Vulnerability (Location)" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "empty" , min = -3 , max = 0 @@ -215,7 +215,7 @@ statvar[[ 4]] = list( vname = "dlocation.rel" )#end list statvar[[ 5]] = list( vname = "dscale.rel" , desc = "Vulnerability (Scale)" - , cscheme = "ihue.hot" + , cscheme = "imagma" , unit = "empty" , min = 0.0 , max = 3.0 @@ -223,7 +223,7 @@ statvar[[ 5]] = list( vname = "dscale.rel" )#end list statvar[[ 6]] = list( vname = "dshape.abs" , desc = "Vulnerability (Shape)" - , cscheme = "hue.hot" + , cscheme = "magma" , unit = "empty" , min = -3.0 , max = 0.0 @@ -231,7 +231,7 @@ statvar[[ 6]] = list( vname = "dshape.abs" )#end list statvar[[ 7]] = list( vname = "mean" , desc = "Mean" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "mmoyr" , min = 900 , max = 3500 @@ -239,7 +239,7 @@ statvar[[ 7]] = list( vname = "mean" )#end list statvar[[ 8]] = list( vname = "sdev" , desc = "Standard Deviation" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "mmoyr" , min = 100 , max = 800 @@ -247,7 +247,7 @@ statvar[[ 8]] = list( vname = "sdev" )#end list statvar[[ 9]] = list( vname = "skew" , desc = "Skewness" - , cscheme = "ipanoply" + , cscheme = "rdbu" , unit = "empty" , min = -1.5 , max = 1.5 @@ -255,7 +255,7 @@ statvar[[ 9]] = list( vname = "skew" )#end list statvar[[10]] = list( vname = "sn.cvar" , desc = "Coeff. of Variation (SN)" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "empty" , min = 0.1 , max = 0.3 @@ -263,7 +263,7 @@ statvar[[10]] = list( vname = "sn.cvar" )#end list statvar[[11]] = list( vname = "norm.cvar" , desc = "Coeff. of Variation" - , cscheme = "panoply" + , cscheme = "irdbu" , unit = "empty" , min = 0.10 , max = 0.25 @@ -434,9 +434,7 @@ nptref = length(ptref) #------ List of schemes to use col1. ------------------------------------------------------# -col1.schemes = c("panoply","ipanoply","muitas","imuitas","hue.purple","ihue.purple" - ,"cloudy","icloudy","hue.blue","ihue.blue","hue.green","ihue.green" - ,"clife","iclife","hue.cold","ihue.cold") +col1.schemes = c("irdbu","rdbu","bugy","ibugy","prgn","iprgn","magma","imagma") #------------------------------------------------------------------------------------------# @@ -1628,7 +1626,7 @@ for (v in sequence(nstatvar)){ cat (" + Plot the RMSE for each site and data set...","\n") #---- Select colour for sites. ---------------------------------------------------------# - if ("panoply" %in% col1.schemes){ + if ("irdbu" %in% col1.schemes){ col.key = "col1" }else{ col.key = "col2" @@ -1732,7 +1730,7 @@ cat (" + Plot the RMSE for each site and data set...","\n") , fixed.ylim = TRUE , xlim = longitude.limit , ylim = latitude.limit - , colour.palette = panoply + , colour.palette = irdbu , levels = this.levels , nlevels = this.nlevels , pch = pch.wmo @@ -2145,7 +2143,7 @@ for (v in sequence(nthree.dim)){ n.pretty.fourth = length(pretty.fourth) fourth.breaks = c(-Inf,pretty.fourth[-c(1,n.pretty.fourth)],Inf) fourth.colour = cut(ymean[[vname.fourth]],fourth.breaks) - fourth.cscheme = clife(n=length(levels(fourth.colour))-1) + fourth.cscheme = prgn(n=length(levels(fourth.colour))-1) fourth.colour = fourth.cscheme[match(fourth.colour,levels(fourth.colour))] #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/bring_figures.sh b/ED/Template/scripts/COMMON/bring_figures.sh new file mode 100755 index 000000000..5d265ea8d --- /dev/null +++ b/ED/Template/scripts/COMMON/bring_figures.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# +here=$(pwd) +#----- Description of this simulation, used to create unique job names. -------------------# +desc=$(basename ${here}) +#----- File containing the list of jobs and their settings: -------------------------------# +joborder="${here}/joborder.txt" # ! File with the job instructions +#----- Sub-directory to copy. -------------------------------------------------------------# +subdir="monthly" +#----- Sub-sub-directory to copy (for all, set all). --------------------------------------# +subsub="compemean compmmean tspft tsdbh theme_mmean" +#----- Prefix of files to bring that are in the main directory. ---------------------------# +subpref="disturb" +#------------------------------------------------------------------------------------------# + + +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# Unless you are going to modify the way jobs are submitted, you don't need to change # +# anything beyond this point. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + + + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +if [ ${npolys} -lt 100 ] +then + ndig=2 +elif [ ${npolys} -lt 1000 ] +then + ndig=3 +elif [ ${npolys} -lt 10000 ] +then + ndig=4 +else + ndig=5 +fi +format="%${ndig}.${ndig}i" +#------------------------------------------------------------------------------------------# + + + +#----- Create path with output files. -----------------------------------------------------# +outpath="${here}/${desc}_figures" +mkdir -pv ${outpath} +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +n_submit=0 +while [[ ${ff} -lt ${npolys} ]] +do + let ff=${ff}+1 + let line=${ff}+3 + ffout=$(printf "${format}" ${ff}) + + + + + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + echo " + Copy figures from simulation: ${polyname}." + #---------------------------------------------------------------------------------------# + + + #------ Create output path for this simulation. ----------------------------------------# + inpoly="${here}/${polyname}/${subdir}" + outpoly="${outpath}/${polyname}" + mkdir -p ${outpoly} + #---------------------------------------------------------------------------------------# + + + #------ Copy files. --------------------------------------------------------------------# + for subnow in ${subsub} + do + #----- Check whether to copy everything or a specific directory. --------------------# + case ${subnow} in + all) + rsync -Purtv ${inpoly}/* ${outpoly} + ;; + tsdbh) + mkdir -p ${outpoly}/tsdbh + rsync -Purtv ${inpoly}/tsdbh/*/*-pft-00-* ${outpoly}/tsdbh + ;; + *) + rsync -Purtv ${inpoly}/${subnow} ${outpoly} + ;; + esac + #------------------------------------------------------------------------------------# + done + #---------------------------------------------------------------------------------------# + + + #------ Copy files in the main sub-directory, in case any is to be copied. -------------# + if [[ "${subpref}" != "" ]] + then + #------------------------------------------------------------------------------------# + # Loop through prefixes. # + #------------------------------------------------------------------------------------# + for prefnow in ${subpref} + do + #----- Check whether to copy everything or a specific directory. -----------------# + rsync -Putv ${inpoly}/${prefnow}*.??? ${outpoly} + #---------------------------------------------------------------------------------# + done + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# + +done +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/email_reset.sh b/ED/Template/scripts/COMMON/email_reset.sh similarity index 100% rename from ED/Template/scripts/PBS/email_reset.sh rename to ED/Template/scripts/COMMON/email_reset.sh diff --git a/ED/Template/scripts/SLURM/last_histo.sh b/ED/Template/scripts/COMMON/last_histo.sh similarity index 75% rename from ED/Template/scripts/SLURM/last_histo.sh rename to ED/Template/scripts/COMMON/last_histo.sh index d1b819f60..55fac6e42 100755 --- a/ED/Template/scripts/SLURM/last_histo.sh +++ b/ED/Template/scripts/COMMON/last_histo.sh @@ -148,128 +148,129 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #--------------------------------------------------------------------------------------- diff --git a/ED/Template/scripts/COMMON/reset.sh b/ED/Template/scripts/COMMON/reset.sh new file mode 100755 index 000000000..e6b175eb0 --- /dev/null +++ b/ED/Template/scripts/COMMON/reset.sh @@ -0,0 +1,436 @@ +#!/bin/sh +here=$(pwd) +moi=$(whoami) +diskthere="/n/moorcroftfs2" +joborder="${here}/joborder.txt" + +desc=$(basename ${here}) + +#----- Executable name. -------------------------------------------------------------------# +execname="ed_2.2-opt" +execsrc="${HOME}/EDBRAMS/ED/build" +#------------------------------------------------------------------------------------------# + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + platform="SLURM" + ;; +au*|ha*|sun-master|cmm*) + platform="PBS" + ;; +*) + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + ;; +esac +#------------------------------------------------------------------------------------------# + + +#----- Find the output path (both local and remote paths will be cleaned). ----------------# +basehere=$(basename ${here}) +dirhere=$(dirname ${here}) +while [ ${basehere} != ${moi} ] +do + basehere=$(basename ${dirhere}) + dirhere=$(dirname ${dirhere}) +done +diskhere=${dirhere} +echo "-------------------------------------------------------------------------------" +echo " - Simulation control on disk: ${diskhere}" +echo " - Output on disk: ${diskthere}" +echo "-------------------------------------------------------------------------------" +there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) +#------------------------------------------------------------------------------------------# + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +#------------------------------------------------------------------------------------------# + + +#----- Check that the user is aware that it will remove everything... ---------------------# +if [ "x${1}" == "x-d" ] +then + echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" +else + echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" +fi +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo " " +echo " Look, this will really stop ALL your jobs and delete all files!!!" +echo " Are you sure? [y/N]" +echo " " +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "Okay then, but if you regret later don't say that I did not warn you..." +echo "I'm giving you a few seconds to kill this script in case you change your mind..." +delfun=11 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Job stopping will begin in ${delfun} seconds..." + sleep 1 +done +#------------------------------------------------------------------------------------------# + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #------ Define job name. ---------------------------------------------------------------# + jobname="${desc}-${polyname}" + #---------------------------------------------------------------------------------------# + + + #------- Delete jobs. ------------------------------------------------------------------# + case "${platform}" in + SLURM) + scancel -n ${jobname} + ;; + PBS) + jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + qdel ${jobid} + fi + ;; + esac + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + +delfun=16 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Files will be deleted in ${delfun} seconds..." + sleep 1 +done + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + if [ "x${1}" == "x-d" ] + then + find "${here}/${polyname}" -print -delete + find "${there}/${polyname}" -print -delete + else + /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" + /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" + cd "${here}/${polyname}" + ./purge.sh + cd "${there}/${polyname}" + ./purge.sh + fi +done +#------------------------------------------------------------------------------------------# + + + + +#------------------------------------------------------------------------------------------# +# Replace the executable. # +#------------------------------------------------------------------------------------------# +cd ${here} +if [ -s ${here}/executable/${execname} ] +then + rm -frv ${here}/executable/${execname} + cp -fv ${execsrc}/${execname} ${here}/executable +fi +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/sim_sitter.sh b/ED/Template/scripts/COMMON/sim_sitter.sh new file mode 100755 index 000000000..d90799d3d --- /dev/null +++ b/ED/Template/scripts/COMMON/sim_sitter.sh @@ -0,0 +1,360 @@ +#!/bin/bash + + + +#------------------------------------------------------------------------------------------# +# Which scripts to run. # +# # +# - read_monthly.r - This reads the monthly mean files (results can then be used for # +# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # +# thing.) # +# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it is # +# intended to simplify the output for learning purposes. # +# - plot_monthly.r - This creates several plots based on the monthly mean output. # +# - plot_yearly.r - This creates plots with year time series. # +# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # +# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # +# # +# The following scripts should work too, but I haven't tested them. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # +# the step to be rejected. # +#------------------------------------------------------------------------------------------# + + +#----- Main settings. Do look at run_sitter.sh and epost.sh for additional settings. -----# +here=$(pwd) # Current path. +there="/path/to/permanent/storage" # Permanent storage path (leave empty for no transfer) +email="myself\@myserver.com" # Your e-mail. Put a backslash before the @ +sbatch=$(which sbatch) # SLURM command to submit job. +sitter_queue="myqueue" # Queue to run run_sitter.sh +sitter_runtime="mytime" # Run time request for run_sitter.sh +sitter_memory=0 # Requested memory (Mb) for run_sitter.sh +lhisto_queue="myqueue" # Queue to run last_histo.sh +lhisto_runtime="mytime" # Run time request for last_histo.sh +lhisto_memory=0 # Requested memory (Mb) for last_histo.sh +transfer_full=false # Flag to decide between full and partial transfer +epost_queue="myqueue" # Queue to run epost.sh +epost_runtime="mytime" # Run time request for epost.sh +epost_memory=0 # Requested memory (Mb) for epost.sh +epost_reserve="" # Reservation flag (leave blank unless you have + # reservation privileges). +rscript="nothing.r" # Which script to run with epost.sh. See options above. + # Multiple scripts are allowed, put spaces between + # them. (e.g. rscript="plot_monthly.r plot_fast.r") +overcommit=false # Ignore maximum number of tasks when submitting + # epost tasks? +frqemail=43200 # How often to send emails on simulation status? +delay1st_min=20 # Time (in minutes) to wait before the first check + # (needed in case the run_sitter script is submitted + # before the simulation starts. In case the + # simulation is already running, it is fine to set + # this to zero). +wait_minutes=60 # Waiting time before checking run again (in minutes) +frqpost=3 # How often to run post-processing and file management + # This number is in iterations. Zero means never. +frqtouch=0 # How often to touch executable, scripts, and Template? + # This number is in iterations. Zero means never. +checkhourly="n" # Check hourly files. +checkstatus="y" # Check status before compressing +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# THINK TWICE BEFORE CHANGING ANYTHING BEYOND THIS POINT. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + +#----- Make sure e-mail and queue are pre-defined. ----------------------------------------# +if [[ "${email}" == "myself\@myserver.com" ]] || + [[ "${there}" == "/path/to/permanent/storage" ]] || + [[ "${rscript}" == "nothing.r" ]] || + [[ "${sitter_queue}" == "myqueue" ]] || + [[ "${sitter_runtime}" == "mytime" ]] || + [[ ${sitter_memory} -eq 0 ]] || + [[ "${lhisto_queue}" == "myqueue" ]] || + [[ "${lhisto_runtime}" == "mytime" ]] || + [[ ${lhisto_memory} -eq 0 ]] || + [[ "${epost_queue}" == "myqueue" ]] || + [[ "${epost_runtime}" == "mytime" ]] || + [[ ${epost_memory} -eq 0 ]] +then + echo "---------------------------------------------------------------------------------" + echo " The following variables must be set. In case any of them have dummy values, " + echo " check your script sim_sitter.sh." + echo " " + echo " email = ${email}" + echo " there = ${there}" + echo " rscript = ${rscript}" + echo " sitter_queue = ${sitter_queue}" + echo " epost_queue = ${epost_queue}" + echo " lhisto_queue = ${lhisto_queue}" + echo " sitter_queue = ${sitter_queue}" + echo " sitter_runtime = ${sitter_runtime}" + echo " sitter_memory = ${sitter_memory}" + echo " lhisto_queue = ${lhisto_queue}" + echo " lhisto_runtime = ${lhisto_runtime}" + echo " lhisto_memory = ${lhisto_memory}" + echo " epost_queue = ${epost_queue}" + echo " epost_runtime = ${epost_runtime}" + echo " epost_memory = ${epost_memory}" + echo " " + echo "---------------------------------------------------------------------------------" + exit 99 +fi +#------------------------------------------------------------------------------------------# + + + +#----- Find out which platform we are using. ----------------------------------------------# +if [ "${1}" == "" ] +then + #------ No platform provided. Try to guess, and if failed, then prompts the user. -----# + host=$(hostname -s) + case ${host} in + rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + #----- Use SLURM scripts. --------------------------------------------------------# + platform="SLURM" + #---------------------------------------------------------------------------------# + ;; + au*|ha*|sun-master|cmm*) + #----- Use PBS scripts. ----------------------------------------------------------# + platform="PBS" + #---------------------------------------------------------------------------------# + ;; + *) + #----- Host name is not one of the known ones. -----------------------------------# + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + #---------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# +else + #------ Platform is provided as argument. ----------------------------------------------# + platform=${1} + #---------------------------------------------------------------------------------------# +fi +#------------------------------------------------------------------------------------------# + + + + +#------ List of scripts. ------------------------------------------------------------------# +run_sitter="${here}/run_sitter.sh" +epost="${here}/epost.sh" +transfer="${here}/transfer.sh" +orig_histo="${here}/scripts/COMMON/last_histo.sh" +last_histo="${here}/last_histo.sh" +#------------------------------------------------------------------------------------------# + + + +#----- Set job prefix. --------------------------------------------------------------------# +desc=$(basename ${here}) +#------------------------------------------------------------------------------------------# + + + + +#------------------------------------------------------------------------------------------# +# In case this is a SLURM cluster, append header to last_histo.sh. # +#------------------------------------------------------------------------------------------# +case "${platform}" in +SLURM) + #----- Reset last_histo. ---------------------------------------------------------------# + echo " + Reset $(basename ${last_histo})" + /bin/rm -f ${last_histo} + touch ${last_histo} + chmod u+x ${last_histo} + #---------------------------------------------------------------------------------------# + + + #----- Set some job instructions. ------------------------------------------------------# + lhisto_task="${desc}-last_histo.sh" + lhisto_sto="${here}/out_last_histo.out" + lhisto_ste="${here}/out_last_histo.err" + #---------------------------------------------------------------------------------------# + + + + #----- Add header. ---------------------------------------------------------------------# + echo "#!/bin/bash" >> ${last_histo} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${last_histo} + echo "#SBATCH --cpus-per-task=1 # CPUs per task" >> ${last_histo} + echo "#SBATCH --partition=${lhisto_queue} # Job partition" >> ${last_histo} + echo "#SBATCH --job-name=${lhisto_task} # Task name" >> ${last_histo} + echo "#SBATCH --mem-per-cpu=${lhisto_memory} # Memory per CPU" >> ${last_histo} + echo "#SBATCH --time=${lhisto_runtime} # Time for job" >> ${last_histo} + echo "#SBATCH --output=${lhisto_sto} # Standard output path" >> ${last_histo} + echo "#SBATCH --error=${lhisto_ste} # Standard error path" >> ${last_histo} + echo "#SBATCH --chdir=${here} # Main directory" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Initial settings." >> ${last_histo} + echo "here=\"${here}\" # Main path" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Print information about this job." >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"----- Summary of current job -------------------------\"" >> ${last_histo} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${last_histo} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${last_histo} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${last_histo} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${last_histo} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${last_histo} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${last_histo} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${last_histo} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${last_histo} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${last_histo} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${last_histo} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${last_histo} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${last_histo} + echo "echo \"------------------------------------------------------\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "echo \"\"" >> ${last_histo} + echo "" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Define home in case home is not set" >> ${last_histo} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${last_histo} + echo "then" >> ${last_histo} + echo " export HOME=\$(echo ~)" >> ${last_histo} + echo "fi" >> ${last_histo} + echo "" >> ${last_histo} + echo "#--- Load modules and settings." >> ${last_histo} + echo ". \${HOME}/.bashrc" >> ${last_histo} + #---------------------------------------------------------------------------------------# + + + + #----- Append the template last_histo.sh, skipping the first two lines. ----------------# + tail -n +3 ${orig_histo} >> ${last_histo} + #---------------------------------------------------------------------------------------# + + ;; +esac +#------------------------------------------------------------------------------------------# + + + + + + +#------------------------------------------------------------------------------------------# +# Make substitutions. # +# IMPORTANT: make sure "there" substitutions precede "here", otherwise the script will # +# not work as intended. # +#------------------------------------------------------------------------------------------# +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${run_sitter} +sed -i~ s@"recipient=\"\""@"recipient=\"${email}\""@g ${run_sitter} +sed -i~ s@"frqemail=\"\""@"frqemail=${frqemail}"@g ${run_sitter} +sed -i~ s@"delay1st_min=\"\""@"delay1st_min=${delay1st_min}"@g ${run_sitter} +sed -i~ s@"wait_minutes=\"\""@"wait_minutes=${wait_minutes}"@g ${run_sitter} +sed -i~ s@"frqpost=\"\""@"frqpost=${frqpost}"@g ${run_sitter} +sed -i~ s@"frqtouch=\"\""@"frqtouch=${frqtouch}"@g ${run_sitter} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${epost} +sed -i~ s@"global_queue=\"\""@"global_queue=\"${epost_queue}\""@g ${epost} +sed -i~ s@"rscript=\"\""@"rscript=\"${rscript}\""@g ${epost} +sed -i~ s@"submit=false"@"submit=true"@g ${epost} +sed -i~ s@"reservation=\"\""@"reservation=\"${epost_reserve}\""@g ${epost} +sed -i~ s@"sim_memory=0"@"sim_memory=${epost_memory}"@g ${epost} +sed -i~ s@"runtime=\"00:00:00\""@"runtime=\"${epost_runtime}\""@g ${epost} +sed -i~ s@"overcommit=\"\""@"overcommit=${overcommit}"@g ${epost} +sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${transfer} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${transfer} +sed -i~ s@"full_transfer=boolean"@"full_transfer=${transfer_full}"@g ${transfer} +sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${last_histo} +sed -i~ s@"checkhourly=\"\""@"checkhourly=\"${checkhourly}\""@g ${last_histo} +sed -i~ s@"checkstatus=\"\""@"checkstatus=\"${checkstatus}\""@g ${last_histo} +#------------------------------------------------------------------------------------------# + + +#----- Substitute paths in sit_utils R scripts. -------------------------------------------# +sed -i~ s@"mypath"@"${here}"@g ${here}/sit_utils/plot.region.r +sed -i~ s@"mypath"@"${here}"@g ${here}/sit_utils/plot.status.r +#------------------------------------------------------------------------------------------# + + +#----- Job preferences. -------------------------------------------------------------------# +sitter_joblog="${here}/out_sitter.out" +sitter_jobpref=$(basename ${here}) +sitter_jobname="${desc}-sitter" +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Check whether to submit the job. # +#------------------------------------------------------------------------------------------# +if [[ -s "${here}/run_sitter.lock" ]] || [[ -s "${here}/transfer.lock" ]] +then + echo " Lock file found for run_sitter.sh and/or transfer.lock." + echo " The scripts may be already running." + echo " Submit the script anyway [y|N]?" + read goahead +else + goahead="y" +fi +goahead="$(echo ${goahead} | tr '[:upper:]' '[:lower:]')" +#------------------------------------------------------------------------------------------# + + +#----- Submit run_sitter.sh in batch mode. ------------------------------------------------# +comm="${sbatch} -p ${sitter_queue} --mem-per-cpu=${sitter_memory} -t ${sitter_runtime}" +comm="${comm} -o ${sitter_joblog} -J ${sitter_jobname} -n 1 " +comm="${comm} --wrap=\"${here}/run_sitter.sh\"" +case ${goahead} in +y|yes) + /bin/rm -f ${here}/run_sitter.lock + /bin/rm -f ${here}/transfer.lock + /bin/rm -f ${here}/sit_utils/mycheck.txt + /bin/rm -f ${here}/sit_utils/lastcheck.txt + echo ${comm} + ${comm} + ;; +*) + bann="Script run_sitter was not submitted. In case you want to submit manually" + bann="${bann} this is the command:" + echo ${bann} + echo " " + echo ${comm} + ;; +esac +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/COMMON/stopalljobs.sh b/ED/Template/scripts/COMMON/stopalljobs.sh new file mode 100755 index 000000000..f95640dcc --- /dev/null +++ b/ED/Template/scripts/COMMON/stopalljobs.sh @@ -0,0 +1,228 @@ +#!/bin/bash +here=$(pwd) +joborder="${here}/joborder.txt" +desc=$(basename ${here}) + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*|sdumont*) + platform="SLURM" + ;; +au*|ha*|sun-master|cmm*) + platform="PBS" + ;; +*) + echo -n "Failed guessing platform from node name. Please type the name: " + read platform + ;; +esac +#------------------------------------------------------------------------------------------# + + + + +#----- Determine the number of polygons to stop. ------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 + +echo "Are you sure that you want to stop all jobs? [y/N]" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi +#------------------------------------------------------------------------------------------# + + +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo " " +echo " Look, this will really stop ALL your jobs... Are you sure? [y/N]" +echo " " +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +read proceed + +if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] +then + exit +fi + +echo "Alright then, but in case you regret later don't say that I didn't warn you..." +echo "I am giving you a few seconds to kill this script in case you change your mind..." +delfun=11 +while [ ${delfun} -gt 1 ] +do + let delfun=${delfun}-1 + echo " - Job stopping will begin in ${delfun} seconds..." + sleep 1 +done + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [ ${ff} -lt ${npolys} ] +do + let ff=${ff}+1 + let line=${ff}+3 + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #------ Define job name. ---------------------------------------------------------------# + jobname="${desc}-${polyname}" + #---------------------------------------------------------------------------------------# + + + #------- Delete jobs. ------------------------------------------------------------------# + case "${platform}" in + SLURM) + scancel -n ${jobname} + ;; + PBS) + jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + qdel ${jobid} + fi + ;; + esac + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + + diff --git a/ED/Template/scripts/COMMON/transfer.sh b/ED/Template/scripts/COMMON/transfer.sh new file mode 100755 index 000000000..75544238f --- /dev/null +++ b/ED/Template/scripts/COMMON/transfer.sh @@ -0,0 +1,332 @@ +#!/bin/bash + +#==========================================================================================# +#==========================================================================================# +# Main settings: # +#------------------------------------------------------------------------------------------# +#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# +here="" +#----- Location to create the copy of these files. ----------------------------------------# +there="" +#----- File containing the list of jobs and their settings: -------------------------------# +joborder="${here}/joborder.txt" +#----- Command to be used for rsync. ------------------------------------------------------# +frsync="rsync -Putq --links --copy-unsafe-links" +rrsync="rsync -Prutq --links --copy-unsafe-links" +#----- Decide between copying everything or just some key files. --------------------------# +full_transfer=boolean +#------------------------------------------------------------------------------------------# + + + + + +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +# Unless you are going to modify the scripts, you don't need to change anything beyond # +# this point. # +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# +#==========================================================================================# + + +#------------------------------------------------------------------------------------------# +# First check that the main path and e-mail have been set. If not, don't run. # +#------------------------------------------------------------------------------------------# +if [[ "x${here}" == "x" ]] || [[ "x${there}" == "x" ]] || + [[ "x${full_transfer}" == "xboolean" ]] +then + echo " You must set some variables before running the script:" + echo " Check variables \"here\", \"there\", and \"full_transfer}!" + exit 99 +fi +#------------------------------------------------------------------------------------------# + + + + +#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# +if [[ "${here}" == "${there}" ]] +then + echo " Source and destination paths are the same. Transfer is not needed." + exit 0 +elif [[ -s ${here}/transfer.lock ]] +then + echo " Script transfer is running. Skip transfer for the time being." + exit +else + echo "I am going to back up your run." > ${here}/transfer.lock +fi +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Create the output path in case it isn't there. # +#------------------------------------------------------------------------------------------# +if [[ ! -s ${there} ]] +then + echo "Create backup path: ${there}." + mkdir -p ${there} +fi +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# First, copy the files at the basal directory. # +#------------------------------------------------------------------------------------------# +echo " + Copy files from the main directory." +${frsync} ${here}/* ${there} +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Then copy the fixed directories. # +#------------------------------------------------------------------------------------------# +echo " + Copy executable." +${rrsync} ${here}/executable ${there} +echo " + Copy sit_utils." +${rrsync} ${here}/sit_utils ${there} +echo " + Copy Template." +${rrsync} ${here}/Template ${there} +#------------------------------------------------------------------------------------------# + + + + +#----- Determine the number of polygons to run. -------------------------------------------# +let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Loop over all polygons. # +#------------------------------------------------------------------------------------------# +ff=0 +while [[ ${ff} -lt ${npolys} ]] +do + let ff=${ff}+1 + let line=${ff}+3 + + + #---------------------------------------------------------------------------------------# + # Format count. # + #---------------------------------------------------------------------------------------# + if [[ ${npolys} -ge 10 ]] && [[ ${npolys} -lt 100 ]] + then + ffout=$(printf '%2.2i' ${ff}) + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 1000 ]] + then + ffout=$(printf '%3.3i' ${ff}) + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 10000 ]] + then + ffout=$(printf '%4.4i' ${ff}) + else + ffout=${ff} + fi + ffout="${ffout} of ${npolys}" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Read the ffth line of the polygon list. There must be smarter ways of doing # + # this, but this works. Here we obtain the polygon name, and its longitude and # + # latitude. # + #---------------------------------------------------------------------------------------# + oi=$(head -${line} ${joborder} | tail -1) + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #----- Check whether the directories exist or not, and stop the script if they do. -----# + if [[ -s ${here}/${polyname} ]] + then + echo -n " + Copy ${polyname} (${ffout})... " + + #------------------------------------------------------------------------------------# + # Sync this directory. Decide between full or partial transfer. # + #------------------------------------------------------------------------------------# + if ${full_transfer} + then + #----- Copy the entire directory. ------------------------------------------------# + ${rrsync} ${here}/${polyname} ${there} + #---------------------------------------------------------------------------------# + else + #----- Copy the base directory and the R output. ---------------------------------# + mkdir -p ${there}/${polyname} + mkdir -p ${there}/${polyname}/histo + ${frsync} ${here}/${polyname}/* ${there}/${polyname} + ${rrsync} ${here}/${polyname}/rdata_month ${there}/${polyname} + #---------------------------------------------------------------------------------# + + + #----- Copy the first and last history file. -------------------------------------# + ahisto="${polyname}-S-${yeara}-${montha}-${datea}-${timea}00-g01.h5" + zhisto="${polyname}-S-${yearz}-${monthz}-${datez}-${timez}00-g01.h5" + ${frsync} ${here}/${polyname}/histo/${ahisto} ${there}/${polyname}/histo + ${frsync} ${here}/${polyname}/histo/${zhisto} ${there}/${polyname}/histo + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# + echo "Done!" + + else + #----- Directory is not found. ------------------------------------------------------# + echo " + Skip ${polyname} (${ffout})." + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# +done +#------------------------------------------------------------------------------------------# + + +#----- Clean-up stuff. --------------------------------------------------------------------# +echo " Unlock transfer.sh." +/bin/rm -f ${here}/transfer.lock +echo "==== transfer.sh execution ends. ====" +#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/check_run.sh b/ED/Template/scripts/PBS/check_run.sh index 4bd3f5e8c..f2146e4ed 100755 --- a/ED/Template/scripts/PBS/check_run.sh +++ b/ED/Template/scripts/PBS/check_run.sh @@ -86,128 +86,129 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/cspost.sh b/ED/Template/scripts/PBS/cspost.sh deleted file mode 100755 index db4957d22..000000000 --- a/ED/Template/scripts/PBS/cspost.sh +++ /dev/null @@ -1,306 +0,0 @@ -#!/bin/bash -. ~/.bashrc -here=$(pwd) -thisqueue="moorcroft2b" # ! Queue where jobs should be submitted -#----- Check whether to use openlava or typical job submission. ---------------------------# -openlava="y" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Grab arguments and also set some defaults. # -#------------------------------------------------------------------------------------------# -nargs=$# # Number of arguments -args=$@ # List of arguments -ibg="0" # Background is white by default -rdata="RData_scenario" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Check whether this machine supports openlava or not (in case this is a openlava. # -#------------------------------------------------------------------------------------------# -thismach=$(hostname -s) -if [ ${thismach} == "rclogin01" ] && [ ${openlava} == "y" -o ${openlava} == "Y" ] -then - . /opt/openlava-2.0/etc/openlava-client.sh -elif [ ${thismach} != "rclogin01" ] && [ ${openlava} == "y" -o ${openlava} == "Y" ] -then - echo " This machine (${hostname}) doesn't support openlava, sorry!" - exit 39 -fi -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all arguments, and assign soil texture and temperature based on the # -# options. # -#------------------------------------------------------------------------------------------# -istext=16 -itemp=0 -irain=0 -if [ ${nargs} -gt 0 ] -then - nextstext="n" - nexttemp="n" - nextrain="n" - nextbg="n" - n=0 - for arg in ${args} - do - let n=${n}+1 - - if [ ${nextstext} == "y" ] - then - istext=${arg} - nextstext="n" - elif [ ${nexttemp} == "y" ] - then - itemp=${arg} - nexttemp="n" - elif [ ${nextrain} == "y" ] - then - irain=${arg} - nextrain="n" - elif [ ${nextbg} == "y" ] - then - ibg=${arg} - nextbg="n" - elif [ "x${arg}" == "x-s" ] - then - nextstext="y" - elif [ "x${arg}" == "x-r" ] - then - nextrain="y" - elif [ "x${arg}" == "x-t" ] - then - nexttemp="y" - elif [ "x${arg}" == "x-b" ] - then - nextbg="y" - else - echo "Not sure what you mean..." - echo "Argument ${n} (${arg}) doesn't make sense!" - exit 91 - fi - done -fi -#------------------------------------------------------------------------------------------# - - -bad=0 - - -#------------------------------------------------------------------------------------------# -# Check that soil texture makes sense. # -#------------------------------------------------------------------------------------------# -case ${istext} in -2|stext02) - stext="stext02" - ;; -6|stext06) - stext="stext06" - ;; -8|stext08) - stext="stext08" - ;; -11|stext11) - stext="stext11" - ;; -16|stext16) - stext="stext16" - ;; -*) - echo "Invalid 'stext' argument (${istext})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that temperature makes sense. # -#------------------------------------------------------------------------------------------# -case ${itemp} in -0|"t+000") - temp="t+000" - idxtemp="1" - ;; -1|"t+100") - temp="t+100" - idxtemp="2" - ;; -2|"t+200") - temp="t+200" - idxtemp="3" - ;; -3|"t+300") - temp="t+300" - idxtemp="4" - ;; -*) - echo "Invalid 'temp' argument (${itemp})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that rainfall makes sense. # -#------------------------------------------------------------------------------------------# -case ${irain} in -0|00|"r+000") - rain="r+000" - ;; -2|02|"r-020") - rain="r-020" - ;; -4|04|"r-040") - rain="r-040" - ;; -6|06|"r-060") - rain="r-060" - ;; -8|08|"r-080") - rain="r-080" - ;; -10|"r-100") - rain="r-100" - ;; -12|"r-120") - rain="r-120" - ;; -14|"r-140") - rain="r-140" - ;; -16|"r-160") - rain="r-160" - ;; -*) - echo "Invalid 'rain' argument (${irain})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Check that ibackground makes sense. # -#------------------------------------------------------------------------------------------# - -case ${ibg} in -0) - bg="ibg00" - ;; -1) - bg="ibg01" - ;; -2) - bg="ibg02" - ;; -*) - echo "Invalid 'bg' argument (${ibg})" - let bad=${bad}+1 - ;; -esac -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Stop in case anything is wrongly set. # -#------------------------------------------------------------------------------------------# -if [ ${bad} -gt 0 ] -then - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Create a unique job name. # -#------------------------------------------------------------------------------------------# -job="cscen_${stext}_${rain}_${temp}_${bg}" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Define some R-related settings. # -#------------------------------------------------------------------------------------------# -R_Comm="R CMD BATCH --no-save --no-restore" -R_Out="${here}/.${job}_out.out" -R_Orig="${here}/compare_scenarios.r" -R_Submit="${here}/.${job}.r" -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Switch settings to the current configuration. # -#------------------------------------------------------------------------------------------# -/bin/cp ${R_Orig} ${R_Submit} -stext_ostr=$(grep stext.default ${R_Submit} | head -1) -temp_ostr=$(grep use.global ${R_Submit} | head -1) -rain_ostr=$(grep drain.default ${R_Submit} | head -1) -bg_ostr=$(grep ibackground ${R_Submit} | head -1) -rdata_ostr=$(grep rdata.path ${R_Submit} | head -1) - -stext_nstr="stext.default = \"${stext}\" # Default soil texture" -temp_nstr="use.global = ${idxtemp} # Which global to use (TRUE means all of them)" -rain_nstr="drain.default = \"${rain}\" # Default rainfall scenario" -bg_nstr="ibackground = ${ibg} # Target background colour:" -rdata_nstr="rdata.path = file.path(here,\"${rdata}\") # Path with R object." -sed -i s@"${stext_ostr}"@"${stext_nstr}"@g ${R_Submit} -sed -i s@"${rain_ostr}"@"${rain_nstr}"@g ${R_Submit} -sed -i s@"${temp_ostr}"@"${temp_nstr}"@g ${R_Submit} -sed -i s@"${bg_ostr}"@"${bg_nstr}"@g ${R_Submit} -sed -i s@"${rdata_ostr}"@"${rdata_nstr}"@g ${R_Submit} -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Create the script to submit to LSF. # -#------------------------------------------------------------------------------------------# -cspost="${here}/.${job}.sh" -csout="${here}/.${job}_lsf.out" -cscomm="${R_Comm} ${R_Submit} ${R_Out}" -status="${here}/${rdata}/status_stext_sim_${temp}.txt" -echo "#!/bin/bash" > ${cspost} -echo "/bin/rm -fr ${status}" >> ${cspost} -echo "while [ ! -s ${status} ]" >> ${cspost} -echo "do" >> ${cspost} -echo " sleep 3" >> ${cspost} -echo " ${cscomm}" >> ${cspost} -echo "done" >> ${cspost} -chmod +x ${cspost} -#------------------------------------------------------------------------------------------# - - - - -#------ Check whether to use openlava or LSF. ---------------------------------------------# -if [ 'x'${openlava} == 'xy' ] || [ 'x'${openlava} == 'xY' ] -then - bcall="iobsub -J ${job} -o ${csout}" -else - bcall="bsub -q ${thisqueue} -J ${job} -o ${csout}" -fi -bsub="${bcall} ${cspost} 1> /dev/null 2> /dev/null" -${bsub} -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/delall.sh b/ED/Template/scripts/PBS/delall.sh deleted file mode 100755 index 8718b930a..000000000 --- a/ED/Template/scripts/PBS/delall.sh +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure that you want to remove all files and directories? [y/N]" -else - echo "Are you sure that you want to remove all files? [y/N]" -fi -read proceed -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -echo " " -if [ "x${1}" == "x-d" ] -then - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output directories and files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -else - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -fi - -echo "This is PERMANENT, once they are gone, adieu, no chance to recover them!" -echo "Is that what you really want? [y/N]" -read proceed - -echo " " - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later do not say that I did not warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Deletion will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/epost.sh b/ED/Template/scripts/PBS/epost.sh index 808fe44b4..0e87dcabf 100755 --- a/ED/Template/scripts/PBS/epost.sh +++ b/ED/Template/scripts/PBS/epost.sh @@ -62,39 +62,47 @@ global_queue="" # Queue sim_memory=0 # Memory per simulation. If zero, then it will be # automatically determined by the maximum number of tasks # per node. +skip_end=true # Skip processing in case the R script has already loaded + # all files through the end of the simulation + # (true/false). This is only used for "monthly"-based + # scripts (those marked with (*) in the table below). #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# # Which scripts to run. # # # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # +# - read_monthly.r - (*) This reads the monthly mean files (results can then be used # +# for plot_monthly.r, plot_yearly.r, and others, but it doesn't plot # +# anything.) # +# - yearly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - monthly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - plot_monthly.r - (*) This creates several plots based on the monthly mean output. # +# - plot_yearly.r - (*) This creates plots with year time series. # +# - plot_ycomp.r - (*) This creates yearly comparisons based on the monthly mean # +# output. # +# - plot_povray.r - (*) This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # # # # The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what # +# caused the step to be rejected. # #------------------------------------------------------------------------------------------# rscripts="plot_yearly.r" #rscripts="yearly_ascii.r" @@ -159,7 +167,7 @@ monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late #------------------------------------------------------------------------------------------# # First check that the main path and e-mail have been set. If not, don't run. # #------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${global_queue}" == "x" ] || [ "x${rscript}" == "x" ] +if [[ "x${here}" == "x" ]] || [[ "x${global_queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] then echo " You must set some variables before running the script:" echo " Check variables \"here\", \"global_queue\" and \"rscript\"!" @@ -169,7 +177,7 @@ fi #----- Load settings. ---------------------------------------------------------------------# -if [ -s ${initrc} ] +if [[ -s ${initrc} ]] then . ${initrc} fi @@ -237,7 +245,7 @@ au*|ha*) #---------------------------------------------------------------------------------------# ;; esac -if [ ${n_cpt} -gt ${n_cpt_max} ] +if [[ ${n_cpt} -gt ${n_cpt_max} ]] then echo " Too many CPUs per task requested:" echo " Queue = ${global_queue}" @@ -276,6 +284,9 @@ read_monthly.r) yearly_ascii.r) epostkey="yasc" ;; +monthly_ascii.r) + epostkey="masc" + ;; r10_monthly.r) epostkey="rm10" ;; @@ -329,7 +340,7 @@ plot_fast.r) # If the script is here, then it could not find the script... And this should never # # happen, so interrupt the script! # #---------------------------------------------------------------------------------------# - echo " Script ${script} is not recognised by epost.sh!" + echo " Script ${rscript} is not recognised by epost.sh!" exit 1 #---------------------------------------------------------------------------------------# ;; @@ -342,18 +353,18 @@ esac #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_tpn} let node_memory=${n_tpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 else #------ Set memory and number of CPUs per task. ----------------------------------------# let n_tpn_try=${node_memory}/${sim_memory} - if [ ${n_tpn_try} -le ${n_tpn} ] + if [[ ${n_tpn_try} -le ${n_tpn} ]] then n_tpn=${n_tpn_try} let sim_memory=${node_memory}/${n_tpn} @@ -367,13 +378,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -390,7 +401,7 @@ echo "Number of polygons: ${npolys}..." # Loop over all polygons. # #------------------------------------------------------------------------------------------# ff=0 -while [ ${ff} -lt ${npolys} ] +while [[ ${ff} -lt ${npolys} ]] do #---------------------------------------------------------------------------------------# @@ -410,128 +421,144 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #------ Last month and year for monthly-based scripts. ---------------------------------# + if [[ ${monthz} -eq 1 ]] + then + rm_monthz=12 + let rm_yearz=${yearz}-1 + else + let rm_monthz=${monthz}-1 + rm_yearz=${yearz} + fi + #------ Update the time. ---------------------------------------------------------------# + let rm_whenz=12*${rm_yearz}+${rm_monthz} #---------------------------------------------------------------------------------------# @@ -667,11 +694,11 @@ do #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] + if [[ ${useperiod} == "f" ]] then metcyca=${eftyeara} metcycz=${eftyearz} - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then metcyca=${bioyeara} metcycz=${bioyearz} @@ -683,7 +710,7 @@ do #---------------------------------------------------------------------------------------# # Switch years in case this is a specific drought run. # #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] + if [[ ${droughtmark} == "TRUE" ]] then let yeara=${droughtyeara}-1 let yearz=${droughtyearz}+1 @@ -692,32 +719,21 @@ do - #----- Print a banner. -----------------------------------------------------------------# - if [ ${rscript} == "plot_census.r" ] && [ ${subcens} -eq 0 ] - then - echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." - else - echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." - fi - #---------------------------------------------------------------------------------------# - - - #---------------------------------------------------------------------------------------# # Set up the time and output variables according to the script. # #---------------------------------------------------------------------------------------# case ${rscript} in - read_monthly.r|yearly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) + read_monthly.r|yearly_ascii.r|monthly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) #------------------------------------------------------------------------------------# # Scripts that are based on monthly means. The set up is the same, the only # # difference is in the output names. # #------------------------------------------------------------------------------------# #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] + if [[ ${useperiod} == "t" ]] then #------ One meteorological cycle. Check the type of meteorological driver. ------# case ${metdriver} in - Sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) thisyeara=${metcyca} thisyearz=${metcycz} ;; @@ -730,34 +746,34 @@ do thisyearz=${metcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then echo " -> Shifting met cycle" let metcycle=${metcycz}-${metcyca}+1 let deltayr=${shiftcycle}*${metcycle} let thisyeara=${metcyca}+${deltayr} let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} ;; esac # ${metdriver} in #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "u" ] + elif [[ ${useperiod} == "u" ]] then #----- The user said which period to use. ----------------------------------------# thisyeara=${yusera} thisyearz=${yuserz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "f" ] + elif [[ ${useperiod} == "f" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${eftyeara} thisyearz=${eftyearz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${bioyeara} @@ -769,7 +785,7 @@ do thisyeara=${yeara} thisyearz=${yearz} #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] + fi # end [[ ${useperiod} == "t" ]] #------------------------------------------------------------------------------------# @@ -779,6 +795,53 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Check whether or not to submit the task. -------------------------------------# + if [[ ${rscript} == "plot_census.r" ]] && [[ ${subcens} -eq 0 ]] + then + #---- No need to submit the job if plot_census.r and place doesn't have census. --# + submit_now=false + #---------------------------------------------------------------------------------# + elif ${skip_end} + then + status="${here}/${polyname}/rdata_month/status_${polyname}.txt" + if [[ -s ${status} ]] + then + #----- Retrieve current status of the post-processing. ------------------------# + st_yearz=$(cat ${status} | awk '{print $1}') + st_monthz=$(cat ${status} | awk '{print $2}') + let st_whenz=12*${st_yearz}+${st_monthz} + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # Compare the processed time with the last time needed for processing. # + #------------------------------------------------------------------------------# + if [[ ${st_whenz} -ge ${rm_whenz} ]] + then + #----- Skip submission because it has reached the end. ---------------------# + submit_now=false + #---------------------------------------------------------------------------# + else + #----- Run script as it has not reached the end yet. -----------------------# + submit_now=true + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + else + #----- File not find, run the script. -----------------------------------------# + submit_now=true + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + else + #----- Submit job. ---------------------------------------------------------------# + submit_now=true + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# ;; plot_eval_ed.r) #------------------------------------------------------------------------------------# @@ -786,7 +849,7 @@ do # Petrolina (output variables exist only for 2004, so we don't need to process # # all years). # #------------------------------------------------------------------------------------# - if [ ${metdriver} == "Petrolina" ] + if [[ ${metdriver} == "Petrolina" ]] then thismetcyca=2004 thismetcycz=2004 @@ -806,7 +869,7 @@ do thisyearz=${thismetcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then #----- Always use the true met driver to find the cycle shift. ----------------# echo " -> Shifting met cycle" @@ -815,7 +878,7 @@ do let thisyeara=${thismetcyca}+${deltayr} let thisyearz=${thismetcycz}+${deltayr} #------------------------------------------------------------------------------# - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} #------------------------------------------------------------------------------------# @@ -826,6 +889,12 @@ do thismonthz=12 thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_budget.r|plot_rk4.r|plot_rk4pc.r|plot_photo.r|reject_ed.r) @@ -835,7 +904,7 @@ do # at the first time step), so we normally skip the first day. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -852,6 +921,12 @@ do thismonthz=${monthz} let thisdatea=${datea}+1 #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; @@ -860,7 +935,7 @@ do # Script with time-independent patch properties. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -877,13 +952,19 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_daily.r) #------------------------------------------------------------------------------------# # Script with daily means. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -900,6 +981,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_fast.r) @@ -907,7 +994,7 @@ do # Script with short-term averages (usually hourly). No need to skip any- # # thing. # #------------------------------------------------------------------------------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -924,6 +1011,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -984,8 +1077,14 @@ do #----- Make sure this is not the census script for a site we don't have census. --------# - if [ ${rscript} != "plot_census.r" ] || [ ${subcens} -ne 0 ] + if ${submit_now} then + #----- Submit script. ---------------------------------------------------------------# + echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." + #------------------------------------------------------------------------------------# + + + #----- Set script- and site-specific variables. -------------------------------------# epostjob="${epostkey}-${desc}-${polyname}" epostnow="${here}/${polyname}/${epostkey}_epost.sh" @@ -1017,7 +1116,7 @@ do case ${rscript} in plot_eval_ed.r) echo "/bin/rm -fr ${complete}" >> ${epostnow} - echo "while [ ! -s ${complete} ]" >> ${epostnow} + echo "while [[ ! -s ${complete} ]" >> ${epostnow} echo "do" >> ${epostnow} echo " sleep 3" >> ${epostnow} echo " ${epostexe}" >> ${epostnow} @@ -1065,7 +1164,7 @@ do if [[ ${nfail} -gt 0 ]] && [[ ${attempt} -eq ${nsubtry_max} ]] then echo " Failed. Giving up, check for errors in your script." - elif [ ${nfail} -eq 0 ] + elif [[ ${nfail} -eq 0 ]] then echo " Success." else @@ -1078,6 +1177,10 @@ do ;; esac #------------------------------------------------------------------------------------# + else + #----- Skip submission. -------------------------------------------------------------# + echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/last_histo.sh b/ED/Template/scripts/PBS/last_histo.sh deleted file mode 100755 index 4efd50824..000000000 --- a/ED/Template/scripts/PBS/last_histo.sh +++ /dev/null @@ -1,516 +0,0 @@ -#!/bin/bash -. ~/.bashrc - -#==========================================================================================# -#==========================================================================================# -# This script keeps only the latest few history files (in case it needs to resume the # -# simulation), and compresses analysis files. # -#------------------------------------------------------------------------------------------# -here="" # Main path -diskthere="" # Disk where the output files are -joborder="${here}/joborder.txt" # File with the job instructions -bzip2="/bin/gzip -9" # Program to compress files (with options) -checkhourly="y" # Check hourly files. -checkstatus="y" # Check status before compressing -#------ Calculator. -----------------------------------------------------------------------# -ccc="${HOME}/Util/calc.sh" # Calculator -#------ # of history files to keep (in odyssey's world, always keep more than one). -------# -retain=3 -#------------------------------------------------------------------------------------------# - - - - -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -# No need to change anything beyond this point unless you are developing the code. # -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# - - - -#------------------------------------------------------------------------------------------# -# Set the maximum number of days for each month. day[0] is a dummy variable. # -#------------------------------------------------------------------------------------------# -daymax=(0 31 28 31 30 31 30 31 31 30 31 30 31) -#------------------------------------------------------------------------------------------# - - - -#----- This script is normally ran with crontab. Make sure the main path is set. ---------# -if [ "x${here}" == "x" ] -then - echo " here = ${here} " - echo " Set up variable here before running email_reset.sh" - exit 92 -fi -#------------------------------------------------------------------------------------------# - - - -#-----Make sure last_histo.sh isn't running. ----------------------------------------------# -if [ -s ${here}/last_histo.lock ] -then - exit -else - echo "I'm going to clean or compress files. Lots of them!" > ${here}/last_histo.lock -fi -#------------------------------------------------------------------------------------------# - - - -#----- Make yes/no choices case insensitive. ----------------------------------------------# -checkhourly=$(echo ${checkhourly} | awk '{print substr($1,1,1)}' | tr '[:upper:]' '[:lower:]') -checkstatus=$(echo ${checkstatus} | awk '{print substr($1,1,1)}' | tr '[:upper:]' '[:lower:]') -#------------------------------------------------------------------------------------------# - - -#----- Find the disk here to create the "there" path. -------------------------------------# -moi=$(whoami) -namehere=$(basename ${here}) -diskhere=$(dirname ${here}) -while [ ${namehere} != ${moi} ] -do - namehere=$(basename ${diskhere}) - diskhere=$(dirname ${diskhere}) -done -if [ "x${diskthere}" == "x" ] -then - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -echo "Number of polygons: ${npolys}..." -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #--------------------------------------------------------------------------------------- - - - #----- Find time and minute. -----------------------------------------------------------# - houra=$(echo ${timea} | awk '{print substr($1,1,2)}') - minua=$(echo ${timea} | awk '{print substr($1,3,2)}') - hourz=$(echo ${timez} | awk '{print substr($1,1,2)}') - minuz=$(echo ${timez} | awk '{print substr($1,3,2)}') - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Set gfilout prefix according to ihrzrad. # - #---------------------------------------------------------------------------------------# - case ${ihrzrad} in - 1) - gpref="gap" - ;; - 2) - gpref="pix" - ;; - *) - gpref="dum" - ;; - esac - #---------------------------------------------------------------------------------------# - - - #----- Define the main path for this polygon. ------------------------------------------# - pypath="${there}/${polyname}" - sfilout="${pypath}/histo/${polyname}" - ffilout="${pypath}/analy/${polyname}" - gfilout="${pypath}/shade/${gpref}" - #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # If the directory exists, delete all history files but the last. # - #---------------------------------------------------------------------------------------# - if [ -s ${pypath} ] - then - echo "${ff} - Delete history files for polygon ${polyname}:" - - #---- First we delete all -Z- files. ------------------------------------------------# - nzed=$(/bin/ls -1 ${sfilout}-Z-*h5 2> /dev/null | wc -l) - if [ ${nzed} -gt 0 ] - then - zeds=$(/bin/ls -1 ${sfilout}-Z-*h5 2> /dev/null) - for zed in ${zeds} - do - echo -n " - Delete: $(basename ${zed})..." - /bin/nice /bin/rm -f ${zed} - echo " Gone!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we delete all -S- files except the last ${retain} ones. -------------------# - ness=$(/bin/ls -1 ${sfilout}-S-*h5 2> /dev/null | wc -l) - if [ ${ness} -gt ${retain} ] - then - let head=${ness}-${retain} - esses=$(/bin/ls -1 ${sfilout}-S-*h5 | head -${head}) - for ess in ${esses} - do - echo -n " - Delete: $(basename ${ess})..." - /bin/nice /bin/rm -f ${ess} - echo " Gone!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we compress all raster files except for the last one. ---------------------# - nrst=$(/bin/ls -1 ${gfilout}_raster_isi001_????-01.txt 2> /dev/null | wc -l) - if [ ${nrst} -gt 1 ] - then - let head=${nrst}-1 - rasters=$(/bin/ls -1 ${gfilout}_raster_isi001_????-01.txt | head -${head}) - for rst in ${rasters} - do - echo -n " - Compress: $(basename ${rst})..." - ${bzip2} ${rst} - echo " Compressed!" - done - fi - #------------------------------------------------------------------------------------# - - - - #---- Now we compress all ptable files except for the last one. ---------------------# - nptb=$(/bin/ls -1 ${gfilout}_ptable_isi001_????-01.txt 2> /dev/null | wc -l) - if [ ${nptb} -gt 1 ] - then - let head=${nptb}-1 - ptables=$(/bin/ls -1 ${gfilout}_ptable_isi001_????-01.txt | head -${head}) - for ptb in ${ptables} - do - echo -n " - Compress: $(basename ${ptb})..." - ${bzip2} ${ptb} - echo " Compressed!" - done - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Decide whether to check the status before compressing files. # - #------------------------------------------------------------------------------------# - status="${pypath}/rdata_month/status_${polyname}.txt" - - #----- Check the status before compressing?. ----------------------------------------# - if [ "x${checkstatus}" == "xy" ] - then - #----- Check status of read_monthly.sh. ------------------------------------------# - if [ -s ${status} ] - then - #----- Compress files until the last processed file. --------------------------# - yeare=$(cat ${status} | awk '{print $1}') - monthe=$(cat ${status} | awk '{print $2}') - compress="y" - #------------------------------------------------------------------------------# - else - #----- Do not compress any file. ----------------------------------------------# - compress="n" - #------------------------------------------------------------------------------# - fi - #---------------------------------------------------------------------------------# - else - #----- Ignore checks, just go on and compress everything. ------------------------# - yeare=${yearz} - monthe=${monthz} - compress="y" - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - - - - - #------------------------------------------------------------------------------------# - # If compress is "y", then go on and compress files. # - #------------------------------------------------------------------------------------# - if [ "x${compress}" == "xy" ] - then - let year=${yeara}-1 - - - #---------------------------------------------------------------------------------# - # Loop over the years. # - #---------------------------------------------------------------------------------# - while [ ${year} -lt ${yeare} ] - do - #----- Update year and year string. -------------------------------------------# - let year=${year}+1 - yyyy=$(printf "%4.4i" ${year}) - #------------------------------------------------------------------------------# - - #----- Update daymax for February (check for leap year). ----------------------# - let leap400=${year}%400 - let leap100=${year}%100 - let leap004=${year}%4 - if [ ${leap400} -eq 0 ] || [ ${leap100} -ne 0 -a ${leap004} -eq 0 ] - then - daymax[2]=29 - else - daymax[2]=28 - fi - #------------------------------------------------------------------------------# - - - - - #------ Check last month. -----------------------------------------------------# - if [ ${year} -eq ${yeare} ] - then - monthl=${monthe} - else - monthl=12 - fi - #------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------# - # Loop over the months. # - #------------------------------------------------------------------------------# - month=0 - while [ ${month} -lt ${monthl} ] - do - #----- Update month and month string. --------------------------------------# - let month=${month}+1 - mm=$(printf "%2.2i" ${month}) - datel=${daymax[${month}]} - #---------------------------------------------------------------------------# - - - #----- Compress monthly mean file. -----------------------------------------# - qfile=${ffilout}-Q-${yyyy}-${mm}-00-000000-g01.h5 - if [ -s ${qfile} ] - then - echo -n " - Compress file: $(basename ${qfile})..." - ${bzip2} ${qfile} 2> /dev/null - echo "Zipped!" - fi - #---------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------# - # Check hourly files. # - #---------------------------------------------------------------------------# - if [ "x${checkhourly}" == "xy" ] || [ "x${checkhourly}" == "xY" ] - then - - echo " - Check hourly files: ${mm}/${yyyy}" - - - #------------------------------------------------------------------------# - # Loop over days. # - #------------------------------------------------------------------------# - date=0 - while [ ${date} -lt ${datel} ] - do - let date=${date}+1 - dd=$(printf "%2.2i" ${date}) - hourl=23 - hour=-1 - #---------------------------------------------------------------------# - # Loop over hours. # - #---------------------------------------------------------------------# - while [ ${hour} -lt ${hourl} ] - do - let hour=${hour}+1 - hh=$(printf "%2.2i" ${hour}) - - ifile=${ffilout}-I-${yyyy}-${mm}-${dd}-${hh}0000-g01.h5 - if [ -s ${ifile} ] - then - echo -n " * Compress file: $(basename ${ifile})..." - ${bzip2} ${ifile} 2> /dev/null - echo "Zipped!" - fi - #------------------------------------------------------------------# - done - #---------------------------------------------------------------------# - done - #------------------------------------------------------------------------# - fi - #---------------------------------------------------------------------------# - done - #------------------------------------------------------------------------------# - done - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - else - echo "${ff} - Directory doesn't exist" - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Keep this as the very last command. Release the directory, so last_histo.sh can # -# be called again. # -#------------------------------------------------------------------------------------------# -/bin/rm -f ${here}/last_histo.lock -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/read_monthly.sh b/ED/Template/scripts/PBS/read_monthly.sh deleted file mode 100755 index fb4f21a48..000000000 --- a/ED/Template/scripts/PBS/read_monthly.sh +++ /dev/null @@ -1,807 +0,0 @@ -#!/bin/bash -. ~/.bashrc -here="xxxxxxxxxxxxxxxxxxxxx" # ! Main path -myself=$(whoami) # ! You -diskthere="" # ! Disk where the output files are -thisqueue="qqqqqqqqqq" # ! Queue where jobs should be submitted -joborder="${here}/joborder.txt" # ! File with the job instructions -#----- Outroot is the main output directory. ----------------------------------------------# -outroot="xxxxxxxxxxxxxxxxxxxx" -submit="y" # y = Submit the script; n = Copy the script -#----- Plot only one meteorological cycle. ------------------------------------------------# -useperiod="a" # Which bounds should I use? (Ignored by plot_eval_ed.r) - # "a" -- All period - # "t" -- One eddy flux tower met cycle - # "u" -- User defined period, defined by the variables below. - # "f" -- Force the tower cycle. You may need to edit the script, though -yusera=1972 # First year to use -yuserz=2011 # Last year to use -#----- Yearly comparison . ----------------------------------------------------------------# -seasonmona=1 -#----- Census comparison. -----------------------------------------------------------------# -varcycle="FALSE" # Find the average mortality for various cycles (TRUE/FALSE). -#----- Hourly comparison. -----------------------------------------------------------------# -usedistrib="edf" # Which distribution to plot on top of histograms: - # norm -- Normal distribution - # sn -- Skewed normal distribution (requires package sn) - # edf -- Empirical distribution function (function density) -#----- Output format. ---------------------------------------------------------------------# -outform="c(\"pdf\")" # x11 - On screen (deprecated on shell scripts) - # png - Portable Network Graphics - # eps - Encapsulated Post Script - # pdf - Portable Document Format -#----- DBH classes. -----------------------------------------------------------------------# -idbhtype=3 # Type of DBH class - # 1 -- Every 10 cm until 100cm; > 100cm - # 2 -- 0-10; 10-20; 20-35; 35-50; 50-70; > 70 (cm) - # 3 -- 0-10; 10-35; 35-55; > 55 (cm) -#----- Force to run again from scratch. ---------------------------------------------------# -irerun=0 # Options for re-running: - # 0 -- never; updates only. - # 1 -- re-run only those that have not finished yet - # 2 -- re-run everything, including the finished ones. -#----- Default background colour. ---------------------------------------------------------# -background=0 # 0 -- White - # 1 -- Pitch black - # 2 -- Dark grey -#----- Trim the year comparison for tower years only? -------------------------------------# -efttrim="FALSE" -#----- Correction factor for respiration. -------------------------------------------------# -correct_gs=1.0 # Correction factor for growth and storage respiration -#----- Simple = 1 means that the output is going to be simple. ----------------------------# -simple=0 # 0 -- default - # 1 -- simplified output -#----- Path with R scripts that are useful. -----------------------------------------------# -rscpath="${HOME}/EDBRAMS/R-utils" -#----- bashrc (usually ${HOME}/.bashrc). --------------------------------------------------# -initrc="${HOME}/.bashrc" -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Tell whether to plot pseudo-drought or not. # -#------------------------------------------------------------------------------------------# -droughtmark="FALSE" # Should I plot a rectangle to show the drought? - # capital letters only: TRUE means yes, FALSE means no -droughtyeara=1605 # Year that the first drought instance happens (even if it is - # just the last bit) -droughtyearz=1609 # Year that the last drought instance happens (even if it - # partial) -monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late in the - # year, put the last month first. -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Use the general path. # -#------------------------------------------------------------------------------------------# -case ${myself} in -marcosl|marcos.longo|mlongo) - rscpath="${HOME}/Util/Rsc" - ;; -esac -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Make sure the paths are set. # -#------------------------------------------------------------------------------------------# -if [ "y${here}" == "yxxxxxxxxxxxxxxxxxxxxx" ] || [ "y${here}" == "y" ] - [ "y${outroot}" == "yxxxxxxxxxxxxxxxxxxxxx" ] || [ "y${outroot}" == "y" ] - [ "y${thisqueue}" == "yqqqqqqqqqq" ] || [ "y${thisqueue}" == "y" ] -then - echo " here = ${here}" - echo " outroot = ${outroot}" - echo " queue = ${queue}" - echo " Set up variables here, outroot, and queue before using read_monthly.sh!!!" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -lock="${here}/read_monthly.lock" -if [ -s ${lock} ] -then - exit -else - echo "I am going to submit post-processors. Lots of them!" > ${lock} -fi -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Make sure that the directory there exists, if not, create all parent directories # -# needed. # -#------------------------------------------------------------------------------------------# -while [ ! -s ${outroot} ] -do - namecheck=$(basename ${outroot}) - dircheck=$(dirname ${outroot}) - while [ ! -s ${dircheck} ] && [ ${namecheck} != "/" ] - do - namecheck=$(basename ${dircheck}) - dircheck=$(dirname ${dircheck}) - done - - if [ ${namecheck} == "/" ] - then - echo "Invalid disk for variable outroot:" - echo " DISK = ${diskhere}" - exit 58 - elif [ ${namecheck} == "xxxxxxxx" ] || [ ${namecheck} == "xxx_XXX" ] || - [ ${namecheck} == "XXXXXXXXXXX" ] - then - echo " - Found this directory in your path: ${namecheck} ..." - echo " - Outroot given: ${outroot} ..." - echo " - It looks like you forgot to set up your outroot path, check it!" - exit 92 - else - echo "Making directory: ${dircheck}/${namecheck}" - mkdir ${dircheck}/${namecheck} - fi -done -#------------------------------------------------------------------------------------------# - - -#----- Find the disk here to create the "there" path. -------------------------------------# -moi=$(whoami) -namehere=$(basename ${here}) -diskhere=$(dirname ${here}) -while [ ${namehere} != ${moi} ] -do - namehere=$(basename ${diskhere}) - diskhere=$(dirname ${diskhere}) -done -if [ "x${diskthere}" == "x" ] -then - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -echo "Number of polygons: ${npolys}..." -#------------------------------------------------------------------------------------------# - - - - - -#------------------------------------------------------------------------------------------# -# Set the correct script (full or simple). # -#------------------------------------------------------------------------------------------# -case ${simple} in -0) - read_monthly="read_monthly.r" - rmon="rmon" - rdata_path="rdata_month" - ;; -1) - read_monthly="read_simple.r" - rmon="rsim" - rdata_path="rdata_simple" - ;; -esac -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - - #---------------------------------------------------------------------------------------# - # Format count. # - #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] - then - ffout=$(printf '%2.2i' ${ff}) - else - ffout=${ff} - fi - #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #----- Find time and minute. -----------------------------------------------------------# - houra=$(echo ${timea} | awk '{print substr($1,1,2)}') - minua=$(echo ${timea} | awk '{print substr($1,3,2)}') - hourz=$(echo ${timez} | awk '{print substr($1,1,2)}') - minuz=$(echo ${timez} | awk '{print substr($1,3,2)}') - #---------------------------------------------------------------------------------------# - - - #----- Find the last output time. ------------------------------------------------------# - let monthf=${monthz}-1 - if [ ${monthf} == 0 ] - then - monthf=12 - let yearf=${yearz}-1 - else - yearf=${yearz} - fi - #---------------------------------------------------------------------------------------# - - - #----- Retrieve some information from ED2IN. -------------------------------------------# - ED2IN="${here}/${polyname}/ED2IN" - iphysiol=$(grep -i NL%IPHYSIOL ${ED2IN} | awk '{print $3}') - iallom=$(grep -i NL%IALLOM ${ED2IN} | awk '{print $3}') - islhydro=$(grep -i NL%SOIL_HYDRO_SCHEME ${ED2IN} | awk '{print $3}') - metcyca=$(grep -i NL%METCYC1 ${ED2IN} | awk '{print $3}') - metcycz=$(grep -i NL%METCYCF ${ED2IN} | awk '{print $3}') - klight=$(grep -i NL%DDMORT_CONST ${ED2IN} | awk '{print $3}') - #---------------------------------------------------------------------------------------# - - - #---- Find the forest inventory cycle. -------------------------------------------------# - case ${polyiata} in - gyf|s67) - biocyca=2004 - biocycz=2009 - subcens=1 - ;; - s67) - biocyca=2001 - biocycz=2011 - subcens=1 - ;; - *) - biocyca=${metcyca} - biocycz=${metcycz} - subcens=0 - ;; - esac - #---------------------------------------------------------------------------------------# - - - - #---- The eddy flux tower cycles. ------------------------------------------------------# - case ${polyiata} in - gyf) - eftyeara=2004 - eftyearz=2012 - ;; - cax) - eftyeara=1999 - eftyearz=2003 - ;; - l[0-5][0-3]) - eftyeara=2006 - eftyearz=2016 - ;; - m34) - eftyeara=1999 - eftyearz=2006 - ;; - s67) - eftyeara=2001 - eftyearz=2010 - ;; - s77) - eftyeara=2001 - eftyearz=2005 - ;; - s83) - eftyeara=2000 - eftyearz=2003 - ;; - pnz) - eftyeara=2004 - eftyearz=2004 - ;; - ban) - eftyeara=2004 - eftyearz=2006 - ;; - rja) - eftyeara=1999 - eftyearz=2002 - ;; - fns) - eftyeara=1999 - eftyearz=2002 - ;; - bsb) - eftyeara=2006 - eftyearz=2011 - ;; - pdg) - eftyeara=2001 - eftyearz=2003 - ;; - hvd) - eftyeara=1992 - eftyearz=2003 - ;; - *) - eftyeara=${metcyca} - eftyearz=${metcycz} - ;; - esac - #---------------------------------------------------------------------------------------# - - - - #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] - then - metcyca=${eftyeara} - metcycz=${eftyearz} - fi - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Switch years in case this is a specific drought run. # - #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] - then - let yeara=${droughtyeara}-1 - let yearz=${droughtyearz}+1 - fi - #---------------------------------------------------------------------------------------# - - - if [ -s ${here}/${polyname} ] - then - - - #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] - then - #------ One meteorological cycle. Check the type of meteorological driver. ------# - if [ ${metdriver} != "Sheffield" ] - then - thisyeara=${metcyca} - thisyearz=${metcycz} - for i in ${shiftiata} - do - if [ "x${i}" == "x${polyiata}" ] - then - echo " -> Shifting met cycle" - let metcycle=${metcycz}-${metcyca}+1 - let deltayr=${shiftcycle}*${metcycle} - let thisyeara=${metcyca}+${deltayr} - let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] - done #end for i in ${shiftiata} - else - thisyeara=${metcyca} - thisyearz=${metcycz} - fi # end [ ${metdriver} != "Sheffield" ] - #---------------------------------------------------------------------------------# - - elif [ ${useperiod} == "u" ] - then - #----- The user said which period to use. ----------------------------------------# - thisyeara=${yusera} - thisyearz=${yuserz} - #---------------------------------------------------------------------------------# - - elif [ ${useperiod} == "f" ] - then - #----- The user said to use the eddy flux period. --------------------------------# - thisyeara=${eftyeara} - thisyearz=${eftyearz} - #---------------------------------------------------------------------------------# - - else - #----- Grab all years that the simulation is supposed to run. --------------------# - thisyeara=${yeara} - thisyearz=${yearz} - #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] - #------------------------------------------------------------------------------------# - - - - #----- Set up months and days. ------------------------------------------------------# - thismontha=${montha} - thismonthz=${monthz} - thisdatea=${datea} - #------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------# - # Define the job name, and the names of the output files. # - #------------------------------------------------------------------------------------# - epostout="${rmon}_epost.out" - epostsh="${rmon}_epost.sh" - epostlsf="${rmon}_epost.lsf" - epostjob="eb-${rmon}-${polyname}" - #------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------# - # Check the status of the run. # - #------------------------------------------------------------------------------------# - /bin/rm -f ${here}/${polyname}/statusrun.txt - /bin/rm -f ${here}/${polyname}/whichrun.r - /bin/cp -f ${here}/Template/whichrun.r ${here}/${polyname}/whichrun.r - whichrun="${here}/${polyname}/whichrun.r" - outwhich="${here}/${polyname}/outwhichrun.txt" - sed -i s@thispoly@${polyname}@g ${whichrun} - sed -i s@thisqueue@${queue}@g ${whichrun} - sed -i s@pathhere@${here}@g ${whichrun} - sed -i s@paththere@${there}@g ${whichrun} - sed -i s@thisyeara@${yeara}@g ${whichrun} - sed -i s@thismontha@${montha}@g ${whichrun} - sed -i s@thisdatea@${datea}@g ${whichrun} - sed -i s@thistimea@${timea}@g ${whichrun} - sed -i s@thischecksteady@FALSE@g ${whichrun} - sed -i s@thismetcyc1@${metcyc1}@g ${whichrun} - sed -i s@thismetcycf@${metcycf}@g ${whichrun} - sed -i s@thisnyearmin@10000@g ${whichrun} - sed -i s@thisststcrit@0.0@g ${whichrun} - R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - while [ ! -s ${here}/${polyname}/statusrun.txt ] - do - sleep 0.5 - done - year=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $2}') - month=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $3}') - date=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $4}') - time=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $5}') - runt=$(cat ${here}/${polyname}/statusrun.txt | awk '{print $6}') - if [ ${runt} != "INITIAL" ] - then - runt="RESTORE" - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # We submit only the jobs that haven't finished. If the job has just finished, # - # we submit once again, but save a file to remember that this polygon is loaded. # - #------------------------------------------------------------------------------------# - status="${here}/${polyname}/${rdata_path}/status_${polyname}.txt" - rdata="${here}/${polyname}/${rdata_path}/${polyname}.RData" - if [ -s ${status} ] - then - yearl=$(cat ${status} | awk '{print $1}') - monthl=$(cat ${status} | awk '{print $2}') - if [ ${yearl} -eq ${yearf} ] && [ ${monthl} -eq ${monthf} ] - then - cestfini="y" - else - cestfini="n" - fi - lasttime=${monthl}/${yearl} - else - lasttime="Never" - cestfini="n" - fi - #------------------------------------------------------------------------------------# - - - - - #----- Print banner. ----------------------------------------------------------------# - echo " ${fflab} - ${polyname}" - echo " - ED-2.2 Status: ${runt}" - echo " - Last time processed: ${lasttime}. Finished: ${cestfini}" - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Decide whether to change the status to force running again. # - #------------------------------------------------------------------------------------# - case ${irerun} in - 0) - byeprev="n" - ;; - 1) - byeprev="y" - ;; - 2) - cestfini="n" - byeprev="y" - ;; - esac - #------------------------------------------------------------------------------------# - - - if [ ${runt} == "INITIAL" ] - then - submitnow="n" - echo "${ff} - ${polyname} : polygon hasn't started yet" - - elif [ ${runt} == "THE_END" ] && [ ${cestfini} == "y" ] - then - #----- Job has ended and all files have been processed. --------------------------# - submitnow="n" - #---------------------------------------------------------------------------------# - - echo "${ff} - ${polyname} : polygon is already loaded or queued for the last time" - else - #---------------------------------------------------------------------------------# - # Job is still running or it has started again... Remove the blocker and # - # re-submit if the post-processor is not queued. # - #---------------------------------------------------------------------------------# - #----- Check that the script is not in the queue. --------------------------------# - inqueue=$(bjobs -w -q ${thisqueue} -J ${epostjob} 2> /dev/null | wc -l) - if [ ${inqueue} -eq 0 ] - then - submitnow="y" - echo "${ff} - ${polyname}: submit post-processor script." - else - submitnow="n" - echo "${ff} - ${polyname}: post-processor job has already been queued." - fi - #---------------------------------------------------------------------------------# - fi - #------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------# - # Find out whether the job is on the queue. In case it is not, re-submit. # - #------------------------------------------------------------------------------------# - if [ "x${submitnow}" == "xy" ] - then - #----- Check whether to delete the previous post-processing or not. --------------# - if [ ${byeprev} == "y" ] - then - echo " * Delete previous post-processing..." - /bin/rm -fr ${status} ${rdata} - elif [ -s ${rdata} ] - then - echo " * Continuing previous post-processing..." - else - echo " * Starting new post-processing..." - fi - #---------------------------------------------------------------------------------# - - #----- Copy the R script from the Template folder to the local path. -------------# - cp -f ${here}/Template/${read_monthly} ${here}/${polyname} - scriptnow=${here}/${polyname}/${read_monthly} - #---------------------------------------------------------------------------------# - - - - #----- Switch the keywords by the current settings. ------------------------------# - sed -i s@thispoly@${polyname}@g ${scriptnow} - sed -i s@thisoutroot@${outroot}@g ${scriptnow} - sed -i s@thispath@${here}@g ${scriptnow} - sed -i s@thatpath@${there}@g ${scriptnow} - sed -i s@thisrscpath@${rscpath}@g ${scriptnow} - sed -i s@thisyeara@${thisyeara}@g ${scriptnow} - sed -i s@thismontha@${thismontha}@g ${scriptnow} - sed -i s@thisdatea@${thisdatea}@g ${scriptnow} - sed -i s@thishoura@${houra}@g ${scriptnow} - sed -i s@thisminua@${minua}@g ${scriptnow} - sed -i s@thisyearz@${thisyearz}@g ${scriptnow} - sed -i s@thismonthz@${thismonthz}@g ${scriptnow} - sed -i s@thisdatez@${datez}@g ${scriptnow} - sed -i s@thishourz@${hourz}@g ${scriptnow} - sed -i s@thisminuz@${minuz}@g ${scriptnow} - sed -i s@thisseasonmona@${seasonmona}@g ${scriptnow} - sed -i s@myphysiol@${iphysiol}@g ${scriptnow} - sed -i s@myallom@${iallom}@g ${scriptnow} - sed -i s@myslhydro@${slhydro}@g ${scriptnow} - sed -i s@mydroughtmark@${droughtmark}@g ${scriptnow} - sed -i s@mydroughtyeara@${droughtyeara}@g ${scriptnow} - sed -i s@mydroughtyearz@${droughtyearz}@g ${scriptnow} - sed -i s@mymonthsdrought@${monthsdrought}@g ${scriptnow} - sed -i s@myvarcycle@${varcycle}@g ${scriptnow} - sed -i s@thisoutform@${outform}@g ${scriptnow} - sed -i s@mydistrib@${usedistrib}@g ${scriptnow} - sed -i s@mymetcyca@${metcyca}@g ${scriptnow} - sed -i s@mymetcycz@${metcycz}@g ${scriptnow} - sed -i s@mybiocyca@${biocyca}@g ${scriptnow} - sed -i s@mybiocycz@${biocycz}@g ${scriptnow} - sed -i s@myidbhtype@${idbhtype}@g ${scriptnow} - sed -i s@mybackground@${background}@g ${scriptnow} - sed -i s@mycorrection@${correct_gs}@g ${scriptnow} - sed -i s@myklight@${klight}@g ${scriptnow} - sed -i s@myefttrim@${efttrim}@g ${scriptnow} - sed -i s@myeftyeara@${eftyeara}@g ${scriptnow} - sed -i s@myeftyearz@${eftyearz}@g ${scriptnow} - #---------------------------------------------------------------------------------# - - - - #----- Run R to get the plots. ---------------------------------------------------# - rbin="R CMD BATCH --no-save --no-restore" - comm="${rbin} ${scriptnow} ${here}/${polyname}/${epostout}" - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Create shell script with job instructions. # - #---------------------------------------------------------------------------------# - sbatchout="${here}/${polyname}/${epostlsf}" - epostnow="${here}/${polyname}/${epostsh}" - complete="${here}/${polyname}/eval_load_complete.txt" - rm -f ${epostnow} - echo "#$ -S /bin/bash" > ${epostnow} - echo "#$ -q ${thisqueue}" >> ${epostnow} - echo "#$ -o ${sbatchout}" >> ${epostnow} - echo "#$ -N ${epostjob}" >> ${epostnow} - echo "#$ -j y" >> ${epostnow} - echo "#$ -r n" >> ${epostnow} - echo " " >> ${epostnow} - echo ". ${initrc}" >> ${epostnow} - echo ${comm} >> ${epostnow} - chmod +x ${epostnow} - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Submit the job. # - #---------------------------------------------------------------------------------# - if [ "x${submit}" == "xy" ] || [ "x${submit}" == "xY" ] - then - qsub ${epostnow} 1> /dev/null 2> /dev/null - sleep 3 - fi - #---------------------------------------------------------------------------------# - - fi - #------------------------------------------------------------------------------------# - else - echo "${fflab} - ${polyname}: directory not found." - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - -/bin/rm -f ${lock} - diff --git a/ED/Template/scripts/PBS/reset.sh b/ED/Template/scripts/PBS/reset.sh deleted file mode 100755 index d91253da0..000000000 --- a/ED/Template/scripts/PBS/reset.sh +++ /dev/null @@ -1,424 +0,0 @@ -#!/bin/bash -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -desc=$(basename ${here}) - -#----- Executable name. -------------------------------------------------------------------# -execname="ed_2.2-opt" -execsrc="${HOME}/EDBRAMS/ED/build" -#------------------------------------------------------------------------------------------# - - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# If diskthere is empty, assume diskthere=diskhere. # -#------------------------------------------------------------------------------------------# -if [ "x${diskthere}" == "x" ] -then - diskthere=${diskhere} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Find where stuff to be delete are located. # -#------------------------------------------------------------------------------------------# -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" -else - echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" -fi -read proceed -#------------------------------------------------------------------------------------------# - -#----- Quit in case the user is not sure about. -------------------------------------------# -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs and delete all files!!!" -echo " Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Alright then, but in case you regret later don't say that I didn't warn you..." -echo "I'm giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - #------- Delete jobs. ------------------------------------------------------------------# - jobname="${desc}-${polyname}" - jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') - qdel ${jobid} - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Files will be deleted in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Replace the executable. # -#------------------------------------------------------------------------------------------# -cd ${here} -if [ -s ${here}/executable/${execname} ] -then - rm -frv ${here}/executable/${execname} - cp -fv ${execsrc}/${execname} ${here}/executable -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/PBS/sim_sitter.sh b/ED/Template/scripts/PBS/run_sitter.sh similarity index 98% rename from ED/Template/scripts/PBS/sim_sitter.sh rename to ED/Template/scripts/PBS/run_sitter.sh index f3cb01977..161d64e31 100755 --- a/ED/Template/scripts/PBS/sim_sitter.sh +++ b/ED/Template/scripts/PBS/run_sitter.sh @@ -9,6 +9,7 @@ the_end_msg="has finished" unknown_msg="status is unknown" sigsegv_msg="HAD SEGMENTATION VIOLATION" crashed_msg="RK4 PROBLEM" +hydfail_msg="HYDRODYNAMICS" metmiss_msg="DID NOT FIND MET DRIVERS" stopped_msg="UNKNOWN REASON" fstline_msg="Number of polygons:" @@ -65,6 +66,7 @@ do n_unknown=$(cat ${check_out} | grep "${unknown_msg}" | wc -l) n_sigsegv=$(cat ${check_out} | grep "${sigsegv_msg}" | wc -l) n_crashed=$(cat ${check_out} | grep "${crashed_msg}" | wc -l) + n_hydfail=$(cat ${check_out} | grep "${hydfail_msg}" | wc -l) n_metmiss=$(cat ${check_out} | grep "${metmiss_msg}" | wc -l) n_stopped=$(cat ${check_out} | grep "${stopped_msg}" | wc -l) let n_ongoing=${n_polygon}-${n_the_end} diff --git a/ED/Template/scripts/PBS/spawn_poly.sh b/ED/Template/scripts/PBS/spawn_poly.sh index 45cd510bb..6747dbbc2 100755 --- a/ED/Template/scripts/PBS/spawn_poly.sh +++ b/ED/Template/scripts/PBS/spawn_poly.sh @@ -10,6 +10,8 @@ here=$(pwd) moi=$(whoami) #----- Description of this simulation, used to create unique job names. -------------------# desc=$(basename ${here}) +#----- Source path for ED code and executable. --------------------------------------------# +srcpath="${HOME}/EDBRAMS/ED" #----- Select main file system path. ------------------------------------------------------# ordinateur=$(hostname -s) case ${ordinateur} in @@ -23,11 +25,13 @@ bioinit="${fs0}/Data/ed2_data/site_bio_data" alsinit="${fs0}/Data/ed2_data/lidar_spline_bio_data" intinit="${fs0}/Data/ed2_data/lidar_intensity_bio_data" lutinit="${fs0}/Data/ed2_data/lidar_lookup_bio_data" +ebainit="${d_path}/ed2_data/lidar_eba_bio_data" biotype=0 # 0 -- "default" setting (isizepft controls default/nounder) # 1 -- isizepft controls number of PFTs, whereas iage controls patches. # 2 -- airborne lidar initialisation using return counts ("default"). # 3 -- airborne lidar initialisation using intensity counts. # 4 -- airborne lidar/inventory hybrid initialisation ("lookup table"). + # 5 -- airborne lidar (EBA Transects). # For lidar initialisation (2-4), isizepft is the disturbance history key. #----- Path and file prefix for init_mode = 5. --------------------------------------------# restart="${fs0}/Data/ed2_data/restarts_XXX" @@ -39,7 +43,7 @@ shefhead='SHEF_NCEP_DRIVER_DS314' metmaindef="${fs0}/Data/ed2_data" packdatasrc="${fs0}/Data/2scratch" #----- Path with land use scenarios. ------------------------------------------------------# -lumain="${fs0}/Data/lu_scenarios" +lumain="${fs0}/Data/ed2_data/lcluc_scenarios" #----- Path with other input data bases (soil texture, DGD, land mask, etc). --------------# inpmain="${fs0}/Data/ed2_data" #----- If submit is "n", we create paths but skip submission. -----------------------------# @@ -62,13 +66,24 @@ dateh="01" # Day timeh="0000" # Hour #----- Default tolerance. -----------------------------------------------------------------# toldef="0.01" -#----- Executable names. ------------------------------------------------------------------# -execname="ed_2.2-opt" # Normal executable, for most queues #----- Initialisation scripts. ------------------------------------------------------------# -initrc="${HOME}/.bashrc" # Initialisation script for most nodes +initrc="${HOME}/.bashrc" # Initialisation script for most nodes +#----- Executable names. ------------------------------------------------------------------# +execname="ed_2.2-opt" # Normal executable, for most queues +checkexec=true # Check executable #----- Settings for this group of polygons. -----------------------------------------------# -global_queue="verylongq" # Queue -n_cpt=8 # Number of cpus per task (it will be limited by maximum) +init_only=true # Run model initialisation only? + # This can be useful when the initialisation step + # demands much more memory than the time steps (e.g., + # when using lidar data to initialisate the model). +if ${init_only} +then + global_queue="shortq" # Queue + n_cpt=1 # Number of cpus per task (it will be limited by maximum) +else + global_queue="verylongq" # Queue + n_cpt=8 # Number of cpus per task (it will be limited by maximum) +fi #------------------------------------------------------------------------------------------# #==========================================================================================# #==========================================================================================# @@ -138,11 +153,30 @@ echo "Number of polygons: ${npolys}..." # script. # #------------------------------------------------------------------------------------------# exec_full="${here}/executable/${execname}" -if [ ! -s ${exec_full} ] +exec_src="${srcpath}/build/${execname}" +if [[ ! -s ${exec_full} ]] then echo "Executable file : ${exec_full} is not in the executable directory" echo "Copy the executable to the file before running this script!" exit 99 +elif ${checkexec} +then + #----- Check whether the executable is up to date. -------------------------------------# + idiff=$(diff ${exec_full} ${exec_src} 2> /dev/null | wc -l) + if [[ ${idiff} -gt 0 ]] + then + #----- Executable is not up to date, warn user and offer to update it. --------------# + echo "Executable ${exec_full} is not the same as the most recently compiled file." + echo "Most recent: ${exec_src}." + echo "Do you want to update the executable? [y/N]" + read update + update=$(echo ${update} | tr '[:upper:]' '[:lower:]') + case "${update}" in + y*) rsync - Putv ${exec_src} ${exec_full} ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# @@ -238,7 +272,6 @@ echo " Memory per cpu: ${sim_memory}" echo " CPUs per node: ${n_cpn}" echo " CPUs per task: ${n_cpt}" echo " Queue: ${global_queue}" -echo " Job Name: ${jobname}" echo " Total polygon count: ${npolys}" echo " " echo "------------------------------------------------" @@ -267,128 +300,143 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case this is an "init_only" run, impose final time to be the initial time. # + #---------------------------------------------------------------------------------------# + if ${init_only} + then + yearz=${yeara} + monthz=${montha} + datez=${datea} + timez=${timea} + fi #---------------------------------------------------------------------------------------# @@ -465,20 +513,20 @@ do # This step is necessary because we may have killed the run while it was # # writing, and as a result, the file may be corrupt. # #------------------------------------------------------------------------------------# - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) if [ ${nhdf5} -gt 0 ] then h5fine=0 while [ ${h5fine} -eq 0 ] do - lasthdf5=$(ls -1 ${here}/${polyname}/histo/* | tail -1) + lasthdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 | tail -1) h5dump -H ${lasthdf5} 1> /dev/null 2> ${here}/badfile.txt if [ -s ${here}/badfile.txt ] then /bin/rm -fv ${lasthdf5} - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) if [ ${nhdf5} -eq 0 ] then h5fine=1 @@ -531,6 +579,35 @@ do #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Run the small R script to generate specific observation times. # + #---------------------------------------------------------------------------------------# + /bin/rm -f ${here}/${polyname}/gen_obstimes.r + /bin/cp -f ${here}/Template/gen_obstimes.r ${here}/${polyname}/gen_obstimes.r + obstimes="${here}/${polyname}/gen_obstimes.r" + outtimes="${here}/${polyname}/out_obstimes.txt" + sed -i~ s@thispoly@${polyname}@g ${obstimes} + sed -i~ s@thisqueue@${queue}@g ${obstimes} + sed -i~ s@pathhere@${here}@g ${obstimes} + sed -i~ s@paththere@${here}@g ${obstimes} + sed -i~ s@thisyeara@${yeara}@g ${obstimes} + sed -i~ s@thismontha@${montha}@g ${obstimes} + sed -i~ s@thisdatea@${datea}@g ${obstimes} + sed -i~ s@thistimea@${timea}@g ${obstimes} + sed -i~ s@thisyearz@${yearz}@g ${obstimes} + sed -i~ s@thismonthz@${monthz}@g ${obstimes} + sed -i~ s@thisdatez@${datez}@g ${obstimes} + sed -i~ s@thistimez@${timez}@g ${obstimes} + sed -i~ s@thislon@${polylon}@g ${obstimes} + sed -i~ s@thislat@${polylat}@g ${obstimes} + R CMD BATCH --no-save --no-restore ${obstimes} ${outtimes} + while [[ ! -s ${here}/${polyname}/${polyname}_obstimes.txt ]] + do + sleep 0.2 + done + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # This should no longer occur, but it runtype is set to INITIAL, replace it with # @@ -773,6 +850,11 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). -----------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# scentype="ERA_Interim" @@ -823,6 +905,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# scentype="WFDEI" @@ -911,6 +998,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1061,6 +1154,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1098,7 +1197,7 @@ do # Correct years so it is not tower-based or Sheffield. # #---------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) echo "Nothing" > /dev/null ;; *) @@ -1155,6 +1254,12 @@ do ;; esac ;; + sa2-ril) + ludatabase="${lumain}/SimAmazonia2/ril/sa2_ril_" + ;; + sa2-cvl) + ludatabase="${lumain}/SimAmazonia2/cvl/sa2_cvl_" + ;; lurcp26) ludatabase="${lumain}/luh-1.1+rcp26_image/luh-1.1+rcp26_image-" ;; @@ -1274,8 +1379,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-4.032,-3.584,-3.159,-2.757,-2.377,-2.021,-1.689,-1.382,-1.101," - polyslz2="-0.846,-0.620,-0.424,-0.260,-0.130,-0.040" + polyslz1="-5.000,-4.468,-3.963,-3.483,-3.030,-2.604,-2.205,-1.836,-1.495,-1.185," + polyslz2="-0.906,-0.660,-0.447,-0.271,-0.134,-0.040" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1309,6 +1414,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.934,-6.934,-5.999,-5.131,-4.329,-3.593,-2.925,-2.324,-1.790," + polyslz2="-1.325,-0.928,-0.600,-0.342,-0.155,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.223,-8.029,-6.919,-5.891,-4.946,-4.084,-3.305,-2.609,-1.995," polyslz2="-1.464,-1.015,-0.648,-0.364,-0.161,-0.040" @@ -1317,6 +1431,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.51,-9.118,-7.828,-6.640,-5.552,-4.563,-3.674,-2.883,-2.191" + polyslz2="-1.595,-1.096,-0.693,-0.383,-0.166,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -1416,8 +1539,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-3.967,-3.467,-3.000,-2.565,-2.164,-1.797,-1.462,-1.162,-0.895," - polyslz2="-0.662,-0.464,-0.300,-0.171,-0.077,-0.020" + polyslz1="-5.000,-4.397,-3.833,-3.307,-2.819,-2.371,-1.961,-1.590,-1.257,-0.964," + polyslz2="-0.709,-0.493,-0.316,-0.178,-0.080,-0.020" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1451,6 +1574,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.807,-6.706,-5.696,-4.775,-3.942,-3.195,-2.533,-1,954,-1.456," + polyslz2="-1.037,-0.694,-0.424,-0.225,-0.092,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.076,-7.766,-6.569,-5.482,-4.504,-3.631,-2.862,-2.194,-1.622," polyslz2="-1.145,-0.759,-0.458,-0.239,-0.096,-0.020" @@ -1705,7 +1837,7 @@ do #----- Check whether to use SFILIN as restart or history. ------------------------------# - if [ ${runt} == "RESTORE" ] && [ ${forcehisto} -eq 1 ] + if [[ ${runt} == "RESTORE" ]] && [[ ${forcehisto} -eq 1 ]] then runt="HISTORY" year=${yearh} @@ -1713,125 +1845,192 @@ do date=${dateh} time=${timeh} thissfilin=${fullygrown} - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 5 ] + elif [[ ${runt} == "RESTORE" ]] then - if [ ! -s ${restart} ] - then - echo " Directory restart does not exist!" - echo " Change the variable restart at the beginning of the script" - exit 44 - else - runt="RESTORE" - thissfilin=${restart} - fi - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 6 ] - then - thissfilin=${fullygrown} - - - - #------------------------------------------------------------------------------------# - # Find the biometric files. This has been checked in spawn_poly.sh so they are # - # correct. Add a dummy name in case this is not supposed to be a biomass # - # initialisation run. # - #------------------------------------------------------------------------------------# - case ${biotype} in - 0) - #----- isizepft controls everything, and iage is ignored. ------------------------# - case ${isizepft} in - 0) - #----- Frankeinstein's under storey. ------------------------------------------# - thissfilin="${bioinit}/${polyiata}_default." - ;; - 1) - #----- No under storey. -------------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_nounder." - ;; - 2) - #----- ALS initialisation. ----------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_alsinit." - ;; - *) - #----- Invalid option. Stop the script. ---------------------------------------# - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 57 - ;; - esac + case ${initmode} in + 5|7) + #---------------------------------------------------------------------------------# + # Initialise ED2 with hdf5 files, which should be in directory restart. # + #---------------------------------------------------------------------------------# + if [[ ! -s ${restart} ]] + then + echo " Directory restart does not exist!" + echo " Change the variable restart at the beginning of the script" + exit 44 + else + runt="RESTORE" + thissfilin=${restart} + fi #---------------------------------------------------------------------------------# ;; - 1) + 1|2|3|6|8) #---------------------------------------------------------------------------------# - # 'isizepft' controls how many PFTs to use. # + # Find the biometric files. This has been checked in spawn_poly.sh so they # + # are correct. Add a dummy name in case this is not supposed to be a biomass # + # initialisation run. # #---------------------------------------------------------------------------------# - case ${isizepft} in - 0|5) - pftname="pft05" - ;; - 2) - pftname="pft02" + case ${biotype} in + 0) + #----- isizepft controls everything, and iage is ignored. ---------------------# + case ${isizepft} in + 0) + #----- Frankeinstein's under storey. ---------------------------------------# + thissfilin="${bioinit}/${polyiata}_default." + ;; + 1) + #----- No under storey. ----------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_nounder." + ;; + 2) + #----- ALS initialisation. -------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_alsinit." + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initialised with these ISIZEPFT and INITMODE!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------# - # 'iage' controls how many patches to use. # - #---------------------------------------------------------------------------------# - case ${iage} in 1) - agename="age01" + #------------------------------------------------------------------------------# + # 'isizepft' controls how many PFTs to use. # + #------------------------------------------------------------------------------# + case ${isizepft} in + 0|5) + pftname="pft05" + ;; + 2) + pftname="pft02" + ;; + esac + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # 'iage' controls how many patches to use. # + #------------------------------------------------------------------------------# + case ${iage} in + 1) + agename="age01" + ;; + *) + agename="age00" + ;; + esac + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether the site has the PFT and age structure. # + #------------------------------------------------------------------------------# + case ${polyiata} in + hvd|s77|fns|cau|and|par|tap|dcm) + thissfilin="${bioinit}/${polyiata}_default." + ;; + cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) + thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + ;; + *) + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " IAGE: ${iage}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 59 + ;; + esac + #------------------------------------------------------------------------------# ;; - *) - agename="age00" + 2) + #------------------------------------------------------------------------------# + # ALS initialisation. ISIZEPFT has disturbance history information. # + #------------------------------------------------------------------------------# + case ${polyiata} in + l[0-5][0-3]) + thissfilin="${alsinit}/${polyiata}." + ;; + *) + thissfilin="${alsinit}/${polyiata}_${isizepft}." + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - - - - - #---------------------------------------------------------------------------------# - # Check whether the site has the PFT and age structure. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - hvd|s77|fns|cau|and|par|tap|dcm) - thissfilin="${bioinit}/${polyiata}_default." + 3) + #------------------------------------------------------------------------------# + # ALS initialisation using intensity. ISIZEPFT has disturbance history # + # information. # + #------------------------------------------------------------------------------# + thissfilin="${intinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) - thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + 4) + #------------------------------------------------------------------------------# + # ALS initialisation using the lookup table. ISIZEPFT has disturbance # + # history information. # + #------------------------------------------------------------------------------# + thissfilin="${lutinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - *) - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " IAGE: ${iage}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 59 + 5) + #----- isizepft controls actual or majestic initialisation. -------------------# + case ${isizepft} in + 0) + #----- Actual sampling. ----------------------------------------------------# + thissfilin="${ebainit}/eba_actual_default." + #---------------------------------------------------------------------------# + ;; + 1) + #----- Majestic sampling. --------------------------------------------------# + thissfilin="${ebainit}/eba_majestic_default." + #---------------------------------------------------------------------------# + ;; + 2) + #----- Actual sampling + land use (pasture/cropland/plantation). -----------# + thissfilin="${ebainit}/eba_luactual_default." + #---------------------------------------------------------------------------# + ;; + 3) + #----- Majestic sampling + land use (pasture/cropland/plantation). ---------# + thissfilin="${ebainit}/eba_lumajestic_default." + #---------------------------------------------------------------------------# + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------# ;; - 2) - #---------------------------------------------------------------------------------# - # ALS initialisation. ISIZEPFT has disturbance history information. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - l[0-5][0-3]) - thissfilin="${alsinit}/${polyiata}." - ;; - *) - thissfilin="${alsinit}/${polyiata}_${isizepft}." - ;; - esac + *) + #----- No initial file needed; set the history file. -----------------------------# + thissfilin=${here}/${polyname}/histo/${polyname} #---------------------------------------------------------------------------------# ;; + #---------------------------------------------------------------------------------# esac #------------------------------------------------------------------------------------# else + #----- Set the history file. --------------------------------------------------------# thissfilin=${here}/${polyname}/histo/${polyname} + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -1998,6 +2197,7 @@ do sed -i~ s@mydbhharv@${dbhharv}@g ${ED2IN} sed -i~ s@mybioharv@${bioharv}@g ${ED2IN} sed -i~ s@myskidarea@${skidarea}@g ${ED2IN} + sed -i~ s@myskiddbhthresh@${skiddbhthresh}@g ${ED2IN} sed -i~ s@myskidsmall@${skidsmall}@g ${ED2IN} sed -i~ s@myskidlarge@${skidlarge}@g ${ED2IN} sed -i~ s@myfellingsmall@${fellingsmall}@g ${ED2IN} @@ -2081,7 +2281,7 @@ do echo "Polygon population has gone extinct. No need to re-submit it." submit_now=false ;; - "CRASHED"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") + "CRASHED"|"HYDFAIL"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") echo "Polygon has serious errors. Script will not submit the job this time." submit_now=false ;; diff --git a/ED/Template/scripts/PBS/stopalljobs.sh b/ED/Template/scripts/PBS/stopalljobs.sh deleted file mode 100755 index 1aa6e1a85..000000000 --- a/ED/Template/scripts/PBS/stopalljobs.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bash -here=$(pwd) -joborder="${here}/joborder.txt" -desc=$(basename ${here}) - -#----- Determine the number of polygons to stop. ------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 - -echo "Are you sure that you want to stop all jobs? [y/N]" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs... Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Alright then, but in case you regret later don't say that I didn't warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #------- Delete jobs. ------------------------------------------------------------------# - jobname="${desc}-${polyname}" - jobid=$(qjobs -j ${jobname} -n | awk '{print $1}') - qdel ${jobid} - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - - diff --git a/ED/Template/scripts/SLURM/check_run.sh b/ED/Template/scripts/SLURM/check_run.sh index 42ef6ad18..64f209cd3 100755 --- a/ED/Template/scripts/SLURM/check_run.sh +++ b/ED/Template/scripts/SLURM/check_run.sh @@ -2,7 +2,7 @@ here=$(pwd) joborder="${here}/joborder.txt" desc=$(basename ${here}) -jobname="${desc}-sims" +jobname="${desc}-sims*" moi=$(whoami) outform="JobName%200,State%12" #----- Determine the number of polygons to run. -------------------------------------------# @@ -10,6 +10,26 @@ let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 echo "Number of polygons: ${npolys}..." + + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*) + cluster="CANNON" + ;; +sdumont*) + cluster="SDUMONT" + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + polya=1 polyz=${npolys} @@ -75,147 +95,184 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. -------------# + taskname="${polyname}" + #------------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. -----------------------# + taskname="${desc}-${polyname}" + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Set some variables to check whether the simulation is running. # #---------------------------------------------------------------------------------------# stdout="${here}/${polyname}/serial_out.out" stderr="${here}/${polyname}/serial_out.err" - lsfout="${here}/${polyname}/serial_lsf.out" skipper="${here}/${polyname}/skipper.txt" #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# # Check whether the simulation is still running, and if not, why it isn't. # #---------------------------------------------------------------------------------------# if [ -s ${stdout} ] then + + #----- Set task inquire command. ----------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Multi-task job, search for specific task. ---------------------------------# + stask="stask --noheader -u ${moi} -t ${taskname} -j ${jobname}" + #---------------------------------------------------------------------------------# + ;; + CANNON) + #----- Single-task jobs, search the task using the job name. ---------------------# + stask="stask --noheader -u ${moi} -j ${taskname}" + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + + #----- Check whether the simulation is running, and when in model time it is. -------# - stask="stask --noheader -u ${moi} -t ${polyname} -j ${jobname}" running=$(${stask} -o "${outform}" | grep "RUNNING" | wc -l) pending=$(${stask} -o "${outform}" | grep "PENDING" | wc -l) suspended=$(${stask} -o "${outform}" | grep "SUSPENDED" | wc -l) @@ -247,9 +304,10 @@ do #----- Check for other possible outcomes. -------------------------------------------# - stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) - crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) - the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) + stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) + crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) + hydfail=$(grep "Plant Hydrodynamics is off-track." ${stdout} | wc -l) + the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) #------------------------------------------------------------------------------------# @@ -271,6 +329,9 @@ do elif [ ${crashed} -gt 0 ] then echo -e "${ffout}: ${polyname} HAS CRASHED (RK4 PROBLEM)... <===========" + elif [ ${hydfail} -gt 0 ] + then + echo -e "${ffout}: ${polyname} HAS CRASHED (HYDRODYNAMICS)... <===========" elif [ ${metmiss} -gt 0 ] then echo -e "${ffout}: ${polyname} DID NOT FIND MET DRIVERS... <===========" diff --git a/ED/Template/scripts/SLURM/clean_scratch.sh b/ED/Template/scripts/SLURM/clean_scratch.sh deleted file mode 100755 index 43766e350..000000000 --- a/ED/Template/scripts/SLURM/clean_scratch.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -myself=$(whoami) - -#----- Check which queue we will clean. ---------------------------------------------------# -if [ "x${1}" == "x" ] -then - echo -n "Which queue do you want to clean?" - read queue -else - queue=${1} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Select the nodes to be deleted. # -#------------------------------------------------------------------------------------------# -case ${queue} in -moorcroft_6100a) - nodes="moorcroft01 moorcroft02 moorcroft03 moorcroft04" - ;; -moorcroft_6100b) - nodes="moorcroft05 moorcroft06 moorcroft07 moorcroft08 moorcroft09 - moorcroft10 moorcroft11 moorcroft12 moorcroft13 moorcroft14 - moorcroft15 moorcroft16 moorcroft17 moorcroft18 moorcroft19 - moorcroft20 moorcroft21 moorcroft22 moorcroft23 moorcroft24 - moorcroft25 moorcroft26 moorcroft27 moorcroft28 moorcroft29 - moorcroft30 moorcroft31 moorcroft32 moorcroft33 moorcroft34 - moorcroft35 moorcroft36 moorcroft37 moorcroft38 moorcroft39 - moorcroft40 moorcroft41 moorcroft42 moorcroft43 moorcroft44" - ;; -moorcroft2a) - nodes="hero4001 hero4002 hero4003 hero4004 hero4005 hero4006 - hero4007 hero4008 hero4009 hero4010 hero4011" - ;; -moorcroft2b) - nodes="hero4014 hero4015 hero4016 hero4101 hero4102 hero4103 - hero4104 hero4105 hero4106 hero4107 hero4108" - ;; -moorcroft2c) - nodes="hero4109 hero4110 hero4111 hero4112 hero4113 hero4114 hero4115 hero4116" - ;; -wofsy) - nodes="wofsy011 wofsy012 wofsy013 wofsy014 wofsy021 wofsy022 wofsy023 wofsy024" - ;; -camd) - nodes="camd04 camd05 camd06 camd07 camd09 camd10 camd11 camd13" - ;; -unrestricted_parallel) - nodes="hero3103 hero3104 hero3107 hero3108 hero3109 hero3110 - hero3111 hero3112 hero3113 hero3114 hero3115 hero3116 - hero3201 hero3202 hero3203 hero3204 hero3205 hero3206 - hero3207 hero3208 hero3209 hero3210 hero3211 hero3212 - hero3213 hero3214 hero3215 hero3216" - ;; -unrestricted_serial) - nodes="hero1301 hero1912 soph57 soph58 soph59 soph60 soph61 soph62 soph63 soph64" - ;; -long_serial) - nodes="soph01 soph02 soph03 soph04 soph05 soph06 soph07 soph08 - soph09 soph10 soph11 soph12 soph13 soph14 soph15 soph16 - soph17 soph18 soph19 soph20 soph22 soph23 soph24 soph25 - soph26 soph27 soph28 soph29 soph30 soph31 soph32 soph33 - soph34 soph35 soph36 soph37 soph38 soph39 soph40 soph41 - soph42 soph43 soph44 soph45 soph46 soph47 soph48 soph49 - soph51 soph52 soph53 soph54 soph55 soph56" - ;; -*) - echo " I cannot recognise queue ${queue}..." - exit 39 - ;; -esac -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Delete the files in all nodes that the queue uses. # -#------------------------------------------------------------------------------------------# -for node in ${nodes} -do - echo -n " Scheduling files for deletion - node ${node}..." - ssh ${node} /bin/mv /scratch/${myself} /scratch/goodbye-${myself} 1> /dev/null 2>&1 - ssh ${node} rm -fr /scratch/goodbye-${myself} 1> /dev/null 2>&1 & - echo "Done!" -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/delall.sh b/ED/Template/scripts/SLURM/delall.sh deleted file mode 100755 index d06c12487..000000000 --- a/ED/Template/scripts/SLURM/delall.sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/bash -here=$(pwd) -moi=$(whoami) -diskthere="" -joborder="${here}/joborder.txt" - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -if [ "x${diskthere}" == "x" ] -then - diskthere=${diskhere} - there=${here} -else - there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -fi -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure that you want to remove all files and directories? [y/N]" -else - echo "Are you sure that you want to remove all files? [y/N]" -fi -read proceed -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi -#------------------------------------------------------------------------------------------# - - - -#----- Check that the user is aware that it will remove everything... ---------------------# -echo " " -if [ "x${1}" == "x-d" ] -then - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output directories and files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -else - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo " " - echo " Look, this will REALLY delete all ${npolys} output files..." - echo " " - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -fi - -echo "This is PERMANENT, once they are gone, adieu, no chance to recover them!" -echo "Is that what you really want? [y/N]" -read proceed - -echo " " - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later do not say that I did not warn you..." -echo "I am giving you a few seconds to kill this script in case you change your mind..." -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Deletion will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/epost.sh b/ED/Template/scripts/SLURM/epost.sh index 7159f9c09..f0c0c8163 100755 --- a/ED/Template/scripts/SLURM/epost.sh +++ b/ED/Template/scripts/SLURM/epost.sh @@ -67,8 +67,14 @@ optsrc="-n" # Option for .bashrc (for special submission setti # In case none is needed, leave it blank (""). #----- Settings for this group of polygons. -----------------------------------------------# global_queue="" # Queue +reservation="" # Reservation +overcommit="" # Ignore maximum task limit for partition? (true/false) partial=false # Partial submission (false will ignore polya and npartial # and send all polygons. +skip_end=true # Skip processing in case the R script has already loaded + # all files through the end of the simulation + # (true/false). This is only used for "monthly"-based + # scripts (those marked with (*) in the table below). polya=501 # First polygon to submit npartial=100 # Maximum number of polygons to include in this bundle # (actual number will be adjusted for total number of @@ -84,35 +90,39 @@ runtime="00:00:00" # Simulation time in hours. If zero, then it will #------------------------------------------------------------------------------------------# -# Which script to run (multiple scripts are not allowed). # +# Which scripts to run. # # # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # +# - read_monthly.r - (*) This reads the monthly mean files (results can then be used # +# for plot_monthly.r, plot_yearly.r, and others, but it doesn't plot # +# anything.) # +# - yearly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - monthly_ascii.r - (*) This creates three ascii (csv) files with annual averages of # +# various variables. It doesn't have all possible variables as it # +# is intended to simplify the output for learning purposes. # +# - plot_monthly.r - (*) This creates several plots based on the monthly mean output. # +# - plot_yearly.r - (*) This creates plots with year time series. # +# - plot_ycomp.r - (*) This creates yearly comparisons based on the monthly mean # +# output. # +# - plot_povray.r - (*) This creates yearly plots of the polygon using POV-Ray. # +# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch-level only). # +# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # +# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # +# (patch- and cohort-level). # +# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # +# (patch-level only). # +# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # +# - plot_census.r - This creates plots comparing model with biometric data. # +# - whichrun.r - This checks the run status. # # # # The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # +# - plot_daily.r - This creates plots from the daily mean output. # +# - plot_fast.r - This creates plots from the analysis files. # +# - patchprops.r - This creates simple plots showing the patch structure. # +# - reject_ed.r - This tracks the number of steps that were rejected, and what # +# caused the step to be rejected. # #------------------------------------------------------------------------------------------# rscript="" #rscript="yearly_ascii.r" @@ -177,7 +187,7 @@ monthsdrought="c(12,1,2,3)" # List of months that get drought, if it starts late #------------------------------------------------------------------------------------------# # First check that the main path and e-mail have been set. If not, don't run. # #------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${global_queue}" == "x" ] || [ "x${rscript}" == "x" ] +if [[ "x${here}" == "x" ]] || [[ "x${global_queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] then echo " You must set some variables before running the script:" echo " Check variables \"here\", \"global_queue\" and \"rscript\"!" @@ -187,85 +197,37 @@ fi #----- Load settings. ---------------------------------------------------------------------# -if [ -s ${initrc} ] +if [[ -s ${initrc} ]] then . ${initrc} fi #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Configurations depend on the global_queue. # -#------------------------------------------------------------------------------------------# -case ${ordinateur} in +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in rclogin*|holy*|moorcroft*|rcnx*) - #----- Odyssey queues. -----------------------------------------------------------------# - case ${global_queue} in - "general") - n_nodes_max=166 - n_cpt=1 - n_tpn=32 - runtime_max="7-00:00:00" - node_memory=262499 - ;; - "shared,huce_intel"|"huce_intel,shared") - n_nodes_max=276 - n_cpt=1 - n_tpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared") - n_nodes_max=456 - n_cpt=1 - n_tpn=48 - runtime_max="7-00:00:00" - node_memory=192892 - ;; - "huce_intel") - n_nodes_max=276 - n_cpt=1 - n_tpn=24 - runtime_max="14-00:00:00" - node_memory=126820 - ;; - "huce_amd") - n_nodes_max=65 - n_cpt=1 - n_tpn=32 - runtime_max="14-00:00:00" - node_memory=262499 - ;; - "moorcroft_amd") - n_nodes_max=8 - n_cpt=1 - n_tpn=64 - runtime_max="infinite" - node_memory=256302 - ;; - "moorcroft_6100") - n_nodes_max=35 - n_cpt=1 - n_tpn=12 - runtime_max="infinite" - node_memory=22150 - ;; - "unrestricted") - n_nodes_max=8 - n_cpt=1 - n_tpn=64 - runtime_max="31-00:00:00" - node_memory=262499 - ;; - *) - echo "Global queue ${global_queue} is not recognised!" - exit - ;; - esac - #---------------------------------------------------------------------------------------# + cluster="CANNON" ;; sdumont*) - #----- SantosDumont. -------------------------------------------------------------------# + cluster="SDUMONT" + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Configurations depend on the global_queue and cluster. # +#------------------------------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #----- Set parameters according to partitions. -----------------------------------------# case ${global_queue} in cpu_long|nvidia_long) n_nodes_max=10 @@ -309,13 +271,70 @@ sdumont*) esac #---------------------------------------------------------------------------------------# ;; -*) - #----- Computer is not listed. Crash. -------------------------------------------------# - echo " Invalid computer ${ordinateur}. Check queue settings in the script." - exit 31 +CANNON) + #----- Set parameters according to partitions. -----------------------------------------# + case ${global_queue} in + "commons") + n_nodes_max=5 + n_cpt=1 + n_tpn=32 + runtime_max="14-00:00:00" + node_memory=126820 + ;; + "huce_cascade") + n_nodes_max=30 + n_cpt=1 + n_tpn=48 + runtime_max="14-00:00:00" + node_memory=183240 + ;; + "huce_intel") + n_nodes_max=150 + n_cpt=1 + n_tpn=24 + runtime_max="14-00:00:00" + node_memory=122090 + ;; + "shared,huce_intel"|"huce_intel,shared") + n_nodes_max=150 + n_cpt=1 + n_tpn=24 + runtime_max="7-00:00:00" + node_memory=122090 + ;; + "shared") + n_nodes_max=220 + n_cpt=1 + n_tpn=48 + runtime_max="7-00:00:00" + node_memory=183240 + ;; + "test") + n_nodes_max=9 + n_cpt=1 + n_tpn=48 + runtime_max="8:00:00" + node_memory=183240 + ;; + "unrestricted") + n_nodes_max=4 + n_cpt=1 + n_tpn=48 + runtime_max="infinite" + node_memory=183240 + ;; + *) + echo "Global queue ${global_queue} is not recognised!" + exit + ;; + esac #---------------------------------------------------------------------------------------# ;; esac +#------------------------------------------------------------------------------------------# + + +#----- Set the number of tasks. -----------------------------------------------------------# let n_tasks_max=${n_nodes_max}*${n_tpn} #------------------------------------------------------------------------------------------# @@ -459,6 +478,9 @@ read_monthly.r) yearly_ascii.r) epostkey="yasc" ;; +monthly_ascii.r) + epostkey="masc" + ;; r10_monthly.r) epostkey="rm10" ;; @@ -512,7 +534,7 @@ plot_fast.r) # If the script is here, then it could not find the script... And this should never # # happen, so interrupt the script! # #---------------------------------------------------------------------------------------# - echo " Script ${script} is not recognised by epost.sh!" + echo " Script ${rscript} is not recognised by epost.sh!" exit 1 #---------------------------------------------------------------------------------------# ;; @@ -522,32 +544,21 @@ esac -#----- Set script information. ------------------------------------------------------------# -epoststo="${epostkey}_epost.sto" -epostste="${epostkey}_epost.ste" -epostout="${epostkey}_epost.out" -epostjob="${epostkey}-${desc}" -epostexe="R CMD BATCH --no-save --no-restore ${rscript} ${epostout}" -#------------------------------------------------------------------------------------------# - - - - #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_tpn} let node_memory=${n_tpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 else #------ Set memory and number of CPUs per task. ----------------------------------------# let n_tpn_try=${node_memory}/${sim_memory} - if [ ${n_tpn_try} -le ${n_tpn} ] + if [[ ${n_tpn_try} -le ${n_tpn} ]] then n_tpn=${n_tpn_try} let sim_memory=${node_memory}/${n_tpn} @@ -563,13 +574,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -585,7 +596,7 @@ if ${partial} then let ff=${polya}-1 let polyz=${ff}+${npartial} - if [ ${polyz} -gt ${npolys} ] + if [[ ${polyz} -gt ${npolys} ]] then polyz=${npolys} fi @@ -593,6 +604,7 @@ then sbatch="${here}/sub_${rprefix}_${partlabel}.sh" obatch="${here}/out_${rprefix}_${partlabel}.log" ebatch="${here}/err_${rprefix}_${partlabel}.log" + epostjob="${epostkey}-${desc}_${partlabel}" else ff=0 polya=1 @@ -600,91 +612,143 @@ else sbatch="${here}/sub_${rprefix}.sh" obatch="${here}/out_${rprefix}.log" ebatch="${here}/err_${rprefix}.log" + epostjob="${epostkey}-${desc}" fi let ntasks=1+${polyz}-${polya} #------------------------------------------------------------------------------------------# + + #----- Summary for this submission preparation. Then give 5 seconds for user to cancel. --# echo "------------------------------------------------" echo " Submission summary: " echo "" echo " Memory per cpu: ${sim_memory}" echo " Tasks per node: ${n_tpn}" -echo " Queue: ${global_queue}" +echo " Partition: ${global_queue}" echo " Run time: ${runtime}" echo " First polygon: ${polya}" echo " Last polygon: ${polyz}" -echo " Job Name: ${epostjob}" echo " Total polygon count: ${npolys}" echo " " echo " Partial submission: ${partial}" echo " Automatic submission: ${submit}" echo " " echo " R script: ${rscript}" +echo " Submission script: $(basename ${sbatch})" echo "------------------------------------------------" echo "" +echo "" +echo -n " Waiting five seconds before proceeding... " sleep 5 +echo "Done!" #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Initialise executable. # +# Initialise executable. The main executable will have different settings depending # +# on whether this is to be a multi-task single job, or multiple single-task jobs. # #------------------------------------------------------------------------------------------# -rm -fr ${sbatch} -touch ${sbatch} -chmod u+x ${sbatch} -echo "#!/bin/bash" >> ${sbatch} -echo "#SBATCH --ntasks=${ntasks} # Number of tasks" >> ${sbatch} -echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${sbatch} -echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} -echo "#SBATCH --job-name=${epostjob} # Job name" >> ${sbatch} -echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} -echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} -echo "#SBATCH --output=${here}/out_epost.out # Standard output path" >> ${sbatch} -echo "#SBATCH --error=${here}/out_epost.err # Standard error path" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Get plenty of memory." >> ${sbatch} -echo "ulimit -s unlimited" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Initial settings." >> ${sbatch} -echo "here=\"${here}\" # Main path" >> ${sbatch} -echo "rscript=\"${rscript}\" # R Script" >> ${sbatch} -echo "rstdout=\"${epostout}\" # Standard output" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Print information about this job." >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"----- Summary of current job ---------------------------------\"" >> ${sbatch} -echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} -echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} -echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} -echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} -echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} -echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} -echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} -echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} -echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} -echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} -echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Define home in case home is not set" >> ${sbatch} -echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export HOME=\$(echo ~)" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Load modules and settings." >> ${sbatch} -echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Task list." >> ${sbatch} +case "${cluster}" in +SDUMONT) + #----- Initialise script to submit a single multi-task job. ----------------------------# + rm -fr ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "#SBATCH --ntasks=${ntasks} # Number of tasks" >> ${sbatch} + echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${sbatch} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} + if [[ "${reservation}" != "" ]] + then + echo "#SBATCH --reservation=${reservation} # Reserved nodes" >> ${sbatch} + fi + echo "#SBATCH --job-name=${epostjob} # Job name" >> ${sbatch} + echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} + echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "rscript=\"${rscript}\" # R Script" >> ${sbatch} + echo "rstdout=\"${epostout}\" # Standard output" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Print information about this job." >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"----- Summary of current job ------------------------------\"" >> ${sbatch} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} + echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +CANNON) + #----- Initialise script to submit multiple single-task jobs. --------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +esac #------------------------------------------------------------------------------------------# @@ -694,7 +758,7 @@ echo "#----- Task list." > # Loop over all polygons. # #------------------------------------------------------------------------------------------# n_submit=0 -while [ ${ff} -lt ${polyz} ] +while [[ ${ff} -lt ${polyz} ]] do let ff=${ff}+1 let line=${ff}+3 @@ -703,13 +767,13 @@ do #---------------------------------------------------------------------------------------# # Format count. # #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] + if [[ ${npolys} -ge 10 ]] && [[ ${npolys} -lt 100 ]] then ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 1000 ]] then ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] + elif [[ ${npolys} -ge 100 ]] && [[ ${npolys} -lt 10000 ]] then ffout=$(printf '%4.4i' ${ff}) else @@ -726,128 +790,144 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #------ Last month and year for monthly-based scripts. ---------------------------------# + if [[ ${monthz} -eq 1 ]] + then + rm_monthz=12 + let rm_yearz=${yearz}-1 + else + let rm_monthz=${monthz}-1 + rm_yearz=${yearz} + fi + #------ Update the time. ---------------------------------------------------------------# + let rm_whenz=12*${rm_yearz}+${rm_monthz} #---------------------------------------------------------------------------------------# @@ -983,11 +1063,11 @@ do #---- Cheat and force the met cycle to be the tower cycle. -----------------------------# - if [ ${useperiod} == "f" ] + if [[ ${useperiod} == "f" ]] then metcyca=${eftyeara} metcycz=${eftyearz} - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then metcyca=${bioyeara} metcycz=${bioyearz} @@ -999,7 +1079,7 @@ do #---------------------------------------------------------------------------------------# # Switch years in case this is a specific drought run. # #---------------------------------------------------------------------------------------# - if [ ${droughtmark} == "TRUE" ] + if [[ ${droughtmark} == "TRUE" ]] then let yeara=${droughtyeara}-1 let yearz=${droughtyearz}+1 @@ -1008,32 +1088,21 @@ do - #----- Print a banner. -----------------------------------------------------------------# - if [ ${rscript} == "plot_census.r" ] && [ ${subcens} -eq 0 ] - then - echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." - else - echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." - fi - #---------------------------------------------------------------------------------------# - - - #---------------------------------------------------------------------------------------# # Set up the time and output variables according to the script. # #---------------------------------------------------------------------------------------# case ${rscript} in - read_monthly.r|yearly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) + read_monthly.r|yearly_ascii.r|monthly_ascii.r|plot_monthly.r|plot_yearly.r|plot_ycomp.r|plot_census.r|plot_povray.r|r10_monthly.r) #------------------------------------------------------------------------------------# # Scripts that are based on monthly means. The set up is the same, the only # # difference is in the output names. # #------------------------------------------------------------------------------------# #------ Check which period to use. --------------------------------------------------# - if [ ${useperiod} == "t" ] + if [[ ${useperiod} == "t" ]] then #------ One meteorological cycle. Check the type of meteorological driver. ------# case ${metdriver} in - Sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) thisyeara=${metcyca} thisyearz=${metcycz} ;; @@ -1046,34 +1115,34 @@ do thisyearz=${metcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then echo " -> Shifting met cycle" let metcycle=${metcycz}-${metcyca}+1 let deltayr=${shiftcycle}*${metcycle} let thisyeara=${metcyca}+${deltayr} let thisyearz=${metcycz}+${deltayr} - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} ;; esac # ${metdriver} in #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "u" ] + elif [[ ${useperiod} == "u" ]] then #----- The user said which period to use. ----------------------------------------# thisyeara=${yusera} thisyearz=${yuserz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "f" ] + elif [[ ${useperiod} == "f" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${eftyeara} thisyearz=${eftyearz} #---------------------------------------------------------------------------------# - elif [ ${useperiod} == "b" ] + elif [[ ${useperiod} == "b" ]] then #----- The user said to use the eddy flux period. --------------------------------# thisyeara=${bioyeara} @@ -1085,7 +1154,7 @@ do thisyeara=${yeara} thisyearz=${yearz} #---------------------------------------------------------------------------------# - fi # end [ ${useperiod} == "t" ] + fi # end [[ ${useperiod} == "t" ]] #------------------------------------------------------------------------------------# @@ -1095,6 +1164,53 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Check whether or not to submit the task. -------------------------------------# + if [[ ${rscript} == "plot_census.r" ]] && [[ ${subcens} -eq 0 ]] + then + #---- No need to submit the job if plot_census.r and place doesn't have census. --# + submit_now=false + #---------------------------------------------------------------------------------# + elif ${skip_end} + then + status="${here}/${polyname}/rdata_month/status_${polyname}.txt" + if [[ -s ${status} ]] + then + #----- Retrieve current status of the post-processing. ------------------------# + st_yearz=$(cat ${status} | awk '{print $1}') + st_monthz=$(cat ${status} | awk '{print $2}') + let st_whenz=12*${st_yearz}+${st_monthz} + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # Compare the processed time with the last time needed for processing. # + #------------------------------------------------------------------------------# + if [[ ${st_whenz} -ge ${rm_whenz} ]] + then + #----- Skip submission because it has reached the end. ---------------------# + submit_now=false + #---------------------------------------------------------------------------# + else + #----- Run script as it has not reached the end yet. -----------------------# + submit_now=true + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + else + #----- File not find, run the script. -----------------------------------------# + submit_now=true + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + else + #----- Submit job. ---------------------------------------------------------------# + submit_now=true + #---------------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------------# ;; plot_eval_ed.r) #------------------------------------------------------------------------------------# @@ -1102,7 +1218,7 @@ do # Petrolina (output variables exist only for 2004, so we don't need to process # # all years). # #------------------------------------------------------------------------------------# - if [ ${metdriver} == "Petrolina" ] + if [[ ${metdriver} == "Petrolina" ]] then thismetcyca=2004 thismetcycz=2004 @@ -1122,7 +1238,7 @@ do thisyearz=${thismetcycz} for i in ${shiftiata} do - if [ "x${i}" == "x${polyiata}" ] + if [[ "x${i}" == "x${polyiata}" ]] then #----- Always use the true met driver to find the cycle shift. ----------------# echo " -> Shifting met cycle" @@ -1131,7 +1247,7 @@ do let thisyeara=${thismetcyca}+${deltayr} let thisyearz=${thismetcycz}+${deltayr} #------------------------------------------------------------------------------# - fi # end [ ${i} == ${iata} ] + fi # end [[ ${i} == ${iata} ]] done #end for i in ${shiftiata} #------------------------------------------------------------------------------------# @@ -1142,6 +1258,12 @@ do thismonthz=12 thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_budget.r|plot_rk4.r|plot_rk4pc.r|plot_photo.r|reject_ed.r) @@ -1151,7 +1273,7 @@ do # at the first time step), so we normally skip the first day. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1168,6 +1290,12 @@ do thismonthz=${monthz} let thisdatea=${datea}+1 #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; @@ -1176,7 +1304,7 @@ do # Script with time-independent patch properties. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1193,13 +1321,19 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_daily.r) #------------------------------------------------------------------------------------# # Script with daily means. No need to skip anything. # #------------------------------------------------------------------------------------# #----- Check whether to use the user choice of year or the default. -----------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1216,6 +1350,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; plot_fast.r) @@ -1223,7 +1363,7 @@ do # Script with short-term averages (usually hourly). No need to skip any- # # thing. # #------------------------------------------------------------------------------------# - if [ ${useperiod} == "u" ] + if [[ ${useperiod} == "u" ]] then thisyeara=${yusera} thisyearz=${yuserz} @@ -1240,6 +1380,12 @@ do thismonthz=${monthz} thisdatea=${datea} #------------------------------------------------------------------------------------# + + + + #----- Assume this should be submitted. ---------------------------------------------# + submit_now=true + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -1273,7 +1419,7 @@ do sed -i s@thisseasonmona@${seasonmona}@g ${scriptnow} sed -i s@myphysiol@${iphysiol}@g ${scriptnow} sed -i s@myallom@${iallom}@g ${scriptnow} - sed -i s@myslhydro@${slhydro}@g ${scriptnow} + sed -i s@myslhydro@${islhydro}@g ${scriptnow} sed -i s@mydroughtmark@${droughtmark}@g ${scriptnow} sed -i s@mydroughtyeara@${droughtyeara}@g ${scriptnow} sed -i s@mydroughtyearz@${droughtyearz}@g ${scriptnow} @@ -1297,6 +1443,112 @@ do #---------------------------------------------------------------------------------------# + #----- Initialise script. --------------------------------------------------------------# + epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" + complete="${here}/${polyname}/eval_load_complete.txt" + epoststo="${here}/${polyname}/${epostkey}_epost.sto" + epostste="${here}/${polyname}/${epostkey}_epost.ste" + epostout="${here}/${polyname}/${epostkey}_epost.out" + epostexe="R CMD BATCH --no-save --no-restore ${rscript} ${epostout}" + rm -fr ${epostsh} + touch ${epostsh} + chmod u+x ${epostsh} + #---------------------------------------------------------------------------------------# + + + #----- The script header must check which type of submission to use. -------------------# + case "${cluster}" in + SDUMONT) + #----- Task name with the prefix. ---------------------------------------------------# + eposttask="${polyname}" + #------------------------------------------------------------------------------------# + + + #----- Header doesn't need to have SBATCH instructions. -----------------------------# + echo "#!/bin/bash" >> ${epostsh} + echo "main=\"${here}/${polyname}\"" >> ${epostsh} + echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} + echo "yeara=${thisyeara}" >> ${epostsh} + echo "yearz=${thisyearz}" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + + ;; + CANNON) + #----- Task name with the prefix. ---------------------------------------------------# + eposttask="${epostkey}-${desc}-${polyname}" + #------------------------------------------------------------------------------------# + + + #----- Header must have SBATCH instructions. ----------------------------------------# + echo "#!/bin/bash" >> ${epostsh} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${epostsh} + echo "#SBATCH --cpus-per-task=1 # Number of CPUs per task" >> ${epostsh} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${epostsh} + if [[ "${reservation}" != "" ]] + then + echo "#SBATCH --reservation=${reservation} # Reserved nodes" >> ${epostsh} + fi + echo "#SBATCH --job-name=${eposttask} # Task name" >> ${epostsh} + echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${epostsh} + echo "#SBATCH --time=${runtime} # Time for job" >> ${epostsh} + echo "#SBATCH --output=${epoststo} # Standard output path" >> ${epostsh} + echo "#SBATCH --error=${epostste} # Standard error path" >> ${epostsh} + echo "#SBATCH --chdir=${here}/${polyname} # Main directory" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Get plenty of memory." >> ${epostsh} + echo "ulimit -s unlimited" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Initial settings." >> ${epostsh} + echo "here=\"${here}\" # Main path" >> ${epostsh} + echo "rscript=\"${rscript}\" # R Script" >> ${epostsh} + echo "rstdout=\"${epostout}\" # Standard output" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Print information about this job." >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"----- Summary of current job -------------------------\"" >> ${epostsh} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${epostsh} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${epostsh} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${epostsh} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${epostsh} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${epostsh} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${epostsh} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${epostsh} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${epostsh} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${epostsh} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${epostsh} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${epostsh} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${epostsh} + echo "echo \"------------------------------------------------------\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "echo \"\"" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Define home in case home is not set" >> ${epostsh} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} + echo "then" >> ${epostsh} + echo " export HOME=\$(echo ~)" >> ${epostsh} + echo "fi" >> ${epostsh} + echo "" >> ${epostsh} + echo "#--- Load modules and settings." >> ${epostsh} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${epostsh} + echo "" >> ${epostsh} + echo "main=\"${here}/${polyname}\"" >> ${epostsh} + echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} + echo "yeara=${thisyeara}" >> ${epostsh} + echo "yearz=${thisyearz}" >> ${epostsh} + echo "" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + + ;; + esac + #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# @@ -1306,28 +1558,6 @@ do case ${rscript} in plot_eval_ed.r) #----- Create script that will run R until all files have been read. ----------------# - epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" - complete="${here}/${polyname}/eval_load_complete.txt" - rm -fr ${epostsh} - touch ${epostsh} - chmod u+x ${epostsh} - echo "#!/bin/bash" >> ${epostsh} - echo "main=\"${here}/${polyname}\"" >> ${epostsh} - echo "complete=\"\${main}/eval_load_complete.txt\"" >> ${epostsh} - echo "yeara=${thisyeara}" >> ${epostsh} - echo "yearz=${thisyearz}" >> ${epostsh} - echo "" >> ${epostsh} - echo "" >> ${epostsh} - echo "#--- Define home in case home is not set" >> ${epostsh} - echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} - echo "then" >> ${epostsh} - echo " export HOME=\$(echo ~)" >> ${epostsh} - echo "fi" >> ${epostsh} - echo "" >> ${epostsh} - echo ". \${HOME}/.bashrc" >> ${epostsh} - echo "" >> ${epostsh} - echo "cd \${main}" >> ${epostsh} - echo "" >> ${epostsh} echo "let itmax=\${yearz}-\${yeara}+2" >> ${epostsh} echo "" >> ${epostsh} echo "/bin/rm -fr \${complete}" >> ${epostsh} @@ -1342,24 +1572,6 @@ do ;; *) #----- Create script that will run R until all files have been read. ----------------# - epostsh="${here}/${polyname}/exec_$(basename ${rscript} .r).sh" - rm -fr ${epostsh} - touch ${epostsh} - chmod u+x ${epostsh} - echo "#!/bin/bash" >> ${epostsh} - echo "main=\"${here}/${polyname}\"" >> ${epostsh} - echo "" >> ${epostsh} - echo "" >> ${epostsh} - echo "#--- Define home in case home is not set" >> ${epostsh} - echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${epostsh} - echo "then" >> ${epostsh} - echo " export HOME=\$(echo ~)" >> ${epostsh} - echo "fi" >> ${epostsh} - echo "" >> ${epostsh} - echo ". \${HOME}/.bashrc" >> ${epostsh} - echo "" >> ${epostsh} - echo "cd \${main}" >> ${epostsh} - echo "" >> ${epostsh} echo "${epostexe}" >> ${epostsh} echo "" >> ${epostsh} #------------------------------------------------------------------------------------# @@ -1370,9 +1582,36 @@ do - #----- Make sure this is not the census script for a site we don't have census. --------# - if [ ${rscript} != "plot_census.r" ] || [ ${subcens} -ne 0 ] + #----- In case of single task jobs, add commands to complete the job. ------------------# + case "${cluster}" in + CANNON) + #----- Wait for the processing to finish before killing it, and write runtime info. -# + echo "" >> ${epostsh} + echo "" >> ${epostsh} + echo "#----- Make sure that jobs complete before terminating script" >> ${epostsh} + echo "wait" >> ${epostsh} + echo "" >> ${epostsh} + echo "#----- Report efficiency of this job" >> ${epostsh} + echo "seff \${SLURM_JOBID}" >> ${epostsh} + echo "" >> ${epostsh} + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Decide whether or not to submit task. # + #---------------------------------------------------------------------------------------# + if ${submit_now} then + #----- Submit script. ---------------------------------------------------------------# + echo "${ffout} - Copying script ${rscript} to polygon: ${polyname}..." + #------------------------------------------------------------------------------------# + + #----- Update the list of scripts to be included in the batch. ----------------------# let n_submit=${n_submit}+1 #------------------------------------------------------------------------------------# @@ -1380,15 +1619,32 @@ do - #----- Append job to submission list. -----------------------------------------------# - srun="srun --nodes=1 --ntasks=1" - srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" - srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" - srun="${srun} --job-name=${polyname}" - srun="${srun} --chdir=\${here}/${polyname}" - srun="${srun} --output=\${here}/${polyname}/${epoststo}" - srun="${srun} --error=\${here}/${polyname}/${epostste}" - echo "${srun} ${epostsh} &" >> ${sbatch} + #----- Decide how to submit the job. ------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Append task to main job submission script. --------------------------------# + srun="srun --nodes=1 --ntasks=1" + srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" + srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" + srun="${srun} --job-name=${eposttask}" + srun="${srun} --chdir=\${here}/${polyname}" + srun="${srun} --output=\${here}/${polyname}/${epoststo}" + srun="${srun} --error=\${here}/${polyname}/${epostste}" + echo "${srun} ${epostsh} &" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + + #----- Add task submission command to the main script. ---------------------------# + echo "echo \" + Submit post-processing for: ${polyname}.\"" >> ${sbatch} + echo "sbatch ${epostsh}" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + else + #----- Skip submission. -------------------------------------------------------------# + echo "${ffout} - Skipping submission of ${rscript} for polygon: ${polyname}..." #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -1400,40 +1656,62 @@ done #------------------------------------------------------------------------------------------# # Make sure job list doesn't request too many nodes. # #------------------------------------------------------------------------------------------# -if [ ${n_submit} -gt ${n_tasks_max} ] +if ! ${overcommit} && [[ ${n_submit} -gt ${n_tasks_max} ]] then echo " Number of jobs to submit: ${n_submit}" echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" echo " Reduce the number of simulations or try another queue..." exit 99 +elif ${submit} +then + echo " Submitting jobs." + #------- How we submit depends on the cluster. -----------------------------------------# + case "${cluster}" in + SDUMONT) + #------------------------------------------------------------------------------------# + # Single multi-task job. Submit the main script using sbatch. # + #------------------------------------------------------------------------------------# + sbatch ${sbatch} + #------------------------------------------------------------------------------------# + ;; + CANNON) + #------------------------------------------------------------------------------------# + # Multiple single-task jobs. Run the script, the sbatch commands are in there. # + #------------------------------------------------------------------------------------# + ${sbatch} + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# else - #----- Find the right number of nodes to submit. ---------------------------------------# - let n_nodes=(${n_submit}+${n_tpn}-1)/${n_tpn} - let n_tasks=(${n_submit}+${n_nodes}-1)/${n_nodes} - sed -i~ s@mynnodes@${n_nodes}@g ${sbatch} - sed -i~ s@myntasks@${n_tasks}@g ${sbatch} + #------- Provide instructions to the user for a later submission. ----------------------# + case "${cluster}" in + SDUMONT) + #----- Instruct the user to use sbatch. ---------------------------------------------# + echo "-------------------------------------------------------------------------" + echo " To submit the simulations, you must use sbatch. " + echo " Copy and paste the following command in the terminal. " + echo " " + echo " sbatch ${sbatch}" + echo " " + #------------------------------------------------------------------------------------# + ;; + CANNON) + #----- Instruct the user NOT to use sbatch. -----------------------------------------# + echo "-------------------------------------------------------------------------" + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo "-------------------------------------------------------------------------" + echo " Do NOT use sbatch ${sbatch}." + echo " Instead, call the following script directly in your terminal." + echo " " + echo " ${sbatch}" + echo " " + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# - - -#----- Make sure the script waits until all tasks are completed... ------------------------# -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Make sure that jobs complete before terminating script" >> ${sbatch} -echo "wait" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Report efficiency of this job" >> ${sbatch} -echo "seff \${SLURM_JOBID}" >> ${sbatch} -echo "" >> ${sbatch} -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# In case all looks good, go for it! # -#------------------------------------------------------------------------------------------# -if ${submit} -then - sbatch ${sbatch} -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/reset.sh b/ED/Template/scripts/SLURM/reset.sh deleted file mode 100755 index f5d1e0015..000000000 --- a/ED/Template/scripts/SLURM/reset.sh +++ /dev/null @@ -1,398 +0,0 @@ -#!/bin/sh -here=$(pwd) -moi=$(whoami) -diskthere="/n/moorcroftfs2" -joborder="${here}/joborder.txt" - -desc=$(basename ${here}) - -#----- Executable name. -------------------------------------------------------------------# -execname="ed_2.2-opt" -execsrc="${HOME}/EDBRAMS/ED/build" -#------------------------------------------------------------------------------------------# - - -#----- Find the output path (both local and remote paths will be cleaned). ----------------# -basehere=$(basename ${here}) -dirhere=$(dirname ${here}) -while [ ${basehere} != ${moi} ] -do - basehere=$(basename ${dirhere}) - dirhere=$(dirname ${dirhere}) -done -diskhere=${dirhere} -echo "-------------------------------------------------------------------------------" -echo " - Simulation control on disk: ${diskhere}" -echo " - Output on disk: ${diskthere}" -echo "-------------------------------------------------------------------------------" -there=$(echo ${here} | sed s@${diskhere}@${diskthere}@g) -#------------------------------------------------------------------------------------------# - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - -#----- Check that the user is aware that it will remove everything... ---------------------# -if [ "x${1}" == "x-d" ] -then - echo "Are you sure you want to stop all jobs, and remove all files and folders? [y/N]" -else - echo "Are you sure you want to stop all jobs, and remove all files? [y/N]" -fi -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo " " -echo " Look, this will really stop ALL your jobs and delete all files!!!" -echo " Are you sure? [y/N]" -echo " " -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -read proceed - -if [ "x${proceed}" != "xy" ] && [ "x${proceed}" != "xY" ] -then - exit -fi - -echo "Okay then, but if you regret later don't say that I did not warn you..." -echo "I'm giving you a few seconds to kill this script in case you change your mind..." -delfun=11 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Job stopping will begin in ${delfun} seconds..." - sleep 1 -done -#------------------------------------------------------------------------------------------# - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - scancel -n ${desc}-${polyname} -p ${queue} -done -#------------------------------------------------------------------------------------------# - - -delfun=16 -while [ ${delfun} -gt 1 ] -do - let delfun=${delfun}-1 - echo " - Files will be deleted in ${delfun} seconds..." - sleep 1 -done - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - - if [ "x${1}" == "x-d" ] - then - rm -frv "${here}/${polyname}" - rm -frv "${there}/${polyname}" - else - /bin/cp "${here}/Template/purge.sh" "${here}/${polyname}/purge.sh" - /bin/cp "${here}/Template/purge.sh" "${there}/${polyname}/purge.sh" - cd "${here}/${polyname}" - ./purge.sh - cd "${there}/${polyname}" - ./purge.sh - fi -done -#------------------------------------------------------------------------------------------# - - - - -#------------------------------------------------------------------------------------------# -# Replace the executable. # -#------------------------------------------------------------------------------------------# -cd ${here} -if [ -s ${here}/executable/${execname} ] -then - rm -frv ${here}/executable/${execname} - cp -fv ${execsrc}/${execname} ${here}/executable -fi -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/run_sitter.sh b/ED/Template/scripts/SLURM/run_sitter.sh index e5da240cf..63b80b35a 100755 --- a/ED/Template/scripts/SLURM/run_sitter.sh +++ b/ED/Template/scripts/SLURM/run_sitter.sh @@ -32,6 +32,7 @@ situtils="${here}/sit_utils" # runtitle -- Full name of this simulation, this is used only in the e-mail subject. # #------------------------------------------------------------------------------------------# desc=$(basename ${here}) +jobname="${desc}-sims*" runtitle="Simulation group: ${desc}" #------------------------------------------------------------------------------------------# @@ -50,6 +51,11 @@ check_out="/tmp/check_run_${$}.out" #------------------------------------------------------------------------------------------# +#------ User name. ------------------------------------------------------------------------# +moi=$(whoami) # User name +#------------------------------------------------------------------------------------------# + + #------ Calculator. -----------------------------------------------------------------------# ccc="${HOME}/util/calc.sh" # Calculator #------------------------------------------------------------------------------------------# @@ -66,7 +72,7 @@ ststcrit=0.01 # Maximum change allowed between two cycles #------------------------------------------------------------------------------------------# # E-mail options (normally only the first three options may require changes. # -# email1day -- Should I e-mail once a day (1) or every time I run (0)? # +# emailevery -- Should I e-mail everytime (true) or every frqemail (false)? # # recipient -- To which e-mail should I send the update? # # mailprog -- Which e-mail program to use? mutt works best, I installed in my util # # directory. Give a try, if it doesn't work you may need to install # @@ -85,7 +91,7 @@ ststcrit=0.01 # Maximum change allowed between two cycles # pendfile -- File with pending status # # email1day -- Reminder so the script knows whether an e-mail has been sent or not. # #------------------------------------------------------------------------------------------# -email1day=1 +emailevery=false recipient="" mailprog=$(which mutt) frqemail="" @@ -118,10 +124,18 @@ frqtouch="" #----- Format for checking simulations. ---------------------------------------------------# -outform="JobName%200,State%12" +outform="JobId%20,JobName%200,State%12" #------------------------------------------------------------------------------------------# +#------------------------------------------------------------------------------------------# +# Optional feature to reset stalled polygons. This feature is particularly useful # +# when using serial_requeue, as some jobs land in faulty nodes. This feature is currently # +# available for CANNON only. # +#------------------------------------------------------------------------------------------# +stall_reset=true +nstall=2 +#------------------------------------------------------------------------------------------# @@ -180,7 +194,7 @@ fi #----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -if [ -s ${here}/run_sitter.lock ] +if [[ -s ${here}/run_sitter.lock ]] then exit else @@ -190,6 +204,26 @@ fi + +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case ${host} in +rclogin*|holy*|moorcroft*|rcnx*) + cluster="CANNON" + ;; +sdumont*) + cluster="SDUMONT" + stall_reset=false + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + ;; +esac +#------------------------------------------------------------------------------------------# + + + #------ Move to the current directory. ----------------------------------------------------# cd ${here} #------------------------------------------------------------------------------------------# @@ -205,13 +239,13 @@ sed -i~ s@"${hereline}"@"here=\"${here}\""@g ${transfer} #----- Determine the number of polygons to run. -------------------------------------------# let n_polygon=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${n_polygon} -lt 100 ] +if [[ ${n_polygon} -lt 100 ]] then ndig=2 -elif [ ${n_polygon} -lt 1000 ] +elif [[ ${n_polygon} -lt 1000 ]] then ndig=3 -elif [ ${n_polygon} -lt 10000 ] +elif [[ ${n_polygon} -lt 10000 ]] then ndig=4 else @@ -223,9 +257,8 @@ echo "Number of polygons: ${n_polygon}..." -#----- Set job name. ----------------------------------------------------------------------# +#----- Set job prefix. --------------------------------------------------------------------# desc=$(basename ${here}) -jobname="${desc}-sims" #------------------------------------------------------------------------------------------# @@ -235,7 +268,7 @@ jobname="${desc}-sims" if [[ ${delay1st_min} -gt 0 ]] then let nsl=${delay1st_min}+1 - while [ ${nsl} -gt 1 ] + while [[ ${nsl} -gt 1 ]] do let nsl=${nsl}-1 case ${nsl} in @@ -259,7 +292,7 @@ fi #------------------------------------------------------------------------------------------# n_ongoing=9999 iter=0 -while [ ${n_ongoing} -gt 0 ] +while [[ ${n_ongoing} -gt 0 ]] do #------ Update iteration counter. ------------------------------------------------------# let iter=${iter}+1 @@ -267,11 +300,13 @@ do #---- Reset count of polygons. ---------------------------------------------------------# n_running=0 + n_stalled=0 n_suspend=0 n_the_end=0 n_unknown=0 n_sigsegv=0 n_crashed=0 + n_hydfail=0 n_metmiss=0 n_stopped=0 #---------------------------------------------------------------------------------------# @@ -281,10 +316,10 @@ do #---------------------------------------------------------------------------------------# # Check whether it's time to update simulation setting files. # #---------------------------------------------------------------------------------------# - if [ ${frqtouch} -gt 0 ] + if [[ ${frqtouch} -gt 0 ]] then let xtouch=${iter}%${frqtouch} - if [ ${xtouch} -eq 0 ] + if [[ ${xtouch} -eq 0 ]] then echo " Touch main files." touch ${here}/*.sh @@ -301,7 +336,7 @@ do #----- Transfer files. -----------------------------------------------------------------# - if [ ! -s ${translock} ] + if [[ ! -s ${translock} ]] then echo " Backup files." nice nohup ${transfer} 1> ${here}/out_transfer.out 2>&1 & @@ -310,9 +345,19 @@ do #----- Move current check to the last check. -------------------------------------------# - rm -f ${lastcheck} - mv ${outcheck} ${lastcheck} - touch ${outcheck} + if [[ -s "${outcheck}" ]] + then + nlnout=$(cat ${outcheck} | wc -l) + if [[ ${nlnout} -eq ${n_polygon} ]] + then + rm -f ${lastcheck} + mv ${outcheck} ${lastcheck} + touch ${outcheck} + else + rm -f ${outcheck} + touch ${outcheck} + fi + fi #---------------------------------------------------------------------------------------# @@ -321,7 +366,7 @@ do # Go through all polygons. # #---------------------------------------------------------------------------------------# ff=0 - while [ ${ff} -lt ${n_polygon} ] + while [[ ${ff} -lt ${n_polygon} ]] do #------------------------------------------------------------------------------------# @@ -340,131 +385,148 @@ do # latitude. # #------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. ----------# + taskname="${polyname}" + #---------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. --------------------# + taskname="${desc}-${polyname}" + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# @@ -474,6 +536,11 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). --------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ------------------------------------# scentype="ERA_Interim" @@ -524,6 +591,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ------------------------------------------# scentype="WFDEI" @@ -613,6 +685,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -763,6 +841,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -800,7 +884,7 @@ do # Correct years so it is not tower-based or Sheffield. # #------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|WFDE5*|WFDEI*|Sheffield) echo "Nothing" > /dev/null ;; *) @@ -848,7 +932,7 @@ do # again. # #------------------------------------------------------------------------------------# statrun=${here}/${polyname}/statusrun.txt - if [ -s ${statrun} ] + if [[ -s ${statrun} ]] then #----- Obtain previous status. ---------------------------------------------------# yearh_old=$(cat ${statrun} | awk '{print $2}') @@ -866,7 +950,7 @@ do #----- In case the simulation never started, force it to be INITIAL. -------------# - if [ ${yearh_old} -eq ${yeara} ] && [ ${monthh_old} -eq ${montha} ] + if [[ ${yearh_old} -eq ${yeara} ]] && [[ ${monthh_old} -eq ${montha} ]] then yearh_old=${yeara} monthh_old=${montha} @@ -892,10 +976,25 @@ do scb_old="NA" npa_old="NA" fi - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Initially assume stall=0. This will be checked and updated only if the # + # simulation is running. Also retrieve the previous stall count if there is one, # + # in case we must update the stall check. # + #------------------------------------------------------------------------------------# + stall=0 + #----- Load previous stall. ---------------------------------------------------------# + if [[ -s ${lastcheck} ]] + then + stall_old=$(cat ${lastcheck} | grep ${polyname} | awk '{print $8}') + else + stall_old=0 + fi + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# # We only check those polygons that may be running, so the check doesn't take too # @@ -907,7 +1006,7 @@ do whichrun=${here}/${polyname}/whichrun.r outwhich=${here}/${polyname}/outwhich.txt R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - if [ -s ${statrun} ] + if [[ -s ${statrun} ]] then yearh=$(cat ${statrun} | awk '{print $2}') monthh=$(cat ${statrun} | awk '{print $3}') @@ -935,41 +1034,9 @@ do - #------------------------------------------------------------------------------------# - # Check whether the simulations are stalled. # - #------------------------------------------------------------------------------------# - case ${runt} in - "HISTORY") - #----- Check whether the runs are stalled. ---------------------------------------# - if [ ${yearh} == ${yearh_old} ] && [ ${monthh} == ${monthh_old} ] && - [ ${dateh} == ${dateh_old} ] && [ ${timeh} == ${timeh_old} ] - then - stall_old=$(cat ${lastcheck} | grep ${polyname} | awk '{print $8}') - let stall=${stall_old}+1 - else - stall=0 - fi - #---------------------------------------------------------------------------------# - ;; - *) - #----- Not in history, simulations are unlikely to be stalled. -------------------# - stall=0 - #---------------------------------------------------------------------------------# - ;; - esac - #------------------------------------------------------------------------------------# - - - #----- Write polygon check into a single table. -------------------------------------# - output="${polyname} ${polylon} ${polylat} ${yearh} ${monthh} ${dateh} ${timeh}" - output="${output} ${stall} ${runt} ${agb} ${bsa} ${lai} ${scb} ${npa}" - echo ${output} >> ${outcheck} - #------------------------------------------------------------------------------------# - - #----- Update files that may be used to check status or to re-submit. ---------------# - if [ ${xtouch} -eq 0 ] + if [[ ${xtouch} -eq 0 ]] then touch ${here}/${polyname}/*.r touch ${here}/${polyname}/ED2IN @@ -983,10 +1050,25 @@ do #------------------------------------------------------------------------------------# # Check whether the simulation is still running, and if not, why it isn't. # #------------------------------------------------------------------------------------# - if [ -s ${stdout} ] + if [[ -s ${stdout} ]] then + #----- Set task inquire command. -------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Multi-task job, search for specific task. ------------------------------# + stask="stask --noheader -u ${moi} -t ${taskname} -j ${jobname}" + #------------------------------------------------------------------------------# + ;; + CANNON) + #----- Single-task jobs, search the task using the job name. ------------------# + stask="stask --noheader -u ${moi} -j ${taskname}" + #------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------# + + #----- Check whether the simulation is running, and when in model time it is. ----# - stask="stask --noheader -u $(whoami) -t ${polyname} -j ${jobname} " running=$(${stask} -o "${outform}" | grep "RUNNING" | wc -l) pending=$(${stask} -o "${outform}" | grep "PENDING" | wc -l) suspended=$(${stask} -o "${outform}" | grep "SUSPENDED" | wc -l) @@ -996,8 +1078,54 @@ do + #---------------------------------------------------------------------------------# + # Check whether the simulations are stalled. # + #---------------------------------------------------------------------------------# + if [[ ${running} -gt 0 ]] + then + #----- Check whether the runs are stalled. ------------------------------------# + if [[ ${yearh} == ${yearh_old} ]] && [[ ${monthh} == ${monthh_old} ]] && + [[ ${dateh} == ${dateh_old} ]] && [[ ${timeh} == ${timeh_old} ]] + then + let stall=${stall_old}+1 + else + stall=0 + fi + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether to kill and resubmit the job. # + #------------------------------------------------------------------------------# + if ${stall_reset} && [[ ${stall} -ge ${nstall} ]] + then + #------- Set stalled flag to one so it is clear the run is not running. ----# + stalled=true + #---------------------------------------------------------------------------# + else + #------- Set stalled flag to zero. It is either running or something else. -# + stalled=false + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + + else + #----- Not in history, simulations are unlikely to be stalled. ----------------# + stall=0 + stalled=false + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + + + + #----- Check for segmentation violations. ----------------------------------------# - if [ -s ${stderr} ] + if [[ -s ${stderr} ]] then segv1=$(grep -i "sigsegv" ${stderr} | wc -l) segv2=$(grep -i "segmentation fault" ${stderr} | wc -l) @@ -1018,50 +1146,157 @@ do #----- Check for other possible outcomes. ----------------------------------------# - stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) - crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) - the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) + stopped=$(grep "FATAL ERROR" ${stdout} | wc -l) + crashed=$(grep "IFLAG1 problem." ${stdout} | wc -l) + hydfail=$(grep "Plant Hydrodynamics is off-track." ${stdout} | wc -l) + the_end=$(grep "ED-2.2 execution ends" ${stdout} | wc -l) #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# # Plot a message so the user knows what is going on. # #---------------------------------------------------------------------------------# - if [ ${pending} -gt 0 ] + if [[ ${pending} -gt 0 ]] then let n_pending=${n_pending}+1 echo -e "${ffout}: ${polyname} is pending..." - elif [ ${suspended} -gt 0 ] + elif [[ ${suspended} -gt 0 ]] then let n_suspend=${n_suspend}+1 echo -e "${ffout}: ${polyname} is SUSPENDED." - elif [ ${running} -gt 0 ] && [ ${sigsegv} -eq 0 ] + elif ${stalled} + then + let n_stalled=${n_stalled}+1 + echo -e "${ffout}: ${polyname} is STALLED (${stall} - ${runtime})." + + #------------------------------------------------------------------------------# + # Kill jobs, it must be stalled. # + #------------------------------------------------------------------------------# + jobid="enter_loop" + kcnt=0 + while [[ "${jobid}" != "" ]] && [[ ${kcnt} -lt 10 ]] + do + #----- Ensure to eliminate potential duplicates. ---------------------------# + let kcnt=${kcnt}+1 + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + echo " - Cancel Job ${jobid} (${taskname})." + scancel ${jobid} + fi + #---------------------------------------------------------------------------# + done + if [[ ${kcnt} -ge 10 ]] + then + #------ The script is bogus. -----------------------------------------------# + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " JOB NUMBER IS LIKELY INCORRECT IN STASK. STOPPING THE SCRIPT. " + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " Output of stask command:" + ${stask} -o "${outform}" + echo " Resulting JobId:" + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + echo " Job Line=${jobln}" + echo " JobId=${jobid}" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 99 + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + #----- Re-submit job. ---------------------------------------------------------# + echo " - Submit New job (${taskname})." + callserial="${here}/${polyname}/callserial.sh" + sbatch ${callserial} + stall=0 + #------------------------------------------------------------------------------# + + elif [[ ${running} -gt 0 ]] && [[ ${sigsegv} -eq 0 ]] then let n_running=${n_running}+1 echo -e "${ffout}: ${polyname} is running (${runtime})." - elif [ ${sigsegv} -gt 0 ] + elif [[ ${sigsegv} -gt 0 ]] then let n_sigsegv=${n_sigsegv}+1 echo -e "${ffout}: ${polyname} HAD SEGMENTATION VIOLATION." - elif [ ${crashed} -gt 0 ] + elif [[ ${crashed} -gt 0 ]] then let n_crashed=${n_crashed}+1 echo -e "${ffout}: ${polyname} HAS CRASHED (RK4 PROBLEM)." - elif [ ${metmiss} -gt 0 ] + elif [[ ${hydfail} -gt 0 ]] + then + let n_hydfail=${n_hydfail}+1 + echo -e "${ffout}: ${polyname} HAS CRASHED (HYDRODYNAMICS)." + elif [[ ${metmiss} -gt 0 ]] then let n_metmiss=${n_metmiss}+1 echo -e "${ffout}: ${polyname} DID NOT FIND MET DRIVERS." - elif [ ${stopped} -gt 0 ] + elif [[ ${stopped} -gt 0 ]] then let n_stopped=${n_stopped}+1 echo -e "${ffout}: ${polyname} STOPPED (UNKNOWN REASON)." - elif [ ${the_end} -gt 0 ] + elif [[ ${the_end} -gt 0 ]] then let n_the_end=${n_the_end}+1 echo -e "${ffout}: ${polyname} has finished." else let n_unknown=${n_unknown}+1 echo -e "${ffout}: ${polyname} status is UNKNOWN." + + #------------------------------------------------------------------------------# + # Kill jobs, it must be stalled. # + #------------------------------------------------------------------------------# + jobid="enter_loop" + kcnt=0 + while [[ "${jobid}" != "" ]] && [[ ${kcnt} -lt 10 ]] + do + #----- Ensure to eliminate potential duplicates. ---------------------------# + let kcnt=${kcnt}+1 + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + if [[ "${jobid}" != "" ]] + then + echo " - Cancel Job ${jobid} (${taskname})." + scancel ${jobid} + fi + #---------------------------------------------------------------------------# + done + if [[ ${kcnt} -ge 10 ]] + then + #------ The script is bogus. -----------------------------------------------# + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " JOB NUMBER IS LIKELY INCORRECT IN STASK. STOPPING THE SCRIPT. " + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo " Output of stask command:" + ${stask} -o "${outform}" + echo " Resulting JobId:" + jobln=$(${stask} -o "${outform}" | grep -v "CANCEL" | grep -v "COMPLET" \ + | head -1) + jobid=$(echo ${jobln} | awk '{print $1}') + echo " JobLine=${jobid}" + echo " JobId=${jobid}" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + exit 99 + #---------------------------------------------------------------------------# + fi + #------------------------------------------------------------------------------# + + + #----- Re-submit job. ---------------------------------------------------------# + echo " - Submit New job (${taskname})." + callserial="${here}/${polyname}/callserial.sh" + sbatch ${callserial} + #------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------# else @@ -1072,32 +1307,10 @@ do - #------------------------------------------------------------------------------------# - # Update the history time for ED2IN so it doesn't start from the beginning in # - # case the job is resubmitted automatically. # - #------------------------------------------------------------------------------------# - if [ -s ${stdout} ] - then - ED2IN="${here}/${polyname}/ED2IN" - runtype_new=" NL%RUNTYPE = 'HISTORY'" - sfilin_new=" NL%SFILIN = '${here}/${polyname}/histo/${polyname}'" - itimeh_new=" NL%ITIMEH = ${timeh}" - idateh_new=" NL%IDATEH = ${dateh}" - imonthh_new=" NL%IMONTHH = ${monthh}" - iyearh_new=" NL%IYEARH = ${yearh}" - runtype_old=$(grep -i "NL%RUNTYPE" ${ED2IN} | grep -v "\!") - sfilin_old=$(grep -i "NL%SFILIN" ${ED2IN} | grep -v "\!") - itimeh_old=$(grep -i "NL%ITIMEH" ${ED2IN} ) - idateh_old=$(grep -i "NL%IDATEH" ${ED2IN} ) - imonthh_old=$(grep -i "NL%IMONTHH" ${ED2IN} ) - iyearh_old=$(grep -i "NL%IYEARH" ${ED2IN} ) - sed -i~ s@"${runtype_old}"@"${runtype_new}"@g ${ED2IN} - sed -i~ s@"${sfilin_old}"@"${sfilin_new}"@g ${ED2IN} - sed -i~ s@"${itimeh_old}"@"${itimeh_new}"@g ${ED2IN} - sed -i~ s@"${idateh_old}"@"${idateh_new}"@g ${ED2IN} - sed -i~ s@"${imonthh_old}"@"${imonthh_new}"@g ${ED2IN} - sed -i~ s@"${iyearh_old}"@"${iyearh_new}"@g ${ED2IN} - fi + #----- Write polygon check into a single table. -------------------------------------# + output="${polyname} ${polylon} ${polylat} ${yearh} ${monthh} ${dateh} ${timeh}" + output="${output} ${stall} ${runt} ${agb} ${bsa} ${lai} ${scb} ${npa}" + echo ${output} >> ${outcheck} #------------------------------------------------------------------------------------# done #---------------------------------------------------------------------------------------# @@ -1107,17 +1320,18 @@ do #---------------------------------------------------------------------------------------# # Run the post processing. # #---------------------------------------------------------------------------------------# - if [ ${frqpost} -gt 0 ] + if [[ ${frqpost} -gt 0 ]] then let xpost=${iter}%${frqpost} - if [ -s "${here}/epost.sh" ] && [ ${xpost} -eq 0 -o ${n_ongoing} -eq 0 ] + + if [[ ${xpost} -eq 0 ]] || [[ ${n_ongoing} -eq 0 ]] then echo " Run post-processing." ${here}/epost.sh echo " Compress/clean files." - ${here}/last_histo.sh + sbatch ${here}/last_histo.sh fi fi #---------------------------------------------------------------------------------------# @@ -1141,6 +1355,7 @@ do n_metmiss=$(grep METMISS ${outcheck} | wc -l) n_bad_met=$(grep BAD_MET ${outcheck} | wc -l) n_crashed=$(grep CRASHED ${outcheck} | wc -l) + n_hydfail=$(grep HYDFAIL ${outcheck} | wc -l) n_stopped=$(grep STOPPED ${outcheck} | wc -l) n_extinct=$(grep EXTINCT ${outcheck} | wc -l) n_ststate=$(grep STSTATE ${outcheck} | wc -l) @@ -1151,9 +1366,11 @@ do echo "------- Simulation status. --------------------------------------" >> ${statfile} echo " Number of polygons that have never started : ${n_initial}" >> ${statfile} echo " Number of polygons that have partially run : ${n_running}" >> ${statfile} + echo " Number of polygons that have stalled : ${n_stalled}" >> ${statfile} echo " Number of polygons that haven't found met drivers : ${n_metmiss}" >> ${statfile} echo " Number of polygons that have bad met drivers : ${n_bad_met}" >> ${statfile} - echo " Number of polygons that have crashed : ${n_crashed}" >> ${statfile} + echo " Number of polygons that have crashed (RK4) : ${n_crashed}" >> ${statfile} + echo " Number of polygons that have crashed (Hydrodyn.) : ${n_hydfail}" >> ${statfile} echo " Number of polygons that have mysteriously stopped : ${n_stopped}" >> ${statfile} echo " Number of polygons that became desert : ${n_extinct}" >> ${statfile} echo " Number of polygons that have reached steady state : ${n_ststate}" >> ${statfile} @@ -1173,10 +1390,6 @@ do echo " " >> ${emailbody} cat ${statfile} >> ${emailbody} echo " " >> ${emailbody} - cat ${recefile} >> ${emailbody} - echo " " >> ${emailbody} - cat ${queuefile} >> ${emailbody} - echo " " >> ${emailbody} cat ${tailfile} >> ${emailbody} echo " " >> ${emailbody} #----- Check whether to append some plots. ---------------------------------------------# @@ -1185,7 +1398,7 @@ do attach="" for fichier in ${R_figlist} do - if [ -s ${fichier} ] + if [[ -s ${fichier} ]] then attach="${attach} -a ${fichier}" fi @@ -1209,17 +1422,17 @@ do #---------------------------------------------------------------------------------------# # Check whether to send the e-mail or not. # #---------------------------------------------------------------------------------------# - if [ ${email1day} -eq 0 ] + if ${emailevery} then #----- Always send e-mail. -----------------------------------------------------------# sendemail=true #-------------------------------------------------------------------------------------# - elif [ -s ${emailday} ] + elif [[ -s ${emailday} ]] then #----- E-mail has been sent. Check whether it is time to send again. ---------------# elast=$(cat ${emailday}) - let elast=${elapsed}-${elast} - if [ ${elast} -gt ${frqemail} ] + let ediff=${elapsed}-${elast} + if [[ ${ediff} -ge ${frqemail} ]] then #----- Time to send another e-mail. ----------------------------------------------# sendemail=true @@ -1257,11 +1470,11 @@ do # In case any simulation is still on the works, take a break before checking # # again. # #---------------------------------------------------------------------------------------# - if [ ${n_ongoing} -gt 0 ] + if [[ ${n_ongoing} -gt 0 ]] then echo " + Take a break before checking again." let nsl=${wait_minutes}+1 - while [ ${nsl} -gt 1 ] + while [[ ${nsl} -gt 1 ]] do let nsl=${nsl}-1 case ${nsl} in @@ -1281,12 +1494,6 @@ do echo "===================================================================" echo "" #---------------------------------------------------------------------------------------# - - - #----- Clean-up stuff. -----------------------------------------------------------------# - echo " + Delete some temporary files..." - /bin/rm -f ${queuefile} ${recefile} - #---------------------------------------------------------------------------------------# done #------------------------------------------------------------------------------------------# @@ -1297,7 +1504,7 @@ done # transferring the files. # #------------------------------------------------------------------------------------------# nwait=0 -while [ -s ${translock} ] +while [[ -s ${translock} ]] do let nwait=${nwait}+1 echo " + Attempt ${nwait}, script transfer is running. Wait 10 minutes and try again." diff --git a/ED/Template/scripts/SLURM/sim_sitter.sh b/ED/Template/scripts/SLURM/sim_sitter.sh deleted file mode 100755 index ca6ae2732..000000000 --- a/ED/Template/scripts/SLURM/sim_sitter.sh +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash - -#----- Main settings. Do look at run_sitter.sh and epost.sh for additional settings. -----# -here=$(pwd) # Current path. -there="/path/to/permanent/storage" # Permanent storage path (leave empty for no transfer) -email="myself\@myserver.com" # Your e-mail. Put a backslash before the @ -queue="myqueue" # Queue to run run_sitter.sh and epost.sh -runtime="infinite" # Run time request -memory=2048 # Requested memory (Mb) -sbatch=$(which sbatch) # SLURM command to submit job. -rscript="read_monthly.r" # Which script to run with epost.sh. See options below. - # Multiple scripts are allowed, put spaces between - # them. (e.g. rscript="plot_monthly.r plot_fast.r") -frqemail=43200 # How often to send emails on simulation status? -delay1st_min=20 # Time (in minutes) to wait before the first check - # (needed in case the run_sitter script is submitted - # before the simulation starts. In case the - # simulation is already running, it is fine to set - # this to zero). -wait_minutes=60 # Waiting time before checking run again (in minutes) -frqpost=3 # How often to run post-processing and file management - # This number is in iterations. Zero means never. -frqtouch=0 # How often to touch executable, scripts, and Template? - # This number is in iterations. Zero means never. -checkhourly="n" # Check hourly files. -checkstatus="y" # Check status before compressing -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Which scripts to run. # -# # -# - read_monthly.r - This reads the monthly mean files (results can then be used for # -# plot_monthly.r, plot_yearly.r, and others, but it doesn't plot any- # -# thing.) # -# - yearly_ascii.r - This creates three ascii (csv) files with annual averages of # -# various variables. It doesn't have all possible variables as it is # -# intended to simplify the output for learning purposes. # -# - plot_monthly.r - This creates several plots based on the monthly mean output. # -# - plot_yearly.r - This creates plots with year time series. # -# - plot_ycomp.r - This creates yearly comparisons based on the monthly mean output. # -# - plot_povray.r - This creates yearly plots of the polygon using POV-Ray. # -# - plot_rk4.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch-level only). # -# - plot_photo.r - This creates plots from the detailed output for Farquhar-Leuning. # -# - plot_rk4pc.r - This creates plots from the detailed output for Runge-Kutta. # -# (patch- and cohort-level). # -# - plot_budget.r - This creates plots from the detailed budget for Runge-Kutta. # -# (patch-level only). # -# - plot_eval_ed.r - This creates plots comparing model with eddy flux observations. # -# - plot_census.r - This creates plots comparing model with biometric data. # -# - whichrun.r - This checks the run status. # -# # -# The following scripts should work too, but I haven't tested them. # -# - plot_daily.r - This creates plots from the daily mean output. # -# - plot_fast.r - This creates plots from the analysis files. # -# - patchprops.r - This creates simple plots showing the patch structure. # -# - reject_ed.r - This tracks the number of steps that were rejected, and what caused # -# the step to be rejected. # -#------------------------------------------------------------------------------------------# - - -#----- Make sure e-mail and queue are pre-defined. ----------------------------------------# -if [[ "x${email}" == "x" ]] || [[ "x${queue}" == "x" ]] || [[ "x${rscript}" == "x" ]] -then - echo "---------------------------------------------------------------------------------" - echo " The following variables must be set. In case any of them are empty, check" - echo " your script sim_sitter.sh." - echo " " - echo " email = ${email}" - echo " queue = ${queue}" - echo " rscript = ${rscript}" - echo " " - echo "---------------------------------------------------------------------------------" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - -#----- Make substitutions. ----------------------------------------------------------------# -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/run_sitter.sh -sed -i~ s@"recipient=\"\""@"recipient=\"${email}\""@g ${here}/run_sitter.sh -sed -i~ s@"frqemail=\"\""@"frqemail=${frqemail}"@g ${here}/run_sitter.sh -sed -i~ s@"delay1st_min=\"\""@"delay1st_min=${delay1st_min}"@g ${here}/run_sitter.sh -sed -i~ s@"wait_minutes=\"\""@"wait_minutes=${wait_minutes}"@g ${here}/run_sitter.sh -sed -i~ s@"frqpost=\"\""@"frqpost=${frqpost}"@g ${here}/run_sitter.sh -sed -i~ s@"frqtouch=\"\""@"frqtouch=${frqtouch}"@g ${here}/run_sitter.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/epost.sh -sed -i~ s@"global_queue=\"\""@"global_queue=\"${queue}\""@g ${here}/epost.sh -sed -i~ s@"rscript=\"\""@"rscript=\"${rscript}\""@g ${here}/epost.sh -sed -i~ s@"submit=false"@"submit=true"@g ${here}/epost.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/transfer.sh -sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${here}/transfer.sh -sed -i~ s@"here=\"\""@"here=\"${here}\""@g ${here}/last_histo.sh -sed -i~ s@"there=\"\""@"there=\"${there}\""@g ${here}/last_histo.sh -sed -i~ s@"checkhourly=\"\""@"checkhourly=\"${checkhourly}\""@g ${here}/last_histo.sh -sed -i~ s@"checkstatus=\"\""@"checkstatus=\"${checkstatus}\""@g ${here}/last_histo.sh -#------------------------------------------------------------------------------------------# - - -#----- Job preferences. -------------------------------------------------------------------# -joblog="${here}/out_sitter.out" -jobpref=$(basename ${here}) -jobname="${jobpref}-control" -jobmain="${jobpref}-sims" -#------------------------------------------------------------------------------------------# - - -#------ Check ID of main job name, so it includes a dependency. ---------------------------# -mainid=$(sjobs | grep -i ${jobmain} | grep -v CANCELLED | grep -v COMPLETED | grep -v COMPLETING | grep -v FAILED | awk '{print $1}') -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Check whether to submit the job. # -#------------------------------------------------------------------------------------------# -if [[ "x${mainid}" == "x" ]] -then - echo " Job name ${jobmain} was not found, so the run_sitter.sh job will not be queued." - goahead="n" -elif [[ -s "${here}/run_sitter.lock" ]] || [[ -s "${here}/transfer.lock" ]] -then - echo " Lock file found for run_sitter.sh and/or transfer.lock." - echo " The scripts may be already running." - echo " Submit the script anyway [y|N]?" - read goahead -else - goahead="y" -fi -goahead="$(echo ${goahead} | tr '[:upper:]' '[:lower:]')" -#------------------------------------------------------------------------------------------# - - -#----- Submit run_sitter.sh in batch mode. ------------------------------------------------# -comm="${sbatch} -p ${queue} --mem-per-cpu=${memory} -t ${runtime} -o ${joblog}" -comm="${comm} -J ${jobname} -n 1 --dependency=after:${mainid}" -comm="${comm} --wrap=\"${here}/run_sitter.sh\"" -case ${goahead} in -y|yes) - /bin/rm -f ${here}/run_sitter.lock - /bin/rm -f ${here}/transfer.lock - echo ${comm} - ${comm} - ;; -*) - bann="Script run_sitter was not submitted. In case you want to submit manually" - bann="${bann} this is the command:" - echo ${bann} - echo " " - echo ${comm} - ;; -esac -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/spawn_poly.sh b/ED/Template/scripts/SLURM/spawn_poly.sh index 7b3146087..4cc98dbdb 100755 --- a/ED/Template/scripts/SLURM/spawn_poly.sh +++ b/ED/Template/scripts/SLURM/spawn_poly.sh @@ -10,23 +10,23 @@ here=$(pwd) moi=$(whoami) #----- Description of this simulation, used to create unique job names. -------------------# desc=$(basename ${here}) +#----- Source path for ED code and executable. --------------------------------------------# +srcpath="${HOME}/EDBRAMS/ED" #----- Original and scratch main data paths. ----------------------------------------------# ordinateur=$(hostname -s) -case ${ordinateur} in - sdumont*) export d_path="${SCRATCH}/Data" ;; - rclogin*|holy*|moorcroft*|rcnx*) export d_path="${HOME}/data" ;; - *) echo " Invalid computer ${ordinateur}. Check script header."; exit ;; -esac +d_path="${HOME}/data" #----- Path where biomass initialisation files are: ---------------------------------------# bioinit="${d_path}/ed2_data/site_bio_data" alsinit="${d_path}/ed2_data/lidar_spline_bio_data" intinit="${d_path}/ed2_data/lidar_intensity_bio_data" lutinit="${d_path}/ed2_data/lidar_lookup_bio_data" +ebainit="${d_path}/ed2_data/lidar_eba_bio_data" biotype=0 # 0 -- "default" setting (isizepft controls default/nounder) # 1 -- isizepft controls number of PFTs, whereas iage controls patches. # 2 -- airborne lidar initialisation using return counts ("default"). # 3 -- airborne lidar initialisation using intensity counts. # 4 -- airborne lidar/inventory hybrid initialisation ("lookup table"). + # 5 -- airborne lidar (EBA Transects). # For lidar initialisation (2-4), isizepft is the disturbance history key. #----- Path and file prefix for init_mode = 5. --------------------------------------------# restart="${d_path}/ed2_data/restarts_XXX" @@ -38,7 +38,7 @@ shefhead='SHEF_NCEP_DRIVER_DS314' metmaindef="${d_path}/ed2_data" packdatasrc="${d_path}/to_scratch" #----- Path with land use scenarios. ------------------------------------------------------# -lumain="${d_path}/ed2_data/land_use" +lumain="${d_path}/ed2_data/lcluc_scenarios" #----- Path with other input data bases (soil texture, DGD, land mask, etc). --------------# inpmain="${d_path}/ed2_data" #----- Should the met driver be copied to local scratch disks? ----------------------------# @@ -59,19 +59,20 @@ dateh="01" # Day timeh="0000" # Hour #----- Default tolerance. -----------------------------------------------------------------# toldef="0.01" -#----- Executable names. ------------------------------------------------------------------# -execname="ed_2.2-opt" # Normal executable, for most queues #----- Initialisation scripts. ------------------------------------------------------------# initrc="${HOME}/.bashrc" # Initialisation script for most nodes #----- Initialisation scripts. ------------------------------------------------------------# optsrc="-n" # Option for .bashrc (for special submission settings) # In case none is needed, leave it blank (""). #----- Submit job automatically? (It may become false if something prevents submission). --# -submit=false +submit=false # This checks whether to submit runs or not. +on_the_fly=false # In case submit=true and this is the CANNON cluster, on_the_fly allows + # directories are jobs to be submitted as the directories are ready. +#----- Executable names. ------------------------------------------------------------------# +execname="ed_2.2-opt" # Normal executable, for most queues +checkexec=true # Check executable #----- Settings for this group of polygons. -----------------------------------------------# global_queue="shared,huce_intel" # Queue -sim_memory=0 # Memory per simulation. Zero uses queue's default -n_cpt=12 # Number of cpus per task (Zero uses queue's maximum) partial=false # Partial submission (false will ignore polya and npartial # and send all polygons. polya=21 # First polygon to submit @@ -79,7 +80,20 @@ npartial=300 # Maximum number of polygons to include in this # (actual number will be adjusted for total number of # polygons if needed be). dttask=2 # Time to wait between task submission -runtime="00:00:00" # Requested runtime. Zero uses the queue's maximum. +init_only=false # Run model initialisation only? + # This can be useful when the initialisation step + # demands much more memory than the time steps (e.g., + # when using lidar data to initialisate the model). +if ${init_only} +then + sim_memory=64000 # Memory per simulation. Zero uses queue's default + n_cpt=1 # Number of cpus per task (Zero uses queue's maximum) + runtime="01-00:00:00" # Requested runtime. Zero uses the queue's maximum. +else + sim_memory=3072 # Memory per simulation. Zero uses queue's default + n_cpt=12 # Number of cpus per task (Zero uses queue's maximum) + runtime="07-00:00:00" # Requested runtime. Zero uses the queue's maximum. +fi #------------------------------------------------------------------------------------------# #==========================================================================================# @@ -123,6 +137,64 @@ squeue="squeue --noheader -u ${moi}" #------------------------------------------------------------------------------------------# +#----- Find out which platform we are using. ----------------------------------------------# +host=$(hostname -s) +case "${host}" in +rclogin*|holy*|moorcroft*|rcnx*) + #----- Cluster is CANNON (formerly known as ODYSSEY). ----------------------------------# + cluster="CANNON" + #---------------------------------------------------------------------------------------# + ;; +sdumont*) + #----- Cluster is SDUMONT. Ironically perhaps, we cannot submit jobs on the fly. -------# + cluster="SDUMONT" + on_the_fly=false + #---------------------------------------------------------------------------------------# + ;; +*) + echo -n "Failed guessing cluster from node name. Please type the name: " + read cluster + cluster=$(echo ${cluster} | tr '[:lower:]' '[:upper:]') + case "${cluster}" in + CANNON|CANNO|CANN|CAN|CA|C) + #----- Set cluster to CANNON. -------------------------------------------------------# + cluster="CANNON" + #------------------------------------------------------------------------------------# + ;; + ODYSSEY|ODYSSE|ODYSS|ODYS|ODY|OD|O) + #----- Set cluster to CANNON. -------------------------------------------------------# + cluster="CANNON" + echo " - Odyssey is now known as Cannon. Using Cannon settings." + #------------------------------------------------------------------------------------# + ;; + SDUMONT|SDUMON|SDUMO|SDUM|SDU|SD|S) + #----- Cluster is SDUMONT. Ironically perhaps, we cannot submit jobs on the fly. ----# + cluster="SDUMONT" + on_the_fly=false + #------------------------------------------------------------------------------------# + ;; + *) + #----- Unknown cluster. -------------------------------------------------------------# + echo " Cluster ${cluster} is not recognised. Pick either CANNON or SDUMONT." + echo " (or edit the script to add the new cluster)." + exit 92 + #------------------------------------------------------------------------------------# + ;; + esac + ;; +esac +#------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# Do not let on_the_fly if submit is false. # +#------------------------------------------------------------------------------------------# +if ! ${submit} +then + on_the_fly=false +fi +#------------------------------------------------------------------------------------------# + + #----- Set the main path for the site, pseudo past and Sheffield met drivers. -------------# if ${copy2scratch} then @@ -136,13 +208,13 @@ fi #----- Determine the number of polygons to run. -------------------------------------------# let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -if [ ${npolys} -lt 100 ] +if [[ ${npolys} -lt 100 ]] then ndig=2 -elif [ ${npolys} -lt 1000 ] +elif [[ ${npolys} -lt 1000 ]] then ndig=3 -elif [ ${npolys} -lt 10000 ] +elif [[ ${npolys} -lt 10000 ]] then ndig=4 else @@ -186,67 +258,41 @@ done # script. # #------------------------------------------------------------------------------------------# exec_full="${here}/executable/${execname}" -if [ ! -s ${exec_full} ] +exec_src="${srcpath}/build/${execname}" +if [[ ! -s ${exec_full} ]] then echo "Executable file : ${exec_full} is not in the executable directory" echo "Copy the executable to the file before running this script!" exit 99 +elif ${checkexec} +then + #----- Check whether the executable is up to date. -------------------------------------# + idiff=$(diff ${exec_full} ${exec_src} 2> /dev/null | wc -l) + if [[ ${idiff} -gt 0 ]] + then + #----- Executable is not up to date, warn user and offer to update it. --------------# + echo "Executable ${exec_full} is not the same as the most recently compiled file." + echo "Most recent: ${exec_src}." + echo "Do you want to update the executable? [y/N]" + read update + update=$(echo ${update} | tr '[:upper:]' '[:lower:]') + case "${update}" in + y*) rsync - Putv ${exec_src} ${exec_full} ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Configurations depend on the global_queue. # +# Configurations depend on the global_queue and cluster. # #------------------------------------------------------------------------------------------# -case ${ordinateur} in -rclogin*|holy*|moorcroft*|rcnx*) - #----- Odyssey queues. -----------------------------------------------------------------# - case ${global_queue} in - "serial_requeue") - n_nodes_max=900 - n_cpt_max=12 - n_cpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared,huce_intel"|"huce_intel,shared") - n_nodes_max=276 - n_cpt_max=12 - n_cpn=24 - runtime_max="7-00:00:00" - node_memory=126820 - ;; - "shared") - n_nodes_max=456 - n_cpt_max=24 - n_cpn=48 - runtime_max="7-00:00:00" - node_memory=192892 - ;; - "huce_intel") - n_nodes_max=276 - n_cpt_max=12 - n_cpn=24 - runtime_max="14-00:00:00" - node_memory=126820 - ;; - "unrestricted") - n_nodes_max=8 - n_cpt_max=24 - n_cpn=48 - runtime_max="infinite" - node_memory=262499 - ;; - *) - echo "Global queue ${global_queue} is not recognised!" - exit - ;; - esac - #---------------------------------------------------------------------------------------# - ;; -sdumont*) - #----- SantosDumont. -------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #----- Set parameters according to partitions. -----------------------------------------# case ${global_queue} in cpu_long|nvidia_long) n_nodes_max=10 @@ -290,15 +336,78 @@ sdumont*) esac #---------------------------------------------------------------------------------------# ;; -*) - #----- Computer is not listed. Crash. -------------------------------------------------# - echo " Invalid computer ${ordinateur}. Check queue settings in the script." - exit 31 +CANNON) + #----- Set parameters according to partitions. -----------------------------------------# + case ${global_queue} in + "commons") + n_nodes_max=5 + n_cpt_max=18 + n_cpn=32 + runtime_max="14-00:00:00" + node_memory=244660 + ;; + "huce_cascade") + n_nodes_max=30 + n_cpt_max=48 + n_cpn=24 + runtime_max="14-00:00:00" + node_memory=183240 + ;; + "huce_intel") + n_nodes_max=150 + n_cpt_max=12 + n_cpn=24 + runtime_max="14-00:00:00" + node_memory=122090 + ;; + "serial_requeue") + n_nodes_max=900 + n_cpt_max=24 + n_cpn=48 + runtime_max="7-00:00:00" + node_memory=30362 + ;; + "shared,huce_intel"|"huce_intel,shared") + n_nodes_max=150 + n_cpt_max=12 + n_cpn=24 + runtime_max="7-00:00:00" + node_memory=122090 + ;; + "shared") + n_nodes_max=220 + n_cpt_max=24 + n_cpn=48 + runtime_max="7-00:00:00" + node_memory=183240 + ;; + "test") + n_nodes_max=9 + n_cpt_max=24 + n_cpn=48 + runtime_max="08:00:00" + node_memory=183240 + ;; + "unrestricted") + n_nodes_max=4 + n_cpt_max=24 + n_cpn=48 + runtime_max="infinite" + node_memory=183240 + ;; + *) + echo "Global queue ${global_queue} is not recognised!" + exit + ;; + esac #---------------------------------------------------------------------------------------# ;; esac #------------------------------------------------------------------------------------------# -if [ ${n_cpt} -gt ${n_cpt_max} ] + + +#----- Check that the resources requested are reasonable. ---------------------------------# +if [[ ${n_cpt} -gt ${n_cpt_max} ]] then echo " Too many CPUs per task requested:" echo " Queue = ${global_queue}" @@ -435,36 +544,31 @@ esac #------------------------------------------------------------------------------------------# # Make sure memory does not exceed maximum amount that can be requested. # #------------------------------------------------------------------------------------------# -if [ ${sim_memory} -eq 0 ] +if [[ ${sim_memory} -eq 0 ]] then let sim_memory=${node_memory}/${n_cpn} let node_memory=${n_cpn}*${sim_memory} -elif [ ${sim_memory} -gt ${node_memory} ] +elif [[ ${sim_memory} -gt ${node_memory} ]] then echo "Simulation memory ${sim_memory} cannot exceed node memory ${node_memory}!" exit 99 -else - #------ Set memory and number of CPUs per task. ----------------------------------------# - let n_cpn_try=${node_memory}/${sim_memory} - if [ ${n_cpn_try} -le ${n_cpn} ] - then - n_cpn=${n_cpn_try} - let sim_memory=${node_memory}/${n_cpn} - else - let node_memory=${n_cpn}*${sim_memory} - fi - #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# +#----- Limit the memory per CPU based on the simulation memory. ---------------------------# +let cpu_memory=${sim_memory}/${n_cpt} +#------------------------------------------------------------------------------------------# + + #---- Partial or complete. ----------------------------------------------------------------# + if ${partial} then let ff=${polya}-1 let polyz=${ff}+${npartial} - if [ ${polyz} -gt ${npolys} ] + if [[ ${polyz} -gt ${npolys} ]] then polyz=${npolys} fi @@ -491,19 +595,20 @@ let ntasks=1+${polyz}-${polya} echo "------------------------------------------------" echo " Submission summary: " echo "" -echo " Memory per cpu: ${sim_memory}" +echo " Memory per task: ${sim_memory}" +echo " Memory per cpu: ${cpu_memory}" echo " CPUs per node: ${n_cpn}" echo " CPUs per task: ${n_cpt}" -echo " Queue: ${global_queue}" +echo " Partition: ${global_queue}" echo " Run time: ${runtime}" echo " First polygon: ${polya}" echo " Last polygon: ${polyz}" echo " Potl. task count: ${ntasks}" -echo " Job Name: ${jobname}" echo " Total polygon count: ${npolys}" echo " " echo " Partial submission: ${partial}" echo " Automatic submission: ${submit}" +echo " Script: $(basename ${sbatch})" echo "------------------------------------------------" echo "" echo -n " Waiting five seconds before proceeding... " @@ -514,88 +619,132 @@ echo "Done!" #------------------------------------------------------------------------------------------# -# Check whether there is already a job submitted that looks like this one. # -#------------------------------------------------------------------------------------------# -queued=$(${squeue} -o "${outform}" | grep ${jobname} | wc -l) -if [ ${queued} -gt 0 ] -then - echo "There is already a job called \"${jobname}\" running." - echo "New submissions must have different names: be creative!" - exit 99 -fi +# Initialise executable. This depends on the cluster because in some of them it is # +# better to submit a single multi-task job, whereas in others it makes more sense to # +# submit individual jobs. # #------------------------------------------------------------------------------------------# +case "${cluster}" in +SDUMONT) + #---------------------------------------------------------------------------------------# + # Check whether there is already a job submitted that looks like this one. # + #---------------------------------------------------------------------------------------# + queued=$(${squeue} -o "${outform}" | grep ${jobname} | wc -l) + if [[ ${queued} -gt 0 ]] + then + echo "There is already a job called \"${jobname}\" running." + echo "New submissions must have different names: be creative!" + exit 99 + fi + #---------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Initialise executable. # -#------------------------------------------------------------------------------------------# -rm -f ${sbatch} -touch ${sbatch} -chmod u+x ${sbatch} -echo "#!/bin/bash" >> ${sbatch} -echo "#SBATCH --ntasks=myntasks # Number of tasks" >> ${sbatch} -echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${sbatch} -echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} -echo "#SBATCH --job-name=${jobname} # Job name" >> ${sbatch} -echo "#SBATCH --mem-per-cpu=${sim_memory} # Memory per CPU" >> ${sbatch} -echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} -echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} -echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Initial settings." >> ${sbatch} -echo "here=\"${here}\" # Main path" >> ${sbatch} -echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Print information about this job." >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"----- Summary of current job ---------------------------------\"" >> ${sbatch} -echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} -echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} -echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} -echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} -echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} -echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} -echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} -echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} -echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} -echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} -echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "echo \"----- Global settings for this array of simulations ----------\"" >> ${sbatch} -echo "echo \" Main path: \${here}\"" >> ${sbatch} -echo "echo \" Executable: \${exec}\"" >> ${sbatch} -echo "echo \"--------------------------------------------------------------\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "echo \"\"" >> ${sbatch} -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Define home in case home is not set" >> ${sbatch} -echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export HOME=\$(echo ~)" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Load modules and settings." >> ${sbatch} -echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Get plenty of memory." >> ${sbatch} -echo "ulimit -s unlimited" >> ${sbatch} -echo "ulimit -u unlimited" >> ${sbatch} -echo "" >> ${sbatch} -echo "#--- Set OpenMP parameters" >> ${sbatch} -echo "if [ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]" >> ${sbatch} -echo "then" >> ${sbatch} -echo " export OMP_NUM_THREADS=1" >> ${sbatch} -echo "else" >> ${sbatch} -echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${sbatch} -echo "fi" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Task list." >> ${sbatch} + #----- Initialise script to submit a single multi-task job. ----------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "#SBATCH --ntasks=myntasks # Number of tasks" >> ${sbatch} + echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${sbatch} + echo "#SBATCH --cores-per-socket=${n_cpt} # Min. # of cores per socket" >> ${sbatch} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${sbatch} + echo "#SBATCH --job-name=${jobname} # Job name" >> ${sbatch} + echo "#SBATCH --mem-per-cpu=${cpu_memory} # Memory per CPU" >> ${sbatch} + echo "#SBATCH --time=${runtime} # Time for job" >> ${sbatch} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${sbatch} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Print information about this job." >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"----- Summary of current job ------------------------------\"" >> ${sbatch} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${sbatch} + echo "echo \" Job: \${SLURM_JOB_NAME} (\${SLURM_JOB_ID})\"" >> ${sbatch} + echo "echo \" Queue: \${SLURM_JOB_PARTITION}\"" >> ${sbatch} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${sbatch} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${sbatch} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${sbatch} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${sbatch} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${sbatch} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${sbatch} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${sbatch} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Set OpenMP parameters" >> ${sbatch} + echo "if [ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export OMP_NUM_THREADS=1" >> ${sbatch} + echo "else" >> ${sbatch} + echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Task list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +CANNON) + #----- Initialise script to submit multiple single-task jobs. --------------------------# + rm -f ${sbatch} + touch ${sbatch} + chmod u+x ${sbatch} + echo "#!/bin/bash" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Initial settings." >> ${sbatch} + echo "here=\"${here}\" # Main path" >> ${sbatch} + echo "exec=\"${exec_full}\" # Executable" >> ${sbatch} + echo "" >> ${sbatch} + echo "echo \"----- Global settings for this array of simulations -------\"" >> ${sbatch} + echo "echo \" Main path: \${here}\"" >> ${sbatch} + echo "echo \" Executable: \${exec}\"" >> ${sbatch} + echo "echo \"-----------------------------------------------------------\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "echo \"\"" >> ${sbatch} + echo "" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Define home in case home is not set" >> ${sbatch} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${sbatch} + echo "then" >> ${sbatch} + echo " export HOME=\$(echo ~)" >> ${sbatch} + echo "fi" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Load modules and settings." >> ${sbatch} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${sbatch} + echo "" >> ${sbatch} + echo "#--- Get plenty of memory." >> ${sbatch} + echo "ulimit -s unlimited" >> ${sbatch} + echo "ulimit -u unlimited" >> ${sbatch} + echo "" >> ${sbatch} + echo "#----- Job list." >> ${sbatch} + #---------------------------------------------------------------------------------------# + ;; +esac #------------------------------------------------------------------------------------------# @@ -604,7 +753,7 @@ echo "#----- Task list." > # Loop over all polygons. # #------------------------------------------------------------------------------------------# n_submit=0 -while [ ${ff} -lt ${polyz} ] +while [[ ${ff} -lt ${polyz} ]] do let ff=${ff}+1 let line=${ff}+3 @@ -613,13 +762,13 @@ do #---------------------------------------------------------------------------------------# # Format count. # #---------------------------------------------------------------------------------------# - if [ ${npolys} -lt 100 ] + if [[ ${npolys} -lt 100 ]] then ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -lt 1000 ] + elif [[ ${npolys} -lt 1000 ]] then ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -lt 10000 ] + elif [[ ${npolys} -lt 10000 ]] then ffout=$(printf '%4.4i' ${ff}) else @@ -635,142 +784,190 @@ do # latitude. # #---------------------------------------------------------------------------------------# oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') + polyname=$(echo ${oi} | awk '{print $1 }') + polyiata=$(echo ${oi} | awk '{print $2 }') + polylon=$(echo ${oi} | awk '{print $3 }') + polylat=$(echo ${oi} | awk '{print $4 }') + yeara=$(echo ${oi} | awk '{print $5 }') + montha=$(echo ${oi} | awk '{print $6 }') + datea=$(echo ${oi} | awk '{print $7 }') + timea=$(echo ${oi} | awk '{print $8 }') + yearz=$(echo ${oi} | awk '{print $9 }') + monthz=$(echo ${oi} | awk '{print $10 }') + datez=$(echo ${oi} | awk '{print $11 }') + timez=$(echo ${oi} | awk '{print $12 }') + initmode=$(echo ${oi} | awk '{print $13 }') + iscenario=$(echo ${oi} | awk '{print $14 }') + isizepft=$(echo ${oi} | awk '{print $15 }') + iage=$(echo ${oi} | awk '{print $16 }') + imaxcohort=$(echo ${oi} | awk '{print $17 }') + polyisoil=$(echo ${oi} | awk '{print $18 }') + polyntext=$(echo ${oi} | awk '{print $19 }') + polysand=$(echo ${oi} | awk '{print $20 }') + polyclay=$(echo ${oi} | awk '{print $21 }') + polyslsoc=$(echo ${oi} | awk '{print $22 }') + polyslph=$(echo ${oi} | awk '{print $23 }') + polyslcec=$(echo ${oi} | awk '{print $24 }') + polysldbd=$(echo ${oi} | awk '{print $25 }') + polydepth=$(echo ${oi} | awk '{print $26 }') + polyslhydro=$(echo ${oi} | awk '{print $27 }') + polysoilbc=$(echo ${oi} | awk '{print $28 }') + polysldrain=$(echo ${oi} | awk '{print $29 }') + polycol=$(echo ${oi} | awk '{print $30 }') + slzres=$(echo ${oi} | awk '{print $31 }') + queue=$(echo ${oi} | awk '{print $32 }') + metdriver=$(echo ${oi} | awk '{print $33 }') + dtlsm=$(echo ${oi} | awk '{print $34 }') + monyrstep=$(echo ${oi} | awk '{print $35 }') + iphysiol=$(echo ${oi} | awk '{print $36 }') + vmfactc3=$(echo ${oi} | awk '{print $37 }') + vmfactc4=$(echo ${oi} | awk '{print $38 }') + mphototrc3=$(echo ${oi} | awk '{print $39 }') + mphototec3=$(echo ${oi} | awk '{print $40 }') + mphotoc4=$(echo ${oi} | awk '{print $41 }') + bphotoblc3=$(echo ${oi} | awk '{print $42 }') + bphotonlc3=$(echo ${oi} | awk '{print $43 }') + bphotoc4=$(echo ${oi} | awk '{print $44 }') + kwgrass=$(echo ${oi} | awk '{print $45 }') + kwtree=$(echo ${oi} | awk '{print $46 }') + gammac3=$(echo ${oi} | awk '{print $47 }') + gammac4=$(echo ${oi} | awk '{print $48 }') + d0grass=$(echo ${oi} | awk '{print $49 }') + d0tree=$(echo ${oi} | awk '{print $50 }') + alphac3=$(echo ${oi} | awk '{print $51 }') + alphac4=$(echo ${oi} | awk '{print $52 }') + klowco2=$(echo ${oi} | awk '{print $53 }') + decomp=$(echo ${oi} | awk '{print $54 }') + rrffact=$(echo ${oi} | awk '{print $55 }') + growthresp=$(echo ${oi} | awk '{print $56 }') + lwidthgrass=$(echo ${oi} | awk '{print $57 }') + lwidthbltree=$(echo ${oi} | awk '{print $58 }') + lwidthnltree=$(echo ${oi} | awk '{print $59 }') + q10c3=$(echo ${oi} | awk '{print $60 }') + q10c4=$(echo ${oi} | awk '{print $61 }') + h2olimit=$(echo ${oi} | awk '{print $62 }') + imortscheme=$(echo ${oi} | awk '{print $63 }') + ddmortconst=$(echo ${oi} | awk '{print $64 }') + cbrscheme=$(echo ${oi} | awk '{print $65 }') + isfclyrm=$(echo ${oi} | awk '{print $66 }') + icanturb=$(echo ${oi} | awk '{print $67 }') + ubmin=$(echo ${oi} | awk '{print $68 }') + ugbmin=$(echo ${oi} | awk '{print $69 }') + ustmin=$(echo ${oi} | awk '{print $70 }') + gamm=$(echo ${oi} | awk '{print $71 }') + gamh=$(echo ${oi} | awk '{print $72 }') + tprandtl=$(echo ${oi} | awk '{print $73 }') + ribmax=$(echo ${oi} | awk '{print $74 }') + atmco2=$(echo ${oi} | awk '{print $75 }') + thcrit=$(echo ${oi} | awk '{print $76 }') + smfire=$(echo ${oi} | awk '{print $77 }') + ifire=$(echo ${oi} | awk '{print $78 }') + fireparm=$(echo ${oi} | awk '{print $79 }') + ipercol=$(echo ${oi} | awk '{print $80 }') + runoff=$(echo ${oi} | awk '{print $81 }') + imetrad=$(echo ${oi} | awk '{print $82 }') + ibranch=$(echo ${oi} | awk '{print $83 }') + icanrad=$(echo ${oi} | awk '{print $84 }') + ihrzrad=$(echo ${oi} | awk '{print $85 }') + crown=$(echo ${oi} | awk '{print $86 }') + ltransvis=$(echo ${oi} | awk '{print $87 }') + lreflectvis=$(echo ${oi} | awk '{print $88 }') + ltransnir=$(echo ${oi} | awk '{print $89 }') + lreflectnir=$(echo ${oi} | awk '{print $90 }') + orienttree=$(echo ${oi} | awk '{print $91 }') + orientgrass=$(echo ${oi} | awk '{print $92 }') + clumptree=$(echo ${oi} | awk '{print $93 }') + clumpgrass=$(echo ${oi} | awk '{print $94 }') + igoutput=$(echo ${oi} | awk '{print $95 }') + ivegtdyn=$(echo ${oi} | awk '{print $96 }') + ihydro=$(echo ${oi} | awk '{print $97 }') + istemresp=$(echo ${oi} | awk '{print $98 }') + istomata=$(echo ${oi} | awk '{print $99 }') + iplastic=$(echo ${oi} | awk '{print $100}') + icarbonmort=$(echo ${oi} | awk '{print $101}') + ihydromort=$(echo ${oi} | awk '{print $102}') + igndvap=$(echo ${oi} | awk '{print $103}') + iphen=$(echo ${oi} | awk '{print $104}') + iallom=$(echo ${oi} | awk '{print $105}') + ieconomics=$(echo ${oi} | awk '{print $106}') + igrass=$(echo ${oi} | awk '{print $107}') + ibigleaf=$(echo ${oi} | awk '{print $108}') + integscheme=$(echo ${oi} | awk '{print $109}') + nsubeuler=$(echo ${oi} | awk '{print $110}') + irepro=$(echo ${oi} | awk '{print $111}') + treefall=$(echo ${oi} | awk '{print $112}') + ianthdisturb=$(echo ${oi} | awk '{print $113}') + ianthdataset=$(echo ${oi} | awk '{print $114}') + slscale=$(echo ${oi} | awk '{print $115}') + slyrfirst=$(echo ${oi} | awk '{print $116}') + slnyrs=$(echo ${oi} | awk '{print $117}') + bioharv=$(echo ${oi} | awk '{print $118}') + skidarea=$(echo ${oi} | awk '{print $119}') + skiddbhthresh=$(echo ${oi} | awk '{print $120}') + skidsmall=$(echo ${oi} | awk '{print $121}') + skidlarge=$(echo ${oi} | awk '{print $122}') + fellingsmall=$(echo ${oi} | awk '{print $123}') + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case this is an "init_only" run, impose final time to be the initial time. # + #---------------------------------------------------------------------------------------# + if ${init_only} + then + yearz=${yeara} + monthz=${montha} + datez=${datea} + timez=${timea} + fi + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Task name. This depends on the type of submission (just to avoid clutter). # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #----- Task name is bound to the global jobname, no need to add prefix. -------------# + taskname="${polyname}" + #------------------------------------------------------------------------------------# + ;; + CANNON ) + #----- Add prefix to the task name, which will name this job. -----------------------# + taskname="${desc}-${polyname}" + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Check whether there is already a job submitted that looks like this one. # + #------------------------------------------------------------------------------------# + queued=$(${squeue} -o "${outform}" | grep ${taskname} | wc -l) + if [[ ${queued} -gt 0 ]] + then + echo "There is already a job called \"${taskname}\" running." + echo "New submissions must have different names: be creative!" + exit 99 + fi + #------------------------------------------------------------------------------------# + ;; + esac #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Decide units for restart files. # #---------------------------------------------------------------------------------------# let elapseda=12*${yeara}+${montha} let elapsedz=12*${yearz}+${monthz} let nmonths=${elapsedz}-${elapseda} - if [ ${nmonths} -ge 240 ] + if [[ ${nmonths} -ge 240 ]] then iunitstate=3 - elif [ ${nmonths} -ge 3 ] + elif [[ ${nmonths} -ge 3 ]] then iunitstate=2 else @@ -780,7 +977,7 @@ do #----- Check whether the directories exist or not, and stop the script if they do. -----# - if [ -s ${here}/${polyname} ] + if [[ -s ${here}/${polyname} ]] then echo -n "${ffout} ${polyname}: updating files..." @@ -804,7 +1001,7 @@ do #---------------------------------------------------------------------------------------# # Make sure that we have a reasonable tolerance. # #---------------------------------------------------------------------------------------# - if [ "x${oldtol}" == "xmytoler" -o "x${oldtol}" == "x" ] + if [[ "x${oldtol}" == "xmytoler" ]] || [[ "x${oldtol}" == "x" ]] then toler=${toldef} else @@ -822,28 +1019,28 @@ do # we simply copy the template, and assume initial run. Otherwise, we must find out # # where the simulation was when it stopped. # #---------------------------------------------------------------------------------------# - if [ -s ${here}/${polyname} ] + if [[ -s ${here}/${polyname} ]] then #------------------------------------------------------------------------------------# # This step is necessary because we may have killed the run while it was # # writing, and as a result, the file may be corrupt. # #------------------------------------------------------------------------------------# - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) - if [ ${nhdf5} -gt 0 ] + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) + if [[ ${nhdf5} -gt 0 ]] then h5fine=0 - while [ ${h5fine} -eq 0 ] + while [[ ${h5fine} -eq 0 ]] do - lasthdf5=$(ls -1 ${here}/${polyname}/histo/* | tail -1) + lasthdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 | tail -1) h5dump -H ${lasthdf5} 1> /dev/null 2> ${here}/badfile.txt - if [ -s ${here}/badfile.txt ] + if [[ -s ${here}/badfile.txt ]] then /bin/rm -fv ${lasthdf5} - nhdf5=$(ls -1 ${here}/${polyname}/histo/* 2> /dev/null | wc -l) - if [ ${nhdf5} -eq 0 ] + nhdf5=$(ls -1 ${here}/${polyname}/histo/*.h5 2> /dev/null | wc -l) + if [[ ${nhdf5} -eq 0 ]] then h5fine=1 fi @@ -883,7 +1080,7 @@ do sed -i~ s@thisnyearmin@10000@g ${whichrun} sed -i~ s@thisststcrit@0.0@g ${whichrun} R CMD BATCH --no-save --no-restore ${whichrun} ${outwhich} - while [ ! -s ${here}/${polyname}/statusrun.txt ] + while [[ ! -s ${here}/${polyname}/statusrun.txt ]] do sleep 0.2 done @@ -895,13 +1092,42 @@ do #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Run the small R script to generate specific observation times. # + #---------------------------------------------------------------------------------------# + /bin/rm -f ${here}/${polyname}/gen_obstimes.r + /bin/cp -f ${here}/Template/gen_obstimes.r ${here}/${polyname}/gen_obstimes.r + obstimes="${here}/${polyname}/gen_obstimes.r" + outtimes="${here}/${polyname}/out_obstimes.txt" + sed -i~ s@thispoly@${polyname}@g ${obstimes} + sed -i~ s@thisqueue@${queue}@g ${obstimes} + sed -i~ s@pathhere@${here}@g ${obstimes} + sed -i~ s@paththere@${here}@g ${obstimes} + sed -i~ s@thisyeara@${yeara}@g ${obstimes} + sed -i~ s@thismontha@${montha}@g ${obstimes} + sed -i~ s@thisdatea@${datea}@g ${obstimes} + sed -i~ s@thistimea@${timea}@g ${obstimes} + sed -i~ s@thisyearz@${yearz}@g ${obstimes} + sed -i~ s@thismonthz@${monthz}@g ${obstimes} + sed -i~ s@thisdatez@${datez}@g ${obstimes} + sed -i~ s@thistimez@${timez}@g ${obstimes} + sed -i~ s@thislon@${polylon}@g ${obstimes} + sed -i~ s@thislat@${polylat}@g ${obstimes} + R CMD BATCH --no-save --no-restore ${obstimes} ${outtimes} + while [[ ! -s ${here}/${polyname}/${polyname}_obstimes.txt ]] + do + sleep 0.2 + done + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # To ensure simulations can be requeued, we no longer set RUNTYPE to INITIAL or # # HISTORY (except when we should force history). Instead, we select RESTORE and let # # the model decide between initial or history. # #---------------------------------------------------------------------------------------# - if [ "${runt}" == "INITIAL" ] || [ "${runt}" == "HISTORY" ] + if [[ "${runt}" == "INITIAL" ]] || [[ "${runt}" == "HISTORY" ]] then runt="RESTORE" fi @@ -1139,6 +1365,16 @@ do case ${iscenario} in default) case ${metdriver} in + ERA5_CHIRPS) + #----- ERA5 (CHIRPS precipitation, Brazilian Amazon only). -----------------------# + scentype="ERA5" + iscenario="ERA5_SOUTHAM_CHIRPS" + ;; + ERA5_CHIRPS) + #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# + scentype="ERA_Interim" + iscenario="ERAINT_SOUTHAM_CHIRPS" + ;; ERAINT_CHIRPS) #----- ERA-Interim (CHIRPS precipitation). ---------------------------------------# scentype="ERA_Interim" @@ -1189,6 +1425,11 @@ do scentype="sheffield" iscenario="sheffield" ;; + WFDE5_CHIRPS) + #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# + scentype="WFDE5" + iscenario="WFDE5_SOUTHAM_CHIRPS" + ;; WFDEI_CHIRPS) #----- WFDEI (CHIRPS Precipitation). ---------------------------------------------# scentype="WFDEI" @@ -1277,6 +1518,12 @@ do metcycf=2003 imetavg=1 ;; + ERA5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2019 + imetavg=1 + ;; ERAINT_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1427,6 +1674,12 @@ do metcycf=2010 imetavg=1 ;; + WFDE5_CHIRPS) + metdriverdb="${fullscen}/${iscenario}_HEADER" + metcyc1=1981 + metcycf=2018 + imetavg=2 + ;; WFDEI_CHIRPS) metdriverdb="${fullscen}/${iscenario}_HEADER" metcyc1=1981 @@ -1464,7 +1717,7 @@ do # Correct years so it is not tower-based or Sheffield. # #---------------------------------------------------------------------------------------# case ${iscenario} in - default|eft|shr|sheffield|WFDEI*|ERAINT*|MERRA2*|PGMF3*) + default|eft|shr|ERA5*|ERAINT*|MERRA2*|PGMF3*|Sheffield|WFDE5*|WFDEI*) echo "Nothing" > /dev/null ;; *) @@ -1521,6 +1774,12 @@ do ;; esac ;; + sa2-ril) + ludatabase="${lumain}/SimAmazonia2/ril/sa2_ril_" + ;; + sa2-cvl) + ludatabase="${lumain}/SimAmazonia2/cvl/sa2_cvl_" + ;; lurcp26) ludatabase="${lumain}/luh-1.1+rcp26_image/luh-1.1+rcp26_image-" ;; @@ -1538,7 +1797,7 @@ do # Stop the script if anthropogenic dataset is invalid and this is a simulation # # with anthropogenic disturbance. # #------------------------------------------------------------------------------------# - if [ ${ianthdisturb} -eq 1 ] + if [[ ${ianthdisturb} -eq 1 ]] then echo " Polygon: ${polyname}" echo " IATA: ${polyiata}" @@ -1558,13 +1817,13 @@ do # Define whether we use the met cycle to define the first and last year, or the # # default year. # #---------------------------------------------------------------------------------------# - if [ ${yeara} -eq 0 ] + if [[ ${yeara} -eq 0 ]] then thisyeara=${metcyc1} else thisyeara=${yeara} fi - if [ ${yearz} -eq 0 ] + if [[ ${yearz} -eq 0 ]] then thisyearz=${metcycf} else @@ -1641,8 +1900,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-4.032,-3.584,-3.159,-2.757,-2.377,-2.021,-1.689,-1.382,-1.101," - polyslz2="-0.846,-0.620,-0.424,-0.260,-0.130,-0.040" + polyslz1="-5.000,-4.468,-3.963,-3.483,-3.030,-2.604,-2.205,-1.836,-1.495,-1.185," + polyslz2="-0.906,-0.660,-0.447,-0.271,-0.134,-0.040" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1676,6 +1935,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.934,-6.934,-5.999,-5.131,-4.329,-3.593,-2.925,-2.324,-1.790," + polyslz2="-1.325,-0.928,-0.600,-0.342,-0.155,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.223,-8.029,-6.919,-5.891,-4.946,-4.084,-3.305,-2.609,-1.995," polyslz2="-1.464,-1.015,-0.648,-0.364,-0.161,-0.040" @@ -1684,6 +1952,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.51,-9.118,-7.828,-6.640,-5.552,-4.563,-3.674,-2.883,-2.191" + polyslz2="-1.595,-1.096,-0.693,-0.383,-0.166,-0.040" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -1783,8 +2060,8 @@ do ;; E) polynzg=16 - polyslz1="-4.500,-3.967,-3.467,-3.000,-2.565,-2.164,-1.797,-1.462,-1.162,-0.895," - polyslz2="-0.662,-0.464,-0.300,-0.171,-0.077,-0.020" + polyslz1="-5.000,-4.397,-3.833,-3.307,-2.819,-2.371,-1.961,-1.590,-1.257,-0.964," + polyslz2="-0.709,-0.493,-0.316,-0.178,-0.080,-0.020" polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," @@ -1818,6 +2095,15 @@ do polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; I) + polynzg=16 + polyslz1="-9.000,-7.807,-6.706,-5.696,-4.775,-3.942,-3.195,-2.533,-1,954,-1.456," + polyslz2="-1.037,-0.694,-0.424,-0.225,-0.092,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; + J) polynzg=16 polyslz1="-10.50,-9.076,-7.766,-6.569,-5.482,-4.504,-3.631,-2.862,-2.194,-1.622," polyslz2="-1.145,-0.759,-0.458,-0.239,-0.096,-0.020" @@ -1826,6 +2112,15 @@ do polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" ;; + K) + polynzg=16 + polyslz1="-12.00,-10.34,-8.818,-7.432,-6.179,-5.055,-4.057,-3.182,-2.425,-1.782" + polyslz2="-1.248,-0.820,-0.490,-0.252,-0.099,-0.020" + polyslm1=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000," + polyslm2=" 1.000, 1.000, 1.000, 1.000, 1.000, 1.000" + polyslt1=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000," + polyslt2=" 0.000, 0.000, 0.000, 0.000, 0.000, 0.000" + ;; P) polynzg=7 polyslz1="-0.580,-0.420,-0.300,-0.200,-0.120,-0.060,-0.020" @@ -2072,7 +2367,7 @@ do #----- Check whether to use SFILIN as restart or history. ------------------------------# - if [ ${runt} == "RESTORE" ] && [ ${forcehisto} -eq 1 ] + if [[ ${runt} == "RESTORE" ]] && [[ ${forcehisto} -eq 1 ]] then runt="HISTORY" year=${yearh} @@ -2080,141 +2375,192 @@ do date=${dateh} time=${timeh} thissfilin=${fullygrown} - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 5 ] - then - if [ ! -s ${restart} ] - then - echo " Directory restart does not exist!" - echo " Change the variable restart at the beginning of the script" - exit 44 - else - runt="RESTORE" - thissfilin=${restart} - fi - elif [ ${runt} == "RESTORE" ] && [ ${initmode} -eq 6 ] + elif [[ ${runt} == "RESTORE" ]] then - thissfilin=${fullygrown} - - - - #------------------------------------------------------------------------------------# - # Find the biometric files. This has been checked in spawn_poly.sh so they are # - # correct. Add a dummy name in case this is not supposed to be a biomass # - # initialisation run. # - #------------------------------------------------------------------------------------# - case ${biotype} in - 0) - #----- isizepft controls everything, and iage is ignored. ------------------------# - case ${isizepft} in - 0) - #----- Frankeinstein's under storey. ------------------------------------------# - thissfilin="${bioinit}/${polyiata}_default." - ;; - 1) - #----- No under storey. -------------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_nounder." - ;; - 2) - #----- ALS initialisation. ----------------------------------------------------# - thissfilin="${bioinit}/${polyiata}_alsinit." - ;; - *) - #----- Invalid option. Stop the script. ---------------------------------------# - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 57 - ;; - esac - #---------------------------------------------------------------------------------# - ;; - - 1) + case ${initmode} in + 5|7) #---------------------------------------------------------------------------------# - # 'isizepft' controls how many PFTs to use. # + # Initialise ED2 with hdf5 files, which should be in directory restart. # #---------------------------------------------------------------------------------# - case ${isizepft} in - 0|5) - pftname="pft05" - ;; - 2) - pftname="pft02" - ;; - esac + if [[ ! -s ${restart} ]] + then + echo " Directory restart does not exist!" + echo " Change the variable restart at the beginning of the script" + exit 44 + else + runt="RESTORE" + thissfilin=${restart} + fi #---------------------------------------------------------------------------------# + ;; + 1|2|3|6|8) #---------------------------------------------------------------------------------# - # 'iage' controls how many patches to use. # + # Find the biometric files. This has been checked in spawn_poly.sh so they # + # are correct. Add a dummy name in case this is not supposed to be a biomass # + # initialisation run. # #---------------------------------------------------------------------------------# - case ${iage} in - 1) - agename="age01" - ;; - *) - agename="age00" + case ${biotype} in + 0) + #----- isizepft controls everything, and iage is ignored. ---------------------# + case ${isizepft} in + 0) + #----- Frankeinstein's under storey. ---------------------------------------# + thissfilin="${bioinit}/${polyiata}_default." + ;; + 1) + #----- No under storey. ----------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_nounder." + ;; + 2) + #----- ALS initialisation. -------------------------------------------------# + thissfilin="${bioinit}/${polyiata}_alsinit." + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initialised with these ISIZEPFT and INITMODE!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------# - # Check whether the site has the PFT and age structure. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - hvd|s77|fns|cau|and|par|tap|dcm) - thissfilin="${bioinit}/${polyiata}_default." + 1) + #------------------------------------------------------------------------------# + # 'isizepft' controls how many PFTs to use. # + #------------------------------------------------------------------------------# + case ${isizepft} in + 0|5) + pftname="pft05" + ;; + 2) + pftname="pft02" + ;; + esac + #------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------# + # 'iage' controls how many patches to use. # + #------------------------------------------------------------------------------# + case ${iage} in + 1) + agename="age01" + ;; + *) + agename="age00" + ;; + esac + #------------------------------------------------------------------------------# + + + + + #------------------------------------------------------------------------------# + # Check whether the site has the PFT and age structure. # + #------------------------------------------------------------------------------# + case ${polyiata} in + hvd|s77|fns|cau|and|par|tap|dcm) + thissfilin="${bioinit}/${polyiata}_default." + ;; + cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) + thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + ;; + *) + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " IAGE: ${iage}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 59 + ;; + esac + #------------------------------------------------------------------------------# ;; - cax|s67|s83|m34|gyf|pdg|rja|pnz|ban) - thissfilin="${bioinit}/${polyiata}_${pftname}+${agename}." + 2) + #------------------------------------------------------------------------------# + # ALS initialisation. ISIZEPFT has disturbance history information. # + #------------------------------------------------------------------------------# + case ${polyiata} in + l[0-5][0-3]) + thissfilin="${alsinit}/${polyiata}." + ;; + *) + thissfilin="${alsinit}/${polyiata}_${isizepft}." + ;; + esac + #------------------------------------------------------------------------------# ;; - *) - echo " Polygon: ${polyname}" - echo " IATA: ${polyiata}" - echo " IAGE: ${iage}" - echo " ISIZEPFT: ${isizepft}" - echo "This IATA cannot be used by biomass initialisation with this ISIZEPFT!" - exit 59 + 3) + #------------------------------------------------------------------------------# + # ALS initialisation using intensity. ISIZEPFT has disturbance history # + # information. # + #------------------------------------------------------------------------------# + thissfilin="${intinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - esac - #---------------------------------------------------------------------------------# - ;; - 2) - #---------------------------------------------------------------------------------# - # ALS initialisation. ISIZEPFT has disturbance history information. # - #---------------------------------------------------------------------------------# - case ${polyiata} in - l[0-5][0-3]) - thissfilin="${alsinit}/${polyiata}." + 4) + #------------------------------------------------------------------------------# + # ALS initialisation using the lookup table. ISIZEPFT has disturbance # + # history information. # + #------------------------------------------------------------------------------# + thissfilin="${lutinit}/${polyiata}_${isizepft}." + #------------------------------------------------------------------------------# ;; - *) - thissfilin="${alsinit}/${polyiata}_${isizepft}." + 5) + #----- isizepft controls actual or majestic initialisation. -------------------# + case ${isizepft} in + 0) + #----- Actual sampling. ----------------------------------------------------# + thissfilin="${ebainit}/eba_actual_default." + #---------------------------------------------------------------------------# + ;; + 1) + #----- Majestic sampling. --------------------------------------------------# + thissfilin="${ebainit}/eba_majestic_default." + #---------------------------------------------------------------------------# + ;; + 2) + #----- Actual sampling + land use (pasture/cropland/plantation). -----------# + thissfilin="${ebainit}/eba_luactual_default." + #---------------------------------------------------------------------------# + ;; + 3) + #----- Majestic sampling + land use (pasture/cropland/plantation). ---------# + thissfilin="${ebainit}/eba_lumajestic_default." + #---------------------------------------------------------------------------# + ;; + *) + #----- Invalid option. Stop the script. ------------------------------------# + echo " Polygon: ${polyname}" + echo " IATA: ${polyiata}" + echo " ISIZEPFT: ${isizepft}" + echo " INITMODE: ${initmode}" + echo "This IATA cannot be initiealised with these settings!" + exit 57 + ;; + esac + #------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------# ;; - 3) - #---------------------------------------------------------------------------------# - # ALS initialisation using intensity. ISIZEPFT has disturbance history # - # information. # - #---------------------------------------------------------------------------------# - thissfilin="${intinit}/${polyiata}_${isizepft}." + *) + #----- No initial file needed; set the history file. -----------------------------# + thissfilin=${here}/${polyname}/histo/${polyname} #---------------------------------------------------------------------------------# ;; - 4) - #---------------------------------------------------------------------------------# - # ALS initialisation using the lookup table. ISIZEPFT has disturbance history # - # information. # - #---------------------------------------------------------------------------------# - thissfilin="${lutinit}/${polyiata}_${isizepft}." #---------------------------------------------------------------------------------# - ;; esac #------------------------------------------------------------------------------------# else + #----- Set the history file. --------------------------------------------------------# thissfilin=${here}/${polyname}/histo/${polyname} + #------------------------------------------------------------------------------------# fi #---------------------------------------------------------------------------------------# @@ -2381,6 +2727,7 @@ do sed -i~ s@mydbhharv@${dbhharv}@g ${ED2IN} sed -i~ s@mybioharv@${bioharv}@g ${ED2IN} sed -i~ s@myskidarea@${skidarea}@g ${ED2IN} + sed -i~ s@myskiddbhthresh@${skiddbhthresh}@g ${ED2IN} sed -i~ s@myskidsmall@${skidsmall}@g ${ED2IN} sed -i~ s@myskidlarge@${skidlarge}@g ${ED2IN} sed -i~ s@myfellingsmall@${fellingsmall}@g ${ED2IN} @@ -2426,11 +2773,137 @@ do exec_sub=${exec_full} ;; esac + #---------------------------------------------------------------------------------------# + + - #----- Change the callserial.sh file. --------------------------------------------------# + #----- Script names. -------------------------------------------------------------------# + tempserial="${here}/Template/callserial.sh" callserial="${here}/${polyname}/callserial.sh" - rm -f ${callserial} - cp -f ${here}/Template/callserial.sh ${callserial} + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Set script callserial.sh. Depending on the settings (single multi-task jobs or # + # multiple single-task jobs), we must update the header. # + #---------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #------------------------------------------------------------------------------------# + # Single multi task job, callserial.sh doesn't need header updates. # + #------------------------------------------------------------------------------------# + /bin/rm -f ${callserial} + /bin/cp -f ${tempserial} ${callserial} + #------------------------------------------------------------------------------------# + ;; + CANNON) + #------------------------------------------------------------------------------------# + # Update header with sbatch instructions for multiple single task jobs. # + #------------------------------------------------------------------------------------# + + #----- Output files. ----------------------------------------------------------------# + obatch="${here}/${polyname}/serial_slm.out" + ebatch="${here}/${polyname}/serial_slm.err" + #------------------------------------------------------------------------------------# + + #----- Initialise the callserial.sh file. -------------------------------------------# + rm -f ${callserial} + touch ${callserial} + chmod u+x ${callserial} + echo "#!/bin/bash" >> ${callserial} + echo "#SBATCH --ntasks=1 # Number of tasks" >> ${callserial} + echo "#SBATCH --cpus-per-task=${n_cpt} # Number of CPUs per task" >> ${callserial} + echo "#SBATCH --cores-per-socket=${n_cpt} # Min. # of cores/socket" >> ${callserial} + echo "#SBATCH --partition=${global_queue} # Queue that will run job" >> ${callserial} + echo "#SBATCH --job-name=${taskname} # Job name" >> ${callserial} + echo "#SBATCH --mem-per-cpu=${cpu_memory} # Memory per CPU" >> ${callserial} + echo "#SBATCH --time=${runtime} # Time for job" >> ${callserial} + echo "#SBATCH --output=${obatch} # Standard output path" >> ${callserial} + echo "#SBATCH --error=${ebatch} # Standard error path" >> ${callserial} + echo "#SBATCH --chdir=${here}/${polyname} # Main directory" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Initial settings." >> ${callserial} + echo "here=\"${here}\" # Main path" >> ${callserial} + echo "exec=\"${exec_full}\" # Executable" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Print information about this job." >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"----- Summary of current job -----------------------\"" >> ${callserial} + echo "echo \" CPUs per task: \${SLURM_CPUS_PER_TASK}\"" >> ${callserial} + echo "echo \" Job name: \${SLURM_JOB_NAME}\"" >> ${callserial} + echo "echo \" Job ID: \${SLURM_JOB_ID}\"" >> ${callserial} + echo "echo \" Partition: \${SLURM_JOB_PARTITION}\"" >> ${callserial} + echo "echo \" Number of nodes: \${SLURM_NNODES}\"" >> ${callserial} + echo "echo \" Number of tasks: \${SLURM_NTASKS}\"" >> ${callserial} + echo "echo \" Memory per CPU: \${SLURM_MEM_PER_CPU}\"" >> ${callserial} + echo "echo \" Memory per node: \${SLURM_MEM_PER_NODE}\"" >> ${callserial} + echo "echo \" Node list: \${SLURM_JOB_NODELIST}\"" >> ${callserial} + echo "echo \" Time limit: \${SLURM_TIMELIMIT}\"" >> ${callserial} + echo "echo \" Std. Output: \${SLURM_STDOUTMODE}\"" >> ${callserial} + echo "echo \" Std. Error: \${SLURM_STDERRMODE}\"" >> ${callserial} + echo "echo \"----------------------------------------------------\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "" >> ${callserial} + echo "echo \"----- Global settings for this simulation. ---\"" >> ${callserial} + echo "echo \" Main path: \${here}\"" >> ${callserial} + echo "echo \" Executable: \${exec}\"" >> ${callserial} + echo "echo \"----------------------------------------------------\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "echo \"\"" >> ${callserial} + echo "" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Define home in case home is not set" >> ${callserial} + echo "if [[ \"x\${HOME}\" == \"x\" ]]" >> ${callserial} + echo "then" >> ${callserial} + echo " export HOME=\$(echo ~)" >> ${callserial} + echo "fi" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Load modules and settings." >> ${callserial} + echo ". \${HOME}/.bashrc ${optsrc}" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Get plenty of memory." >> ${callserial} + echo "ulimit -s unlimited" >> ${callserial} + echo "ulimit -u unlimited" >> ${callserial} + echo "" >> ${callserial} + echo "#--- Set OpenMP parameters" >> ${callserial} + echo "if [[ \"\${SLURM_CPUS_PER_TASK}\" == \"\" ]]" >> ${callserial} + echo "then" >> ${callserial} + echo " export OMP_NUM_THREADS=1" >> ${callserial} + echo "else" >> ${callserial} + echo " export OMP_NUM_THREADS=\${SLURM_CPUS_PER_TASK}" >> ${callserial} + echo "fi" >> ${callserial} + echo "" >> ${callserial} + #------------------------------------------------------------------------------------# + + + + #----- Append the template callserial.sh, skipping the first line. ------------------# + tail -n +2 ${tempserial} >> ${callserial} + #------------------------------------------------------------------------------------# + + + #----- Make sure the script waits until all tasks are completed... ------------------# + echo "" >> ${callserial} + echo "" >> ${callserial} + echo "#----- Ensure that jobs complete before terminating script." >> ${callserial} + echo "wait" >> ${callserial} + echo "" >> ${callserial} + echo "#----- Report efficiency of this job." >> ${callserial} + echo "seff \${SLURM_JOBID}" >> ${callserial} + echo "" >> ${callserial} + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + ;; + esac + #---------------------------------------------------------------------------------------# + + + #----- Substitute placeholders with specific data. -------------------------------------# sed -i s@thisroot@${here}@g ${callserial} sed -i s@thispoly@${polyname}@g ${callserial} sed -i s@myname@${moi}@g ${callserial} @@ -2459,9 +2932,16 @@ do "EXTINCT") echo "Polygon population has gone extinct. No need to re-submit it." ;; - "CRASHED"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") - echo "Polygon has serious errors. Script will not submit any job this time." - submit=false + "CRASHED"|"HYDFAIL"|"METMISS"|"SIGSEGV"|"BAD_MET"|"STOPPED") + #----- Decide whether to skip this job submission or every job submission. ----------# + if ${on_the_fly} + then + echo "Polygon has serious errors. Script will not submit this job." + else + echo "Polygon has serious errors. Script will not submit any job this time." + submit=false + fi + #------------------------------------------------------------------------------------# ;; "RESTORE"|"HISTORY") @@ -2471,25 +2951,79 @@ do #------------------------------------------------------------------------------------# echo " Polygon scheduled for submission." let n_submit=${n_submit}+1 - let dtwait=${dtwait}+2 #------------------------------------------------------------------------------------# - #----- Append job to submission list. -----------------------------------------------# - srun="srun --nodes=1 --ntasks=1 --cpu_bind=cores" - srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" - srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" - srun="${srun} --job-name=${polyname}" - srun="${srun} --chdir=\${here}/${polyname}" - srun="${srun} --output=\${here}/${polyname}/serial_slm.out" - srun="${srun} --error=\${here}/${polyname}/serial_slm.err" - echo "${srun} \${here}/${polyname}/callserial.sh &" >> ${sbatch} - echo "sleep ${dttask}" >> ${sbatch} + #------------------------------------------------------------------------------------# + # Set command to the main script. Again, this depends on the type of job # + # submission. # + #------------------------------------------------------------------------------------# + case "${cluster}" in + SDUMONT) + #---------------------------------------------------------------------------------# + # Append task in the single multi-task job script. # + #---------------------------------------------------------------------------------# + srun="srun --nodes=1 --ntasks=1 --cpu_bind=cores" + srun="${srun} --cpus-per-task=\${SLURM_CPUS_PER_TASK}" + srun="${srun} --mem-per-cpu=\${SLURM_MEM_PER_CPU}" + srun="${srun} --job-name=${polyname}" + srun="${srun} --chdir=\${here}/${polyname}" + srun="${srun} --output=\${here}/${polyname}/serial_slm.out" + srun="${srun} --error=\${here}/${polyname}/serial_slm.err" + echo "${srun} \${here}/${polyname}/callserial.sh &" >> ${sbatch} + echo "sleep ${dttask}" >> ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + #---------------------------------------------------------------------------------# + # Make sure we don't exceed the maximum number of jobs. # + #---------------------------------------------------------------------------------# + if [[ ${n_submit} -gt ${n_tasks_max} ]] && ${on_the_fly} + then + echo " Number of jobs to submit: ${n_submit}" + echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" + echo " Reduce the number of simulations or try another queue..." + echo " Appending remaining jobs to $(basename ${sbatch}) for later submission." + on_the_fly=false + fi + #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # If on the fly, submit the job now. Otherwise, append job to sbatch. # + #---------------------------------------------------------------------------------# + if ${on_the_fly} + then + #----- Submit job on the fly. -------------------------------------------------# + sbatch ${callserial} + #------------------------------------------------------------------------------# + else + #------------------------------------------------------------------------------# + # Append submission to the script to submit the multiple single-task jobs. # + #------------------------------------------------------------------------------# + echo "echo \" + ${ffout}/${ntasks}. Submit job: ${polyname}.\"" >> ${sbatch} + echo "sbatch ${callserial}" >> ${sbatch} + echo "sleep ${dttask}" >> ${sbatch} + #------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------# + + ;; + esac #------------------------------------------------------------------------------------# ;; *) - echo "Unknown polygon state (${runt})! Script will not submit any job this time." - submit=false + #------------------------------------------------------------------------------------# + # Unknown state, either skip this job submission, or every job submission. # + #------------------------------------------------------------------------------------# + if ${on_the_fly} + then + echo "Unknown polygon state (${runt})! Script will not submit this job." + else + echo "Unknown polygon state (${runt})! Script will not submit any job this time." + submit=false + fi + #------------------------------------------------------------------------------------# ;; esac #---------------------------------------------------------------------------------------# @@ -2497,41 +3031,86 @@ done #------------------------------------------------------------------------------------------# - #------------------------------------------------------------------------------------------# -# Make sure job list doesn't request too many nodes. # +# Update the main submission script to reflect the correct number of tasks (done only # +# when running a single multi-task job). # #------------------------------------------------------------------------------------------# -if [ ${n_submit} -gt ${n_tasks_max} ] -then - echo " Number of jobs to submit: ${n_submit}" - echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" - echo " Reduce the number of simulations or try another queue..." - exit 99 -else +case "${cluster}" in +SDUMONT) #----- Update the number of tasks in batch script. -------------------------------------# sed -i~ s@myntasks@${n_submit}@g ${sbatch} #---------------------------------------------------------------------------------------# -fi + ;; +esac #------------------------------------------------------------------------------------------# -#----- Make sure the script waits until all tasks are completed... ------------------------# -echo "" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Make sure that jobs complete before terminating script" >> ${sbatch} -echo "wait" >> ${sbatch} -echo "" >> ${sbatch} -echo "#----- Report efficiency of this job" >> ${sbatch} -echo "seff \${SLURM_JOBID}" >> ${sbatch} -echo "" >> ${sbatch} -#------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# In case all looks good, go for it! # +# Make sure job list doesn't request too many nodes. # #------------------------------------------------------------------------------------------# -if ${submit} +if ! ${on_the_fly} then - sbatch ${sbatch} + if [[ ${n_submit} -gt ${n_tasks_max} ]] + then + echo " Number of jobs to submit: ${n_submit}" + echo " Maximum number of tasks in queue ${global_queue}: ${n_tasks_max}" + echo " Reduce the number of simulations or try another queue..." + exit 99 + elif ${submit} + then + echo " Submitting jobs." + #------- How we submit depends on the cluster. --------------------------------------# + case "${cluster}" in + SDUMONT) + #---------------------------------------------------------------------------------# + # Single multi-task job. Submit the main script using sbatch. # + #---------------------------------------------------------------------------------# + sbatch ${sbatch} + #---------------------------------------------------------------------------------# + ;; + CANNON) + #---------------------------------------------------------------------------------# + # Multiple single-task jobs. Run the script, the sbatch commands are in # + # there. # + #---------------------------------------------------------------------------------# + ${sbatch} + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + else + #------- Provide instructions to the user for a later submission. -------------------# + case "${cluster}" in + SDUMONT) + #----- Instruct the user to use sbatch. ------------------------------------------# + echo "-------------------------------------------------------------------------" + echo " To submit the simulations, you must use sbatch. " + echo " Copy and paste the following command in the terminal. " + echo " " + echo " sbatch ${sbatch}" + echo " " + #---------------------------------------------------------------------------------# + ;; + CANNON) + #----- Instruct the user NOT to use sbatch. --------------------------------------# + echo "-------------------------------------------------------------------------" + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo " WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! " + echo "-------------------------------------------------------------------------" + echo " Do NOT use sbatch ${sbatch}." + echo " Instead, call the following script directly in your terminal." + echo " " + echo " ${sbatch}" + echo " " + #---------------------------------------------------------------------------------# + ;; + esac + #------------------------------------------------------------------------------------# + fi + #---------------------------------------------------------------------------------------# fi #------------------------------------------------------------------------------------------# diff --git a/ED/Template/scripts/SLURM/transfer.sh b/ED/Template/scripts/SLURM/transfer.sh deleted file mode 100755 index f2c39f890..000000000 --- a/ED/Template/scripts/SLURM/transfer.sh +++ /dev/null @@ -1,304 +0,0 @@ -#!/bin/bash - -#==========================================================================================# -#==========================================================================================# -# Main settings: # -#------------------------------------------------------------------------------------------# -#----- Main path, usually set by $(pwd) so you don't need to change it. -------------------# -here="" -#----- Location to create the copy of these files. ----------------------------------------# -there="" -#----- File containing the list of jobs and their settings: -------------------------------# -joborder="${here}/joborder.txt" -#----- Command to be used for rsync. ------------------------------------------------------# -frsync="rsync -Putq --links --copy-unsafe-links" -rrsync="rsync -Prutq --links --copy-unsafe-links" -#------------------------------------------------------------------------------------------# - - - - - -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -# Unless you are going to modify the scripts, you don't need to change anything beyond # -# this point. # -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# -#==========================================================================================# - - -#------------------------------------------------------------------------------------------# -# First check that the main path and e-mail have been set. If not, don't run. # -#------------------------------------------------------------------------------------------# -if [ "x${here}" == "x" ] || [ "x${there}" == "x" ] -then - echo " You must set some variables before running the script:" - echo " Check variables \"here\" and \"there\"!" - exit 99 -fi -#------------------------------------------------------------------------------------------# - - - - -#----- Check whether run_sitter.sh is still running or not. If it is, exit. --------------# -if [[ "${here}" == "${there}" ]] -then - echo " Source and destination paths are the same. Transfer is not needed." - exit 0 -elif [[ -s ${here}/transfer.lock ]] -then - echo " Script transfer is running. Skip transfer for the time being." - exit -else - echo "I am going to back up your run." > ${here}/transfer.lock -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Create the output path in case it isn't there. # -#------------------------------------------------------------------------------------------# -if [ ! -s ${there} ] -then - echo "Create backup path: ${there}." - mkdir -p ${there} -fi -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# First, copy the files at the basal directory. # -#------------------------------------------------------------------------------------------# -echo " + Copy files from the main directory." -${frsync} ${here}/* ${there} -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Then copy the fixed directories. # -#------------------------------------------------------------------------------------------# -echo " + Copy executable." -${rrsync} ${here}/executable ${there} -echo " + Copy sit_utils." -${rrsync} ${here}/sit_utils ${there} -echo " + Copy Template." -${rrsync} ${here}/Template ${there} -#------------------------------------------------------------------------------------------# - - - - -#----- Determine the number of polygons to run. -------------------------------------------# -let npolys=$(wc -l ${joborder} | awk '{print $1 }')-3 -#------------------------------------------------------------------------------------------# - - - -#------------------------------------------------------------------------------------------# -# Loop over all polygons. # -#------------------------------------------------------------------------------------------# -ff=0 -while [ ${ff} -lt ${npolys} ] -do - let ff=${ff}+1 - let line=${ff}+3 - - - #---------------------------------------------------------------------------------------# - # Format count. # - #---------------------------------------------------------------------------------------# - if [ ${npolys} -ge 10 ] && [ ${npolys} -lt 100 ] - then - ffout=$(printf '%2.2i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 1000 ] - then - ffout=$(printf '%3.3i' ${ff}) - elif [ ${npolys} -ge 100 ] && [ ${npolys} -lt 10000 ] - then - ffout=$(printf '%4.4i' ${ff}) - else - ffout=${ff} - fi - ffout="${ffout} of ${npolys}" - #---------------------------------------------------------------------------------------# - - - - #---------------------------------------------------------------------------------------# - # Read the ffth line of the polygon list. There must be smarter ways of doing # - # this, but this works. Here we obtain the polygon name, and its longitude and # - # latitude. # - #---------------------------------------------------------------------------------------# - oi=$(head -${line} ${joborder} | tail -1) - polyname=$(echo ${oi} | awk '{print $1 }') - polyiata=$(echo ${oi} | awk '{print $2 }') - polylon=$(echo ${oi} | awk '{print $3 }') - polylat=$(echo ${oi} | awk '{print $4 }') - yeara=$(echo ${oi} | awk '{print $5 }') - montha=$(echo ${oi} | awk '{print $6 }') - datea=$(echo ${oi} | awk '{print $7 }') - timea=$(echo ${oi} | awk '{print $8 }') - yearz=$(echo ${oi} | awk '{print $9 }') - monthz=$(echo ${oi} | awk '{print $10 }') - datez=$(echo ${oi} | awk '{print $11 }') - timez=$(echo ${oi} | awk '{print $12 }') - initmode=$(echo ${oi} | awk '{print $13 }') - iscenario=$(echo ${oi} | awk '{print $14 }') - isizepft=$(echo ${oi} | awk '{print $15 }') - iage=$(echo ${oi} | awk '{print $16 }') - imaxcohort=$(echo ${oi} | awk '{print $17 }') - polyisoil=$(echo ${oi} | awk '{print $18 }') - polyntext=$(echo ${oi} | awk '{print $19 }') - polysand=$(echo ${oi} | awk '{print $20 }') - polyclay=$(echo ${oi} | awk '{print $21 }') - polyslsoc=$(echo ${oi} | awk '{print $22 }') - polyslph=$(echo ${oi} | awk '{print $23 }') - polyslcec=$(echo ${oi} | awk '{print $24 }') - polysldbd=$(echo ${oi} | awk '{print $25 }') - polydepth=$(echo ${oi} | awk '{print $26 }') - polyslhydro=$(echo ${oi} | awk '{print $27 }') - polysoilbc=$(echo ${oi} | awk '{print $28 }') - polysldrain=$(echo ${oi} | awk '{print $29 }') - polycol=$(echo ${oi} | awk '{print $30 }') - slzres=$(echo ${oi} | awk '{print $31 }') - queue=$(echo ${oi} | awk '{print $32 }') - metdriver=$(echo ${oi} | awk '{print $33 }') - dtlsm=$(echo ${oi} | awk '{print $34 }') - monyrstep=$(echo ${oi} | awk '{print $35 }') - iphysiol=$(echo ${oi} | awk '{print $36 }') - vmfactc3=$(echo ${oi} | awk '{print $37 }') - vmfactc4=$(echo ${oi} | awk '{print $38 }') - mphototrc3=$(echo ${oi} | awk '{print $39 }') - mphototec3=$(echo ${oi} | awk '{print $40 }') - mphotoc4=$(echo ${oi} | awk '{print $41 }') - bphotoblc3=$(echo ${oi} | awk '{print $42 }') - bphotonlc3=$(echo ${oi} | awk '{print $43 }') - bphotoc4=$(echo ${oi} | awk '{print $44 }') - kwgrass=$(echo ${oi} | awk '{print $45 }') - kwtree=$(echo ${oi} | awk '{print $46 }') - gammac3=$(echo ${oi} | awk '{print $47 }') - gammac4=$(echo ${oi} | awk '{print $48 }') - d0grass=$(echo ${oi} | awk '{print $49 }') - d0tree=$(echo ${oi} | awk '{print $50 }') - alphac3=$(echo ${oi} | awk '{print $51 }') - alphac4=$(echo ${oi} | awk '{print $52 }') - klowco2=$(echo ${oi} | awk '{print $53 }') - decomp=$(echo ${oi} | awk '{print $54 }') - rrffact=$(echo ${oi} | awk '{print $55 }') - growthresp=$(echo ${oi} | awk '{print $56 }') - lwidthgrass=$(echo ${oi} | awk '{print $57 }') - lwidthbltree=$(echo ${oi} | awk '{print $58 }') - lwidthnltree=$(echo ${oi} | awk '{print $59 }') - q10c3=$(echo ${oi} | awk '{print $60 }') - q10c4=$(echo ${oi} | awk '{print $61 }') - h2olimit=$(echo ${oi} | awk '{print $62 }') - imortscheme=$(echo ${oi} | awk '{print $63 }') - ddmortconst=$(echo ${oi} | awk '{print $64 }') - cbrscheme=$(echo ${oi} | awk '{print $65 }') - isfclyrm=$(echo ${oi} | awk '{print $66 }') - icanturb=$(echo ${oi} | awk '{print $67 }') - ubmin=$(echo ${oi} | awk '{print $68 }') - ugbmin=$(echo ${oi} | awk '{print $69 }') - ustmin=$(echo ${oi} | awk '{print $70 }') - gamm=$(echo ${oi} | awk '{print $71 }') - gamh=$(echo ${oi} | awk '{print $72 }') - tprandtl=$(echo ${oi} | awk '{print $73 }') - ribmax=$(echo ${oi} | awk '{print $74 }') - atmco2=$(echo ${oi} | awk '{print $75 }') - thcrit=$(echo ${oi} | awk '{print $76 }') - smfire=$(echo ${oi} | awk '{print $77 }') - ifire=$(echo ${oi} | awk '{print $78 }') - fireparm=$(echo ${oi} | awk '{print $79 }') - ipercol=$(echo ${oi} | awk '{print $80 }') - runoff=$(echo ${oi} | awk '{print $81 }') - imetrad=$(echo ${oi} | awk '{print $82 }') - ibranch=$(echo ${oi} | awk '{print $83 }') - icanrad=$(echo ${oi} | awk '{print $84 }') - ihrzrad=$(echo ${oi} | awk '{print $85 }') - crown=$(echo ${oi} | awk '{print $86 }') - ltransvis=$(echo ${oi} | awk '{print $87 }') - lreflectvis=$(echo ${oi} | awk '{print $88 }') - ltransnir=$(echo ${oi} | awk '{print $89 }') - lreflectnir=$(echo ${oi} | awk '{print $90 }') - orienttree=$(echo ${oi} | awk '{print $91 }') - orientgrass=$(echo ${oi} | awk '{print $92 }') - clumptree=$(echo ${oi} | awk '{print $93 }') - clumpgrass=$(echo ${oi} | awk '{print $94 }') - igoutput=$(echo ${oi} | awk '{print $95 }') - ivegtdyn=$(echo ${oi} | awk '{print $96 }') - ihydro=$(echo ${oi} | awk '{print $97 }') - istemresp=$(echo ${oi} | awk '{print $98 }') - istomata=$(echo ${oi} | awk '{print $99 }') - iplastic=$(echo ${oi} | awk '{print $100}') - icarbonmort=$(echo ${oi} | awk '{print $101}') - ihydromort=$(echo ${oi} | awk '{print $102}') - igndvap=$(echo ${oi} | awk '{print $103}') - iphen=$(echo ${oi} | awk '{print $104}') - iallom=$(echo ${oi} | awk '{print $105}') - ieconomics=$(echo ${oi} | awk '{print $106}') - igrass=$(echo ${oi} | awk '{print $107}') - ibigleaf=$(echo ${oi} | awk '{print $108}') - integscheme=$(echo ${oi} | awk '{print $109}') - nsubeuler=$(echo ${oi} | awk '{print $110}') - irepro=$(echo ${oi} | awk '{print $111}') - treefall=$(echo ${oi} | awk '{print $112}') - ianthdisturb=$(echo ${oi} | awk '{print $113}') - ianthdataset=$(echo ${oi} | awk '{print $114}') - slscale=$(echo ${oi} | awk '{print $115}') - slyrfirst=$(echo ${oi} | awk '{print $116}') - slnyrs=$(echo ${oi} | awk '{print $117}') - bioharv=$(echo ${oi} | awk '{print $118}') - skidarea=$(echo ${oi} | awk '{print $119}') - skidsmall=$(echo ${oi} | awk '{print $120}') - skidlarge=$(echo ${oi} | awk '{print $121}') - fellingsmall=$(echo ${oi} | awk '{print $122}') - #---------------------------------------------------------------------------------------# - - - #----- Check whether the directories exist or not, and stop the script if they do. -----# - if [ -s ${here}/${polyname} ] - then - echo -n " + Copy ${polyname} (${ffout})." - - #----- Sync this directory. ---------------------------------------------------------# - ${rrsync} ${here}/${polyname} ${there} - #------------------------------------------------------------------------------------# - - echo "Done!" - else - echo " + Skip ${polyname} (${ffout})." - fi - #---------------------------------------------------------------------------------------# -done -#------------------------------------------------------------------------------------------# - - -#----- Clean-up stuff. --------------------------------------------------------------------# -echo " Unlock transfer.sh." -/bin/rm -f ${here}/transfer.lock -echo "==== transfer.sh execution ends. ====" -#------------------------------------------------------------------------------------------# diff --git a/ED/Template/sit_utils/plot.region.r b/ED/Template/sit_utils/plot.region.r index bcf263c39..97e907dd4 100644 --- a/ED/Template/sit_utils/plot.region.r +++ b/ED/Template/sit_utils/plot.region.r @@ -4,6 +4,8 @@ #------------------------------------------------------------------------------------------# rm(list=ls()) graphics.off() +gc() +options(warn=0) #==========================================================================================# #==========================================================================================# @@ -16,10 +18,16 @@ graphics.off() #----- Paths. -----------------------------------------------------------------------------# -main = "/n/moorcroftfs2/mlongo/EDBRAMS/final_ed/trop_southam/pve+sas" # Main path. -here = file.path(main,"sit_utils") # This path -srcdir = "/n/home00/mlongo/util/Rsc" # Source directory. -outroot = here # Directory for figures +main = "mypath" # Main path. +here = file.path(main,"sit_utils") # This path +srcdir = c( "/home/mlongo/Util/Rsc" # Possible paths with libraries + , "/Users/mlongo/Util/Rsc" # R will select the first + , "/prj/prjidfca/marcosl/Util/Rsc" # one that is found. + , "/prj/bramsolam/marcos.longo/Util/Rsc" # + , "/scratch/bramsolam/marcos.longo/Util/Rsc" # + , "/n/home00/mlongo/Util/Rsc" # + )#end c # +outroot = here # Directory for figures #------------------------------------------------------------------------------------------# @@ -38,22 +46,56 @@ mycheck = file.path(here,"mycheck.txt" ) #----- Plot options. ----------------------------------------------------------------------# -outform = c("png","eps","pdf") # Formats for output file. Supported formats are: - # - "X11" - for printing on screen - # - "eps" - for postscript printing - # - "png" - for PNG printing - # - "pdf" - for PDF printing -depth = 96 # PNG resolution, in pixels per inch -paper = "letter" # Paper size, to define the plot shape -ptsz = 14 # Font size. -lwidth = 2.5 # Line width -inset = 0.01 # inset between legend and edge of plot region. -fracexp = 0.40 # Expand the y axis by this amount. -ncolours = 20 # Number of colours to split the real variables -mtext.xoff = -8.50 # Offset for the x label -mtext.yoff = -1.00 # Offset for the y label -mtext.xadj = 0.50 # Offset for the x label -mtext.yadj = 0.65 # Offset for the y label +outform = c("png") # Formats for output file. Supported formats are: + # - "X11" - for printing on screen + # - "eps" - for postscript printing + # - "png" - for PNG printing + # - "pdf" - for PDF printing +depth = 96 # PNG resolution, in pixels per inch +paper = "letter" # Paper size, to define the plot shape +ptsz = 16 # Font size. +lwidth = 2.5 # Line width +inset = 0.01 # inset between legend and edge of plot region. +fracexp = 0.40 # Expand the y axis by this amount. +ncolours = 20 # Number of colours to split the real variables +st.leg = 1./5. +ey.leg = 1./6. +#------------------------------------------------------------------------------------------# + + +#------ List of variables to make the maps. -----------------------------------------------# +n = 0 +outvars = list() +n = n + 1 +outvars[[n]] = list( vnam = "lai" + , desc = "Leaf area index" + , unit = "m2lom2" + , csch = "pubugn" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "bsa" + , desc = "Basal area" + , unit = "cm2om2" + , csch = "bupu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "agb" + , desc = "Aboveground carbon" + , unit = "kgcom2" + , csch = "ylgnbu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "scb" + , desc = "Soil carbon" + , unit = "kgcom2" + , csch = "orrd" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "npa" + , desc = "Patch count" + , unit = "empty" + , csch = "magma" + )#end list #------------------------------------------------------------------------------------------# @@ -72,10 +114,18 @@ mtext.yadj = 0.65 # Offset for the y label #==========================================================================================# #==========================================================================================# +#----- Check that directory main has been set. --------------------------------------------# +if (! dir.exists(main)){ + cat (" Main: ",main,"\n") + stop(" Directory main is incorrect or has not been set!!!") +}#end if +#------------------------------------------------------------------------------------------# + #----- Loading some packages and scripts. -------------------------------------------------# +srcdir = (srcdir[file.exists(srcdir)])[1] source(file.path(srcdir,"load.everything.r")) #------------------------------------------------------------------------------------------# @@ -87,20 +137,16 @@ nout = length (outform) #------------------------------------------------------------------------------------------# -#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# -options(locatorBell=FALSE) -#------------------------------------------------------------------------------------------# - - -#----- Define plot window size ------------------------------------------------------------# -size = plotsize(proje=FALSE,paper=paper) +#----- Convert output var list to data table. ---------------------------------------------# +outvars = list.2.data.table(outvars) +noutvars = nrow(outvars) #------------------------------------------------------------------------------------------# #---- Create the main output directory in case there is none. -----------------------------# -if (! file.exists(outroot)) dir.create(outroot) +dummy = dir.create(outroot,recursive=TRUE,showWarnings=FALSE) #------------------------------------------------------------------------------------------# @@ -108,38 +154,131 @@ if (! file.exists(outroot)) dir.create(outroot) #------------------------------------------------------------------------------------------# # Read job order. We always use this file to build the array. # #------------------------------------------------------------------------------------------# -cat (" + Reading ",basename(joborder),"...","\n") -names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) -names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) -jobs = read.table(file=joborder,skip=3,header=FALSE,comment.char="" - ,stringsAsFactors=FALSE) -names(jobs) = names.jobs -njobs = nrow(jobs) +cat0(" + Read ",basename(joborder),".") +names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) +names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) +jobs = read.table(file = joborder + ,skip = 3 + ,header = FALSE + ,comment.char = "" + ,stringsAsFactors = FALSE + )#end read.table +names(jobs) = names.jobs +jobs = data.table(jobs) +njobs = nrow(jobs) #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# # Read the last and the current check. For the current check, we normally skip the # -# last line to avoid trouble, unless the file is complete. # -#------------------------------------------------------------------------------------------# -names.check = c("run","lon","lat","year","month","day","hhmm","runt" - ,"agb","bsa","lai","scb") -cat (" + Reading ",basename(lastcheck),"...","\n") -last = read.table(file=lastcheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -cat (" + Reading ",basename(mycheck),"...","\n") -ncurr = length(readLines(mycheck)) -if (ncurr == njobs){ - curr = read.table(file=mycheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -}else if (ncurr > 0){ - curr = read.table(file=mycheck,skip=0,nrows=ncurr-1,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) +# last line to avoid trouble, unless the file is complete. Sometimes one of the files # +# (typically last) may be missing. Account for that too. # +#------------------------------------------------------------------------------------------# +names.check = c("run","lon","lat","year","month","day","hhmm","stall","runt" + ,"agb","bsa","lai","scb","npa") +if (file.exists(lastcheck) && file.exists(mycheck)){ + #------ Both files exist, read both. ---------------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + curr = last[ 1,,drop=FALSE] + curr = curr[-1,,drop=FALSE] + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# +}else if(file.exists(lastcheck)){ + #------ Only lastcheck exists, duplicate it. -------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + #---------------------------------------------------------------------------------------# + + #---- Duplicate last. ------------------------------------------------------------------# + curr = last + #---------------------------------------------------------------------------------------# +}else if(file.exists(mycheck )){ + #------ Only mycheck exists. -----------------------------------------------------------# + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + #------ Nothing to read, stop the run. ----------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" Last check file not found and current check file is empty/almost empty!") + cat0(" Lastcheck: " ,lastcheck,".") + cat0(" Mycheck: " ,mycheck ,".") + cat0(" Line count in mycheck: ",ncurr ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #------------------------------------------------------------------------------------# + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# + + #---- Duplicate curr. ------------------------------------------------------------------# + last = curr + #---------------------------------------------------------------------------------------# }else{ - curr = data.frame(rep(NA,times=length(names.check)),names=names.check) - curr = curr[-1,] -}#end f + #------ Nothing to read, stop the run. -------------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" None of the check files was found!") + cat0(" Lastcheck: ",lastcheck,".") + cat0(" Mycheck: ",mycheck ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #---------------------------------------------------------------------------------------# +}#end if (file.exists(lastcheck) && file.exists(mycheck)) +#------------------------------------------------------------------------------------------# + + +#----- Turn data frames into data tables. -------------------------------------------------# +last = data.table(last) +curr = data.table(curr) #------------------------------------------------------------------------------------------# @@ -149,12 +288,12 @@ if (ncurr == njobs){ #------------------------------------------------------------------------------------------# # Find the dimensions. # #------------------------------------------------------------------------------------------# -lon = unique(sort(jobs$lon )) -lat = unique(sort(jobs$lat )) +lon = unique(sort(jobs$lon)) +lat = unique(sort(jobs$lat)) dlon = median(diff(lon)) dlat = median(diff(lat)) -n.lon = length(lon ) -n.lat = length(lat ) +n.lon = length(lon) +n.lat = length(lat) key.lon = sprintf("%+06.2f",lon) key.lat = sprintf("%+06.2f",lat) #------------------------------------------------------------------------------------------# @@ -165,31 +304,60 @@ key.lat = sprintf("%+06.2f",lat) #------------------------------------------------------------------------------------------# # Initialise the variables. # #------------------------------------------------------------------------------------------# -template = array( data = NA +r.template = array( data = NA_real_ , dim = c(n.lon,n.lat) , dimnames = list(key.lon,key.lat) )#end array -datum = list ( agb = template - , lai = template - , bsa = template - , scb = template - , status = template - , yearn = template +i.template = array( data = NA_integer_ + , dim = c(n.lon,n.lat) + , dimnames = list(key.lon,key.lat) + )#end array +datum = list ( agb = r.template + , lai = r.template + , bsa = r.template + , scb = r.template + , npa = i.template + , status = i.template + , yearn = i.template )#end list #------------------------------------------------------------------------------------------# +#----- Define plot window size ------------------------------------------------------------# +limlon = range(lon) +limlat = range(lat) +st.ext = st.leg / (1. - st.leg) +st.size = plotsize( proje = TRUE + , limlon = limlon + , limlat = limlat + , extendfc = "lat" + , extfactor = st.ext + , paper = paper + ) +ey.ext = ey.leg / (1. - ey.leg) +ey.size = plotsize( proje = TRUE + , limlon = limlon + , limlat = limlat + , extendfc = "lat" + , extfactor = ey.ext + , paper = paper + ) +#------------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------------# # Copy the information from last check to joborder. # #------------------------------------------------------------------------------------------# jobs$status = rep("INITIAL",times=njobs) jobs$yearn = jobs$yeara -jobs$agb = rep(NA,times=njobs) -jobs$bsa = rep(NA,times=njobs) -jobs$lai = rep(NA,times=njobs) -jobs$scb = rep(NA,times=njobs) +jobs$agb = rep(NA_real_ ,times=njobs) +jobs$bsa = rep(NA_real_ ,times=njobs) +jobs$lai = rep(NA_real_ ,times=njobs) +jobs$scb = rep(NA_real_ ,times=njobs) +jobs$npa = rep(NA_integer_,times=njobs) il = match(last$run,jobs$run); l.sel = ! is.na(il) ic = match(curr$run,jobs$run); c.sel = ! is.na(ic) @@ -198,17 +366,17 @@ jobs$agb [il[l.sel]] = last$agb [l.sel] ; jobs$agb [ic[c.sel]] = curr$agb [ jobs$lai [il[l.sel]] = last$lai [l.sel] ; jobs$lai [ic[c.sel]] = curr$lai [c.sel] jobs$bsa [il[l.sel]] = last$bsa [l.sel] ; jobs$bsa [ic[c.sel]] = curr$bsa [c.sel] jobs$scb [il[l.sel]] = last$scb [l.sel] ; jobs$scb [ic[c.sel]] = curr$scb [c.sel] +jobs$npa [il[l.sel]] = last$npa [l.sel] ; jobs$npa [ic[c.sel]] = curr$npa [c.sel] jobs$yearn [il[l.sel]] = last$year[l.sel] ; jobs$yearn [ic[c.sel]] = curr$year[c.sel] +#------------------------------------------------------------------------------------------# - -keep = names(jobs) %in% c("lon","lat","iata","yeara","yearz","yearn","status" - ,"agb","bsa","lai","scb") -jobs = jobs[,keep] -weird = is.finite(jobs$lai) & abs(jobs$lai) > 20 -jobs$lai[weird] = NA +#----- Select layers that are used for plotting. ------------------------------------------# +keep = names(jobs) %in% c("lon","lat","iata","yeara","yearz","yearn","status" + ,"agb","bsa","lai","scb","npa") +jobs = jobs[,..keep,drop=FALSE] #------------------------------------------------------------------------------------------# @@ -216,13 +384,14 @@ jobs$lai[weird] = NA #------------------------------------------------------------------------------------------# # Find the indices to map the data to the arrays. # #------------------------------------------------------------------------------------------# -i.lon = match(jobs$lon ,lon ) -i.lat = match(jobs$lat ,lat ) +i.lon = match(jobs$lon,lon) +i.lat = match(jobs$lat,lat) index = cbind(i.lon,i.lat) datum$agb [index] = jobs$agb datum$lai [index] = jobs$lai datum$bsa [index] = jobs$bsa datum$scb [index] = jobs$scb +datum$npa [index] = jobs$npa datum$status[index] = jobs$status datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# @@ -232,14 +401,16 @@ datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# # Run the matrices. # #------------------------------------------------------------------------------------------# -yr.range = range(c(jobs$yeara,jobs$yearz)) -yr.cut = pretty(yr.range,n=10) -yr.keep = yr.cut > yr.range[1] & yr.cut < yr.range[2] -yr.brks = c(-Inf,c(yr.range[1],yr.cut[yr.keep],yr.range[2])) -n.cut = length(yr.cut)-1 -yr.cut = cut(datum$yearn,yr.brks) -yr.level = levels(yr.cut) -n.level = length(yr.level) +yeara = min(jobs$yeara) +yearz = max(jobs$yearz) +yr.range = pretty.xylim(u=c(yeara,yearz)) +yr.brks = pretty(yr.range,n=10) +yr.keep = (yr.brks %wr% yr.range) & (! yr.brks %in% c(yeara,yearz)) +yr.brks = unique(c(-Inf,yr.brks[yr.keep],Inf)) +n.cut = length(yr.brks)-1 +yr.cut = cut(datum$yearn,yr.brks) +yr.level = levels(yr.cut) +n.level = length(yr.level) #------------------------------------------------------------------------------------------# @@ -248,6 +419,7 @@ n.level = length(yr.level) datum$yr.idx = match(yr.cut,yr.level) + 0 * datum$yearn initial = datum$status == "INITIAL" crashed = datum$status == "CRASHED" +hydfail = datum$status == "HYDFAIL" bad.met = datum$status == "BAD_MET" metmiss = datum$status == "METMISS" stopped = datum$status == "STOPPED" @@ -261,115 +433,124 @@ datum$yr.idx[extinct] = n.level + 3 datum$yr.idx[stopped] = n.level + 4 datum$yr.idx[metmiss] = n.level + 5 datum$yr.idx[bad.met] = n.level + 6 -datum$yr.idx[crashed] = n.level + 7 -yr.cscheme = c("grey89",iatlas(n=n.level),"royalblue4","steelblue3","purple3" - ,"mediumpurple1","deepskyblue","red3","hotpink") -ybottom = rep(0,times=n.level+8) -ytop = rep(1,times=n.level+8) -xleft = seq(from=-1,to=n.level+6) -xright = seq(from= 0,to=n.level+7) -xat = seq(from=-1,to=n.level+6)+0.5 -xbrks = seq(from=-1,to=n.level+7)+0.5 -xlabel = c("Initial",yr.brks[-1],"Finish","StState","Extinct" - ,"Stopped","MetMiss","Bad Met","Crashed") +datum$yr.idx[hydfail] = n.level + 7 +datum$yr.idx[crashed] = n.level + 8 +yr.cscheme = c("grey89",atlas(n=n.level),"royalblue4","steelblue3","purple3" + ,"mediumpurple1","deepskyblue","hotpink","red3","firebrick4") +ybottom = rep(0,times=n.level+9) +ytop = rep(1,times=n.level+9) +xleft = sequence(n.level+9) - 1 +xright = sequence(n.level+9) +xat = c(sequence(n.level+2)-1,n.level+sequence(8)+0.5) +xbrks = sequence(n.level+10)-1-0.5 +xlabel = c("Initial",yeara,yr.brks[-c(1,n.level+1)],yearz,"Finish","StState" + ,"Extinct","Stopped","MetMiss","Bad Met","HydFail","Crashed") #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# Limits for longitude and latitude. # +# Limits and labels for longitude and latitude. # #------------------------------------------------------------------------------------------# -limlon = c(min(lon)-0.5*dlon,max(lon)+0.5*dlon) -limlat = c(min(lat)-0.5*dlat,max(lat)+0.5*dlat) +limlon = c(min(lon)-0.5*dlon,max(lon)+0.5*dlon) +limlat = c(min(lat)-0.5*dlat,max(lat)+0.5*dlat) +lonplot = pretty.lonlat(x=limlon,n=6,type="lon") +latplot = pretty.lonlat(x=limlat,n=6,type="lat") #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# + + +#==========================================================================================# +#==========================================================================================# # Create the status map for all sites. # #------------------------------------------------------------------------------------------# -cat(" Plot the current status...","\n") - -#------ Make plot annotation. -------------------------------------------------------------# -letitre = paste("Polygon status") -#------------------------------------------------------------------------------------------# - -for (o in 1:nout){ - #----- Open file. ----------------------------------------------------------------------# - fichier = paste(here,"/stt_region.",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if +cat0(" Plot the current status.") + + #------ Make plot annotation. ----------------------------------------------------------# + letitre = "Polygon status" #---------------------------------------------------------------------------------------# + for (o in sequence(nout)){ + #----- Open file. -------------------------------------------------------------------# + fichier = file.path(here,paste0("stt_region.",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = st.size + , ptsz = ptsz + , depth = depth + )#end open.plot + #------------------------------------------------------------------------------------# - #----- Save the margins to avoid losing the data. --------------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar - #---------------------------------------------------------------------------------------# + #----- Load settings and split window. ----------------------------------------------# + par.orig = par(par.user) + #------------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------------# - # Split the plotting window. # - #---------------------------------------------------------------------------------------# - layout( mat = rbind(2,1) - , heights = c(3,1) - )#end layout - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # Split the plotting window. # + #------------------------------------------------------------------------------------# + layout(mat = rbind(2,1), heights = c(1.-st.leg,st.leg)) + #------------------------------------------------------------------------------------# - #---------------------------------------------------------------------------------------# - # First, let's plot the legend. # - #---------------------------------------------------------------------------------------# - par(mar=c(3,2,2,2)+0.1) - plot.new() - plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=yr.cscheme) - box() - axis(side=1,at=xat,srt=45,labels=FALSE) - text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=30,adj=1,xpd=TRUE,cex=1.00) - title(main="Status",ylab="",xlab="") - #---------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # First, let's plot the legend. # + #------------------------------------------------------------------------------------# + par(mar=c(3.1,3.1,1.1,1.1)) + plot.new() + plot.window( xlim = range(xleft,xright) + , ylim = range(ybottom,ytop) + , xaxs = "i" + , yaxs = "i" + )#end plot.window + rect( xleft = xleft + , ybottom = ybottom + , xright = xright + , ytop = ytop + , col = yr.cscheme + , border = "grey50" + )#end rect + box() + axis(side=1,at=xat,srt=45,labels=FALSE) + text(x=xat,y=par("usr")[3]-0.2,labels=xlabel,srt=45,adj=1,xpd=TRUE,cex=0.95) + title(main="Status",cex.main=1.0) + #------------------------------------------------------------------------------------# - #----- Set the window. -----------------------------------------------------------------# - par(mar = c(3.1,3.1,4.1,2.1)) - plot.new() - plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") - axis(side=1) - axis(side=2) - box() - title(main=letitre,xlab="",ylab="") - image(x=lon,y=lat,z=datum$yr.idx,col=yr.cscheme,breaks=xbrks,add=TRUE) - southammap() - #---------------------------------------------------------------------------------------# + #----- Set the window. --------------------------------------------------------------# + par(mar = c(2.1,3.1,1.1,1.1)) + plot.new() + plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") + axis(side=1,las=1,at=lonplot$at,labels=lonplot$labels) + axis(side=2,las=1,at=latplot$at,labels=latplot$labels) + box() + image( x = lon + , y = lat + , z = datum$yr.idx + , col = yr.cscheme + , breaks = xbrks + , add = TRUE + )#end image + southammap(col="grey30",lwd=1) + amazonmap (col="black" ,lwd=2) + #------------------------------------------------------------------------------------# - #----- Close the device. ---------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + + #----- Close the device. ------------------------------------------------------------# + dummy = close.plot(outform = outform[o]) + #------------------------------------------------------------------------------------# + }#end for (o in sequence(nout)) #---------------------------------------------------------------------------------------# -}#end for -#------------------------------------------------------------------------------------------# +#==========================================================================================# +#==========================================================================================# @@ -377,17 +558,21 @@ for (o in 1:nout){ #------------------------------------------------------------------------------------------# # Create parameter space maps for all other variables. # #------------------------------------------------------------------------------------------# -cat(" Plot the current properties...","\n") -key.var = c("lai","bsa","agb","scb") -desc.var = c("Leaf area index [m2/m2]","Basal area [cm2/m2]" - ,"Above-ground biomass [kgC/m2]","Soil carbon [kgC/m2]") -n.var = length(key.var) -for (v in 1:n.var){ - cat(" - ",desc.var[v],"...","\n") +cat0(" + Plot the current properties.") +for (v in sequence(noutvars)){ + #----- Handy aliases. ------------------------------------------------------------------# + v.vnam = outvars$vnam[v] + v.desc = outvars$desc[v] + v.unit = untab[[outvars$unit[v]]] + v.csch = match.fun(outvars$csch[v]) + cat0(" - ",v.desc,".") + #---------------------------------------------------------------------------------------# + + #----- Collapse realisations using the median. -----------------------------------------# - this.var = datum[[key.var[v]]] - rien = ! is.finite(this.var) - this.var[rien] = NA + v.value = datum[[v.vnam]] + del = ! is.finite(v.value) + v.value[del] = NA_real_ #---------------------------------------------------------------------------------------# @@ -395,55 +580,38 @@ for (v in 1:n.var){ #---------------------------------------------------------------------------------------# # Break the data into bins. # #---------------------------------------------------------------------------------------# - if (all(is.na(this.var))){ - var.brks = c(-1,0,1) - n.brks = length(var.brks) - var.cut = cut(as.numeric(this.var),breaks=var.brks) - }else{ - var.brks = pretty(this.var,n=ncolours) - n.brks = length(var.brks) - var.cut = cut(this.var,breaks=var.brks) - }#end if - var.lev = levels(var.cut) - var.idx = match(var.cut,var.lev) + 0 * this.var - var.cscheme = iatlas(n=n.brks-1) + v.limit = pretty.xylim(v.value) + v.brks = pretty(v.value,n=ncolours) + n.brks = length(v.brks) + v.cut = cut(as.numeric(v.value),breaks=v.brks) + v.lev = levels(v.cut) + v.idx = match(v.cut,v.lev) + 0 * v.value + v.cscheme = v.csch(n=n.brks-1) #---------------------------------------------------------------------------------------# #----- Make the edges. -----------------------------------------------------------------# - xleft = var.brks[-n.brks] - xright = var.brks[ -1] + xleft = v.brks[-n.brks] + xright = v.brks[ -1] ybottom = rep(0,times=n.brks) ytop = rep(1,times=n.brks) - xat = var.brks + xat = v.brks #---------------------------------------------------------------------------------------# - #------ Find the soil texture key and description. -------------------------------------# - letitre = paste(desc.var[v]) - #---------------------------------------------------------------------------------------# - for (o in 1:nout){ + #---------------------------------------------------------------------------------------# + # Loop through formats. # + #---------------------------------------------------------------------------------------# + for (o in sequence(nout)){ #----- Open file. -------------------------------------------------------------------# - fichier = paste(here,"/",key.var[v],"_region.",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if - #------------------------------------------------------------------------------------# - - - #----- Save the margins to avoid losing the data. -----------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar + fichier = file.path(here,paste0(v.vnam,"_region.",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = ey.size + , ptsz = ptsz + , depth = depth + )#end open.plot #------------------------------------------------------------------------------------# @@ -451,9 +619,8 @@ for (v in 1:n.var){ #------------------------------------------------------------------------------------# # Split the plotting window. # #------------------------------------------------------------------------------------# - layout( mat = rbind(2,1) - , heights = c(4,1) - )#end layout + par(par.user) + layout(mat=rbind(2,1),heights=c(1.-ey.leg,ey.leg)) #------------------------------------------------------------------------------------# @@ -461,41 +628,41 @@ for (v in 1:n.var){ #------------------------------------------------------------------------------------# # First, let's plot the legend. # #------------------------------------------------------------------------------------# - par(mar=c(3,3,2,2)+0.1) + par(mar=c(2.1,3.1,1.6,1.1)) plot.new() plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=var.cscheme) + rect( xleft = xleft + , ybottom = ybottom + , xright = xright + , ytop = ytop + , col = v.cscheme + , border = "transparent" + )#end rect box() axis(side=1,at=xat) - title(main=desc.var[v],xlab="",ylab="") + title(main=desc.unit(desc=v.desc,unit=v.unit),cex.main=1.0) #------------------------------------------------------------------------------------# #----- Set the window. --------------------------------------------------------------# - par(mar = c(3.1,3.1,4.1,2.1)) + par(mar = c(2.1,3.1,1.1,1.1)) plot.new() plot.window(xlim=limlon,ylim=limlat,xaxs="i",yaxs="i") - axis(side=1) - axis(side=2) + axis(side=1,las=1,at=lonplot$at,labels=lonplot$labels) + axis(side=2,las=1,at=latplot$at,labels=latplot$labels) box() - title(main=letitre,xlab="",ylab="") - image(x=lon,y=lat,z=this.var,col=var.cscheme,breaks=var.brks,add=TRUE) - southammap() + image(x=lon,y=lat,z=v.value,col=v.cscheme,breaks=v.brks,add=TRUE) + southammap(col="grey30",lwd=1) + amazonmap (col="black" ,lwd=2) #------------------------------------------------------------------------------------# #----- Close the device. ------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #------------------------------------------------------------------------------------# - }#end for + }#end for (o in sequence(nout)) #---------------------------------------------------------------------------------------# -}#end for +}#end for (v in sequence(noutvars)) #------------------------------------------------------------------------------------------# diff --git a/ED/Template/sit_utils/plot.status.r b/ED/Template/sit_utils/plot.status.r index e148cbc8f..9f0c9001d 100644 --- a/ED/Template/sit_utils/plot.status.r +++ b/ED/Template/sit_utils/plot.status.r @@ -16,11 +16,16 @@ graphics.off() #----- Paths. -----------------------------------------------------------------------------# -main = "/x/xxxxxxxxxxxx/xxxxxx/xxxxxxx/xxxxxxxx" # Main simulation directory. -here = file.path(main,"sit_utils") # This directory. - -srcdir = "/n/home00/mlongo/util/Rsc" # Source directory. -outroot = here # Directory for figures +main = "mypath" # Main path (one up sit_utils). +here = file.path(main,"sit_utils") # This path +srcdir = c( "/home/mlongo/Util/Rsc" # Possible paths with libraries + , "/Users/mlongo/Util/Rsc" # R will select the first + , "/prj/prjidfca/marcosl/Util/Rsc" # one that is found. + , "/prj/bramsolam/marcos.longo/Util/Rsc" # + , "/scratch/bramsolam/marcos.longo/Util/Rsc" # + , "/n/home00/mlongo/Util/Rsc" # + )#end c # +outroot = here # Directory for figures #------------------------------------------------------------------------------------------# @@ -58,6 +63,43 @@ mtext.yadj = 0.65 # Offset for the y label #------------------------------------------------------------------------------------------# +#------ List of variables to make the maps. -----------------------------------------------# +n = 0 +outvars = list() +n = n + 1 +outvars[[n]] = list( vnam = "lai" + , desc = "Leaf area index" + , unit = "m2lom2" + , csch = "pubugn" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "bsa" + , desc = "Basal area" + , unit = "cm2om2" + , csch = "bupu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "agb" + , desc = "Aboveground carbon" + , unit = "kgcom2" + , csch = "ylgnbu" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "scb" + , desc = "Soil carbon" + , unit = "kgcom2" + , csch = "orrd" + )#end list +n = n + 1 +outvars[[n]] = list( vnam = "npa" + , desc = "Patch count" + , unit = "empty" + , csch = "magma" + )#end list +#------------------------------------------------------------------------------------------# + + + #==========================================================================================# #==========================================================================================# @@ -74,28 +116,32 @@ mtext.yadj = 0.65 # Offset for the y label #==========================================================================================# #----- Check that directory main has been set. --------------------------------------------# -if ( main == "/x/xxxxxxxxxxxx/xxxxxx/xxxxxxx/xxxxxxxx"){ +if (! dir.exists(main)){ cat (" Main: ",main,"\n") - stop(" Directory main has not been set!!!") + stop(" Directory main is incorrect or has not been set!!!") }#end if #------------------------------------------------------------------------------------------# + #----- Loading some packages and scripts. -------------------------------------------------# +srcdir = (srcdir[file.exists(srcdir)])[1] source(file.path(srcdir,"load.everything.r")) #------------------------------------------------------------------------------------------# -#----- Set how many formats we must output. -----------------------------------------------# -outform = tolower(outform) -nout = length (outform) +#----- Convert output var list to data table. ---------------------------------------------# +outvars = list.2.data.table(outvars) +noutvars = nrow(outvars) #------------------------------------------------------------------------------------------# -#----- Avoid unecessary and extremely annoying beeps. -------------------------------------# -options(locatorBell=FALSE) + +#----- Set how many formats we must output. -----------------------------------------------# +outform = tolower(outform) +nout = length (outform) #------------------------------------------------------------------------------------------# @@ -107,7 +153,7 @@ size = plotsize(proje=FALSE,paper=paper) #---- Create the main output directory in case there is none. -----------------------------# -if (! file.exists(outroot)) dir.create(outroot) +dummy = dir.create(outroot,recursive=TRUE,showWarnings=FALSE) #------------------------------------------------------------------------------------------# @@ -115,7 +161,7 @@ if (! file.exists(outroot)) dir.create(outroot) #------------------------------------------------------------------------------------------# # Read job order. We always use this file to build the array. # #------------------------------------------------------------------------------------------# -cat (" + Reading ",basename(joborder),"...","\n") +cat0(" + Read ",basename(joborder),".") names.jobs = scan(file=joborder,skip=1,nlines=1,what="character",quiet=TRUE) names.jobs = gsub(pattern="_",replacement=".",x=tolower(names.jobs)) jobs = read.table(file=joborder,skip=3,header=FALSE,comment.char="" @@ -131,25 +177,113 @@ jobs$realisation = as.numeric(substring(jobs$run,23,24)) #------------------------------------------------------------------------------------------# # Read the last and the current check. For the current check, we normally skip the # -# last line to avoid trouble, unless the file is complete. # +# last line to avoid trouble, unless the file is complete. Sometimes one of the files # +# (typically last) may be missing. Account for that too. # #------------------------------------------------------------------------------------------# -names.check = c("run","lon","lat","year","month","day","hhmm","runt" +names.check = c("run","lon","lat","year","month","day","hhmm","stall","runt" ,"agb","bsa","lai","scb","npa") -cat (" + Reading ",basename(lastcheck),"...","\n") -last = read.table(file=lastcheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -cat (" + Reading ",basename(mycheck),"...","\n") -ncurr = length(readLines(mycheck)) -if (ncurr == njobs){ - curr = read.table(file=mycheck,skip=0,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) -}else if (ncurr > 0){ - curr = read.table(file=mycheck,skip=0,nrows=ncurr-1,header=FALSE,comment.char="" - ,col.names=names.check,stringsAsFactors=FALSE) +if (file.exists(lastcheck) && file.exists(mycheck)){ + #------ Both files exist, read both. ---------------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + curr = last[ 1,,drop=FALSE] + curr = curr[-1,,drop=FALSE] + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# +}else if(file.exists(lastcheck)){ + #------ Only lastcheck exists, duplicate it. -------------------------------------------# + cat0(" + Read ",basename(lastcheck),".") + last = read.table( file = lastcheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + #---------------------------------------------------------------------------------------# + + #---- Duplicate last. ------------------------------------------------------------------# + curr = last + #---------------------------------------------------------------------------------------# +}else if(file.exists(mycheck )){ + #------ Only mycheck exists. -----------------------------------------------------------# + cat0(" + Read ",basename(mycheck),".") + ncurr = length(readLines(mycheck)) + if (ncurr == njobs){ + curr = read.table( file = mycheck + , skip = 0 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else if (ncurr > 0){ + curr = read.table( file = mycheck + , skip = 0 + , nrows = ncurr-1 + , header = FALSE + , comment.char = "" + , col.names = names.check + , stringsAsFactors = FALSE + )#end read.table + }else{ + #------ Nothing to read, stop the run. ----------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" Last check file not found and current check file is empty/almost empty!") + cat0(" Lastcheck: " ,lastcheck,".") + cat0(" Mycheck: " ,mycheck ,".") + cat0(" Line count in mycheck: ",ncurr ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #------------------------------------------------------------------------------------# + }#end if (ncurr == njobs) + #---------------------------------------------------------------------------------------# + + #---- Duplicate curr. ------------------------------------------------------------------# + last = curr + #---------------------------------------------------------------------------------------# }else{ - curr = data.frame(rep(NA,times=length(names.check)),names=names.check) - curr = curr[-1,] -}#end f + #------ Nothing to read, stop the run. -------------------------------------------------# + cat0("-----------------------------------------------------------------------------") + cat0(" None of the check files was found!") + cat0(" Lastcheck: ",lastcheck,".") + cat0(" Mycheck: ",mycheck ,".") + cat0("-----------------------------------------------------------------------------") + stop(" At least one of these files must exist (ideally both of them).") + #---------------------------------------------------------------------------------------# +}#end if (file.exists(lastcheck) && file.exists(mycheck)) +#------------------------------------------------------------------------------------------# + + +#----- Turn data frames into data tables. -------------------------------------------------# +last = data.table(last) +curr = data.table(curr) #------------------------------------------------------------------------------------------# @@ -172,10 +306,10 @@ n.realisation = length(realisation) n.stext = length(stext ) n.iphen = length(iphen ) key.iata = toupper(iata ) -key.drain = paste("r" ,sprintf("%+3.3i",sort(100*unique(jobs$drain ))),sep="") -key.dtemp = paste("t" ,sprintf("%+3.3i",sort(100*unique(jobs$dtemp ))),sep="") -key.realisation = paste("real" ,sprintf("%2.2i" ,sort( unique(jobs$realisation))),sep="") -key.stext = paste("stext",sprintf("%2.2i" ,sort( unique(jobs$istext ))),sep="") +key.drain = paste0("r" ,sprintf("%+3.3i",sort(100*unique(jobs$drain )))) +key.dtemp = paste0("t" ,sprintf("%+3.3i",sort(100*unique(jobs$dtemp )))) +key.realisation = paste0("real" ,sprintf("%2.2i" ,sort( unique(jobs$realisation)))) +key.stext = paste0("stext",sprintf("%2.2i" ,sort( unique(jobs$istext )))) key.iphen = c("Evergreen","Deciduous") desc.iata = poilist$longname[match(iata,poilist$iata)] desc.stext = stext.names[stext] @@ -265,14 +399,16 @@ datum$yearn [index] = jobs$yearn #------------------------------------------------------------------------------------------# # Run the matrices. # #------------------------------------------------------------------------------------------# -yr.range = range(c(jobs$yeara,jobs$yearz)) -yr.cut = pretty(yr.range,n=10) -yr.keep = yr.cut > yr.range[1] & yr.cut < yr.range[2] -yr.brks = c(-Inf,c(yr.range[1],yr.cut[yr.keep],yr.range[2])) -n.cut = length(yr.cut)-1 -yr.cut = cut(datum$yearn,yr.brks) -yr.level = levels(yr.cut) -n.level = length(yr.level) +yeara = min(jobs$yeara) +yearz = max(jobs$yearz) +yr.range = pretty.xylim(u=c(yeara,yearz)) +yr.brks = pretty(yr.range,n=10) +yr.keep = (yr.brks %wr% yr.range) & (! yr.brks %in% c(yeara,yearz)) +yr.brks = unique(c(-Inf,yr.brks[yr.keep],Inf)) +n.cut = length(yr.brks)-1 +yr.cut = cut(datum$yearn,yr.brks) +yr.level = levels(yr.cut) +n.level = length(yr.level) #------------------------------------------------------------------------------------------# @@ -281,6 +417,7 @@ n.level = length(yr.level) datum$yr.idx = match(yr.cut,yr.level) + 0 * datum$yearn initial = datum$status == "INITIAL" crashed = datum$status == "CRASHED" +hydfail = datum$status == "HYDFAIL" bad.met = datum$status == "BAD_MET" metmiss = datum$status == "METMISS" stopped = datum$status == "STOPPED" @@ -294,17 +431,18 @@ datum$yr.idx[extinct] = n.level + 3 datum$yr.idx[stopped] = n.level + 4 datum$yr.idx[metmiss] = n.level + 5 datum$yr.idx[bad.met] = n.level + 6 -datum$yr.idx[crashed] = n.level + 7 -yr.cscheme = c("grey89",iatlas(n=n.level),"royalblue4","steelblue3","purple3" - ,"mediumpurple1","deepskyblue","red3","hotpink") -ybottom = rep(0,times=n.level+8) -ytop = rep(1,times=n.level+8) -xleft = seq(from=-1,to=n.level+6) -xright = seq(from= 0,to=n.level+7) -xat = seq(from=-1,to=n.level+6)+0.5 -xbrks = seq(from=-1,to=n.level+7)+0.5 -xlabel = c("Initial",yr.brks[-1],"Finish","StState","Extinct" - ,"Stopped","MetMiss","Bad Met","Crashed") +datum$yr.idx[hydfail] = n.level + 7 +datum$yr.idx[crashed] = n.level + 8 +yr.cscheme = c("grey89",atlas(n=n.level),"royalblue4","steelblue3","purple3" + ,"mediumpurple1","deepskyblue","hotpink","red3","firebrick4") +ybottom = rep(0,times=n.level+9) +ytop = rep(1,times=n.level+9) +xleft = sequence(n.level+9) - 1 +xright = sequence(n.level+9) +xat = c(sequence(n.level+2)-1,n.level+sequence(8)+0.5) +xbrks = sequence(n.level+10)-1-0.5 +xlabel = c("Initial",yeara,yr.brks[-c(1,n.level+1)],yearz,"Finish","StState" + ,"Extinct","Stopped","MetMiss","Bad Met","HydFail","Crashed") #------------------------------------------------------------------------------------------# @@ -326,9 +464,9 @@ use.yr.idx = apply( X = datum$yr.idx #------------------------------------------------------------------------------------------# # Create the status map for all sites. # #------------------------------------------------------------------------------------------# -cat(" Plot the current status...","\n") +cat0(" + lot the current status.") lo.box = pretty.box(n.iphen*n.iata) -for (st in 1:n.stext){ +for (st in sequence(n.stext)){ #------ Find the soil texture key and description. -------------------------------------# this.st.key = key.stext [st] letitre = paste("Polygon status -- Soil type: ",desc.stext[st] @@ -337,27 +475,20 @@ for (st in 1:n.stext){ ley = paste("Temperature change [K]") #---------------------------------------------------------------------------------------# - for (o in 1:nout){ + for (o in sequence(nout)){ #----- Open file. -------------------------------------------------------------------# - fichier = paste(here,"/stt_",this.st.key,".",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if + fichier = file.path(here,paste0("stt_",this.st.key,".",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = size + , ptsz = ptsz + , depth = depth + )#end open.plot #------------------------------------------------------------------------------------# #----- Save the margins to avoid losing the data. -----------------------------------# - par.orig = par(no.readonly = TRUE) - mar.orig = par.orig$mar + par(par.user) #------------------------------------------------------------------------------------# @@ -382,7 +513,7 @@ for (st in 1:n.stext){ rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=yr.cscheme) box() axis(side=1,at=xat,srt=45,labels=FALSE) - text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=30,adj=1,xpd=TRUE,cex=1.1) + text(x=xat,y=par("usr")[3]-0.6,labels=xlabel,srt=45,adj=1,xpd=TRUE,cex=0.95) title(main="Status",ylab="",xlab="") #------------------------------------------------------------------------------------# @@ -392,8 +523,8 @@ for (st in 1:n.stext){ # Now we loop over sites and pheonologies. # #------------------------------------------------------------------------------------# k = 0 - for (ph in 1:n.iphen){ - for (pl in 1:n.iata){ + for (ph in sequence(n.iphen)){ + for (pl in sequence(n.iata)){ #----- Make the sub-title. ----------------------------------------------------# lesub=paste(desc.iata[pl],desc.iphen[ph],sep=" - ") #------------------------------------------------------------------------------# @@ -443,13 +574,7 @@ for (st in 1:n.stext){ #----- Close the device. ------------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #------------------------------------------------------------------------------------# }#end for #---------------------------------------------------------------------------------------# @@ -462,22 +587,26 @@ for (st in 1:n.stext){ #------------------------------------------------------------------------------------------# # Create parameter space maps for all other variables. # #------------------------------------------------------------------------------------------# -cat(" Plot the current properties...","\n") -key.var = c("lai","bsa","agb","scb","npa") -desc.var = c("Leaf area index [m2/m2]","Basal area [cm2/m2]" - ,"Above-ground biomass [kgC/m2]","Soil carbon [kgC/m2]","Patch count [---]") -n.var = length(key.var) +cat0(" Plot the current properties.") lo.box = pretty.box(n.iphen*n.iata) -for (v in 1:n.var){ - cat(" - ",desc.var[v],"...","\n") +for (v in sequence(noutvars)){ + #----- Handy aliases. ------------------------------------------------------------------# + v.vnam = outvars$vnam[v] + v.desc = outvars$desc[v] + v.unit = untab[[outvars$unit[v]]] + v.csch = match.fun(outvars$csch[v]) + cat0(" - ",v.desc,".") + #---------------------------------------------------------------------------------------# + + #----- Collapse realisations using the median. -----------------------------------------# - this.var = apply( X = datum[[key.var[v]]] - , MARGIN = c(1,2,4,5,6) - , FUN = median - , na.rm = TRUE - )#end apply - rien = ! is.finite(this.var) - this.var[rien] = NA + v.value = apply( X = datum[[v.vnam]] + , MARGIN = c(1,2,4,5,6) + , FUN = median + , na.rm = TRUE + )#end apply + rien = ! is.finite(v.value) + v.value[rien] = NA #---------------------------------------------------------------------------------------# @@ -485,18 +614,13 @@ for (v in 1:n.var){ #---------------------------------------------------------------------------------------# # Break the data into bins. # #---------------------------------------------------------------------------------------# - if (all(is.na(this.var))){ - var.brks = c(-1,0,1) - n.brks = length(var.brks) - var.cut = cut(as.numeric(this.var),breaks=var.brks) - }else{ - var.brks = pretty(this.var,n=ncolours) - n.brks = length(var.brks) - var.cut = cut(this.var,breaks=var.brks) - }#end if - var.lev = levels(var.cut) - var.idx = match(var.cut,var.lev) + 0 * this.var - var.cscheme = iatlas(n=n.brks-1) + v.limit = pretty.xylim(v.value) + v.brks = pretty(v.value,n=ncolours) + n.brks = length(v.brks) + v.cut = cut(as.numeric(v.value),breaks=v.brks) + v.lev = levels(v.cut) + v.idx = match(v.cut,v.lev) + 0 * v.value + v.cscheme = v.csch(n=n.brks-1) #---------------------------------------------------------------------------------------# @@ -505,33 +629,27 @@ for (v in 1:n.var){ xright = var.brks[ -1] ybottom = rep(0,times=n.brks) ytop = rep(1,times=n.brks) - xat = var.brks + xat = v.brks #---------------------------------------------------------------------------------------# - for (st in 1:n.stext){ + for (st in sequence(n.stext)){ #------ Find the soil texture key and description. ----------------------------------# this.st.key = key.stext [st] - letitre = paste(desc.var[v]," -- Soil type: ",desc.stext[st],sep="") - lex = paste("Rainfall change [scale parameter]") - ley = paste("Temperature change [K]") + letitre = paste0(desc.var[v]," -- Soil type: ",desc.stext[st]) + lex = paste0("Rainfall change [scale parameter]") + ley = paste0("Temperature change [K]") #------------------------------------------------------------------------------------# - for (o in 1:nout){ + for (o in sequence(nout)){ #----- Open file. ----------------------------------------------------------------# - fichier = paste(here,"/",key.var[v],"_",this.st.key,".",outform[o],sep="") - if(outform[o] == "x11"){ - X11(width=size$width,height=size$height,pointsize=ptsz) - }else if(outform[o] == "png"){ - png(filename=fichier,width=size$width*depth,height=size$height*depth - ,pointsize=ptsz,res=depth) - }else if(outform[o] == "eps"){ - postscript(file=fichier,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }else if(outform[o] == "pdf"){ - pdf(file=fichier,onefile=FALSE,width=size$width,height=size$height - ,pointsize=ptsz,paper=size$paper) - }#end if + fichier = file.path(here,paste0(key.var[v],"_",this.st.key,".",outform[o])) + dummy = open.plot( fichier = fichier + , outform = outform[o] + , size = size + , ptsz = ptsz + , depth = depth + )#end open.plot #---------------------------------------------------------------------------------# @@ -559,10 +677,10 @@ for (v in 1:n.var){ par(mar=c(3,3,2,3)+0.1) plot.new() plot.window(xlim=range(xleft,xright),ylim=range(ybottom,ytop),xaxs="i",yaxs="i") - rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=var.cscheme) + rect(xleft=xleft,ybottom=ybottom,xright=xright,ytop=ytop,col=v.cscheme) box() axis(side=1,at=xat) - title(main=desc.var[v],xlab="",ylab="") + title(main=desc.unit(desc=v.desc,unit=v.unit),cex.main=1.0) #---------------------------------------------------------------------------------# @@ -571,8 +689,8 @@ for (v in 1:n.var){ # Now we loop over sites and pheonologies. # #---------------------------------------------------------------------------------# k = 0 - for (ph in 1:n.iphen){ - for (pl in 1:n.iata){ + for (ph in sequence(n.iphen)){ + for (pl in sequence(n.iata)){ #----- Make the sub-title. -------------------------------------------------# lesub=paste(desc.iata[pl],desc.iphen[ph],sep=" - ") #---------------------------------------------------------------------------# @@ -600,7 +718,7 @@ for (v in 1:n.var){ #----- Set the window. -----------------------------------------------------# par(mar = mar.now) - image(x=drain,y=dtemp,z=this.var[,,ph,pl,st],col=var.cscheme + image(x=drain,y=dtemp,z=v.value[,,ph,pl,st],col=v.cscheme ,breaks=var.brks,xaxt=xaxt,yaxt=yaxt,main=lesub,xlab="",ylab="") #---------------------------------------------------------------------------# }#end for @@ -622,17 +740,11 @@ for (v in 1:n.var){ #----- Close the device. ---------------------------------------------------------# - if (outform[o] == "x11"){ - locator(n=1) - dev.off() - }else{ - dev.off() - }#end if - bye = clean.tmp() + dummy = close.plot(outform=outform[o]) #---------------------------------------------------------------------------------# - }#end for + }#end for (o in sequence(nout)) #------------------------------------------------------------------------------------# - }#end for + }#end for (st in sequence(n.stext)) #---------------------------------------------------------------------------------------# -}#end for +}#end for (v in sequence(noutvars)) #------------------------------------------------------------------------------------------# diff --git a/ED/build/make/include.mk.cannon b/ED/build/make/include.mk.cannon index 256b13d3f..4e28cf388 100644 --- a/ED/build/make/include.mk.cannon +++ b/ED/build/make/include.mk.cannon @@ -103,12 +103,12 @@ ifeq ($(KIND_COMP),B) F_OPTS= -FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ - -warn interfaces -warn declarations -qopenmp -diag-error=all -static + -warn interfaces -warn declarations -warn errors -qopenmp -static C_OPTS= -O0 -DLITTLE -g -traceback -qopenmp -static LOADER_OPTS=-FR -O0 -recursive -check all,noarg_temp_created -g -debug extended \ -debug-parameters all -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check \ -implicitnone -assume byterecl -warn unused -warn uncalled -warn usage \ - -warn interfaces -warn declarations -qopenmp -diag-error=all + -warn interfaces -warn declarations -warn errors -qopenmp #---------------------------------------------------------------------------------------# endif ifeq ($(KIND_COMP),C) diff --git a/ED/build/make/include.mk.docker b/ED/build/make/include.mk.docker index 1ad2869eb..d3e40b250 100644 --- a/ED/build/make/include.mk.docker +++ b/ED/build/make/include.mk.docker @@ -27,13 +27,17 @@ USE_MPIWTIME=1 # gfortran CMACH=PC_LINUX1 -F_COMP=mpif90 +FC_TYPE=GNU +# F_COMP=mpif90 +F_COMP=gfortran F_OPTS=-O3 -ffree-line-length-none -fno-whole-file -C_COMP=mpicc +# C_COMP=mpicc +C_COMP=gcc C_OPTS=-O3 -LOADER=mpif90 +# LOADER=mpif90 +LOADER=gfortran LOADER_OPTS=${F_OPTS} -C_LOADER=mpicc +# C_LOADER=mpicc # C_LOADER is obsolete and can be removed LIBS= MOD_EXT=mod @@ -41,7 +45,8 @@ MOD_EXT=mod MPI_PATH= PAR_INCS= PAR_LIBS= -PAR_DEFS=-DRAMS_MPI +# PAR_DEFS=-DRAMS_MPI +PAR_DEFS= # For IBM,HP,SGI,ALPHA,LINUX use these: ARCHIVE=ar rs diff --git a/ED/build/make/include.mk.macosx b/ED/build/make/include.mk.macosx index 69ed3365c..054f1e11b 100644 --- a/ED/build/make/include.mk.macosx +++ b/ED/build/make/include.mk.macosx @@ -5,7 +5,7 @@ #----- Define make (gnu make works best). -------------------------------------------------# -MAKE=/usr/bin/make +MAKE=/usr/local/bin/make #------------------------------------------------------------------------------------------# #----- Libraries. -------------------------------------------------------------------------# @@ -20,8 +20,8 @@ BASE=$(ED_ROOT)/build/ # libraries compiled with the same compiler you set for F_COMP and C_COMP. You may still # # be able to compile without HDF5 but it will not run. # #------------------------------------------------------------------------------------------# -ZLIB_PATH=/Users/mlongo/Util/ED2_Libs/zlib-1.2.11 -HDF5_PATH=/Users/mlongo/Util/ED2_Libs/hdf5-1.10.2 +ZLIB_PATH=/usr/local +HDF5_PATH=/usr/local HDF5_INCS=-I$(HDF5_PATH)/include HDF5C_INCS=$(HDF5_INCS) HDF5_LIBS=-L$(ZLIB_PATH)/lib -lz -L$(HDF5_PATH)/lib -lhdf5_fortran -lhdf5 -lhdf5_hl @@ -51,10 +51,9 @@ USE_INTERF=1 #################################### COMPILER SETTINGS ##################################### CMACH=MAC_OS_X FC_TYPE=GNU -F_COMP=gfortran -C_COMP=gcc -LOADER=gfortran -C_LOADER=gcc +F_COMP=/usr/local/bin/gfortran-14 +C_COMP=/usr/local/bin/gcc-14 +LOADER=/usr/local/bin/gfortran-14 LIBS= MOD_EXT=mod ############################################################################################ @@ -88,20 +87,17 @@ endif ifeq ($(KIND_COMP),A) F_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ - -fcheck=all -frecursive -fsignaling-nans -Werror -mmacosx-version-min=10.12 \ - -fopenmp -static - C_OPTS= -O0 -DLITTLE -g -static + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace -static + C_OPTS= -O0 -DLITTLE -g -fbacktrace -static LOADER_OPTS= -O0 -ffree-line-length-none -g -fimplicit-none -Wall -finit-real=snan \ -finit-integer=-2147483648 -ffpe-trap=invalid,zero,overflow,underflow \ - -fcheck=all -frecursive -fsignaling-nans -Werror \ - -mmacosx-version-min=10.12 -fopenmp + -fcheck=all -frecursive -fsignaling-nans -Werror -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif ifeq ($(KIND_COMP),E) - F_OPTS= -O3 -ffree-line-length-none -frecursive -mmacosx-version-min=10.12 -fopenmp \ - -static - C_OPTS= -O0 -DLITTLE -g -static - LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -mmacosx-version-min=10.12 -fopenmp + F_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace -static + C_OPTS= -O3 -DLITTLE -g -fbacktrace -static + LOADER_OPTS= -O3 -ffree-line-length-none -frecursive -fopenmp -fbacktrace #---------------------------------------------------------------------------------------# endif #------------------------------------------------------------------------------------------# diff --git a/ED/build/make/objects.mk b/ED/build/make/objects.mk index 51ce5faa7..2eaa696c6 100644 --- a/ED/build/make/objects.mk +++ b/ED/build/make/objects.mk @@ -51,6 +51,7 @@ OBJ_MODEL = \ ed_print.o \ ed_read_ed10_20_history.o \ ed_read_ed21_history.o \ + ed_read_ed22_initial.o \ ed_state_vars.o \ ed_therm_lib.o \ ed_type_init.o \ diff --git a/ED/build/make/rules.mk b/ED/build/make/rules.mk index 4a88bb0eb..c0c03b7e0 100644 --- a/ED/build/make/rules.mk +++ b/ED/build/make/rules.mk @@ -208,6 +208,11 @@ ed_read_ed21_history.o : $(ED_IO)/ed_read_ed21_history.f90 /bin/cp -f $< $( /dev/null +sed -i~ s@mpi.mod@@g dependency.mk sed -i~ s@hdf5.mod@@g dependency.mk sed -i~ s@ifport.mod@@g dependency.mk sed -i~ s@leaf.coms.mod@@g dependency.mk diff --git a/ED/run/ED2IN b/ED/run/ED2IN index 11f752ea3..5a2b56cdc 100644 --- a/ED/run/ED2IN +++ b/ED/run/ED2IN @@ -412,7 +412,7 @@ $ED_NL ! /mypath/P1000-S-1687-01-01-000000-g01.h5: ! ! SFILIN = '/mypath/P' ! ! ! - ! 6 - Initialize with ED-2 style files without multiple sites, exactly like option ! + ! 6. Initialize with ED-2 style files without multiple sites, similar to option ! ! 2, except that the PFT types are preserved. ! ! ! ! 7. Initialize from a list of both POI and gridded ED2.1 state files, organized ! @@ -420,6 +420,10 @@ $ED_NL ! takes the soil texture and soil moisture information from the initializing ! ! ED2.1 state file. It allows for different layering, and assigns via nearest ! ! neighbor. ! + ! ! + ! 8. Initialise ED-2.2 style files with multiple sites that may vary in soil depth, ! + ! texture, and other properties (e.g., colour, pH, cation exchange capacity) but ! + ! without forcing TOPMODEL. ! !---------------------------------------------------------------------------------------! NL%IED_INIT_MODE = 6 !---------------------------------------------------------------------------------------! @@ -728,14 +732,17 @@ $ED_NL !---------------------------------------------------------------------------------------! ! ISOILBC -- This controls the soil moisture boundary condition at the bottom. Choose ! ! the option according to the site characteristics. ! - ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! - ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! + ! -1. Hybrid. If the depth to bedrock is shorter than the deepest layer, use ! + ! flat bedrock, otherwise assume free drainage. This option is more ! + ! relevant when initialising ED2 with multiple sites per polygon. ! + ! 0. Flat bedrock. Flux from the bottom of the bottommost layer is zero. ! + ! 1. Gravitational flow (free drainage). The flux from the bottom of the ! ! bottommost layer is due to gradient of height only. ! - ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! + ! 2. Lateral drainage. Similar to free drainage, but the gradient is ! ! reduced by the slope not being completely vertical. The reduction is ! ! controlled by variable SLDRAIN. In the future options 0, 1, and 2 may ! ! be combined into a single option. ! - ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! + ! 3. Aquifer. Soil moisture of the ficticious layer beneath the bottom is ! ! always at saturation. ! !---------------------------------------------------------------------------------------! NL%ISOILBC = 1 @@ -895,18 +902,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! - ! equations depend on wood density; (b) use leaf area based allometry ! - ! instead of leaf biomass based allometry, which is more compatible with ! - ! trait plasticity in SLA; (c) use height-based root allometry from ! - ! Smith-Martin et al. (2020, New Phyt.) ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 3 !---------------------------------------------------------------------------------------! @@ -976,12 +984,19 @@ $ED_NL ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! + ! ! ! 4: (Beta). ! ! grasses - drought-deciduous (hydraulics scheme); ! ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! diff --git a/ED/src/driver/ed_1st.F90 b/ED/src/driver/ed_1st.F90 index e2d3acd3b..38a5219c3 100644 --- a/ED/src/driver/ed_1st.F90 +++ b/ED/src/driver/ed_1st.F90 @@ -22,13 +22,12 @@ subroutine ed_1st_master (ipara, nnodestotal,nslaves, headnode_num, max_threads, use ed_misc_coms , only : runtype ! ! intent(inout) use ed_state_vars, only : allocate_edglobals & ! subroutine , filltab_alltypes ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: ipara ! 0 if sequential run; 1 if parallel run integer , intent(in) :: nnodestotal ! total number of nodes on any run @@ -176,10 +175,12 @@ end subroutine ed_1st_master !------------------------------------------------------------------------------------------! subroutine ed_1st_node() use ed_mem_alloc, only : ed_memory_allocation ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Pre-compiled variables from MPI. ------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' !----- Local variable (MPI only). ------------------------------------------------------! integer :: ierr #endif diff --git a/ED/src/driver/ed_driver.F90 b/ED/src/driver/ed_driver.F90 index 1c7ff8724..d13c6927e 100644 --- a/ED/src/driver/ed_driver.F90 +++ b/ED/src/driver/ed_driver.F90 @@ -21,13 +21,19 @@ subroutine ed_driver() use ed_state_vars , only : allocate_edglobals & ! sub-routine , filltab_alltypes & ! sub-routine , edgrid_g ! ! intent(inout) - use ed_misc_coms , only : runtype & ! intent(in) - , iooutput ! ! intent(in) + use ed_misc_coms , only : dtlsm & ! intent(in) + , runtype & ! intent(in) + , current_time & ! intent(in) + , isoutput & ! intent(in) + , iooutput & ! intent(in) + , fmtrest & ! intent(in) + , restore_file ! ! intent(in) use soil_coms , only : alloc_soilgrid ! ! sub-routine use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : recvnum ! ! intent(in) #endif use detailed_coms , only : idetailed & ! intent(in) @@ -36,11 +42,8 @@ subroutine ed_driver() use hrzshade_utils , only : init_cci_variables ! ! subroutine use canopy_radiation_coms, only : ihrzrad ! ! intent(in) use random_utils , only : init_random_seed ! ! subroutine + use budget_utils , only : ed_init_budget ! ! subroutine implicit none - !----- Included variables. -------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' ! MPI commons -#endif !----- Local variables. ----------------------------------------------------------------! character(len=12) :: c0 character(len=12) :: c1 @@ -157,14 +160,6 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Allocate soil grid arrays. ! - !---------------------------------------------------------------------------------------! - if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Alloc_Soilgrid...' - call alloc_soilgrid() - !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! ! Set some polygon-level basic information, such as lon/lat/soil texture. ! @@ -176,16 +171,14 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Initialize inherent soil and vegetation properties. ! - !---------------------------------------------------------------------------------------! - if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Sfcdata_ED...' - call sfcdata_ed() + ! Decide whether to initialise ED2 or resume from history files. Note that the ! + ! order of operations will depend upon the run type. If we resume from HISTORY, we ! + ! must read the history first then allocate soil data (as they will be read from the ! + ! history file itself). Otherwise, we allocate and initialise soils, then read/assign ! + ! the initial conditions. ! !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - if (trim(runtype) == 'HISTORY' ) then + select case (trim(runtype)) + case ('HISTORY') !------------------------------------------------------------------------------------! ! Initialize the model state as a replicate image of a previous state. ! !------------------------------------------------------------------------------------! @@ -210,7 +203,26 @@ subroutine ed_driver() if (nnodetot /= 1 ) call MPI_Barrier(MPI_COMM_WORLD,ierr) #endif !------------------------------------------------------------------------------------! - else + + + case default + !------------------------------------------------------------------------------------! + ! Allocate soil grid arrays. ! + !------------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Alloc_Soilgrid...' + call alloc_soilgrid() + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Initialise variables that are related to soil layers. ! + !------------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Sfcdata_ED...' + call sfcdata_ed() + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Initialize state properties of polygons/sites/patches/cohorts. ! @@ -218,7 +230,9 @@ subroutine ed_driver() if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [+] Load_Ecosystem_State...' call load_ecosystem_state() !------------------------------------------------------------------------------------! - end if + end select + !---------------------------------------------------------------------------------------! + !---------------------------------------------------------------------------------------! ! In case the runs is going to produce detailed output, we eliminate all patches ! @@ -291,27 +305,29 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Initialise some derived variables. Skip this in case the simulation is resuming ! + ! Bypass the initialisation of derived variables and phenology when initialising ED2 ! ! from HISTORY. ! !---------------------------------------------------------------------------------------! - if (trim(runtype) /= 'HISTORY' ) then + select case (trim(runtype)) + case ('HISTORY') + !---- Do nothing. -------------------------------------------------------------------! + continue + !------------------------------------------------------------------------------------! + case default + !---- Initialise some derived variables. --------------------------------------------! do ifm=1,ngrids call update_derived_props(edgrid_g(ifm)) end do - end if - !---------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Initialise drought phenology. This should be done after the soil moisture has ! - ! been set up. ! - !---------------------------------------------------------------------------------------! - if (runtype /= 'HISTORY') then + !---- Initialise drought phenology. -------------------------------------------------! do ifm=1,ngrids call first_phenology(edgrid_g(ifm)) end do - end if + !------------------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------------------! @@ -359,26 +375,86 @@ subroutine ed_driver() !---------------------------------------------------------------------------------------! - ! Get the CPU time and print the banner. ! - !---------------------------------------------------------------------------------------! - call timing(1,t1) - w2 = walltime(wtime_start) - if (mynum == nnodetot) then - write(c0,'(f12.2)') t1 - write(c1,'(f12.2)') w2-w1 - write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & - trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & - '; Time integration starts (ed_master) ===' - end if + ! STEP 14. Run the model or skip if it is a zero time run. In case this is a zero time ! + ! run, write the history file and the flag for restoring the run (this can ! + ! be useful for model initialisation with large number of patches in the input ! + ! file. In this case, one may need to request substantially more memory for ! + ! initialisation (but a single CPU as initialisation does not benefit from ! + ! shared-memory parallel processing), then runs can be re-submitted with less ! + ! memory demand but more CPUs, hence reducing impacts on fairshare scores. ! !---------------------------------------------------------------------------------------! + if (time < timmax) then + !------------------------------------------------------------------------------------! + ! Get the CPU time and print the banner. ! + !------------------------------------------------------------------------------------! + call timing(1,t1) + w2 = walltime(wtime_start) + if (mynum == nnodetot) then + write(c0,'(f12.2)') t1 + write(c1,'(f12.2)') w2-w1 + write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & + trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & + '; Time integration starts (ed_model) ===' + end if + !------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! STEP 14. Run the model or skip if it is a zero time run. ! - !---------------------------------------------------------------------------------------! - if (time < timmax) then + !----- Call the time step driver. ---------------------------------------------------! call ed_model() + !------------------------------------------------------------------------------------! + else if ((timmax < dtlsm) .and. (isoutput /= 0)) then + !----- Write the zero-time output only if the run type is 'INITIAL'. ----------------! + select case (trim(runtype)) + case ('INITIAL') + + !---------------------------------------------------------------------------------! + ! We must reset all budget fluxes and set all budget stocks before writing ! + ! the history file. This is needed because when we resume ED2 runs from history ! + ! files, all budget variables are read from history instead of being initialised. ! + !---------------------------------------------------------------------------------! + if (mynum == nnodetot) write(unit=*,fmt='(a)') ' [+] ED_Init_Budget.' + do ifm=1,ngrids + call ed_init_budget(edgrid_g(ifm),.true.) + end do + !---------------------------------------------------------------------------------! + + + !----- Write the output file. ----------------------------------------------------! + call h5_output('HIST') + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Write a file with the current history time. ! + !---------------------------------------------------------------------------------! + if (mynum == nnodetot) then + open (unit=18,file=trim(restore_file),form='formatted',status='replace' & + ,action='write') + write(unit=18,fmt=fmtrest) current_time%year,current_time%month & + ,current_time%date,current_time%hour & + ,current_time%min + close(unit=18,status='keep') + end if + !------------------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Get the CPU time and print the banner. ! + !------------------------------------------------------------------------------------! + call timing(1,t1) + w2 = walltime(wtime_start) + if (mynum == nnodetot) then + write(c0,'(f12.2)') t1 + write(c1,'(f12.2)') w2-w1 + write(unit=*,fmt='(/,a,/)') ' === Finish initialization; CPU(sec)='// & + trim(adjustl(c0))//'; Wall(sec)='//trim(adjustl(c1))// & + ' ===' + end if + !------------------------------------------------------------------------------------! end if !---------------------------------------------------------------------------------------! @@ -544,6 +620,9 @@ subroutine exterminate_patches_except(keeppa) , patchtype ! ! structure use grid_coms , only : ngrids ! ! intent(in) use fuse_fiss_utils, only : terminate_patches ! ! sub-routine + + implicit none + !----- Arguments -----------------------------------------------------------------------! integer , intent(in) :: keeppa !----- Local variables -----------------------------------------------------------------! diff --git a/ED/src/driver/ed_met_driver.f90 b/ED/src/driver/ed_met_driver.f90 index e6fb7449a..a5e6d6628 100644 --- a/ED/src/driver/ed_met_driver.f90 +++ b/ED/src/driver/ed_met_driver.f90 @@ -345,6 +345,8 @@ subroutine read_met_drivers_init type(edtype) , pointer :: cgrid character(len=str_len) :: infile integer :: igr + integer :: year_cyc + integer :: year_cyc_2 integer :: year_use integer :: iformat integer :: iv @@ -526,9 +528,18 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------------! ! We now retrieve the met driver year based on the stored sequence. ! !------------------------------------------------------------------------------------! - iyear = current_time%year-iyeara+1 - year_use = metyears(iyear) - + !----- If we need to recycle over years, find the appropriate year to apply. --------! + year_cyc = current_time%year + ncyc = metcycf - metcyc1 + 1 + !----- If we are after the last year... ---------------------------------------------! + do while(year_cyc > metcycf) + year_cyc = year_cyc - ncyc + end do + !----- If we are before the first year... -------------------------------------------! + do while(year_cyc < metcyc1) + year_cyc = year_cyc + ncyc + end do + !------------------------------------------------------------------------------------! gridloop: do igr = 1,ngrids @@ -536,7 +547,7 @@ subroutine read_met_drivers_init !----- Loop over the different file formats --------------------------------------! formloop: do iformat = 1, nformats - + !------------------------------------------------------------------------------! ! SPECIAL CASE FOR CO2: ! ! Usually we do not want to cycle CO2 but only the other meteorology. ! @@ -545,8 +556,30 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------! not_cycle_co2 = (met_nv(iformat) == 1 .and. trim(met_vars(iformat,1)) == 'co2') if (not_cycle_co2) then - year_use = current_time%year - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),current_time%year & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use = current_time%year + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use = year_cyc + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use = year_cyc + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + !----- Create the file name and check whether it exists. ----------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use & ,mname(current_time%month),'.h5' @@ -555,10 +588,17 @@ subroutine read_met_drivers_init call shdf5_open_f(trim(infile),'R') else write (unit=*,fmt='(a)' ) '------------------------------' - write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 - write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf - write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear - write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - NYEARS =',nyears + write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers_init','ed_met_driver.f90') @@ -573,7 +613,7 @@ subroutine read_met_drivers_init !----- Loop over variables. and read the data. --------------------------------! do iv = 1, met_nv(iformat) offset = 0 - call read_ol_file(infile,iformat, iv, mname(current_time%month) & + call read_ol_file(infile,iformat, iv, mname(current_time%month) & ,current_time%year, offset, cgrid) end do @@ -584,27 +624,61 @@ subroutine read_met_drivers_init !------------------------------------------------------------------------------! ! For all interpolated variables, we also need the next time. ! !------------------------------------------------------------------------------! - !------ Find next month and year ----------------------------------------------! - m2 = current_time%month + 1 - + !------------------------------------------------------------------------------! - ! If this takes us into the next year, take the next year in sequence and ! - ! reset month to January. ! + ! Find next month and year. If this takes us into the next year, increment ! + ! year and reset month to January. ! !------------------------------------------------------------------------------! - if (m2 == 13) then - m2 = 1 - y2 = current_time%year + 1 - else - !----- Otherwise, use the same year. ---------------------------------------! - y2 = current_time%year - end if - iyear = y2 - iyeara + 1 - year_use_2 = metyears(iyear) - - ! Again consider the special case of not cycling co2 + m2 = current_time%month + 1 + select case (m2) + case (13) + m2 = 1 + y2 = current_time%year + 1 + year_cyc_2 = y2 + + !----- If we are now after the last year... --------------------------------! + do while(year_cyc_2 > metcycf) + year_cyc_2 = year_cyc_2 - ncyc + end do + !---------------------------------------------------------------------------! + + !----- If we are now before the first year... ------------------------------! + do while(year_cyc_2 < metcyc1) + year_cyc_2 = year_cyc_2 + ncyc + end do + !---------------------------------------------------------------------------! + case default + !---- Same year as the previous month. -------------------------------------! + y2 = current_time%year + year_cyc_2 = year_cyc + !---------------------------------------------------------------------------! + end select + + !------------------------------------------------------------------------------# + ! Again consider the special case of not cycling co2 + !------------------------------------------------------------------------------# if (not_cycle_co2) then - year_use_2 = y2 - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),y2,mname(m2),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use_2 = y2 + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use_2 = year_cyc_2 + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use_2 = year_cyc_2 + !---------------------------------------------------------------------------! + end if !----- Now, open the file once. -----------------------------------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use_2 & ,mname(m2),'.h5' @@ -612,10 +686,26 @@ subroutine read_met_drivers_init if (exans) then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - NYEARS =',nyears + write (unit=*,fmt='(a,1x,i12)') ' - IYEAR =',iyear + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CYC_2 =',m2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC_2 =',year_cyc_2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE_2 =',year_use_2 + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers_init','ed_met_driver.f90') end if - + !----- Loop over variables. ---------------------------------------------------! varloop: do iv = 1, met_nv(iformat) @@ -674,6 +764,8 @@ subroutine read_met_drivers type(edtype) , pointer :: cgrid character(len=str_len) :: infile integer :: igr + integer :: year_cyc + integer :: year_cyc_2 integer :: year_use integer :: ncyc integer :: iformat @@ -694,17 +786,17 @@ subroutine read_met_drivers !----- If we need to recycle over years, find the appropriate year to apply. --------! - year_use = current_time%year - ncyc = metcycf - metcyc1 + 1 + year_cyc = current_time%year + ncyc = metcycf - metcyc1 + 1 !----- If we are after the last year... ---------------------------------------------! - do while(year_use > metcycf) - year_use = year_use - ncyc + do while(year_cyc > metcycf) + year_cyc = year_cyc - ncyc end do !----- If we are before the first year... -------------------------------------------! - do while(year_use < metcyc1) - year_use = year_use + ncyc + do while(year_cyc < metcyc1) + year_cyc = year_cyc + ncyc end do gridloop: do igr=1,ngrids @@ -713,7 +805,7 @@ subroutine read_met_drivers !----- Loop over the different file formats --------------------------------------! formloop: do iformat = 1, nformats - + !------------------------------------------------------------------------------! ! SPECIAL CASE FOR CO2: ! ! Usually we do not want to cycle CO2 but only the other meteorology. ! @@ -722,8 +814,32 @@ subroutine read_met_drivers !------------------------------------------------------------------------------! not_cycle_co2 = (met_nv(iformat) == 1 .and. trim(met_vars(iformat,1)) == 'co2') if (not_cycle_co2) then - year_use = current_time%year - endif + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),current_time%year & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use = current_time%year + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use = year_cyc + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use = year_cyc + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Create the file name and check whether it exists. ----------------------! write(infile,'(a,i4.4,a,a)')trim(met_names(iformat)), year_use, & mname(current_time%month),'.h5' @@ -732,6 +848,17 @@ subroutine read_met_drivers if(exans)then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers','ed_met_driver.f90') end if @@ -766,37 +893,63 @@ subroutine read_met_drivers !------------------------------------------------------------------------------! ! For all interpolated variables, we also need the next time. ! !------------------------------------------------------------------------------! - !------ Find next month and year ----------------------------------------------! - m2 = current_time%month + 1 - y2 = current_time%year - year_use_2 = year_use - - + !------------------------------------------------------------------------------! - ! If this takes us into the next year, increment year and reset month to ! - ! January. ! + ! Find next month and year. If this takes us into the next year, increment ! + ! year and reset month to January. ! !------------------------------------------------------------------------------! - if(m2 == 13)then + m2 = current_time%month + 1 + select case (m2) + case (13) m2 = 1 y2 = current_time%year + 1 - year_use_2 = y2 + year_cyc_2 = y2 !----- If we are now after the last year... --------------------------------! - do while(year_use_2 > metcycf) - year_use_2 = year_use_2 - ncyc + do while(year_cyc_2 > metcycf) + year_cyc_2 = year_cyc_2 - ncyc end do - + !---------------------------------------------------------------------------! + !----- If we are now before the first year... ------------------------------! - do while(year_use_2 < metcyc1) - year_use_2 = year_use_2 + ncyc + do while(year_cyc_2 < metcyc1) + year_cyc_2 = year_cyc_2 + ncyc end do - end if + !---------------------------------------------------------------------------! + case default + !---- Same year as the previous month. -------------------------------------! + y2 = current_time%year + year_cyc_2 = year_cyc + !---------------------------------------------------------------------------! + end select - ! Again, consider the special case for not_cycle_co2 + !---- Again, consider the special case for not_cycle_co2. ---------------------! if (not_cycle_co2) then - year_use_2 = y2 - endif - + !---------------------------------------------------------------------------! + ! Make sure that the special CO2 file exists. If not, then use the ! + ! default met cycle years. ! + !---------------------------------------------------------------------------! + write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)),y2 & + ,mname(current_time%month),'.h5' + inquire(file=trim(infile),exist=exans) + if (exans) then + !----- Allow CO2 outside met cycle. -------------------------------------! + year_use_2 = y2 + !------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. -----------! + year_use_2 = year_cyc_2 + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + else + !----- Typical case. Pool data from the meteorological cycle. --------------! + year_use_2 = year_cyc_2 + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + !----- Now, open the file once. -----------------------------------------------! write(infile,fmt='(a,i4.4,a,a)') trim(met_names(iformat)), year_use_2 & ,mname(m2),'.h5' @@ -804,6 +957,20 @@ subroutine read_met_drivers if (exans) then call shdf5_open_f(trim(infile),'R') else + write (unit=*,fmt='(a)' ) '------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' - MET_VARS =',trim(met_vars(iformat,1)) + write (unit=*,fmt='(a,1x,l1)' ) ' - CYCLE_CO2 =',.not. not_cycle_co2 + write (unit=*,fmt='(a,1x,i12)') ' - METCYC1 =',metcyc1 + write (unit=*,fmt='(a,1x,i12)') ' - METCYCF =',metcycf + write (unit=*,fmt='(a,1x,i12)') ' - NCYC =',ncyc + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CURR =',current_time%month + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CURR =',current_time%year + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC =',year_cyc + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE =',year_use + write (unit=*,fmt='(a,1x,i12)') ' - MONTH_CYC_2 =',m2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_CYC_2 =',year_cyc_2 + write (unit=*,fmt='(a,1x,i12)') ' - YEAR_USE_2 =',year_use_2 + write (unit=*,fmt='(a)' ) '------------------------------' call fatal_error ('Cannot open met driver input file '//trim(infile)//'!' & ,'read_met_drivers','ed_met_driver.f90') end if diff --git a/ED/src/driver/ed_model.F90 b/ED/src/driver/ed_model.F90 index 77cc8f9d0..b82e35782 100644 --- a/ED/src/driver/ed_model.F90 +++ b/ED/src/driver/ed_model.F90 @@ -11,6 +11,7 @@ !------------------------------------------------------------------------------------------! subroutine ed_model() use ed_misc_coms , only : simtime & ! structure + , fmtrest & ! intent(in) , ivegt_dynamics & ! intent(in) , integration_scheme & ! intent(in) , current_time & ! intent(in) @@ -90,15 +91,14 @@ subroutine ed_model() , initialize_misc_stepvars ! ! sub-routine use stable_cohorts , only : flag_stable_cohorts ! ! sub-routine use update_derived_utils, only : update_model_time_dm ! ! sub-routine - use budget_utils , only : ed_init_budget ! ! intent(in) + use budget_utils , only : ed_init_budget ! ! sub-routine use vegetation_dynamics , only : veg_dynamics_driver ! ! sub-routine use ed_type_init , only : ed_init_viable ! ! sub-routine use soil_respiration , only : zero_litter_inputs ! ! sub-routine - implicit none - !----- Common blocks. ------------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! type(simtime) :: daybefore character(len=28) :: fmthead @@ -108,6 +108,7 @@ subroutine ed_model() integer :: ndays integer :: dbndays integer :: obstime_idx + logical :: last_step logical :: analysis_time logical :: observation_time logical :: new_day @@ -141,8 +142,6 @@ subroutine ed_model() ! during synchronization, so you ! can find out which node is the ! slow one - !----- String for output format. -------------------------------------------------------! - character(len=26), parameter :: fmtrest = '(i4.4,2(1x,i2.2),1x,2i2.2)' !----- External functions. -------------------------------------------------------------! real , external :: walltime ! Wall time integer , external :: num_days ! Number of days in the current month @@ -374,6 +373,7 @@ subroutine ed_model() dcyc_analy_time = new_month .and. writing_dcyc reset_time = mod(time,dble(frqsum)) < dble(dtlsm) annual_time = new_year .and. writing_year + last_step = time >= timmax !------------------------------------------------------------------------------------! @@ -434,6 +434,14 @@ subroutine ed_model() !------------------------------------------------------------------------------------! + !------------------------------------------------------------------------------------! + ! If this is the last step, write the history even if it is not the a typical ! + ! time step to write history. ! + !------------------------------------------------------------------------------------! + history_time = history_time .or. last_step + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Update nrec_fast and nrec_state if it is a new month and outfast/outstate are ! diff --git a/ED/src/driver/edmain.F90 b/ED/src/driver/edmain.F90 index 53995bf4a..7be848c37 100644 --- a/ED/src/driver/edmain.F90 +++ b/ED/src/driver/edmain.F90 @@ -14,6 +14,9 @@ !------------------------------------------------------------------------------------------! program main !$ use omp_lib +#if defined(RAMS_MPI) + use mpi +#endif implicit none !---------------------------------------------------------------------------------------! @@ -49,10 +52,6 @@ program main integer, dimension(64) :: thread_use integer, dimension(64) :: cpu_use integer, external :: findmycpu - !------ MPI interface. -----------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/disturbance.f90 b/ED/src/dynamics/disturbance.f90 index f1dc10627..ad9e35eab 100644 --- a/ED/src/dynamics/disturbance.f90 +++ b/ED/src/dynamics/disturbance.f90 @@ -830,9 +830,9 @@ subroutine apply_disturbances(cgrid) ! canopy air temperature. ! !------------------------------------------------------------------------! call update_patch_thermo_props(csite,onsp+new_lu,onsp+new_lu,nzg,nzs & - ,cpoly%ntext_soil(:,isi)) + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi)) call update_patch_thermo_fmean(csite,onsp+new_lu,onsp+new_lu,nzg & - ,cpoly%ntext_soil(:,isi)) + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi)) !------------------------------------------------------------------------! @@ -1563,7 +1563,7 @@ subroutine site_disturbance_rates(year, cgrid) !---------------------------------------------------------------------------! case default !------ Read anthropogenic disturbance from external data set. -------------! - if (clutime%landuse(12) < 0 .or. clutime%landuse(14) < 0) then + if (clutime%landuse(12) < 0. .or. clutime%landuse(14) < 0.) then find_target = .true. cpoly%primary_harvest_target (isi) = 0. cpoly%secondary_harvest_target(isi) = 0. @@ -2265,6 +2265,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%fmean_sfcw_mass (np) = csite%fmean_sfcw_mass (np) & + csite%fmean_sfcw_mass (cp) & * area_fac + csite%fmean_snowfac (np) = csite%fmean_snowfac (np) & + + csite%fmean_snowfac (cp) & + * area_fac csite%fmean_rshort_gnd (np) = csite%fmean_rshort_gnd (np) & + csite%fmean_rshort_gnd (cp) & * area_fac @@ -2487,6 +2490,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%dmean_sfcw_fliq ( np) = csite%dmean_sfcw_fliq ( np) & + csite%dmean_sfcw_fliq ( cp) & * area_fac + csite%dmean_snowfac ( np) = csite%dmean_snowfac ( np) & + + csite%dmean_snowfac ( cp) & + * area_fac csite%dmean_rshort_gnd ( np) = csite%dmean_rshort_gnd ( np) & + csite%dmean_rshort_gnd ( cp) & * area_fac @@ -2770,6 +2776,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%mmean_sfcw_fliq ( np) = csite%mmean_sfcw_fliq ( np) & + csite%mmean_sfcw_fliq ( cp) & * area_fac + csite%mmean_snowfac ( np) = csite%mmean_snowfac ( np) & + + csite%mmean_snowfac ( cp) & + * area_fac csite%mmean_rshort_gnd ( np) = csite%mmean_rshort_gnd ( np) & + csite%mmean_rshort_gnd ( cp) & * area_fac @@ -3065,6 +3074,9 @@ subroutine increment_patch_vars(csite,np,cp,area_fac,cb_enthalpy,can_exner,cb_ma csite%qmean_sfcw_fliq ( :,np) = csite%qmean_sfcw_fliq ( :,np) & + csite%qmean_sfcw_fliq ( :,cp) & * area_fac + csite%qmean_snowfac ( :,np) = csite%qmean_snowfac ( :,np) & + + csite%qmean_snowfac ( :,cp) & + * area_fac csite%qmean_soil_energy (:,:,np) = csite%qmean_soil_energy (:,:,np) & + csite%qmean_soil_energy (:,:,cp) & * area_fac @@ -4098,7 +4110,8 @@ subroutine prune_lianas(csite, np, lsl) , h2dbh & ! function , size2bl & ! function , size2bd & ! function - , size2krdepth ! ! function + , size2krdepth & ! function + , distrib_root ! ! subroutine use pft_coms, only : qsw & ! intent(in) , qbark & ! intent(in) , agf_bs & ! intent(in) @@ -4222,6 +4235,13 @@ subroutine prune_lianas(csite, np, lsl) !----- Update rooting depth ---------------------------------------------------! cpatch%krdepth(ico) = size2krdepth(cpatch%hite(ico),cpatch%dbh(ico),ipft,lsl) !if new root depth is smaller keep the old one + !------------------------------------------------------------------------------! + + + !----- Update the vertical distribution of roots. -----------------------------! + call distrib_root(cpatch%krdepth(ico),ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------! + !------------------------------------------------------------------------------! ! It is likely that biomass has changed, therefore, update ! diff --git a/ED/src/dynamics/euler_driver.f90 b/ED/src/dynamics/euler_driver.f90 index 416104399..ebfb5719d 100644 --- a/ED/src/dynamics/euler_driver.f90 +++ b/ED/src/dynamics/euler_driver.f90 @@ -19,6 +19,7 @@ subroutine euler_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use ed_max_dims , only : n_dbh ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function @@ -76,6 +77,7 @@ subroutine euler_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !------------------------------------------------------------------------------------! @@ -84,6 +86,31 @@ subroutine euler_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -97,22 +124,22 @@ subroutine euler_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar & - ,cmet%atm_theiv,cmet%atm_vpdef,cmet%atm_theta & - ,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2,cmet%geoht & - ,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & - ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & - ,cgrid%lat(ipy),cgrid%cosz(ipy)) + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & + ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -220,7 +247,8 @@ subroutine euler_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! @@ -432,8 +460,8 @@ subroutine integrate_patch_euler(csite,initp,dinitp,ytemp,yscal,dydx,ipa,isi,ibu !------------------------------------------------------------------------------------! ! Move the state variables from the integrated patch to the model patch. ! !------------------------------------------------------------------------------------! - call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm,ecurr_netrad & - ,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & + call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm & + ,ecurr_netrad,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & ,ecurr_loss2drainage,wcurr_loss2runoff,ecurr_loss2runoff & ,co2curr_denseffect,ecurr_denseffect,wcurr_denseffect) !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/events.f90 b/ED/src/dynamics/events.f90 index df3437763..80a454c83 100644 --- a/ED/src/dynamics/events.f90 +++ b/ED/src/dynamics/events.f90 @@ -509,6 +509,7 @@ end subroutine event_harvest subroutine event_planting(pft,density8) use rk4_integ_utils, only : initialize_rk4patches use update_derived_utils, only : update_patch_thermo_props & + , update_patch_thermo_fmean & , update_patch_derived_props & , update_site_derived_props use grid_coms, only : ngrids,nzg,nzs @@ -553,8 +554,11 @@ subroutine event_planting(pft,density8) csite => cpoly%site(isi) do ipa=1,csite%npatches - call update_patch_thermo_props(csite,ipa,ipa,nzg,nzs,cpoly%ntext_soil(:,isi)) - call plant_patch(csite,ipa,nzg,pft,density,cpoly%ntext_soil(:,isi) & + call update_patch_thermo_props(csite,ipa,ipa,nzg,nzs,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi)) + call update_patch_thermo_fmean(csite,ipa,ipa,nzg,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi)) + call plant_patch(csite,ipa,nzg,pft,density,cpoly%ntext_soil(:,isi) & ,planting_ht,cpoly%lsl(isi)) call update_patch_derived_props(csite,ipa,.true.) call new_patch_sfc_props(csite, ipa,nzg,nzs,cpoly%ntext_soil(:,isi)) diff --git a/ED/src/dynamics/farq_katul.f90 b/ED/src/dynamics/farq_katul.f90 index 529d34a04..0e184f0b1 100644 --- a/ED/src/dynamics/farq_katul.f90 +++ b/ED/src/dynamics/farq_katul.f90 @@ -247,9 +247,6 @@ subroutine katul_lphys(ib,can_prss,can_rhos,can_shv,can_co2,ipft,leaf_par,leaf_t !update photosynthetic parameters with water stress select case (h2o_plant_lim) - case (0,1,2,3) - ! use fsw to account for water stress in photosyn_driv - water_stress_factor = 1. case (4) ! leaf water potential will influence stomata optimization ! at two different scales @@ -268,6 +265,9 @@ subroutine katul_lphys(ib,can_prss,can_rhos,can_shv,can_co2,ipft,leaf_par,leaf_t 1. / (1. + & 0.1 * (leaf_psi / leaf_psi_tlp(ipft)) ** 6.0))) lambda8 = lambda8 * dble(exp(stoma_beta(ipft) * dmax_leaf_psi)) + case default + ! use fsw to account for water stress in photosyn_driv + water_stress_factor = 1. end select !thispft(ib)%vm0 = thispft(ib)%vm0 * dble(water_stress_factor) @@ -848,8 +848,8 @@ subroutine photosynthesis_stomata_solver8(ib,gsc,limit_case, real(kind=8) :: k1,k2 !! Variable used in photosynthesis equation real(kind=8) :: a,b,c !! Coefficients of the quadratic equation to solve ci real(kind=8) :: rad !! sqrt(b2-4ac) - real(kind=8) :: dbdg,dcdg !! derivatives of b,c wrt. gsc - + real(kind=8) :: dbdg !! derivatives of b wrt. gsc + real(kind=8) :: dcdg !! derivatives of c wrt. gsc !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/fire.f90 b/ED/src/dynamics/fire.f90 index 0df3bcbf3..b93c9703e 100644 --- a/ED/src/dynamics/fire.f90 +++ b/ED/src/dynamics/fire.f90 @@ -62,7 +62,7 @@ subroutine fire_frequency(cgrid) real :: fuel real :: ignition_rate real :: mean_fire_intensity - real :: sum_pcpg + real :: sum_accp logical :: people_around !------------------------------------------------------------------------------------! @@ -97,8 +97,8 @@ subroutine fire_frequency(cgrid) ! Find the total rainfall of the past year and reset the counter for this ! ! month. ! !------------------------------------------------------------------------------! - sum_pcpg = sum(cpoly%avg_monthly_pcpg(:,isi)) - cpoly%avg_monthly_pcpg(imon,isi) = 0. + sum_accp = sum(cpoly%avg_monthly_accp(:,isi)) + cpoly%avg_monthly_accp(imon,isi) = 0. !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/forestry.f90 b/ED/src/dynamics/forestry.f90 index 320513cbf..39a27c12a 100644 --- a/ED/src/dynamics/forestry.f90 +++ b/ED/src/dynamics/forestry.f90 @@ -142,6 +142,10 @@ subroutine find_lambda_harvest(cpoly,isi,onsp,lambda_harvest) ! croplands and pastures. ! !---------------------------------------------------------------------------------! select case(ilu) + case (1,8) + !---- Pasture or cropland. Do nothing. ----------------------------------------! + continue + !------------------------------------------------------------------------------! case (2:7) hcoh_loop: do ico=1,cpatch%ncohorts ipft = cpatch%pft(ico) diff --git a/ED/src/dynamics/growth_balive.f90 b/ED/src/dynamics/growth_balive.f90 index e9c66af96..b4309bb59 100644 --- a/ED/src/dynamics/growth_balive.f90 +++ b/ED/src/dynamics/growth_balive.f90 @@ -1379,46 +1379,49 @@ subroutine get_c_xfers(csite,ipa,ico,npp_actual,green_leaf_factor,gr_tfact0 ! net growth (i.e. increment from the value of btissue before ! ! maintenance was applied) is the same every day. ! !------------------------------------------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. (.not. (is_grass(ipft) .and. igrass == 1)) ) then - if (delta_bleaf >= tiny_num) then - gtf_bleaf = ( cpatch%leaf_maintenance(ico) & - + gr_tfact0 * (delta_bleaf - cpatch%leaf_maintenance(ico)) ) & - / delta_bleaf - else - gtf_bleaf = gr_tfact0 - end if - if (delta_broot >= tiny_num) then - gtf_broot = ( cpatch%root_maintenance(ico) & - + gr_tfact0 * (delta_broot - cpatch%root_maintenance(ico)) ) & - / delta_broot - else - gtf_broot = gr_tfact0 - end if - if (delta_bbarka >= tiny_num) then - gtf_bbarka = ( cpatch%barka_maintenance(ico) & - + gr_tfact0 & - * (delta_bbarka - cpatch%barka_maintenance(ico)) ) & - / delta_bbarka - else - gtf_bbarka = gr_tfact0 - end if - if (delta_bbarkb >= tiny_num) then - gtf_bbarkb = ( cpatch%barkb_maintenance(ico) & - + gr_tfact0 & - * (delta_bbarkb - cpatch%barkb_maintenance(ico)) ) & - / delta_bbarkb - else - gtf_bbarkb = gr_tfact0 + select case (iallom) + case (3,4,5) + if (.not. (is_grass(ipft) .and. igrass == 1) ) then + if (delta_bleaf >= tiny_num) then + gtf_bleaf = ( cpatch%leaf_maintenance(ico) & + + gr_tfact0 * (delta_bleaf-cpatch%leaf_maintenance(ico))) & + / delta_bleaf + else + gtf_bleaf = gr_tfact0 + end if + if (delta_broot >= tiny_num) then + gtf_broot = ( cpatch%root_maintenance(ico) & + + gr_tfact0 * (delta_broot-cpatch%root_maintenance(ico))) & + / delta_broot + else + gtf_broot = gr_tfact0 + end if + if (delta_bbarka >= tiny_num) then + gtf_bbarka = ( cpatch%barka_maintenance(ico) & + + gr_tfact0 & + * (delta_bbarka - cpatch%barka_maintenance(ico)) ) & + / delta_bbarka + else + gtf_bbarka = gr_tfact0 + end if + if (delta_bbarkb >= tiny_num) then + gtf_bbarkb = ( cpatch%barkb_maintenance(ico) & + + gr_tfact0 & + * (delta_bbarkb - cpatch%barkb_maintenance(ico)) ) & + / delta_bbarkb + else + gtf_bbarkb = gr_tfact0 + end if + !----- Correct deltas based on the time of the month and turnover. ------! + delta_bleaf = delta_bleaf * gtf_bleaf + delta_broot = delta_broot * gtf_broot + delta_bsapwooda = delta_bsapwooda * gr_tfact0 ! sapwood turnover is zero. + delta_bsapwoodb = delta_bsapwoodb * gr_tfact0 ! sapwood turnover is zero. + delta_bbarka = delta_bbarka * gtf_bbarka + delta_bbarkb = delta_bbarkb * gtf_bbarkb end if - !----- Correct deltas based on the time of the month and turnover. ---------! - delta_bleaf = delta_bleaf * gtf_bleaf - delta_broot = delta_broot * gtf_broot - delta_bsapwooda = delta_bsapwooda * gr_tfact0 ! sapwood turnover is zero. - delta_bsapwoodb = delta_bsapwoodb * gr_tfact0 ! sapwood turnover is zero. - delta_bbarka = delta_bbarka * gtf_bbarka - delta_bbarkb = delta_bbarkb * gtf_bbarkb - end if + !---------------------------------------------------------------------------! + end select !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/heun_driver.f90 b/ED/src/dynamics/heun_driver.f90 index c3c9631b6..19f727337 100644 --- a/ED/src/dynamics/heun_driver.f90 +++ b/ED/src/dynamics/heun_driver.f90 @@ -22,6 +22,7 @@ subroutine heun_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use ed_max_dims , only : n_dbh ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function @@ -78,6 +79,7 @@ subroutine heun_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !------------------------------------------------------------------------------------! @@ -85,6 +87,31 @@ subroutine heun_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -98,19 +125,20 @@ subroutine heun_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2 & - ,cmet%geoht,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -218,7 +246,8 @@ subroutine heun_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! diff --git a/ED/src/dynamics/hybrid_driver.f90 b/ED/src/dynamics/hybrid_driver.f90 index 7aaf1d59f..f1cdb6880 100644 --- a/ED/src/dynamics/hybrid_driver.f90 +++ b/ED/src/dynamics/hybrid_driver.f90 @@ -26,6 +26,7 @@ subroutine hybrid_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function use soil_respiration , only : soil_respiration_driver ! ! function @@ -84,6 +85,7 @@ subroutine hybrid_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -----------------------------------------------! logical , parameter :: test_energy_sanity = .false. !----- External functions. --------------------------------------------! @@ -93,6 +95,31 @@ subroutine hybrid_timestep(cgrid) polyloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + wtime0=walltime(0.) siteloop: do isi = 1,cpoly%nsites @@ -107,22 +134,19 @@ subroutine hybrid_timestep(cgrid) ! Update the monthly rainfall. ! !---------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !---------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv & - ,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv & - ,cmet%atm_co2,cmet%geoht,cmet%exner & - ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss & - ,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam & - ,cmet%nir_diffuse,cmet%geoht & - ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & - ,cpoly%green_leaf_factor(:,isi) & - ,cgrid%lon(ipy),cgrid%lat(ipy) & - ,cgrid%cosz(ipy)) + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & + ,cgrid%lat(ipy),cgrid%cosz(ipy)) @@ -230,7 +254,8 @@ subroutine hybrid_timestep(cgrid) ! placed before canopy_photosynthesis because plant_hydro_driver ! ! needs fs_open from previous timestep. ! !------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi) & + ,cpoly%ntext_soil(:,isi),site_isoilbc) !------------------------------------------------------------------! diff --git a/ED/src/dynamics/phenology_aux.f90 b/ED/src/dynamics/phenology_aux.f90 index a8abed4f4..f91e30ae5 100644 --- a/ED/src/dynamics/phenology_aux.f90 +++ b/ED/src/dynamics/phenology_aux.f90 @@ -288,7 +288,7 @@ subroutine update_turnover(cpoly, isi) !------------------------------------------------------------------------------------! sitepft_loop: do ipft=1,n_pft select case (phenology(ipft)) - case (3) + case (3,6) !------ The actual turnover amplitude is based on a running average. ----------! cpoly%turnover_amp(isi) = (1.0 - turnamp_wgt) * cpoly%turnover_amp(isi) & + turnamp_wgt * turnamp_now @@ -414,7 +414,7 @@ subroutine update_turnover(cpoly, isi) ! -modulated. ! !------------------------------------------------------------------------------! select case (phenology(ipft)) - case (3) + case (3,6) !----- Update the data set. ------------------------------------------------! cpatch%llspan(ico) = cpatch%llspan (ico) & * cpoly%llspan_toc(ipft,isi) / llspan_toc_in(ipft) diff --git a/ED/src/dynamics/phenology_driv.f90 b/ED/src/dynamics/phenology_driv.f90 index c4c6322c2..a5bfbf3f1 100644 --- a/ED/src/dynamics/phenology_driv.f90 +++ b/ED/src/dynamics/phenology_driv.f90 @@ -46,31 +46,51 @@ subroutine phenology_driver(cgrid, doy, month, tfact,veget_dyn_on) do ipa = 1,csite%npatches csite%avg_daily_temp(ipa) = csite%avg_daily_temp(ipa) * tfact end do - + select case (iphen_scheme) - case (-1,0,2) + case (1) !---------------------------------------------------------------------------! - ! Default predictive scheme (Botta et al.) or the modified drought ! - ! deciduous phenology for broadleaf PFTs. ! + ! Use prescribed phenology (M09). ! + ! ! + ! Medvigy DM, Wofsy SC, Munger JW, Hollinger DY , Moorcroft PR. 2009. ! + ! Mechanistic scaling of ecosystem function and dynamics in space and ! + ! time: Ecosystem demography model version 2. J. Geophys. ! + ! Res.-Biogeosci., 114: G01002. doi:10.1029/2008JG000812 (M09). ! !---------------------------------------------------------------------------! - call update_thermal_sums(month, cpoly, isi, cgrid%lat(ipy)) - call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) - - case (1) - !----- Use prescribed phenology. -------------------------------------------! call prescribed_leaf_state(cgrid%lat(ipy), current_time%month & ,current_time%year, doy & ,cpoly%green_leaf_factor(:,isi) & ,cpoly%leaf_aging_factor(:,isi) & ,cpoly%phen_pars(isi) ) call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) + !---------------------------------------------------------------------------! - - case (3,4) - !----- Light-controlled predictive phenology scheme. -----------------------! + case default + !---------------------------------------------------------------------------! + ! Default predictive scheme (B00), the modified drought deciduous ! + ! phenology for broadleaf PFTs (L19), or the light-controlled predictive ! + ! phenology scheme (K12). ! + ! ! + ! Botta A, Viovy N, Ciais P, Friedlingstein P , Monfray P. 2000. A global ! + ! prognostic scheme of leaf onset using satellite data. Glob. Change ! + ! Biol., 6: 709-725. doi:10.1046/j.1365-2486.2000.00362.x (2000). ! + ! ! + ! Kim Y, Knox RG, Longo M, Medvigy D, Hutyra LR, Pyle EH, Wofsy SC, ! + ! Bras RL, Moorcroft PR. 2012. Seasonal carbon dynamics and water fluxes ! + ! in an Amazon rainforest. Glob. Change Biol., 18: 1322-1334. ! + ! doi:10.1111/j.1365-2486.2011.02629.x (K12). ! + ! ! + ! Longo M, Knox RG, Medvigy DM, Levine NM, Dietze MC, Kim Y, Swann ALS, ! + ! Zhang K, Rollinson CR, Bras RL et al. 2019. The biophysics, ecology, ! + ! and biogeochemistry of functionally diverse, vertically and ! + ! horizontally heterogeneous ecosystems: the Ecosystem Demography model, ! + ! version 2.2 -- part 1: Model description. Geosci. Model Dev., 12: ! + ! 4309-4346. doi:10.5194/gmd-12-4309-2019 (L19). + !---------------------------------------------------------------------------! call update_thermal_sums(month, cpoly, isi, cgrid%lat(ipy)) call update_turnover(cpoly,isi) call update_phenology(doy,cpoly,isi,cgrid%lat(ipy),veget_dyn_on) + !---------------------------------------------------------------------------! end select end do end do @@ -95,6 +115,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) use pft_coms , only : phenology & ! intent(in) , c2n_leaf & ! intent(in) , q & ! intent(in) + , leaf_psi_min & ! intent(in) , leaf_psi_tlp & ! intent(in) , high_psi_threshold & ! intent(in) , low_psi_threshold & ! intent(in) @@ -108,7 +129,8 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) , root_phen_factor & ! intent(in) , iphen_scheme & ! intent(in) , elongf_min & ! intent(in) - , elongf_flush ! ! intent(in) + , elongf_flush & ! intent(in) + , f_psi_xdry ! ! intent(in) use consts_coms , only : t3ple & ! intent(in) , cice & ! intent(in) , cliq & ! intent(in) @@ -271,7 +293,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !------------------------------------------------------------------------------! ! Here we decide what to do depending on the phenology habit. There are ! - ! five different types: ! + ! different types: ! ! 0. Evergreen - neither cold nor drought makes these plants to drop ! ! their leaves; ! ! 1. Drought deciduous - these plants will drop all leaves when drought ! @@ -285,6 +307,13 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) ! 4. Drought deciduous - similar to one, but the threshold is compared against ! ! a 10-day running average rather than the instant- ! ! aneous value. ! + ! 5. Hydro-deciduous - similar to four, but the thresholds are based on ! + ! leaf water potential instead (and thus it requires ! + ! plant hydrodynamics). ! + ! 6. Light phenology ! + ! + Hydro-deciduous - similar to three, but the thresholds are based on ! + ! leaf water potential instead (and thus it requires ! + ! plant hydrodynamics). ! !------------------------------------------------------------------------------! select case (phenology(ipft)) case (0) @@ -628,7 +657,7 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !------------------------------------------------------------------------! end if !---------------------------------------------------------------------------! - case (5) + case (5,6) !---------------------------------------------------------------------------! ! Drought deciduous driven by plant hydrodynamics. We track the number ! ! of consecutive wet days and dry days. We then modify the phenology ! @@ -664,7 +693,15 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !----- Modify elongf and phenology_status whenever necessary. --------------! - if (cpatch%low_leaf_psi_days(ico) >= low_psi_threshold(ipft)) then + if ( cpatch%leaf_psi(ico) < ( f_psi_xdry * leaf_psi_min(ipft) ) & + .and. cpatch%wood_psi(ico) < leaf_psi_tlp(ipft) ) then + !------------------------------------------------------------------------! + ! Extremely dry conditions: leaf_psi is too low and even wood_psi is ! + ! below leaf_tlp. Shed all leaves. ! + !------------------------------------------------------------------------! + elongf_try = 0.0 + !------------------------------------------------------------------------! + else if (cpatch%low_leaf_psi_days(ico) >= low_psi_threshold(ipft)) then !----- Too many dry days, decrease elongation factor. -------------------! elongf_try = max(0., cpatch%elongf(ico) - leaf_shed_rate(ipft)) !------------------------------------------------------------------------! @@ -921,15 +958,19 @@ subroutine update_phenology(doy, cpoly, isi, lat,veget_dyn_on) !---------------------------------------------------------------------------! - ! Adjust root biomass in case phenology is 5 (drought-deciduous driven ! - ! by hydrodynamics). ! + ! Adjust root biomass in case phenology is 5 or 6 (drought-deciduous ! + ! driven by hydrodynamics). ! !---------------------------------------------------------------------------! - if (phenology(ipft) == 5 .and. root_phen_factor > 0.) then - cpatch%broot(ico) = q(ipft) * (elongf_try + root_phen_factor - 1.) & - * size2bl(cpatch%dbh(ico),cpatch%hite(ico) & - ,cpatch%sla(ico),ipft) & - / root_phen_factor - end if + select case (phenology(ipft)) + case (5,6) + if (root_phen_factor > 0.) then + cpatch%broot(ico) = q(ipft) * (elongf_try + root_phen_factor - 1.) & + * size2bl(cpatch%dbh(ico),cpatch%hite(ico) & + ,cpatch%sla(ico),ipft) & + / root_phen_factor + end if + !------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/plant_hydro.f90 b/ED/src/dynamics/plant_hydro.f90 index 76d6e7e04..587043c02 100644 --- a/ED/src/dynamics/plant_hydro.f90 +++ b/ED/src/dynamics/plant_hydro.f90 @@ -42,13 +42,20 @@ module plant_hydro !> !> \author Xiangtao Xu, 30 Jan. 2018 !---------------------------------------------------------------------------------------! - subroutine plant_hydro_driver(csite,ipa,ntext_soil) + subroutine plant_hydro_driver(csite,ipa,lsl,ntext_soil,site_isoilbc) use ed_state_vars , only : sitetype & ! structure , patchtype ! ! structure use ed_misc_coms , only : dtlsm & ! intent(in) , dtlsm_o_frqsum & ! intent(in) , current_time ! ! intent(in) use soil_coms , only : soil & ! intent(in) + , slzt & ! intent(in) + , dslz & ! intent(in) + , dslzt & ! intent(in) + , dslzti & ! intent(in) + , dslzi & ! intent(in) + , sin_sldrain & ! intent(in) + , slcons1 & ! intent(in) , matric_potential & ! function , hydr_conduct ! ! function use grid_coms , only : nzg ! ! intent(in) @@ -59,23 +66,30 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) use pft_coms , only : C2B & ! intent(in) , leaf_water_cap & ! intent(in) , leaf_psi_min & ! intent(in) + , wood_psi_min & ! intent(in) , small_psi_min ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! type(sitetype) , target :: csite integer , intent(in) :: ipa + integer , intent(in) :: lsl integer,dimension(nzg), intent(in) :: ntext_soil + integer , intent(in) :: site_isoilbc !----- Local Vars ------------------------------------------------------------------! type(patchtype) , pointer :: cpatch !< patch strcture real :: swater_min !< Min. soil moisture for condct. - real :: swater_max !< Max. soil moisture for condct. + real :: swater_try !< Projected soil water. real :: swater_use !< soil moisture + real :: avg_cond0 !< Interpolated conductance integer :: nsoil !< soil type for soil integer :: k !< iterator for soil lyr integer :: ico !< iterator for cohort integer :: ipft !< PFT index real ,dimension(nzg) :: soil_psi !< soil water potential [ m] + real ,dimension(0:nzg+1) :: soil_psipz0 !< soil water potential [ m] + real ,dimension(0:nzg+1) :: soil_cond0 !< soil water conductance [kg/m2/s] + real ,dimension(0:nzg+1) :: wflux0 !< potential water flux [kg/m2/s] real ,dimension(nzg) :: soil_cond !< soil water conductance [kg/m2/s] real :: sap_frac !< sapwood fraction [ ---] real :: sap_area !< sapwood area [ m2] @@ -85,7 +99,7 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) logical :: track_hydraulics !< whether track hydraulics !----- Variables for debugging purposes ---------------------------------------------! integer, parameter :: dco = 0 ! the cohort to debug - logical, dimension(3) :: error_flag + logical, dimension(6) :: error_flag logical, parameter :: debug_flag = .false. character(len=13) , parameter :: efmt = '(a,1x,es12.5)' character(len=9) , parameter :: ifmt = '(a,1x,i5)' @@ -128,43 +142,107 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) !---------------------------------------------------------------------------------! ! Calculate water potential and conductance in each soil layer in preparation - ! for later calculations. + ! for later calculations. Soil conductance is only allowed for layers above the + ! lowest resolvable soil depth. We calculate the conductance twice: the first + ! time we compute the target conductance, and in the second time we impose bounds + ! to avoid soil water to be over-extracted by plants. !---------------------------------------------------------------------------------! - do k = 1,nzg + soil_cond0 (:) = 0.0 + soil_psipz0(:) = 0.0 + wflux0 (:) = 0.0 + !----- First guess. --------------------------------------------------------------! + guess_1st_loop: do k = lsl,nzg nsoil = ntext_soil(k) - + soil_cond0 (k) = wdns * hydr_conduct(k,nsoil,csite%soil_water (k,ipa) & + ,csite%soil_fracliq(k,ipa) ) + soil_psipz0(k) = csite%soil_mstpot(k,ipa) + slzt(k) + end do guess_1st_loop + !----- Bottom boundary condition. ------------------------------------------------! + select case (site_isoilbc) + case (0) + !----- Bedrock. ---------------------------------------------------------------! + soil_psipz0(lsl-1) = soil_psipz0(lsl) + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - ! Get bounded soil moisture. ! - ! MLO. The lower bound used to be air-dry soil moisture. This causes issues ! - ! in the RK4 integrator if the soil moisture is just slightly above air-dry ! - ! and dtlsm is long. For the time being, I am assuming that soil ! - ! conductivity is halted just below the permanent wilting point. Similarly, ! - ! I am assuming that matric potential cannot exceed a value slightly less ! - ! than the bubbling point. ! + case (1) + !----- Free drainage. ---------------------------------------------------------! + soil_psipz0(lsl-1) = csite%soil_mstpot(lsl,ipa) + slzt(lsl-1) + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - swater_min = mg_safe * soil(nsoil)%soilcp + om_safe * soil(nsoil)%soilwp - swater_max = mg_safe * soil(nsoil)%sfldcap + om_safe * soil(nsoil)%slmsts - swater_use = max( swater_min & - , min(swater_max & - ,csite%soil_water(k,ipa) * csite%soil_fracliq(k,ipa) ) ) + case (2) + !----- Partial drainage. ------------------------------------------------------! + soil_psipz0(lsl-1) = csite%soil_mstpot(lsl,ipa) & + + slzt(lsl) - dslzt(lsl) * sin_sldrain + soil_cond0 (lsl-1) = soil_cond0 (lsl) !------------------------------------------------------------------------------! - - - !----- Clapp & Hornberger curves. ---------------------------------------------! - soil_psi(k) = matric_potential(nsoil,swater_use) + case (3) + !----- Aquifer. ---------------------------------------------------------------! + nsoil = ntext_soil(lsl) + soil_psipz0(lsl-1) = soil(nsoil)%slpots + soil_cond0 (lsl-1) = slcons1(lsl-1,nsoil) !------------------------------------------------------------------------------! + end select + !----- Top boundary condition. ---------------------------------------------------! + soil_psipz0(nzg+1) = soil_psipz0(nzg) + !----- First guess for water flux. -----------------------------------------------! + do k = lsl,nzg + nsoil = ntext_soil(k) + select case (soil(nsoil)%method) + case ('BDRK') + !----- Bedrock, soil conductance should be zero. ---------------------------! + wflux0(k) = 0. + !---------------------------------------------------------------------------! + case default + !----- Log-linear interpolation of conductivity to layer interface. --------! + avg_cond0 = soil_cond0(k-1) * ( soil_cond0(k) / soil_cond0(k-1) ) & + ** ( dslz(k-1) / (dslz(k-1) + dslz(k)) ) + !---------------------------------------------------------------------------! + !------ Estimate flux at interface. ----------------------------------------! + wflux0(k) = - avg_cond0 * ( soil_psipz0(k) - soil_psipz0(k-1) ) * dslzti(k) + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + end do + !----- Find bounded fluxes. ------------------------------------------------------! + soil_cond(:) = 0. + do k = lsl,nzg + !------------------------------------------------------------------------------! + ! Quick estimate of soil water for the next step. ! + !------------------------------------------------------------------------------! + nsoil = ntext_soil(k) + swater_use = csite%soil_water(k,ipa) * csite%soil_fracliq(k,ipa) + swater_min = mg_safe * soil(nsoil)%soilcp + om_safe * soil(nsoil)%soilwp + swater_try = csite%soil_water(k,ipa) & + + dtlsm * dslzi(k) * ( wflux0(k) - wflux0(k+1)) + !------------------------------------------------------------------------------! !------------------------------------------------------------------------------! - ! In the model, soil can't get drier than residual soil moisture. Ensure ! - ! that hydraulic conductivity is effectively zero in case soil moisture ! - ! reaches this level or drier. ! + ! Check whether or not the conductance could drive soil water too low. ! !------------------------------------------------------------------------------! - if (csite%soil_water(k,ipa) < swater_min) then + if ( swater_use < swater_min) then + !------ Soil is already very dry (or frozen). Halt water transport. -------! + swater_use = swater_min soil_cond(k) = 0. + soil_psi (k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! + else if ( (swater_try < swater_use) .and. (swater_try < swater_min)) then + !---------------------------------------------------------------------------! + ! Conductance could desiccate soil layer, down-regulate soil ! + ! conductance and adjust soil matric potential accordingly. We also change ! + ! the units for conductance to kg/m2/s. ! + !---------------------------------------------------------------------------! + soil_cond(k) = wdns * soil_cond0(k) * ( swater_use - swater_min) & + / ( swater_use - swater_try) + soil_psi(k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! else - soil_cond(k) = wdns * hydr_conduct(k,nsoil,csite%soil_water(k,ipa) & - ,csite%soil_fracliq(k,ipa)) + !---------------------------------------------------------------------------! + ! Use the actual conductance (just convert it to kg/m2/s). ! + !---------------------------------------------------------------------------! + soil_cond(k) = wdns * soil_cond0(k) + soil_psi (k) = matric_potential(nsoil,swater_use) + !---------------------------------------------------------------------------! end if !------------------------------------------------------------------------------! end do @@ -226,14 +304,54 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) + transp * dtlsm & ! kgH2O / c_leaf ! ! kgH2O/m !------------------------------------------------------------------------! + + + !------------------------------------------------------------------------! + ! Run sanity check. The code will crash if any of these happens. ! + ! ! + ! 1. If leaf_psi is invalid (run the debugger, the problem may be else- ! + ! where) ! + ! 2. If leaf_psi is positive (non-sensical) ! + ! 3. If leaf_psi is too negative (also non-sensical) ! + !------------------------------------------------------------------------! + error_flag(1) = isnan_real(cpatch%leaf_psi(ico)) ! NaN values + error_flag(2) = cpatch%leaf_psi(ico) > 0. ! Positive potential + error_flag(3) = merge( cpatch%leaf_psi(ico) < small_psi_min(ipft) & + , cpatch%leaf_psi(ico) < leaf_psi_min (ipft) & + , cpatch%is_small(ico) ) + !------------------------------------------------------------------------! else !----- No leaves, set leaf_psi the same as wood_psi - hite. -------------! cpatch%leaf_psi(ico) = cpatch%wood_psi(ico) - cpatch%hite(ico) !------------------------------------------------------------------------! + + + !----- Skip checking leaf psi. ------------------------------------------! + error_flag(1) = .false. + error_flag(2) = .false. + error_flag(3) = .false. + !------------------------------------------------------------------------! end if !---------------------------------------------------------------------------! + !---------------------------------------------------------------------------! + ! Run sanity check for wood. The code will crash if any of these ! + ! happens. ! + ! ! + ! 1. If wood_psi is invalid (run the debugger, the problem may be else- ! + ! where) ! + ! 2. If wood_psi is positive (non-sensical) ! + ! 3. If wood_psi is too negative (also non-sensical) ! + !---------------------------------------------------------------------------! + error_flag(4) = isnan_real(cpatch%wood_psi(ico)) ! NaN values + error_flag(5) = cpatch%wood_psi(ico) > 0. ! Positive potential + error_flag(6) = merge( cpatch%wood_psi(ico) < small_psi_min(ipft) & + , cpatch%wood_psi(ico) < wood_psi_min (ipft) & + , cpatch%is_small(ico) ) + !---------------------------------------------------------------------------! + + !---------------------------------------------------------------------------! ! Run sanity check. The code will crash if any of these happen. ! ! ! @@ -242,17 +360,12 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) ! 2. If leaf_psi is positive (non-sensical) ! ! 3. If leaf_psi is too negative (also non-sensical) ! !---------------------------------------------------------------------------! - error_flag(1) = isnan_real(cpatch%leaf_psi(ico)) ! NaN values - error_flag(2) = cpatch%leaf_psi(ico) > 0. ! Positive potential - error_flag(3) = merge( cpatch%leaf_psi(ico) < small_psi_min(ipft) & - , cpatch%leaf_psi(ico) < leaf_psi_min (ipft) & - , cpatch%is_small(ico) ) if ((debug_flag .and. (dco == 0 .or. ico == dco)) .or. any(error_flag)) then write (unit=*,fmt='(a)') ' ' write (unit=*,fmt='(92a)') ('=',k=1,92) write (unit=*,fmt='(92a)') ('=',k=1,92) write (unit=*,fmt='(a)' ) & - ' Invalid leaf_psi detected.' + ' Invalid leaf_psi or wood_psi detected.' write (unit=*,fmt='(92a)') ('-',k=1,92) write (unit=*,fmt='(a,i4.4,2(1x,i2.2),1x,f6.0)') ' TIME : ' & ,current_time%year,current_time%month & @@ -266,12 +379,17 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) write (unit=*,fmt=lfmt ) ' + SMALL =',cpatch%is_small(ico) write (unit=*,fmt='(a)' ) ' ' - write (unit=*,fmt=lfmt ) ' + FINITE =',.not. error_flag(1) - write (unit=*,fmt=lfmt ) ' + NEGATIVE =',.not. error_flag(2) - write (unit=*,fmt=lfmt ) ' + BOUNDED =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + FINITE (Leaf) =',.not. error_flag(1) + write (unit=*,fmt=lfmt ) ' + NEGATIVE (Leaf) =',.not. error_flag(2) + write (unit=*,fmt=lfmt ) ' + BOUNDED (Leaf) =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + FINITE (Wood) =',.not. error_flag(4) + write (unit=*,fmt=lfmt ) ' + NEGATIVE (Wood) =',.not. error_flag(5) + write (unit=*,fmt=lfmt ) ' + BOUNDED (Wood) =',.not. error_flag(6) write (unit=*,fmt='(a)' ) ' ' write (unit=*,fmt=efmt ) ' + LEAF_PSI_MIN =',leaf_psi_min (ipft) + write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) + write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) write (unit=*,fmt=efmt ) ' + SMALL_PSI_MIN =',small_psi_min(ipft) write (unit=*,fmt='(a)' ) ' ' @@ -340,15 +458,15 @@ subroutine plant_hydro_driver(csite,ipa,ntext_soil) ! and psi_closed. ! !---------------------------------------------------------------------------! call calc_plant_water_flux( & - dtlsm &!input - ,sap_area,cpatch%nplant(ico),ipft &!input - ,cpatch%is_small(ico),cpatch%krdepth(ico) &!input - ,cpatch%bleaf(ico),bsap,cpatch%broot(ico) &!input - ,cpatch%hite(ico),transp &!input - ,cpatch%leaf_psi(ico),cpatch%wood_psi(ico) &!input - ,soil_psi,soil_cond,ipa,ico &!input - ,cpatch%wflux_wl(ico),cpatch%wflux_gw(ico) &!output - ,cpatch%wflux_gw_layer(:,ico)) !!output + dtlsm & ! input + ,sap_area,cpatch%nplant(ico),ipft & ! input + ,cpatch%is_small(ico),cpatch%krdepth(ico) & ! input + ,cpatch%bleaf(ico),bsap,cpatch%broot(ico) & ! input + ,cpatch%hite(ico),cpatch%root_frac(:,ico) & ! input + ,transp,cpatch%leaf_psi(ico),cpatch%wood_psi(ico) & ! input + ,soil_psi,soil_cond,lsl,ipa,ico & ! input + ,cpatch%wflux_wl(ico),cpatch%wflux_gw(ico) & ! output + ,cpatch%wflux_gw_layer(:,ico)) ! ! output !---------------------------------------------------------------------------! else !----- Neither leaves nor wood are resolvable. Assume zero flow. ----------! @@ -450,13 +568,12 @@ end subroutine plant_hydro_driver !---------------------------------------------------------------------------------------! subroutine calc_plant_water_flux(dt & !timestep ,sap_area,nplant,ipft,is_small,krdepth & !plant input - ,bleaf,bsap,broot,hite & !plant input + ,bleaf,bsap,broot,hite ,root_frac & !plant input ,transp,leaf_psi,wood_psi & !plant input - ,soil_psi,soil_cond & !soil input + ,soil_psi,soil_cond,lsl & !soil input ,ipa,ico & !debug input ,wflux_wl,wflux_gw,wflux_gw_layer) ! !flux output - use soil_coms , only : slz8 & ! intent(in) - , dslz8 ! ! intent(in) + use soil_coms , only : dslz8 ! ! intent(in) use grid_coms , only : nzg ! ! intent(in) use consts_coms , only : pi18 & ! intent(in) , lnexp_min8 ! ! intent(in) @@ -470,7 +587,6 @@ subroutine calc_plant_water_flux(dt & !timestep , wood_Kmax & ! intent(in) , wood_Kexp & ! intent(in) , vessel_curl_factor & ! intent(in) - , root_beta & ! intent(in) , SRA & ! intent(in) , C2B ! ! intent(in) use ed_misc_coms , only : current_time ! ! intent(in) @@ -486,11 +602,13 @@ subroutine calc_plant_water_flux(dt & !timestep real , intent(in) :: bsap !sapwood biomass [ kgC/pl] real , intent(in) :: broot !fine root biomass [ kgC/pl] real , intent(in) :: hite !plant height [ m] + real , dimension(nzg), intent(in) :: root_frac !Root fraction [ m] real , intent(in) :: transp !transpiration [ kg/s] real , intent(in) :: leaf_psi !leaf water pot. [ m] real , intent(in) :: wood_psi !wood water pot. [ m] real , dimension(nzg), intent(in) :: soil_psi !soil water pot. [ m] real , dimension(nzg), intent(in) :: soil_cond !soil water cond. [kg/m2/s] + integer, intent(in) :: lsl !lowest active lyr [ ---] integer, intent(in) :: ipa !Patch index [ ---] integer, intent(in) :: ico !Cohort index [ ---] real , intent(out) :: wflux_wl !wood-leaf flux [ kg/s] @@ -517,12 +635,12 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: wood_psi_min_d real(kind=8) :: leaf_psi_lwr_d real(kind=8) :: wood_psi_lwr_d - real(kind=8) :: root_beta_d real(kind=8) :: SRA_d real(kind=8) :: wood_psi50_d real(kind=8) :: wood_Kexp_d real(kind=8) :: wood_Kmax_d real(kind=8) :: vessel_curl_factor_d + real(kind=8) :: root_frac_d !fraction of roots !----- Auxiliary variables. ---------------------------------------------------------! real(kind=8) :: exp_term !exponent term real(kind=8) :: ap ![s-1] @@ -532,7 +650,6 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: c_leaf !leaf water capacitance real(kind=8) :: c_stem !stem water capacitance real(kind=8) :: RAI !root area index - real(kind=8) :: root_frac !fraction of roots real(kind=8) :: proj_leaf_psi !projected leaf water pot. real(kind=8) :: proj_wood_psi !projected wood water pot. real(kind=8) :: gw_cond !g->w water conductivity @@ -540,8 +657,6 @@ subroutine calc_plant_water_flux(dt & !timestep real(kind=8) :: org_leaf_psi !used for small tree real(kind=8) :: weighted_soil_psi real(kind=8) :: weighted_gw_cond - real(kind=8) :: above_layer_depth - real(kind=8) :: current_layer_depth real(kind=8) :: total_water_supply real(kind=8) , dimension(nzg) :: layer_water_supply !----- Counters. --------------------------------------------------------------------! @@ -558,6 +673,7 @@ subroutine calc_plant_water_flux(dt & !timestep logical , parameter :: debug_flag = .false. !----- External function ------------------------------------------------------------! real(kind=4) , external :: sngloff ! Safe dble 2 single precision + logical , external :: isnan_dble ! Check for NaN !------------------------------------------------------------------------------------! @@ -570,14 +686,13 @@ subroutine calc_plant_water_flux(dt & !timestep bleaf_d = dble(bleaf ) bsap_d = dble(bsap ) broot_d = dble(broot ) - nplant_d = dble(nplant ) + nplant_d = dble(nplant ) hite_d = dble(hite ) transp_d = dble(transp ) leaf_psi_d = dble(leaf_psi ) wood_psi_d = dble(wood_psi ) soil_psi_d = dble(soil_psi ) soil_cond_d = dble(soil_cond ) - root_beta_d = dble(root_beta (ipft)) SRA_d = dble(SRA (ipft)) !----- Minimum threshold depends on whether the plant is small or large. ------------! if (is_small) then @@ -718,7 +833,7 @@ subroutine calc_plant_water_flux(dt & !timestep wflux_wl_d = 0.d0 !------ Proj_leaf_psi is only dependent upon transpiration. -------------------! - if (c_leaf > 0.) then + if (c_leaf > 0.d0) then proj_leaf_psi = leaf_psi_d - transp_d * dt_d / c_leaf else proj_leaf_psi = leaf_psi_d @@ -753,7 +868,7 @@ subroutine calc_plant_water_flux(dt & !timestep !------------------------------------------------------------------------------! ! Find sapflow. !------------------------------------------------------------------------------! - if (stem_cond == 0.) then + if (stem_cond == 0.d0) then !---- 1.2.2. Zero flux because stem conductivity is also zero. -------------! wflux_wl_d = 0.d0 !---------------------------------------------------------------------------! @@ -795,26 +910,16 @@ subroutine calc_plant_water_flux(dt & !timestep !----- Loop over all soil layers to get the aggregated water conductance. -----------! do k = krdepth,nzg - !---------------------------------------------------------------------------------! - ! Define layer edges - ! - !---------------------------------------------------------------------------------! - current_layer_depth = -slz8(k) - above_layer_depth = -slz8(k+1) - !---------------------------------------------------------------------------------! - - - !----- Calculate the root fraction of this layer. --------------------------------! - root_frac = ( root_beta_d ** (above_layer_depth / (-slz8(krdepth))) & - - root_beta_d ** (current_layer_depth / (-slz8(krdepth))) ) + !----- Retrieve the root fraction of this layer. ---------------------------------! + root_frac_d = dble(root_frac(k)) !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! ! Calculate RAI in each layer. ! !---------------------------------------------------------------------------------! - RAI = broot_d * SRA_d * root_frac * nplant_d ! m2/m2 + RAI = broot_d * SRA_d * root_frac_d * nplant_d ! m2/m2 !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! @@ -863,7 +968,7 @@ subroutine calc_plant_water_flux(dt & !timestep ! No need to calculate water flow: wood psi is only dependent upon sapflow. !---------------------------------------------------------------------------------! wflux_gw_d = 0.d0 - if (c_stem > 0.) then + if (c_stem > 0.d0) then !----- Make sure that projected wood psi will be bounded. ---------------------! wflux_wl_d = min(wflux_wl_d, (wood_psi_d - wood_psi_lwr_d) * c_stem / dt_d ) proj_wood_psi = wood_psi_d - wflux_wl_d * dt_d / c_stem @@ -937,11 +1042,26 @@ subroutine calc_plant_water_flux(dt & !timestep ! d. Projected leaf/wood potential is less than minimum acceptable ! e. Current leaf/wood potential is less than minimum acceptable !------------------------------------------------------------------------------------! - error_flag(1) = isnan(wflux_wl_d) .or. isnan(wflux_gw_d) - error_flag(2) = proj_leaf_psi > 0. .or. proj_wood_psi > 0. - error_flag(3) = leaf_psi_d > 0. .or. wood_psi_d > 0. - error_flag(4) = proj_leaf_psi < leaf_psi_min_d .or. proj_wood_psi < wood_psi_min_d - error_flag(5) = leaf_psi_d < leaf_psi_min_d .or. wood_psi_d < wood_psi_min_d + if (c_leaf > 0.d0) then + !------ Check for errors in both wood and leaf. ----------------------------------! + error_flag(1) = isnan_dble(wflux_wl_d) .or. isnan_dble(wflux_gw_d) + error_flag(2) = proj_leaf_psi > 0.d0 .or. proj_wood_psi > 0.d0 + error_flag(3) = leaf_psi_d > 0.d0 .or. wood_psi_d > 0.d0 + error_flag(4) = proj_leaf_psi < leaf_psi_min_d .or. proj_wood_psi < wood_psi_min_d + error_flag(5) = leaf_psi_d < leaf_psi_min_d .or. wood_psi_d < wood_psi_min_d + !---------------------------------------------------------------------------------! + else + !---------------------------------------------------------------------------------! + ! Check for errors in wood only, as plant has no leaves. The only exception ! + ! is the flux from wood to leaf, which should never be NaN, so we still check it. ! + !---------------------------------------------------------------------------------! + error_flag(1) = isnan_dble(wflux_wl_d) .or. isnan_dble(wflux_gw_d) + error_flag(2) = proj_wood_psi > 0.d0 + error_flag(3) = wood_psi_d > 0.d0 + error_flag(4) = proj_wood_psi < wood_psi_min_d + error_flag(5) = wood_psi_d < wood_psi_min_d + !---------------------------------------------------------------------------------! + end if if ( (debug_flag .and. (dco == 0 .or. ico == dco)) .or. any(error_flag)) then write (unit=*,fmt='(a)') ' ' @@ -971,15 +1091,15 @@ subroutine calc_plant_water_flux(dt & !timestep write (unit=*,fmt=efmt ) ' + SAPWOOD_AREA =',sap_area write (unit=*,fmt='(a)' ) ' ' - write (unit=*,fmt=lfmt ) ' + Finite fluxes =',.not. error_flag(1) - write (unit=*,fmt=lfmt ) ' + Negative Proj Psi =',.not. error_flag(2) - write (unit=*,fmt=lfmt ) ' + Negative Curr Psi =',.not. error_flag(3) - write (unit=*,fmt=lfmt ) ' + Bounded Proj Psi =',.not. error_flag(4) - write (unit=*,fmt=lfmt ) ' + Bounded Curr Psi =',.not. error_flag(5) + write (unit=*,fmt=lfmt ) ' + Leaves were checked =',c_leaf > 0.d0 + write (unit=*,fmt=lfmt ) ' + Finite fluxes =',.not. error_flag(1) + write (unit=*,fmt=lfmt ) ' + Negative Proj Psi =',.not. error_flag(2) + write (unit=*,fmt=lfmt ) ' + Negative Curr Psi =',.not. error_flag(3) + write (unit=*,fmt=lfmt ) ' + Bounded Proj Psi =',.not. error_flag(4) + write (unit=*,fmt=lfmt ) ' + Bounded Curr Psi =',.not. error_flag(5) write (unit=*,fmt='(a)' ) ' ' write (unit=*,fmt=efmt ) ' + LEAF_PSI_MIN =',leaf_psi_min (ipft) - write (unit=*,fmt=efmt ) ' + WOOD_PSI_MIN =',wood_psi_min (ipft) write (unit=*,fmt=efmt ) ' + SMALL_PSI_MIN =',small_psi_min(ipft) write (unit=*,fmt='(a)' ) ' ' @@ -1017,7 +1137,8 @@ subroutine calc_plant_water_flux(dt & !timestep ! Copy all the results to output variables. !------------------------------------------------------------------------------------! wflux_wl = sngloff(wflux_wl_d,tiny_offset) - do k = 1, nzg + wflux_gw_layer(:) = 0.0 + do k = lsl, nzg wflux_gw_layer(k) = sngloff(wflux_gw_layer_d(k),tiny_offset) end do wflux_gw = sum(wflux_gw_layer) diff --git a/ED/src/dynamics/reproduction.f90 b/ED/src/dynamics/reproduction.f90 index 170fec5a8..52ab6a4d6 100644 --- a/ED/src/dynamics/reproduction.f90 +++ b/ED/src/dynamics/reproduction.f90 @@ -179,6 +179,7 @@ subroutine reproduction_driver(cgrid,month,veget_dyn_on) !----- The big loops start here. -------------------------------------------------! polyloop: do ipy = 1,cgrid%npolygons + cpoly => cgrid%polygon(ipy) !------------------------------------------------------------------------------! ! Check whether this is late spring/early summer. This is needed for ! @@ -187,8 +188,8 @@ subroutine reproduction_driver(cgrid,month,veget_dyn_on) !------------------------------------------------------------------------------! late_spring = (cgrid%lat(ipy) >= 0.0 .and. month == 6) .or. & (cgrid%lat(ipy) < 0.0 .and. month == 12) + !------------------------------------------------------------------------------! - cpoly => cgrid%polygon(ipy) siteloop_sort: do isi = 1,cpoly%nsites csite => cpoly%site(isi) @@ -1286,8 +1287,8 @@ subroutine seed_dispersal(cpoly,late_spring) ! of them will land again in this patch, and we correct for this further ! ! down. ! !------------------------------------------------------------------------! - csite%cbudget_seedrain(donpa) = csite%cbudget_seedrain(donpa) & - - bseed_maygo * frqsumi + donsite%cbudget_seedrain(donpa) = donsite%cbudget_seedrain(donpa) & + - bseed_maygo * frqsumi !------------------------------------------------------------------------! @@ -1314,7 +1315,7 @@ subroutine seed_dispersal(cpoly,late_spring) ! (4) RPY = DPA * AD * AR (1->3) ! ! (5) RPA = DPA * AD (4->2, regardless of the patch) ! !------------------------------------------------------------------------! - bseed_xpatch = bseed_maygo * csite%area(donpa) * cpoly%area(donsi) + bseed_xpatch = bseed_maygo * donsite%area(donpa) * cpoly%area(donsi) !------------------------------------------------------------------------! @@ -1343,8 +1344,8 @@ subroutine seed_dispersal(cpoly,late_spring) ! subtracted all the non-local dispersal outside the receptor site ! ! loop. ! !------------------------------------------------------------------! - csite%cbudget_seedrain(recpa) = csite%cbudget_seedrain(recpa) & - + bseed_xpatch * frqsumi + recsite%cbudget_seedrain(recpa) = recsite%cbudget_seedrain(recpa) & + + bseed_xpatch * frqsumi !------------------------------------------------------------------! diff --git a/ED/src/dynamics/rk4_copy_patch.f90 b/ED/src/dynamics/rk4_copy_patch.f90 index 9fbeff87e..f8d6edffe 100644 --- a/ED/src/dynamics/rk4_copy_patch.f90 +++ b/ED/src/dynamics/rk4_copy_patch.f90 @@ -931,10 +931,11 @@ end subroutine copy_rk4_patch ! This subroutine will copy the variables from the integration buffer to the state ! ! patch and cohorts. ! !---------------------------------------------------------------------------------------! - subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm,ebudget_netrad & - ,ebudget_loss2atm,co2budget_loss2atm,wbudget_loss2drainage & - ,ebudget_loss2drainage,wbudget_loss2runoff,ebudget_loss2runoff & - ,co2budget_denseffect,ebudget_denseffect,wbudget_denseffect) + subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm & + ,ebudget_netrad,ebudget_loss2atm,co2budget_loss2atm & + ,wbudget_loss2drainage,ebudget_loss2drainage,wbudget_loss2runoff & + ,ebudget_loss2runoff,co2budget_denseffect,ebudget_denseffect & + ,wbudget_denseffect) use rk4_coms , only : rk4patchtype & ! structure , rk4site & ! intent(in) , rk4min_veg_temp & ! intent(in) @@ -2092,6 +2093,8 @@ subroutine initp2modelp(hdid,initp,csite,ipa,nighttime,wbudget_loss2atm,ebudget_ + csite%ground_shv (ipa) * dtlsm_o_frqsum csite%fmean_can_ggnd (ipa) = csite%fmean_can_ggnd (ipa) & + csite%ggnet (ipa) * dtlsm_o_frqsum + csite%fmean_snowfac (ipa) = csite%fmean_snowfac (ipa) & + + csite%snowfac (ipa) * dtlsm_o_frqsum !------------------------------------------------------------------------------------! ! Snow/pounding layers. We keep track of the total, not individual layers. ! ! Energy will be integrated as an extensive variable, we will convert it by the ! diff --git a/ED/src/dynamics/rk4_derivs.f90 b/ED/src/dynamics/rk4_derivs.f90 index d413a383f..869f22b5a 100644 --- a/ED/src/dynamics/rk4_derivs.f90 +++ b/ED/src/dynamics/rk4_derivs.f90 @@ -25,7 +25,11 @@ module rk4_derivs !---------------------------------------------------------------------------------------! subroutine leaf_derivs(initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) - use rk4_coms , only : rk4patchtype ! ! structure + use rk4_coms , only : rk4patchtype & ! structure + , rk4aux & ! intent(out) + , zero_rk4_aux & ! sub-routine + , zero_rk4_patch & ! sub-routine + , zero_rk4_cohort ! ! sub-routine use ed_state_vars , only : sitetype & ! structure , polygontype ! ! structure use grid_coms , only : nzg & ! intent(in) @@ -43,10 +47,15 @@ subroutine leaf_derivs(initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) ! solver solution. !------------------------------------------------------------------------------------! - !----- Ensure that theta_Eiv and water storage derivatives are both zero. -----------! - dinitp%ebudget_storage = 0.d0 - dinitp%wbudget_storage = 0.d0 - dinitp%co2budget_storage = 0.d0 + + !---- Flush all derivatives to zero. ------------------------------------------------! + call zero_rk4_patch (dinitp) + call zero_rk4_cohort(dinitp) + !------------------------------------------------------------------------------------! + + + !---- Flush auxiliary variables to zero. --------------------------------------------! + call zero_rk4_aux(rk4aux(ibuff)) !------------------------------------------------------------------------------------! @@ -84,15 +93,13 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) , slzt8 & ! intent(in) , dslzt8 & ! intent(in) , ss & ! intent(in) - , isoilbc & ! intent(in) , sin_sldrain8 & ! intent(in) , hydr_conduct8 ! ! function use rk4_coms , only : checkbudget & ! intent(in) , print_detailed & ! intent(in) , rk4site & ! intent(in) , rk4patchtype & ! structure - , rk4aux & ! intent(out) - , zero_rk4_aux ! ! intent(in) + , rk4aux ! ! intent(out) use ed_state_vars , only : sitetype & ! structure , patchtype & ! structure , polygontype ! ! structure @@ -174,27 +181,6 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------------------! - !---- Flush auxiliary variables to zero. --------------------------------------------! - call zero_rk4_aux(rk4aux(ibuff)) - !------------------------------------------------------------------------------------! - - - - !----- Make sure derivatives are flushed to zero. -----------------------------------! - dinitp%soil_energy(:) = 0.0d0 - dinitp%soil_water(:) = 0.0d0 - dinitp%sfcwater_depth(:) = 0.0d0 - dinitp%sfcwater_energy(:) = 0.0d0 - dinitp%sfcwater_mass(:) = 0.0d0 - dinitp%virtual_energy = 0.0d0 - dinitp%virtual_water = 0.0d0 - dinitp%virtual_depth = 0.0d0 - if (fast_diagnostics .or. print_detailed) then - dinitp%avg_transloss(:) = 0.0d0 - end if - !------------------------------------------------------------------------------------! - - !------------------------------------------------------------------------------------! @@ -355,7 +341,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) ! Find the boundary condition for total potential beneath the bottom layer. ! !------------------------------------------------------------------------------------! nsoil = rk4site%ntext_soil(klsl) - select case (isoilbc) + select case (rk4site%isoilbc) case (0) !---------------------------------------------------------------------------------! ! Bedrock. Make the potential exactly the same as the bottom layer, and the ! @@ -420,6 +406,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) rk4aux(ibuff)%psiplusz (kben) = slzt8(kben) + initp%soil_mstpot(kben) rk4aux(ibuff)%drysoil (kben) = .false. rk4aux(ibuff)%satsoil (kben) = .false. + !---------------------------------------------------------------------------------! end select !------------------------------------------------------------------------------------! @@ -598,7 +585,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) if (initp%virtual_water /= 0.d0) then !!process "virtural water" pool nsoil = rk4site%ntext_soil(mzg) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + continue + case default infilt = - dslzi8(mzg) * 5.d-1 & * hydr_conduct8(mzg,nsoil,initp%soil_water(mzg) & ,initp%soil_fracliq(mzg)) & @@ -610,12 +600,15 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) rk4aux(ibuff)%qw_flux_g(mzg+1) = rk4aux(ibuff)%qw_flux_g(mzg+1) + qinfilt dinitp%virtual_water = dinitp%virtual_water - infilt*wdns8 dinitp%virtual_energy = dinitp%virtual_energy - qinfilt - end if + end select end if !! end virtual water pool if (initp%nlev_sfcwater >= 1) then !----- Process "snow" water pool --------------! surface_water = initp%sfcwater_mass(1)*initp%sfcwater_fracliq(1)*wdnsi8 !(m/m2) nsoil = rk4site%ntext_soil(mzg) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + continue + case default !----- Calculate infiltration rate (m/s) -----------------------------------! infilt = - dslzi8(mzg) * 5.d-1 & * hydr_conduct8(mzg,nsoil,initp%soil_water(mzg) & @@ -629,7 +622,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) dinitp%sfcwater_mass(1) = dinitp%sfcwater_mass(1) - infilt*wdns8 dinitp%sfcwater_energy(1) = dinitp%sfcwater_energy(1) - qinfilt dinitp%sfcwater_depth(1) = dinitp%sfcwater_depth(1) - infilt - end if + end select end if ! End snow water pool end if !! End alternate infiltration !------------------------------------------------------------------------------------! @@ -648,7 +641,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------------------! do k = klsl, mzg nsoil = rk4site%ntext_soil(k) - if (nsoil /= 13) then + select case (trim(soil8(nsoil)%method)) + case ('BDRK') + rk4aux(ibuff)%w_flux_g(k) = 0.d0 + case default !----- Log-linear interpolation of hydraulic conductivity to layer interface. -! avg_hydcond = rk4aux(ibuff)%hydcond(k-1) & @@ -677,10 +673,7 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) end if !------------------------------------------------------------------------------! - - else - rk4aux(ibuff)%w_flux_g(k) = 0.d0 - end if + end select !---------------------------------------------------------------------------------! @@ -780,8 +773,10 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) !------------------------------------------------------------------------! ! Skip calculation if no water is available in this layer. ! !------------------------------------------------------------------------! - if ( rk4site%ntext_soil(k2) == 13 .or. & - rk4aux(ibuff)%avail_h2o_lyr(k2) < tiny_num8 ) cycle k2_transp_loop + if ( trim(soil8(rk4site%ntext_soil(k2))%method) == 'BDRK' .or. & + rk4aux(ibuff)%avail_h2o_lyr(k2) < tiny_num8 ) then + cycle k2_transp_loop + end if !------------------------------------------------------------------------! @@ -862,6 +857,19 @@ subroutine leaftw_derivs(mzg,mzs,initp,dinitp,csite,ipa,ibuff,dt,is_hybrid) qloss_tot = 0.d0 uint_water_k1 = tl2uint8(initp%soil_tempk(k1),1.d0) + + !------------------------------------------------------------------------------! + ! MLO -> XX. I added this if to bypass contributions from this layer to ! + ! transpiration when the soil is completely desiccated. Do you ! + ! foresee any problems? ! + !------------------------------------------------------------------------------! + if (rk4aux(ibuff)%drysoil(k1)) then + cycle k1_transh_loop + end if + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! ! Integrate the total to be removed from this layer. Add water and ! ! internal energy to each cohort, so water and energy are conserved. The ! diff --git a/ED/src/dynamics/rk4_driver.F90 b/ED/src/dynamics/rk4_driver.F90 index ae758614c..8e428ad62 100644 --- a/ED/src/dynamics/rk4_driver.F90 +++ b/ED/src/dynamics/rk4_driver.F90 @@ -25,6 +25,7 @@ subroutine rk4_timestep(cgrid) use grid_coms , only : nzg ! ! intent(in) use ed_misc_coms , only : current_time & ! intent(in) , dtlsm ! ! intent(in) + use soil_coms , only : isoilbc ! ! intent(in) use budget_utils , only : update_cbudget_committed & ! function , compute_budget ! ! function use soil_respiration , only : soil_respiration_driver ! ! sub-routine @@ -87,6 +88,7 @@ subroutine rk4_timestep(cgrid) integer :: ibuff integer :: npa_thread integer :: ita + integer :: site_isoilbc !----- Local constants. -------------------------------------------------------------! logical , parameter :: test_energy_sanity = .false. !----- Functions --------------------------------------------------------------------! @@ -98,6 +100,31 @@ subroutine rk4_timestep(cgrid) polygonloop: do ipy = 1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + !---------------------------------------------------------------------------------! + ! Decide the local soil boundary condition based on depth to bedrock and ! + ! the preferred boundary condition set by the user. ! + !---------------------------------------------------------------------------------! + select case (isoilbc) + case (-1) + !----- Decide boundary condition based on depth to bedrock. -------------------! + select case (cpoly%lsl(isi)) + case (1) + !------ Soil depth is at or below slz(1), assume free drainage. ------------! + site_isoilbc = 1 + !---------------------------------------------------------------------------! + case default + !------ Soil depth is above slz(1), assume flat bedrock. -------------------! + site_isoilbc = 0 + !---------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------! + case default + !----- Default settings, use the namelist settings for every site. ------------! + site_isoilbc = isoilbc + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + siteloop: do isi = 1,cpoly%nsites csite => cpoly%site(isi) cmet => cpoly%met(isi) @@ -112,7 +139,7 @@ subroutine rk4_timestep(cgrid) ! Update the monthly rainfall. ! !------------------------------------------------------------------------------! imon = current_time%month - cpoly%avg_monthly_pcpg(imon,isi) = cpoly%avg_monthly_pcpg(imon,isi) & + cpoly%avg_monthly_accp(imon,isi) = cpoly%avg_monthly_accp(imon,isi) & + cmet%pcpg * dtlsm !------------------------------------------------------------------------------! @@ -121,12 +148,13 @@ subroutine rk4_timestep(cgrid) !------------------------------------------------------------------------------! ! Copy the meteorological variables to the rk4site structure. ! !------------------------------------------------------------------------------! - call copy_met_2_rk4site(nzg,cmet%atm_ustar,cmet%atm_theiv,cmet%atm_vpdef & - ,cmet%atm_theta,cmet%atm_tmp,cmet%atm_shv,cmet%atm_co2 & - ,cmet%geoht,cmet%exner,cmet%pcpg,cmet%qpcpg,cmet%dpcpg & - ,cmet%prss,cmet%rshort,cmet%rlong,cmet%par_beam & - ,cmet%par_diffuse,cmet%nir_beam,cmet%nir_diffuse & - ,cmet%geoht,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + call copy_met_2_rk4site(nzg,site_isoilbc,cmet%atm_ustar,cmet%atm_theiv & + ,cmet%atm_vpdef,cmet%atm_theta,cmet%atm_tmp & + ,cmet%atm_shv,cmet%atm_co2,cmet%geoht,cmet%exner & + ,cmet%pcpg,cmet%qpcpg,cmet%dpcpg,cmet%prss,cmet%rshort & + ,cmet%rlong,cmet%par_beam,cmet%par_diffuse & + ,cmet%nir_beam,cmet%nir_diffuse,cmet%geoht & + ,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & ,cpoly%green_leaf_factor(:,isi),cgrid%lon(ipy) & ,cgrid%lat(ipy),cgrid%cosz(ipy)) !------------------------------------------------------------------------------! @@ -251,7 +279,8 @@ subroutine rk4_timestep(cgrid) ! placed before canopy_photosynthesis, because plant_hydro_driver needs ! ! fs_open from the previous timestep. ! !------------------------------------------------------------------------! - call plant_hydro_driver(csite,ipa,cpoly%ntext_soil(:,isi)) + call plant_hydro_driver(csite,ipa,cpoly%lsl(isi),cpoly%ntext_soil(:,isi) & + ,site_isoilbc) !------------------------------------------------------------------------! @@ -434,8 +463,8 @@ subroutine integrate_patch_rk4(csite,initp,ipa,isi,ibuff,nighttime,wcurr_loss2at !------------------------------------------------------------------------------------! ! Move the state variables from the integrated patch to the model patch. ! !------------------------------------------------------------------------------------! - call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm,ecurr_netrad & - ,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & + call initp2modelp(tend-tbeg,initp,csite,ipa,nighttime,wcurr_loss2atm & + ,ecurr_netrad,ecurr_loss2atm,co2curr_loss2atm,wcurr_loss2drainage & ,ecurr_loss2drainage,wcurr_loss2runoff,ecurr_loss2runoff & ,co2curr_denseffect,ecurr_denseffect,wcurr_denseffect) !------------------------------------------------------------------------------------! diff --git a/ED/src/dynamics/rk4_integ_utils.f90 b/ED/src/dynamics/rk4_integ_utils.f90 index 46db5c36a..de2ee62d9 100644 --- a/ED/src/dynamics/rk4_integ_utils.f90 +++ b/ED/src/dynamics/rk4_integ_utils.f90 @@ -252,10 +252,10 @@ end subroutine odeint ! This is to ensure all variables are in double precision, so consistent with the ! ! buffer variables. ! !---------------------------------------------------------------------------------------! - subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tmp & - ,atm_shv,atm_co2,zoff,exner,pcpg,qpcpg,dpcpg,prss,rshort & - ,rlong,par_beam,par_diffuse,nir_beam,nir_diffuse,geoht & - ,lsl,ntext_soil,green_leaf_factor,lon,lat,cosz) + subroutine copy_met_2_rk4site(mzg,site_isoilbc,atm_ustar,atm_theiv,atm_vpdef,atm_theta & + ,atm_tmp,atm_shv,atm_co2,zoff,exner,pcpg,qpcpg,dpcpg,prss & + ,rshort,rlong,par_beam,par_diffuse,nir_beam,nir_diffuse & + ,geoht,lsl,ntext_soil,green_leaf_factor,lon,lat,cosz) use ed_max_dims , only : n_pft ! ! intent(in) use rk4_coms , only : rk4site ! ! structure use canopy_air_coms, only : ustmin8 ! ! intent(in) @@ -268,9 +268,9 @@ subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tm implicit none !----- Arguments --------------------------------------------------------------------! integer , intent(in) :: mzg + integer , intent(in) :: site_isoilbc integer , intent(in) :: lsl real , intent(in) :: atm_ustar - ! real , intent(in) :: vels real , intent(in) :: atm_theiv real , intent(in) :: atm_vpdef real , intent(in) :: atm_theta @@ -300,8 +300,11 @@ subroutine copy_met_2_rk4site(mzg,atm_ustar,atm_theiv,atm_vpdef,atm_theta,atm_tm !----- Copy the integer variables. --------------------------------------------------! rk4site%lsl = lsl + rk4site%isoilbc = site_isoilbc rk4site%ntext_soil(:) = 0 rk4site%ntext_soil(1:mzg) = ntext_soil(1:mzg) + !------------------------------------------------------------------------------------! + !----- Convert to double precision. -------------------------------------------------! rk4site%atm_theiv = dble(atm_theiv ) @@ -597,8 +600,7 @@ subroutine get_yscal(y,dy,htry,yscal,cpatch) use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) use consts_coms , only : wdnsi8 ! ! intent(in) - use soil_coms , only : isoilbc & ! intent(in) - , dslzi8 ! ! intent(in) + use soil_coms , only : dslzi8 ! ! intent(in) use physiology_coms , only : plant_hydro_scheme ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -993,15 +995,15 @@ subroutine get_yscal(y,dy,htry,yscal,cpatch) ! Drainage terms will be checked only if the boundary condition is free ! ! drainage. ! !---------------------------------------------------------------------------------! - if (isoilbc == 0 .or. (abs(y%ebudget_loss2drainage) < tiny_offset .and. & - abs(dy%ebudget_loss2drainage) < tiny_offset) ) then + if (rk4site%isoilbc == 0 .or. (abs(y%ebudget_loss2drainage) < tiny_offset & + .and. abs(dy%ebudget_loss2drainage) < tiny_offset)) then yscal%ebudget_loss2drainage = huge_offset else yscal%ebudget_loss2drainage = abs(y%ebudget_loss2drainage) & + abs(dy%ebudget_loss2drainage*htry) end if - if (isoilbc == 0 .or. (abs(y%wbudget_loss2drainage) < tiny_offset .and. & - abs(dy%wbudget_loss2drainage) < tiny_offset) ) then + if (rk4site%isoilbc == 0 .or. (abs(y%wbudget_loss2drainage) < tiny_offset & + .and. abs(dy%wbudget_loss2drainage) < tiny_offset)) then yscal%wbudget_loss2drainage = huge_offset else yscal%wbudget_loss2drainage = abs(y%wbudget_loss2drainage) & @@ -1847,7 +1849,8 @@ subroutine rkqs(x,htry,hgoal,hdid,hnext,csite,ipa,isi,ibuff) , patchtype ! ! structure use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) - use ed_misc_coms , only : dtlsm ! ! intent(in) + use ed_misc_coms , only : dtlsm & ! intent(in) + , current_time ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -1945,8 +1948,18 @@ subroutine rkqs(x,htry,hgoal,hdid,hnext,csite,ipa,isi,ibuff) write (unit=*,fmt='(80a)') ('=',k=1,80) write (unit=*,fmt='(a)') ' STEPSIZE UNDERFLOW IN RKQS' write (unit=*,fmt='(80a)') ('-',k=1,80) + write (unit=*,fmt='(a,1x,2(i2.2,a),i4.4,1x,3(i2.2,a))') & + ' + TIME: ' & + ,current_time%month,'/',current_time%date,'/',current_time%year & + ,current_time%hour,':',current_time%min,':',current_time%sec,' UTC' write (unit=*,fmt='(a,1x,f9.4)') ' + LONGITUDE: ',rk4site%lon write (unit=*,fmt='(a,1x,f9.4)') ' + LATITUDE: ',rk4site%lat + write (unit=*,fmt='(a)') ' + SITE INFO: ' + write (unit=*,fmt='(a,1x,i6)') ' - NUMBER: ',isi + write (unit=*,fmt='(a,1x,i6)') ' - NTEXT(NZG) ' & + ,rk4site%ntext_soil(nzg) + write (unit=*,fmt='(a,1x,i6)') ' - LSL: ',rk4site%lsl + write (unit=*,fmt='(a,1x,i6)') ' - ISOILBC: ',rk4site%isoilbc write (unit=*,fmt='(a)') ' + PATCH INFO: ' write (unit=*,fmt='(a,1x,i6)') ' - NUMBER: ',ipa write (unit=*,fmt='(a,1x,es12.4)') ' - AGE: ',csite%age(ipa) diff --git a/ED/src/dynamics/rk4_misc.f90 b/ED/src/dynamics/rk4_misc.f90 index f847831ca..2a083d869 100644 --- a/ED/src/dynamics/rk4_misc.f90 +++ b/ED/src/dynamics/rk4_misc.f90 @@ -3707,8 +3707,8 @@ subroutine print_csiteipa(csite, ipa) write(unit=*,fmt='(80a)') ('-',k=1,80) - write (unit=*,fmt='(a,1x,2(i2.2,a),i4.4,1x,3(i2.2,a))') & - 'Time:',current_time%month,'/',current_time%date,'/',current_time%year & + write (unit=*,fmt='(a,1x,i4.4,2(a,i2.2),1x,3(i2.2,a))') & + 'Time:',current_time%year,'-',current_time%month,'-',current_time%date & ,current_time%hour,':',current_time%min,':',current_time%sec,' UTC' write(unit=*,fmt='(a,1x,es12.4)') 'Attempted step size:',csite%htry(ipa) write (unit=*,fmt='(a,1x,i6)') 'Ncohorts: ',cpatch%ncohorts diff --git a/ED/src/dynamics/vegetation_dynamics.f90 b/ED/src/dynamics/vegetation_dynamics.f90 index 645ae24c9..c30e6dcd7 100644 --- a/ED/src/dynamics/vegetation_dynamics.f90 +++ b/ED/src/dynamics/vegetation_dynamics.f90 @@ -34,7 +34,7 @@ subroutine veg_dynamics_driver(new_month,new_year,gr_tfact0,veget_dyn_on) , yr_day ! ! intent(in) use mem_polygons , only : maxpatch ! ! intent(in) use average_utils , only : normalize_ed_today_vars & ! sub-routine - , normalize_ed_todaynpp_vars & ! sub-routine + , copy_today_to_dmean_vars & ! sub-routine , zero_ed_today_vars ! ! sub-routine use canopy_radiation_coms, only : ihrzrad ! ! intent(in) use hrzshade_utils , only : split_hrzshade & ! sub-routine @@ -129,7 +129,7 @@ subroutine veg_dynamics_driver(new_month,new_year,gr_tfact0,veget_dyn_on) !------ update dmean and mmean values for NPP allocation terms ------------------! - call normalize_ed_todayNPP_vars(cgrid) + call copy_today_to_dmean_vars(cgrid) !---------------------------------------------------------------------------------! diff --git a/ED/src/init/ed_init.F90 b/ED/src/init/ed_init.F90 index b4913d66c..178165208 100644 --- a/ED/src/init/ed_init.F90 +++ b/ED/src/init/ed_init.F90 @@ -34,6 +34,12 @@ subroutine set_polygon_coordinates() cgrid%lat (ipy) = work_v(ifm)%glat (ipy) cgrid%xatm(ipy) = work_v(ifm)%xid (ipy) cgrid%yatm(ipy) = work_v(ifm)%yid (ipy) + + + + !----- Initialise load adjacency with dummy value. ----------------------------! + cgrid%load_adjacency(ipy) = 0 + !------------------------------------------------------------------------------! end do polyloop !---------------------------------------------------------------------------------! end do gridloop @@ -94,9 +100,6 @@ subroutine set_site_defprops() cgrid => edgrid_g(ifm) polyloop: do ipy=1,cgrid%npolygons - - !----- Initialise load adjacency with dummy value. ----------------------------! - cgrid%load_adjacency(ipy) = 0 !----- Alias to current polygon. ----------------------------------------------! cpoly => cgrid%polygon(ipy) @@ -311,6 +314,7 @@ subroutine load_ecosystem_state() , near_bare_ground_big_leaf_init ! ! sub-routine use ed_bigleaf_init , only : sas_to_bigleaf ! ! sub-routine #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum & ! intent(in) @@ -320,9 +324,6 @@ subroutine load_ecosystem_state() #endif implicit none -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Local variables --------------------------------------------------------------! integer :: igr integer :: ping @@ -353,7 +354,7 @@ subroutine load_ecosystem_state() do igr = 1,ngrids call read_site_file(edgrid_g(igr),igr) end do - case (4,7) + case (4,7,8) continue case default call set_site_defprops() @@ -447,6 +448,30 @@ subroutine load_ecosystem_state() end do end select + + + case (8) + !---------------------------------------------------------------------------------! + ! Initialise model with ED-2 initial conditions file. This is somewhat ! + ! similar to option 6, but it allows multiple sites, and these files do not ! + ! require any transformation of PFTs and disturbance type flags. ! + !---------------------------------------------------------------------------------! + write(unit=*,fmt='(a,i3.3)') & + ' + Initialise from ED2 initial conditions file. Node: ',mynum + call read_ed22_initial_file() + !---------------------------------------------------------------------------------! + + + + !----- In case this is a big-leaf simulation, convert initial conditions. --------! + select case (ibigleaf) + case (1) + do igr=1,ngrids + call sas_to_bigleaf(edgrid_g(igr)) + end do + end select + !---------------------------------------------------------------------------------! + end select @@ -529,7 +554,8 @@ subroutine sfcdata_ed() use rk4_coms , only : ipercol ! ! intent(in) use grid_coms , only : nzg & ! intent(in) , nzs ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) + use ed_max_dims , only : ed_nstyp ! ! intent(in) + use soil_coms , only : soil_hydro_scheme & ! intent(in) , slz & ! intent(in) , dslz & ! intent(out) , dslzo2 & ! intent(out) @@ -552,7 +578,8 @@ subroutine sfcdata_ed() , slcons18 & ! intent(out) , soil & ! intent(in) , thicknet & ! intent(out) - , thick ! ! intent(out) + , thick & ! intent(out) + , ed_gen_soil_table ! ! subroutine use consts_coms , only : wdns & ! intent(in) , wdnsi8 ! ! intent(in) use rk4_coms , only : rk4min_sfcw_moist & ! intent(in) @@ -560,11 +587,14 @@ subroutine sfcdata_ed() , rk4min_sfcw_mass & ! intent(out) , rk4min_virt_water ! ! intent(out) use ed_misc_coms, only : dtlsm ! ! intent(in) + use decomp_coms , only : rh_active_depth & ! intent(in) + , k_rh_active ! ! intent(out) implicit none !----- Local variables --------------------------------------------------------------! integer :: k integer :: nnn integer :: kzs + logical :: is_hydr_decay real :: thik real :: stretch real :: slz0 @@ -625,15 +655,19 @@ subroutine sfcdata_ed() end do + + !------------------------------------------------------------------------------------! + ! Generate the look-up table for soil properties. ! + !------------------------------------------------------------------------------------! + call ed_gen_soil_table() + !------------------------------------------------------------------------------------! + + !----- Find layer-dependent hydraulic conductivity. ---------------------------------! + is_hydr_decay = (ipercol == 2) .or. (soil_hydro_scheme == 2) do nnn = 1,ed_nstyp do k = 0,nzg - select case (ipercol) - case (0,1) - !----- Original form, constant with depth. --------------------------------! - slcons1(k,nnn) = soil(nnn)%slcons - !---------------------------------------------------------------------------! - case (2) + if (is_hydr_decay) then !---------------------------------------------------------------------------! ! Define conductivity using the SIMTOP approach (N05). ! ! ! @@ -645,7 +679,12 @@ subroutine sfcdata_ed() !---------------------------------------------------------------------------! slcons1(k,nnn) = soil(nnn)%slcons * exp ( soil(nnn)%fhydraul * slzt(k)) !---------------------------------------------------------------------------! - end select + else + !----- Original form, constant with depth. --------------------------------! + slcons1(k,nnn) = soil(nnn)%slcons + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! !------ Find the double precision. --------------------------------------------! slcons18(k,nnn) = dble(slcons1(k,nnn)) @@ -676,6 +715,20 @@ subroutine sfcdata_ed() !----- Assigning some soil grid-dependent RK4 variables -----------------------------! rk4min_sfcw_mass = rk4min_sfcw_moist * wdns * dslz(nzg) rk4min_virt_water = rk4min_virt_moist * wdns * dslz(nzg) + !------------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------------! + ! Determine the bottommost layer to consider for environmental regulation of ! + ! heterotrophic respiration. ! + !------------------------------------------------------------------------------------! + k_rh_loop: do k_rh_active=nzg-1,1,-1 + if (slz(k_rh_active) < rh_active_depth) exit k_rh_loop + end do k_rh_loop + k_rh_active = k_rh_active + 1 + !------------------------------------------------------------------------------------! return end subroutine sfcdata_ed diff --git a/ED/src/init/ed_init_atm.F90 b/ED/src/init/ed_init_atm.F90 index 65cf07ee4..041ab13d0 100644 --- a/ED/src/init/ed_init_atm.F90 +++ b/ED/src/init/ed_init_atm.F90 @@ -33,6 +33,7 @@ subroutine ed_init_atm() , terminate_cohorts & ! subroutine , split_cohorts ! ! subroutine #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : nnodetot & ! intent(in) , mynum & ! intent(in) , sendnum & ! intent(in) @@ -95,10 +96,6 @@ subroutine ed_init_atm() !----- Local variables (MPI only). -----------------------------------------------------! #if defined(RAMS_MPI) integer :: ierr -#endif - !----- Add the MPI common block. -------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/init/ed_params.f90 b/ED/src/init/ed_params.f90 index 98b14d90b..bc69b26cb 100644 --- a/ED/src/init/ed_params.f90 +++ b/ED/src/init/ed_params.f90 @@ -525,7 +525,7 @@ subroutine init_decomp_params() rh0 = 0.700 ! 0.701 ! 0.425 rh_q10 = 1.500 ! 1.500 ! 1.893 rh_p_smoist = 1.600 ! 0.836 ! 0.606 - rh_p_oxygen = 0.600 ! 0.404 ! 0.164 + rh_p_oxygen = 0.450 ! 0.404 ! 0.164 !---------------------------------------------------------------------------------------! @@ -1525,12 +1525,15 @@ end subroutine init_hydro_coms !==========================================================================================! !==========================================================================================! ! Subroutine that initialises most of the soil parameters. ! +! ! +! MLO: This sub-routine formerly initiliased the soil and soil8 tables, but this creates ! +! a problem for some HISTORY runs (especially those with multiple sites that modify ! +! the default parameters). The soil table is now initialised in a separate sub- ! +! routine (ed_gen_soil_table), after loading HISTORY variables, or right before or ! +! right after reading the initial conditions. ! !------------------------------------------------------------------------------------------! subroutine init_soil_coms - use detailed_coms , only : idetailed ! ! intent(in) - use ed_max_dims , only : str_len ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) - , isoilflg & ! intent(in) + use soil_coms , only : isoilflg & ! intent(in) , nslcon & ! intent(in) , soil_hydro_scheme & ! intent(in) , slxclay & ! intent(in) @@ -1539,11 +1542,17 @@ subroutine init_soil_coms , slph & ! intent(in) , slcec & ! intent(in) , sldbd & ! intent(in) - , soil & ! intent(in) - , soil_class & ! type + , slxkey_ref & ! intent(out) + , slhydro_ref & ! intent(out) + , slxclay_ref & ! intent(out) + , slxsilt_ref & ! intent(out) + , slxsand_ref & ! intent(out) + , slsoc_ref & ! intent(out) + , slph_ref & ! intent(out) + , slcec_ref & ! intent(out) + , sldbd_ref & ! intent(out) , soilcol & ! intent(in) , soilcol_class & ! type - , soil8 & ! intent(out) , water_stab_thresh & ! intent(out) , snowmin & ! intent(out) , dewmax & ! intent(out) @@ -1564,68 +1573,18 @@ subroutine init_soil_coms , sin_sldrain & ! intent(out) , sin_sldrain8 & ! intent(out) , hydcond_min & ! intent(out) - , hydcond_min8 & ! intent(out) - , ed_init_soil & ! subroutine - , matric_potential & ! function - , soil_moisture ! ! function - use phenology_coms , only : thetacrit ! ! intent(in) - use disturb_coms , only : sm_fire ! ! intent(in) + , hydcond_min8 ! ! intent(out) use grid_coms , only : ngrids ! ! intent(in) - use consts_coms , only : grav & ! intent(in) - , wdns & ! intent(in) - , hr_sec & ! intent(in) + use consts_coms , only : wdns & ! intent(in) , day_sec & ! intent(in) , pio180 & ! intent(in) , pio1808 ! ! intent(in) implicit none !----- Local variables. ----------------------------------------------------------------! - integer :: s ! Soil texture flag logical :: update_slx ! Update texture fractions? [ T|F] - logical :: print_soil_table ! Print parameter table? [ T|F] - real(kind=4) :: soilep ! Effective porosity (O19) [ m3/m3] - real(kind=4) :: slpot33 ! Potential for EP (O19) [ m] - real(kind=4) :: slcons_mmhr ! Sat. hydraulic conduct. [ mm/hr] - real(kind=4) :: slcpd_mjm3k ! Soil heat capacity [MJ/m3/K] - real(kind=4) :: ksand ! k-factor for sand (de Vries model) - real(kind=4) :: ksilt ! k-factor for silt (de Vries model) - real(kind=4) :: kclay ! k-factor for clay (de Vries model) - real(kind=4) :: kair ! k-factor for air (de Vries model) - !----- Initial sand and clay volumetric fractions. -------------------------------------! - real(kind=4) , dimension(ed_nstyp) :: xsand_def ! Default sand fraction [ 0-1] - real(kind=4) , dimension(ed_nstyp) :: xclay_def ! Default clay fraction [ 0-1] - !---- Soil texture acronym. ------------------------------------------------------------! - character(len=4), dimension(ed_nstyp) :: xkey_def ! Acronym !----- Local constants. ----------------------------------------------------------------! - real(kind=4), parameter :: fieldcp_K = 0.1 ! hydr. cond. at field cap. [mm/day] - real(kind=4), parameter :: residual_K = 1.e-5 ! minimum hydr. cond. (RS02) [mm/day] - real(kind=4), parameter :: slpots_MPa = -0.0005 ! Saturation for vG80 [ MPa] - real(kind=4), parameter :: slpot33_MPa = -0.033 ! Potential for soilep (O19) [ MPa] - real(kind=4), parameter :: slpotfc_MPa = -0.010 ! Field capacity (TH98) [ MPa] - real(kind=4), parameter :: slpotcp_MPa = -3.1 ! Matric pot. - air dry soil [ MPa] - real(kind=4), parameter :: slpotwp_MPa = -1.5 ! Matric pot. - wilting point [ MPa] - real(kind=4), parameter :: sand_hcapv = 2.128e6 ! Sand vol. heat capacity [J/m3/K] - real(kind=4), parameter :: clay_hcapv = 2.385e6 ! Clay vol. heat capacity [J/m3/K] - real(kind=4), parameter :: silt_hcapv = 2.256e6 ! Silt vol. heat capacity (*) [J/m3/K] - real(kind=4), parameter :: air_hcapv = 1.212e3 ! Air vol. heat capacity [J/m3/K] - real(kind=4), parameter :: sand_thcond = 8.80 ! Sand thermal conduct. [ W/m/K] - real(kind=4), parameter :: clay_thcond = 2.92 ! Clay thermal conduct. [ W/m/K] - real(kind=4), parameter :: silt_thcond = 5.87 ! Silt thermal conduct. (*) [ W/m/K] - real(kind=4), parameter :: air_thcond = 0.025 ! Air thermal conduct. [ W/m/K] - real(kind=4), parameter :: h2o_thcond = 0.57 ! Water thermal conduct. [ W/m/K] - !------ Name for the parameter table. --------------------------------------------------! - character(len=str_len), parameter :: soil_table_fn = 'soil_properties.txt' - !---------------------------------------------------------------------------------------! - ! (*) If anyone has the heat capacity and thermal conductivity for silt, please feel ! - ! free to add it in here, I didn't find any. Apparently no one knows, and I've ! - ! seen in other models that people just assume either the same as sand or the ! - ! average. Here I'm just using halfway. I think the most important thing is to ! - ! take into account the soil and the air, which are the most different. ! - ! ! - ! Sand (quartz), clay, air, and water heat capacities and thermal conductivities values ! - ! are from: ! - ! Monteith and Unsworth, 2008: Environmental Physics. ! - ! Academic Press, Third Edition. Table 15.1, p. 292 ! + real(kind=4), parameter :: residual_K = 1.e-5 ! min. hydr. cond. (RS02) [mm/day] !---------------------------------------------------------------------------------------! @@ -1659,24 +1618,24 @@ subroutine init_soil_coms !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! - ! Initialise the soil and soil8 structures. ! - !---------------------------------------------------------------------------------------! - call ed_init_soil() - !---------------------------------------------------------------------------------------! - - !---------------------------------------------------------------------------------------! ! Removed the hardcoded initialisation of the entire structure. Instead, we set the ! ! texture for every class, then use the equations to populate the structure. ! !---------------------------------------------------------------------------------------! - xsand_def = (/ 0.920, 0.825, 0.660, 0.200, 0.410, 0.590, 0.100, 0.320 & - , 0.520, 0.060, 0.200, 0.200, 0.333, 0.075, 0.100, 0.375, 0.125 /) - xclay_def = (/ 0.030, 0.060, 0.110, 0.160, 0.170, 0.270, 0.340, 0.340 & - , 0.420, 0.470, 0.600, 0.200, 0.333, 0.050, 0.800, 0.525, 0.525 /) - xkey_def = (/' Sa',' LSa',' SaL',' SiL',' L','SaCL','SiCL',' CL' & - ,' SaC',' SiC',' C','Peat','BdRk',' Si',' CC',' CSa',' CSi' /) + slxkey_ref ( :) = (/' Sa',' LSa',' SaL',' SiL',' L','SaCL','SiCL',' CL' & + ,' SaC',' SiC',' C','Peat','BdRk',' Si',' CC',' CSa',' CSi' /) + slxsand_ref( :) = (/ 0.920, 0.825, 0.660, 0.200, 0.410, 0.590, 0.100, 0.320 & + , 0.520, 0.060, 0.200, 0.200, 0.333, 0.075, 0.100, 0.375, 0.125 /) + slxclay_ref( :) = (/ 0.030, 0.060, 0.110, 0.160, 0.170, 0.270, 0.340, 0.340 & + , 0.420, 0.470, 0.600, 0.200, 0.333, 0.050, 0.800, 0.525, 0.525 /) + slxsilt_ref( :) = 1. - slxsand_ref(:) - slxclay_ref(:) + slhydro_ref( :) = soil_hydro_scheme + slhydro_ref(12) = 12 + slhydro_ref(13) = 13 + slsoc_ref ( :) = slsoc + slph_ref ( :) = slph + slcec_ref ( :) = slcec + sldbd_ref ( :) = sldbd !---------------------------------------------------------------------------------------! @@ -1686,620 +1645,15 @@ subroutine init_soil_coms update_slx = any(isoilflg(1:ngrids) == 2) .and. slxclay > 0. .and. slxsand > 0. .and. & (slxclay + slxsand) <= 1. if (update_slx) then - xsand_def(nslcon) = slxsand - xclay_def(nslcon) = slxclay - xkey_def (nslcon) = 'User' + slxsand_ref(nslcon) = slxsand + slxclay_ref(nslcon) = slxclay + slxsilt_ref(nslcon) = 1. - slxsand - slxclay + slxkey_ref (nslcon) = 'User' end if !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Assign texture and silt fraction (method-independent). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - soil(s)%key = xkey_def(s) - soil(s)%xsand = xsand_def(s) - soil(s)%xclay = xclay_def(s) - soil(s)%xsilt = 1. - xsand_def(s) - xclay_def(s) - end do - !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - ! Other soil properties (relevant only when SOIL_HYDRO_SCHEME = 2). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - soil(s)%slsoc = slsoc - soil(s)%slph = slph - soil(s)%slcec = slcec - soil(s)%sldbd = sldbd - end do - !---------------------------------------------------------------------------------------! - - - - !---------------------------------------------------------------------------------------! - ! Calculate method- and texture-dependent properties. For a general overview, ! - ! check (M14). Additional references correspond to specific parametrisations. ! - ! ! - ! References: ! - ! ! - ! Brooks RH , Corey AT. 1964. Hydraulic properties of porous media. Hydrology Papers 3, ! - ! Colorado State University, Fort Collins, U.S.A (BC64). ! - ! Marthews TR, Quesada CA, Galbraith DR, Malhi Y, Mullins CE, Hodnett MG , Dharssi I. ! - ! 2014. High-resolution hydraulic parameter maps for surface soils in tropical South ! - ! America. Geosci. Model Dev. 7: 711-723. doi:10.5194/gmd-7-711-2014 (M14). ! - ! Campbell GS. 1974. A simple method for determining unsaturated conductivity from ! - ! moisture retention data. Soil Science 117: 311-314. ! - ! doi:10.1097/00010694-197406000-00001 (C74). ! - ! Cosby BJ, Hornberger GM, Clapp RB , Ginn TR. 1984. A statistical exploration of the ! - ! relationships of soil moisture characteristics to the physical properties of ! - ! soils. Water Resour. Res. 20: 682-690. doi:10.1029/WR020i006p00682 (C84). ! - ! van Genuchten MT. 1980. A closed-form equation for predicting the hydraulic ! - ! conductivity of unsaturated soils1. Soil Sci. Soc. Am. J. 44: 892-898. ! - ! doi:10.2136/sssaj1980.03615995004400050002x (vG80). ! - ! Hodnett M , Tomasella J. 2002. Marked differences between van Genuchten soil ! - ! water-retention parameters for temperate and tropical soils: a new ! - ! water-retention pedo-transfer functions developed for tropical soils. Geoderma ! - ! 108: 155-180. doi:10.1016/S0016-7061(02)00105-2 (HT02). ! - ! Montzka C, Herbst M, Weihermuller L, Verhoef A , Vereecken H. 2017. A global data set ! - ! of soil hydraulic properties and sub-grid variability of soil water retention and ! - ! hydraulic conductivity curves. Earth Syst. Sci. Data, 9: 529-543. ! - ! doi:10.5194/essd-9-529-2017 (M17). ! - ! Mualem Y. 1976. A new model for predicting the hydraulic conductivity of unsaturated ! - ! porous media. Water Resour. Res., 12: 513-522. doi:10.1029/WR012i003p00513 (M76). ! - ! Ottoni MV, Ottoni Filho TB, Lopes-Assad MLR , Rotunno Filho OC. 2019. Pedotransfer ! - ! functions for saturated hydraulic conductivity using a database with temperate and ! - ! tropical climate soils. J. Hydrol., 575: 1345-1358. ! - ! doi:10.1016/j.jhydrol.2019.05.050 (O19). ! - ! Romano N , Santini A. 2002. Field. In: Methods of soil analysis: Part 4 physical ! - ! methods (eds. Dane JH. & Topp GC.). Soil Science Society of America, Madison, WI, ! - ! SSSA Book Series 5.4, chap. 3.3.3, pp. 721--738 (RS02). ! - ! Schaap MG , Leij FJ. 2000. Improved prediction of unsaturated hydraulic conductivity ! - ! with the Mualem- van Genuchten model. Soil Sci. Soc. Am. J., 64: 843-851. ! - ! doi:10.2136/sssaj2000.643843x (SL00). ! - ! Tomasella J , Hodnett MG. 1998. Estimating soil water retention characteristics from ! - ! limited data in Brazilian Amazonia. Soil Sci. 163: 190-202. ! - ! doi:10.1097/00010694-199803000-00003 (TH98). ! - !---------------------------------------------------------------------------------------! - do s=1,ed_nstyp - - !----- Check soil texture. Peat and bedrock must be handled separately. ------------! - select case (s) - case (12) - !---------------------------------------------------------------------------------! - ! Peat. We always use BC64-M76 approach. This modify hydraulic properties ! - ! to account for high soil organic content. This class becomes obsolete for ! - ! SOIL_HYDRO_SCHEME=2 because we can account for SOC directly. ! - ! ! - ! MLO - I noticed that most parameters do not correspond to what is implemented ! - ! in LEAF3 (as of RAMS-6.0). I left the LEAF3 values as comments next to ! - ! the default values but someone running ED2 for peats should check. I ! - ! think the LEAF3 values intuitively make more sense for peat. ! - !---------------------------------------------------------------------------------! - soil(s)%method = 'BC64' - - !----- Peat, use the default value from LEAF3. -----------------------------------! - soil(s)%slcons = 8.0e-6 ! ED-2.2 2.357930e-6 - !---------------------------------------------------------------------------------! - - !---- Pore tortuosity factor. Assumed 1 to be consistent with BC64. --------------! - soil(s)%sltt = 1.0 - !---------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, aka ! - ! BC64's "b" factor). ! - !---------------------------------------------------------------------------------! - soil(s)%slbs = 7.75 ! ED-2.2 6.180000 - soil(s)%slnm = 1. / soil(s)%slbs - !---------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !---------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !---------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. -------------------------------------------------! - soil(s)%slpots = -0.356 ! ED-2.2 -0.534564359 - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp ! Inverse of bubbling point (not used) - !---------------------------------------------------------------------------------! - - - - !----- Soil moisture at saturation [m3/m3]. --------------------------------------! - soil(s)%slmsts = 0.863 ! ED-2.2 0.469200 - soil(s)%soilbp = soil(s)%slmsts ! Assume the same as saturation - soil(s)%soilpo = soil(s)%slmsts ! Assume the same as saturation - !---------------------------------------------------------------------------------! - - - !---- Field capacity [m3/m3] and potential at field capacity [m]. ----------------! - soil(s)%sfldcap = 0.535 ! ED-2.2 0.285709966 - soil(s)%slpotfc = matric_potential(s,soil(s)%sfldcap) - !---------------------------------------------------------------------------------! - - - !----- Residual moisture [m3/m3]. Ignored in C74 and the default ED2 method. ----! - soil(s)%soilre = 0. - !---------------------------------------------------------------------------------! - - - !----- Heat capacity. ------------------------------------------------------------! - soil(s)%slcpd = 874000. - !---------------------------------------------------------------------------------! - case (13) - !----- Bedrock. Hydraulics is disabled, only heat capacity is needed. -----------! - soil(s)%method = 'BDRK' - soil(s)%slcons = 0.0 - soil(s)%sltt = 0.0 - soil(s)%slnm = 1.0 - soil(s)%slbs = 1.0 - soil(s)%slmm = 1.0 - soil(s)%slmu = 1.0 - soil(s)%malpha = 0.0 - soil(s)%slpots = 0.0 - soil(s)%slmsts = 0.0 - soil(s)%slpotbp = 0.0 - soil(s)%soilbp = 0.0 - soil(s)%slpotpo = 0.0 - soil(s)%soilpo = 0.0 - soil(s)%soilre = 0.0 - soil(s)%sfldcap = 0.0 - soil(s)%slpotfc = 0.0 - soil(s)%slcpd = 2130000. - !---------------------------------------------------------------------------------! - case default - !---------------------------------------------------------------------------------! - ! Other soils. Decide on hydraulic parameters based on the method. ! - !---------------------------------------------------------------------------------! - select case (soil_hydro_scheme) - case (0) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from BC64/M76. Unless noted otherwise, the ! - ! parameters for the functions are from C84, based on measurements in the ! - ! United States. ! - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. ! - !------------------------------------------------------------------------------! - soil(s)%slcons = (10.**(-0.60 + 1.26*soil(s)%xsand - 0.64*soil(s)%xclay)) & - * 0.0254/hr_sec - !------------------------------------------------------------------------------! - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'BC64' - !------------------------------------------------------------------------------! - - - !---- Pore tortuosity factor. Assumed 1 to be consistent with BC64. -----------! - soil(s)%sltt = 1.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = 1. / (3.10 + 15.7*soil(s)%xclay - 0.3*soil(s)%xsand) - soil(s)%slbs = 1. / soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. ----------------------------------------------! - soil(s)%slpots = -1. & - * (10.**(2.17 - 0.63*soil(s)%xclay - 1.58*soil(s)%xsand)) * 0.01 - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - !----- Soil moisture at saturation (porosity) [m3/m3]. ------------------------! - soil(s)%slmsts = 0.01 * (50.5 - 14.2*soil(s)%xsand - 3.7*soil(s)%xclay) - !------------------------------------------------------------------------------! - - - !----- Bubbling point soil moisture and porosity, assume saturation [m3/m3]. --! - soil(s)%soilbp = soil(s)%slmsts ! Bubbling point - soil(s)%soilpo = soil(s)%slmsts ! Porosity - !------------------------------------------------------------------------------! - - - !----- Residual moisture [m3/m3]. Ignored in C74 and the default ED2 method. -! - soil(s)%soilre = 0.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%sfldcap = soil(s)%slmsts & - * ( soil(s)%slcons / ( fieldcp_K / ( wdns * day_sec ) ) ) & - ** soil(s)%slmu - soil(s)%slpotfc = matric_potential(s,soil(s)%sfldcap) - !------------------------------------------------------------------------------! - - case (1) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from BC64/M76. Unless noted otherwise, the ! - ! parameters for the functions are from TH98, based on measurements in the ! - ! Brazilian Amazon. ! - !------------------------------------------------------------------------------! - - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'BC64' - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. Use C84 settings, follow- ! - ! ing M14. ! - !------------------------------------------------------------------------------! - soil(s)%slcons = (10.**(-0.60 + 1.26*soil(s)%xsand - 0.64*soil(s)%xclay)) & - * 0.0254/hr_sec - !------------------------------------------------------------------------------! - - - !---- Pore tortuosity factor. Assumed 0.5, following M14. ---------------------! - soil(s)%sltt = 0.5 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = exp( - 1.197 - 0.417 * soil(s)%xsilt + 0.450 * soil(s)%xclay & - - 8.940 * soil(s)%xsilt * soil(s)%xclay & - + 10.00 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay ) - soil(s)%slbs = 1./ soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 2. + soil(s)%sltt + 2. * soil(s)%slbs - soil(s)%slmu = -1. / soil(s)%slmm - !------------------------------------------------------------------------------! - - - !----- Saturation potential [m]. ----------------------------------------------! - soil(s)%slpots = -1. / grav & - * ( 0.285 + 7.33 * soil(s)%xsilt * soil(s)%xsilt & - - 1.30 * soil(s)%xsilt * soil(s)%xclay & - + 3.60 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay ) - soil(s)%slpotbp = soil(s)%slpots ! Bubbling point, assume saturation - soil(s)%slpotpo = soil(s)%slpots ! Porosity, assume saturation - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - !----- Soil moisture at saturation (porosity) [m3/m3]. ------------------------! - soil(s)%slmsts = 0.4061 + 0.165 * soil(s)%xsilt + 0.162 * soil(s)%xclay & - + 1.37e-3 * soil(s)%xsilt * soil(s)%xsilt & - + 1.80e-5 * soil(s)%xsilt * soil(s)%xsilt * soil(s)%xclay - !------------------------------------------------------------------------------! - - - !----- Bubbling point soil moisture and porosity, assume saturation [m3/m3]. --! - soil(s)%soilbp = soil(s)%slmsts ! Bubbling point - soil(s)%soilpo = soil(s)%slmsts ! Porosity - !------------------------------------------------------------------------------! - - - - !----- Residual moisture [m3/m3]. --------------------------------------------! - soil(s)%soilre = max( 0.0 & - , - 0.02095 + 0.047 * soil(s)%xsilt & - + 0.431 * soil(s)%xclay & - - 0.00827 * soil(s)%xsilt * soil(s)%xclay ) - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%slpotfc = slpotfc_MPa * 1.e6 / (grav * wdns) - soil(s)%sfldcap = soil_moisture(s,soil(s)%slpotfc) - !------------------------------------------------------------------------------! - - case (2) - !------------------------------------------------------------------------------! - ! Pedotransfer functions from vG80/M76. Unless noted otherwise, ! - ! the parameters for the function are from HT02, based on measurements in the ! - ! Brazilian Amazon. ! - !------------------------------------------------------------------------------! - - - !---- Flag for method. --------------------------------------------------------! - soil(s)%method = 'vG80' - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore tortuosity factor. M14 assumed 0.5, but there is evidence that ! - ! this parameter should be regarded as empirical and some studies suggested ! - ! that it should be even negative (e.g., SL00 and M17). We follow SL00 and ! - ! assume the parameter to be -1.0. ! - !------------------------------------------------------------------------------! - soil(s)%sltt = -1.0 - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Pore-size distribution factor (slnm, aka lambda) and its inverse (slbs, ! - ! aka BC64's "b" factor). ! - !------------------------------------------------------------------------------! - soil(s)%slnm = exp( 0.62986 - 0.833 * soil(s)%xclay - 0.529 * soil(s)%slsoc & - + 0.00593 * soil(s)%slph & - + 0.700 * soil(s)%xclay * soil(s)%xclay & - - 1.400 * soil(s)%xsand * soil(s)%xsilt ) - soil(s)%slbs = 1./ soil(s)%slnm - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Ancillary parameters used for hydraulic conductivity. ! - !------------------------------------------------------------------------------! - soil(s)%slmm = 1. - 1. / soil(s)%slnm - soil(s)%slmu = soil(s)%slnm / (1. - soil(s)%slnm) - !------------------------------------------------------------------------------! - - - !----- Bubbling point potential [m]. Assume equivalent to saturation. --------! - soil(s)%slpotbp = -1. / grav & - * exp( 0.02294 + 3.526 * soil(s)%xsilt & - - 2.440 * soil(s)%slsoc + 0.076 * soil(s)%slcec & - + 0.11331 * soil(s)%slph & - - 1.90000 * soil(s)%xsilt * soil(s)%xsilt ) - soil(s)%malpha = 1. / soil(s)%slpotbp - !------------------------------------------------------------------------------! - - - - !----- Soil moisture and potential at porosity [m3/m3]. -----------------------! - soil(s)%soilpo = 0.81799 + 0.099 * soil(s)%xclay - 3.142e-4 * soil(s)%sldbd & - + 0.01800 * soil(s)%slcec + 0.00451 * soil(s)%slph & - - 0.050 * soil(s)%xsand * soil(s)%xclay - soil(s)%slpotpo = matric_potential(s,soil(s)%soilpo) - !------------------------------------------------------------------------------! - - - - !----- Residual moisture [m3/m3]. --------------------------------------------! - soil(s)%soilre = max( 0.0 & - , 0.22733 - 0.164 * soil(s)%xsand + 0.235 * soil(s)%slcec & - - 0.00831 * soil(s)%slph & - + 0.18 * soil(s)%xclay * soil(s)%xclay & - + 0.26 * soil(s)%xsand * soil(s)%xclay ) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Soil moisture at "saturation". The vG80 approach assumes that actual ! - ! saturation occurs when soil matric potential is zero, which causes ! - ! singularities in many applications. To prevent FPE errors, we assume that ! - ! water potential zero corresponds to porosity (admittedly this is not ! - ! entirely accurate), and impose "saturation" for ED-2.2 purposes to be when ! - ! matric potential is -0.5 kPa, similar to the highest saturation potential ! - ! values obtained through Cosby et al. (1984) parametrisation. ! - !------------------------------------------------------------------------------! - soil(s)%slpots = slpots_MPa * 1.e6 / (grav * wdns) - soil(s)%slmsts = soil_moisture(s,soil(s)%slpots) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Soil moisture at bubbling point. Unlike other schemes, we account for ! - ! the differences between bubbling point and porosity. ! - !------------------------------------------------------------------------------! - soil(s)%soilbp = soil_moisture(s,soil(s)%slpotbp) - !------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------! - ! Field capacity is defined based on hydraulic conductivity of 0.1 ! - ! mm/day, following RS02. ! - !------------------------------------------------------------------------------! - soil(s)%slpotfc = slpotfc_MPa * 1.e6 / (grav * wdns) - soil(s)%sfldcap = soil_moisture(s,soil(s)%slpotfc) - !------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------! - ! Hydraulic conductivity at saturation [m/s]. Here we follow O19, which ! - ! depends upon the "effective porosity" (or difference between actual porosity ! - ! and soil moisture at -0.033 MPa). ! - !------------------------------------------------------------------------------! - slpot33 = slpot33_MPa * 1.e6 / (grav * wdns) - soilep = max(0.,soil(s)%slmsts - soil_moisture(s,slpot33)) - soil(s)%slcons = 19.31 / day_sec * soilep ** 1.948 - !------------------------------------------------------------------------------! - end select - !---------------------------------------------------------------------------------! - - end select - !------------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------------! - ! Additional derived parameters. ! - !------------------------------------------------------------------------------------! - select case (s) - case (13) - !----- Bedrock, do nothing. ------------------------------------------------------! - soil(s)%slpotcp = 0.0 - soil(s)%slpotwp = 0.0 - soil(s)%slpotfr = 0.0 - soil(s)%slpotld = 0.0 - soil(s)%slpotfc = 0.0 - soil(s)%slpotbp = 0.0 - soil(s)%slpots = 0.0 - soil(s)%slpotpo = 0.0 - soil(s)%soilcp = 0.0 - soil(s)%soilwp = 0.0 - soil(s)%soilfr = 0.0 - soil(s)%soilld = 0.0 - soil(s)%sfldcap = 0.0 - soil(s)%soilbp = 0.0 - soil(s)%slmsts = 0.0 - soil(s)%soilpo = 0.0 - soil(s)%fhydraul = 0.0 - !---------------------------------------------------------------------------------! - case default - !----- First guess, use water potential. -----------------------------------------! - soil(s)%slpotwp = slpotwp_MPa * 1.e6 / ( grav * wdns ) - soil(s)%slpotcp = slpotcp_MPa * wdns / grav - soil(s)%soilwp = soil_moisture(s,soil(s)%slpotwp) - soil(s)%soilcp = soil_moisture(s,soil(s)%slpotcp) - !----- In case soilcp is less than the residual (very unlikely), recalculate it. -! - if (soil(s)%soilcp < soil(s)%soilre) then - soil(s)%soilcp = soil(s)%soilre - soil(s)%slpotcp = matric_potential(s,soil(s)%soilcp) - end if - !----- Because we may have artificially increased soilcp, check soilwp. ----------! - if (soil(s)%soilwp < soil(s)%soilcp) then - soil(s)%soilwp = soil(s)%soilcp - soil(s)%slpotwp = soil(s)%slpotcp - end if - !---------------------------------------------------------------------------------! - - - - - !---------------------------------------------------------------------------------! - ! Find two remaining properties, that depend on the user choices. ! - ! ! - ! SOILLD/SLPOTLD. ! - ! The critical soil moisture below which drought deciduous plants start drop- ! - ! ping their leaves. The sign of input variable THETACRIT matters here. If ! - ! the user gave a positive number (or 0), then the soil moisture is a ! - ! fraction above wilting point. If it is negative, the value is the potential ! - ! in MPa. ! - ! SOILFR/SLPOTFR. ! - ! The critical soil moisture below which fires may happen, provided that the ! - ! user wants fires, and that there is enough biomass to burn. The sign of the ! - ! input variable SM_FIRE matters here. If the user gave a positive number ! - ! (or 0), then the soil moisture is a fraction above dry air soil. If it is ! - ! negative, the value is the potential in MPa. ! - !---------------------------------------------------------------------------------! - !----- Leaf drop. ----------------------------------------------------------------! - if (thetacrit >= 0.0) then - soil(s)%soilld = soil(s)%soilwp + thetacrit * (soil(s)%slmsts-soil(s)%soilwp) - soil(s)%slpotld = matric_potential(s,soil(s)%soilld) - else - soil(s)%slpotld = thetacrit * 1.e6 / (grav * wdns) - soil(s)%soilld = soil_moisture(s,soil(s)%slpotld) - end if - !----- Fire. ---------------------------------------------------------------------! - if (sm_fire >= 0.0) then - soil(s)%soilfr = soil(s)%soilcp + sm_fire * (soil(s)%slmsts-soil(s)%soilcp) - soil(s)%slpotfr = matric_potential(s,soil(s)%soilfr) - else - soil(s)%slpotfr = sm_fire * 1.e6 / (grav * wdns) - soil(s)%soilfr = soil_moisture(s,soil(s)%slpotfr) - end if - !---------------------------------------------------------------------------------! - - - - - !---------------------------------------------------------------------------------! - ! Define hydraulic parameter decay, similar to TOPMODEL. We currently use ! - ! the default value of 2.0, following N05's SIMTOP model. ! - ! ! - ! Niu GY, Yang ZL, Dickinson RE , Gulden LE. 2005. A simple TOPMODEL-based runoff ! - ! parameterization (SIMTOP) for use in global climate models. J. Geophys. ! - ! Res.-Atmos., 110: D21106. doi:10.1029/2005JD006111 (N05). ! - !---------------------------------------------------------------------------------! - soil(s)%fhydraul = 2.0 - !---------------------------------------------------------------------------------! - end select - !------------------------------------------------------------------------------------! - - - - !------------------------------------------------------------------------------------! - ! Heat capacity (J/m3/K). Here we take the volume average amongst silt, clay, ! - ! and sand, and consider the contribution of air sitting in. In order to keep it ! - ! simple, we assume that the air fraction won't change, although in reality its ! - ! contribution should be a function of soil moisture. Here we use the amount of air ! - ! in case the soil moisture was halfway between dry air and saturated, so the ! - ! error is not too biased. ! - !------------------------------------------------------------------------------------! - soil(s)%slcpd = (1. - soil(s)%slmsts) & - * ( soil(s)%xsand * sand_hcapv + soil(s)%xsilt * silt_hcapv & - + soil(s)%xclay * clay_hcapv ) & - + 0.5 * ( soil(s)%slmsts - soil(s)%soilcp ) * air_hcapv - !------------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------------! - ! Thermal conductivity is the weighted average of thermal conductivities of all ! - ! materials, although a further weighting factor due to thermal gradient of ! - ! different materials. We use the de Vries model described at: ! - ! ! - ! Camillo, P., T.J. Schmugge, 1981: A computer program for the simulation of heat ! - ! and moisture flow in soils, NASA-TM-82121, Greenbelt, MD, United States. ! - ! ! - ! Parlange, M.B., et al., 1998: Review of heat and water movement in field soils, ! - ! Soil Till. Res., 47(1-2), 5-10. ! - ! ! - !------------------------------------------------------------------------------------! - !---- The k-factors, assuming spherical particles. ----------------------------------! - ksand = 3. * h2o_thcond / ( 2. * h2o_thcond + sand_thcond ) - ksilt = 3. * h2o_thcond / ( 2. * h2o_thcond + silt_thcond ) - kclay = 3. * h2o_thcond / ( 2. * h2o_thcond + clay_thcond ) - kair = 3. * h2o_thcond / ( 2. * h2o_thcond + air_thcond ) - !---- The conductivity coefficients. ------------------------------------------------! - soil(s)%thcond0 = (1. - soil(s)%slmsts ) & - * ( ksand * soil(s)%xsand * sand_thcond & - + ksilt * soil(s)%xsilt * silt_thcond & - + kclay * soil(s)%xclay * clay_thcond ) & - + soil(s)%slmsts * kair * air_thcond - soil(s)%thcond1 = h2o_thcond - kair * air_thcond - soil(s)%thcond2 = (1. - soil(s)%slmsts ) & - * ( ksand * soil(s)%xsand + ksilt * soil(s)%xsilt & - + kclay * soil(s)%xclay ) & - + soil(s)%slmsts * kair - soil(s)%thcond3 = 1. - kair - !------------------------------------------------------------------------------------! - - end do - !---------------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------------! ! Fill in the albedo information regarding the soil colour classes. ! @@ -2335,52 +1689,6 @@ subroutine init_soil_coms - !----- Here we fill soil8, which will be used in Runge-Kutta (double precision). -------! - do s=1,ed_nstyp - soil8(s)%key = soil(s)%key - soil8(s)%method = soil(s)%method - soil8(s)%xsand = dble(soil(s)%xsand ) - soil8(s)%xsilt = dble(soil(s)%xsilt ) - soil8(s)%xclay = dble(soil(s)%xclay ) - soil8(s)%slsoc = dble(soil(s)%slsoc ) - soil8(s)%slph = dble(soil(s)%slph ) - soil8(s)%slcec = dble(soil(s)%slcec ) - soil8(s)%sldbd = dble(soil(s)%sldbd ) - soil8(s)%soilre = dble(soil(s)%soilre ) - soil8(s)%soilcp = dble(soil(s)%soilcp ) - soil8(s)%soilwp = dble(soil(s)%soilwp ) - soil8(s)%soilfr = dble(soil(s)%soilfr ) - soil8(s)%soilld = dble(soil(s)%soilld ) - soil8(s)%sfldcap = dble(soil(s)%sfldcap ) - soil8(s)%soilbp = dble(soil(s)%soilbp ) - soil8(s)%slmsts = dble(soil(s)%slmsts ) - soil8(s)%soilpo = dble(soil(s)%soilpo ) - soil8(s)%slpotcp = dble(soil(s)%slpotcp ) - soil8(s)%slpotwp = dble(soil(s)%slpotwp ) - soil8(s)%slpotfr = dble(soil(s)%slpotfr ) - soil8(s)%slpotld = dble(soil(s)%slpotld ) - soil8(s)%slpotfc = dble(soil(s)%slpotfc ) - soil8(s)%slpotbp = dble(soil(s)%slpotbp ) - soil8(s)%slpots = dble(soil(s)%slpots ) - soil8(s)%slpotpo = dble(soil(s)%slpotpo ) - soil8(s)%sltt = dble(soil(s)%sltt ) - soil8(s)%slnm = dble(soil(s)%slnm ) - soil8(s)%slbs = dble(soil(s)%slbs ) - soil8(s)%slmm = dble(soil(s)%slmm ) - soil8(s)%slmu = dble(soil(s)%slmu ) - soil8(s)%malpha = dble(soil(s)%malpha ) - soil8(s)%slcons = dble(soil(s)%slcons ) - soil8(s)%fhydraul = dble(soil(s)%fhydraul) - soil8(s)%slcpd = dble(soil(s)%slcpd ) - soil8(s)%thcond0 = dble(soil(s)%thcond0 ) - soil8(s)%thcond1 = dble(soil(s)%thcond1 ) - soil8(s)%thcond2 = dble(soil(s)%thcond2 ) - soil8(s)%thcond3 = dble(soil(s)%thcond3 ) - end do - !---------------------------------------------------------------------------------------! - - - !----- Double precision of additional scalar variables. --------------------------------! soil_rough8 = dble(soil_rough ) snow_rough8 = dble(snow_rough ) @@ -2401,70 +1709,6 @@ subroutine init_soil_coms sin_sldrain8 = sin(sldrain8 * pio1808) !---------------------------------------------------------------------------------------! - !---------------------------------------------------------------------------------------! - ! Decide whether to write the table with the soil properties. ! - !---------------------------------------------------------------------------------------! - print_soil_table = btest(idetailed,5) - !---------------------------------------------------------------------------------------! - - - !---------------------------------------------------------------------------------------! - ! Print the parameters in case the user wants it. ! - !---------------------------------------------------------------------------------------! - if (print_soil_table) then - !----- Open and write header. -------------------------------------------------------! - open (unit=26,file=trim(soil_table_fn),status='replace',action='write') - write(unit=26,fmt='(38(a,1x))') 'ISOIL', ' KEY', 'TYPE' & - ,' XSAND',' XSILT',' XCLAY' & - ,' SLSOC',' SLPH',' SLCEC' & - ,' SLDBD',' SOILRE',' SOILCP' & - ,' SOILWP',' SOILFR',' SOILLD' & - ,' SOILFC',' SOILBP',' SOILPO' & - ,' SLPOTCP',' SLPOTWP',' SLPOTFR' & - ,' SLPOTLD',' SLPOTFC',' SLPOTBP' & - ,' SLPOTPO',' SLTT',' SLNM' & - ,' SLBS',' SLMM',' SLMU' & - ,' MALPHA',' SLCONS_MMHR',' FHYDRAUL' & - ,' SLCPD_MJm3K',' THCOND0',' THCOND1' & - ,' THCOND2',' THCOND3' - !------------------------------------------------------------------------------------! - - - !------------------------------------------------------------------------------------! - ! Loop over soil texture types. ! - !------------------------------------------------------------------------------------! - do s=1,ed_nstyp - !----- For some variables, we use different units to make them more legible. -----! - slcons_mmhr = soil(s)%slcons*1000.*hr_sec - slcpd_mjm3k = soil(s)%slcpd*0.001 - !---------------------------------------------------------------------------------! - - !----- Add soil characteristics. -------------------------------------------------! - write(unit=26,fmt='(i5,1x,2(a4,1x),35(f12.5,1x))') & - s,adjustr(soil(s)%key),adjustr(soil(s)%method) & - ,soil(s)%xsand ,soil(s)%xsilt ,soil(s)%xclay & - ,soil(s)%slsoc ,soil(s)%slph ,soil(s)%slcec & - ,soil(s)%sldbd ,soil(s)%soilre ,soil(s)%soilcp & - ,soil(s)%soilwp ,soil(s)%soilfr ,soil(s)%soilld & - ,soil(s)%sfldcap ,soil(s)%soilbp ,soil(s)%slmsts & - ,soil(s)%slpotcp ,soil(s)%slpotwp ,soil(s)%slpotfr & - ,soil(s)%slpotld ,soil(s)%slpotfc ,soil(s)%slpotbp & - ,soil(s)%slpots ,soil(s)%sltt ,soil(s)%slnm & - ,soil(s)%slbs ,soil(s)%slmm ,soil(s)%slmu & - ,soil(s)%malpha ,slcons_mmhr ,soil(s)%fhydraul & - ,slcpd_mjm3k ,soil(s)%thcond0 ,soil(s)%thcond1 & - ,soil(s)%thcond2 ,soil(s)%thcond3 - !---------------------------------------------------------------------------------! - end do - !------------------------------------------------------------------------------------! - - - !----- Close table. -----------------------------------------------------------------! - close(unit=26,status='keep') - !------------------------------------------------------------------------------------! - end if - !---------------------------------------------------------------------------------------! - return end subroutine init_soil_coms !==========================================================================================! @@ -2483,6 +1727,7 @@ subroutine init_phen_coms use phenology_coms, only : thetacrit & ! intent(in) , retained_carbon_fraction & ! intent(out) , root_phen_factor & ! intent(out) + , f_psi_xdry & ! intent(out) , elongf_min & ! intent(out) , elongf_flush & ! intent(out) , spot_phen & ! intent(out) @@ -2536,6 +1781,14 @@ subroutine init_phen_coms + !---------------------------------------------------------------------------------------! + ! Threshold for shedding all leaves when leaf water potential is very low. . ! + !---------------------------------------------------------------------------------------! + f_psi_xdry = 0.95 + !---------------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------------! ! Minimum elongation factor before plants give up completely and shed all remain- ! ! ing leaves. ! @@ -3016,13 +2269,13 @@ subroutine init_pft_alloc_params() real, dimension(3) , parameter :: nleaf = (/ 0.0192512, 0.9749494, 2.5858509 /) real, dimension(2) , parameter :: ncrown_area = (/ 0.1184295, 1.0521197 /) !---------------------------------------------------------------------------------------! - ! Coefficients for leaf and structural biomass (iallom = 3). For adult individuals, ! - ! we use the pantropical allometric equation from C14 that estimates AGB and the leaf ! - ! biomass from an allometric equation derived from F15 data (tropical forest, wild ! - ! flowering trees only), and the size- and site-dependent stratified sampling and ! - ! aggregation (J17). Total individual leaf area was fitted, so to get biomass we must ! - ! divide by SLA. The C2B term is added here but is removed when the coefficients are ! - ! set. ! + ! Coefficients for leaf and structural biomass (iallom = 3 or 5). For adult ! + ! individuals, we use the pantropical allometric equation from C14 that estimates AGB ! + ! and the leaf biomass from an allometric equation derived from F15 data (tropical ! + ! forest, wild flowering trees only), and the size- and site-dependent stratified ! + ! sampling and aggregation (J17). Total individual leaf area was fitted, so to get ! + ! biomass we must divide by SLA. The C2B term is added here but is removed when the ! + ! coefficients are set. ! ! ! ! References: ! ! ! @@ -3033,7 +2286,7 @@ subroutine init_pft_alloc_params() ! ! ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, Aiba M, ! ! Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and allometry database for ! - ! woody plants. Ecology, 96 (5):1445-1445. doi:10.1890/14-1889.1 (F16). ! + ! woody plants. Ecology, 96 (5):1445-1445. doi:10.1890/14-1889.1 (F15). ! ! ! ! Jucker T, Caspersen J, Chave J, Antin C, Barbier N, Bongers F, Dalponte M, ! ! van Ewijk KY, Forrester DI, Haeni M et al. 2017. Allometric equations for ! @@ -3041,7 +2294,7 @@ subroutine init_pft_alloc_params() ! Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). ! ! ! !---------------------------------------------------------------------------------------! - real, dimension(2) , parameter :: c14f15_bl_xx = (/ 0.46769540,0.6410495 /) + real, dimension(2) , parameter :: c14f15_bl_xx = (/ 0.23384770,0.6410495 /) real, dimension(3) , parameter :: c14f15_la_wd = (/-0.5874,0.5679,0.5476 /) real, dimension(3) , parameter :: c14f15_ht_xx = (/0.5709,-0.1007,0.6734 /) real, dimension(2) , parameter :: c14f15_bs_tf = (/ 0.06080334,1.0044785 /) @@ -3315,9 +2568,10 @@ subroutine init_pft_alloc_params() !---------------------------------------------------------------------------------------! ! KIM: ED1/ED2 codes and Moorcroft et al. had the incorrect ratio. ! - ! MLO: The ratio is corrected only for tropical PFTs using iallom=3. To extend this ! - ! fix to other PFTs, one must refit parameters for other tissues (e.g. bdead), ! - ! so the total AGB is consistent with the original allometric equation for AGB. ! + ! MLO: The ratio is corrected only for tropical PFTs using iallom = 3 or 5. To ! + ! extend this fix to other PFTs, one must refit parameters for other tissues ! + ! (e.g. bdead), so the total AGB is consistent with the original allometric ! + ! equation for AGB. ! ! ! ! For the PFTs that were updated, we combine the pipe model with the data from ! ! CA08 and shape parameter from F16 to derive the ratio. ! @@ -3354,7 +2608,7 @@ subroutine init_pft_alloc_params() ! ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3) + case (3,5) do ipft=1,n_pft if (is_liana(ipft)) then !------------------------------------------------------------------------------! @@ -3467,12 +2721,18 @@ subroutine init_pft_alloc_params() ! ! ! The root fraction (Y) above depth D cm for a cohort with max rooting depth as ! ! D_max (cm) can be calculated as: ! - ! Y = 1. - (root_beta) ** (D / D_max) ! ! ! - ! Suggested values range from 0.0001 to 0.01. ! + ! Y = ( 1. - (root_beta) ** (D / D_max) ) / (1 - root_beta) ! + ! ! + ! ! + ! MLO (2020-10-27): I added the denominator (1 - root_beta) to ensure that Y at ! + ! D=D_max is always 1, regardless of the value of root_beta, as ! + ! long as root_beta < 1. ! + ! ! + ! Suggested values range from 0.0001 to 0.1. ! ! ! !---------------------------------------------------------------------------------------! - root_beta(:) = 0.01 + root_beta(:) = 0.1 !---------------------------------------------------------------------------------------! @@ -3500,8 +2760,8 @@ subroutine init_pft_alloc_params() !---------------------------------------------------------------------------------------! ! Set bark thickness and carbon allocation to bark. This is currently done only ! - ! for tropical trees when IALLOM=3, because all biomass pools must be corrected to ! - ! ensure that total aboveground biomass is consistent with the allometric equations. ! + ! for tropical trees when IALLOM = 3 or 5, because all biomass pools must be corrected ! + ! to ensure that total aboveground biomass is consistent with the allometric equations. ! ! This may and should be changed in the future. ! ! ! ! References: ! @@ -3531,7 +2791,7 @@ subroutine init_pft_alloc_params() ! qbark - ratio between leaf biomass and bark biomass per unit height. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3) + case (3,5) !------ New allometry, use estimate based on M01. -----------------------------------! b1Xs(:) = 0.315769481 !------------------------------------------------------------------------------------! @@ -3626,17 +2886,17 @@ subroutine init_pft_alloc_params() !----- hgt_ref is their "Hmax". -----------------------------------------------! hgt_ref(ipft) = 61.7 !------------------------------------------------------------------------------! - case (3) + case (3,5) !------------------------------------------------------------------------------! ! Allometric equation based on the fitted curve using the Sustainable ! ! Landscapes data set (L16) and the size- and site-dependent stratified ! - ! sampling and aggregation (J17). This relationship is fitted using ! - ! Standardised Major Axis (SMA) so the same parameters can be used for ! - ! y=f(x) and x=f(y). This is particularly useful when initialising the model ! - ! with airborne lidar data. Because it would be extremely cumbersome to ! - ! derive a SMA-based regression based on Weibull function, we use a log-linear ! - ! relationship. The maximum height is based on the 99% quantile of all trees ! - ! measured by the SL team. ! + ! sampling and aggregation (J17), as described in (L20). This relationship is ! + ! fitted using Standardised Major Axis (SMA) so the same parameters can be ! + ! used for y=f(x) and x=f(y). This is particularly useful when initialising ! + ! the model with airborne lidar data (L20). Because it would be extremely ! + ! cumbersome to derive a SMA-based regression based on Weibull function, we ! + ! use a log-linear relationship. The maximum height is based on the 99% ! + ! quantile of all trees measured by the SL team. ! ! ! ! References: ! ! ! @@ -3650,6 +2910,11 @@ subroutine init_pft_alloc_params() ! biomass variability across intact and degraded forests in the Brazilian ! ! Amazon. Global Biogeochem. Cycles, 30(11):1639-1660. ! ! doi:10.1002/2016GB005465 (L16). ! + ! ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! !------------------------------------------------------------------------------! b1Ht (ipft) = 1.139963 b2Ht (ipft) = 0.564899 @@ -3717,7 +2982,7 @@ subroutine init_pft_alloc_params() ! Minimum and maximum height allowed for each cohort. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------------! ! This value corresponds to the 99% quantile of all trees measured by the ! ! Sustainable Landscapes. ! @@ -3812,13 +3077,15 @@ subroutine init_pft_alloc_params() b1Ca(ipft) = exp(ncrown_area(1)) b2Ca(ipft) = ncrown_area(2) !------------------------------------------------------------------------------! - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------! ! Allometry using the Sustainable Landscapes data. ! !------------------------------------------------------------------------------! ! ! - ! Longo, M. et al. Carbon Debt and Recovery time of degraded forests in ! - ! the Amazon. Environ. Res. Lett., in prep. ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! ! ! ! Equation was derived from forest inventory measurements carried out at ! ! multiple locations in the Brazilian Amazon, and fitted using a ! @@ -3861,11 +3128,13 @@ subroutine init_pft_alloc_params() ! Poorter L., L. Bongers, F. Bongers, 2006: Architecture of 54 moist-forest tree ! ! species: traits, trade-offs, and functional groups. Ecology, 87, 1289-1301. ! ! ! - ! For iallom = 3, we use the allometric equation based on the Sustainable Landscapes ! - ! data set. ! + ! For iallom = 3 or 5, we use the allometric equation based on the Sustainable ! + ! Landscapes data set. ! ! ! - ! Longo, M. et al. Carbon Debt and Recovery time of degraded forests in the Amazon, ! - ! in prep. ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, Bonal D, ! + ! Brando P, Burban B et al. 2020. Impacts of degradation on water, energy, and ! + ! carbon cycling of the Amazon tropical forests. J. Geophys. Res.-Biogeosci., 125: ! + ! e2020JG005677. doi:10.1029/2020JG005677 (L20). ! ! ! ! Equation was derived from forest inventory measurements carried out at multiple ! ! locations in the Brazilian Amazon, and fitted using a heteroscedastic least ! @@ -3885,7 +3154,7 @@ subroutine init_pft_alloc_params() elseif (is_tropical(ipft)) then !----- Tropical PFTs: check allometry settings. ----------------------------------! select case (iallom) - case (3,4) + case (3,4,5) b1Cl(ipft) = 0.29754 b2Cl(ipft) = 1.0324 case default @@ -3913,9 +3182,9 @@ subroutine init_pft_alloc_params() ! Parameters for DBH -> Bleaf allometry. ! ! ! ! IALLOM = 0,1,2 -- Bleaf = b1Bl * DBH^b2Bl ! - ! IALLOM = 3 -- Bleaf = b1Bl * (DBH*DBH*Height)^b2Bl ! - ! IALLOM = 4 -- leaf_A= b1Bl * (DBH*DBH*Height)^b2Bl ! - ! b1Bl is a fucntion of wood density ! + ! IALLOM = 3,4,5 -- leaf_A= b1Bl * (DBH*DBH*Height)^b2Bl ! + ! b1Bl is a function of wood density (IALLOM=4 only). ! + ! For IALLOM=3,4,5, leaf biomass will depend on SLA. ! ! ! ! The coefficients and thresholds depend on the PFT and allometric equations. In ! ! addition to the coefficients, we define the dbh point that defines adult cohorts as ! @@ -3955,33 +3224,43 @@ subroutine init_pft_alloc_params() b1Bl (ipft) = C2B * exp(nleaf(1)) * rho(ipft) / nleaf(3) b2Bl (ipft) = nleaf(2) !------------------------------------------------------------------------------! - case (3) + case (3,5) !------------------------------------------------------------------------------! - ! Allometry based on the BAAD data based (F15). We only used leaves from ! - ! wild tropical, flowering trees, and applied a stratified sample by DBH class ! - ! and location and cross-validation, following (J17). ! + ! Allometry based on the BAAD data based (F15) and described in (L20). We ! + ! only used leaves from wild tropical, flowering trees, and applied a ! + ! stratified sample by DBH class and location and cross-validation, following ! + ! (J17). ! ! ! ! References: ! ! ! + ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, ! + ! Aiba M, Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and ! + ! allometry database for woody plants. Ecology, 96 (5):1445-1445. ! + ! doi:10.1890/14-1889.1 (F15). ! + ! ! ! Jucker T, Caspersen J, Chave J, Antin C, Barbier N, Bongers F, Dalponte M, ! ! van Ewijk KY, Forrester DI, Haeni M et al. 2017. Allometric equations for ! ! integrating remote sensing imagery into forest monitoring programmes. ! ! Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). ! ! ! - ! Longo M, Keller M, dos-Santos MN, Leitold V, Pinage ER, Baccini A, ! - ! Saatchi S, Nogueira EM, Batistella M , Morton DC. 2016. Aboveground ! - ! biomass variability across intact and degraded forests in the Brazilian ! - ! Amazon. Global Biogeochem. Cycles, 30(11):1639-1660. ! - ! doi:10.1002/2016GB005465 (L16). ! + ! Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, ! + ! Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, ! + ! energy, and carbon cycling of the Amazon tropical forests. J. Geophys. ! + ! Res.-Biogeosci., 125: e2020JG005677. doi:10.1029/2020JG005677 (L20). ! !------------------------------------------------------------------------------! - b1Bl(ipft) = c14f15_bl_xx(1) / SLA(ipft) ! XX --> MLO: should ther be a C2B here given c14f15_bl_xx is in m2 (?) and SLA is m2/kgC + b1Bl(ipft) = c14f15_bl_xx(1) b2Bl(ipft) = c14f15_bl_xx(2) !------------------------------------------------------------------------------! case (4) !------------------------------------------------------------------------------! ! Allometry based on the BAAD data based (F15). We only used leaves from ! ! wild tropical, note that b1Bl has the unit of m2 leaf under this scenario ! - ! and will be converted to leaf carbon using SLA in size2bl + ! and will be converted to leaf carbon using SLA in size2bl. ! + ! ! + ! Falster DS, Duursma RA, Ishihara MI, Barneche DR, FitzJohn RG, Vahammar A, ! + ! Aiba M, Ando M, Anten N, Aspinwall MJ. 2015. BAAD: a biomass and ! + ! allometry database for woody plants. Ecology, 96 (5):1445-1445. ! + ! doi:10.1890/14-1889.1 (F15). ! !------------------------------------------------------------------------------! b1Bl(ipft) = exp( c14f15_la_wd(1) + c14f15_la_wd(2) * log(rho(ipft))) b2Bl(ipft) = c14f15_la_wd(3) @@ -4034,7 +3313,7 @@ subroutine init_pft_alloc_params() ! Bdead = { ! ! { b1Bs_large * DBH^b2Bl_large , if dbh > dbh_crit ! ! ! - ! IALLOM = 3, 4 ! + ! IALLOM = 3, 4, 5 ! ! ! ! Bdead = b1Bs_small * (DBH^2 * Height) ^ b2Bs_small ! ! ! @@ -4097,7 +3376,7 @@ subroutine init_pft_alloc_params() b1Bs_large (ipft) = C2B * exp(ndead_large(1)) * rho(ipft) / ndead_large(3) b2Bs_large (ipft) = ndead_large(2) !------------------------------------------------------------------------------! - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------! ! Trees: set parameters based on Chave et al. (2014). ! ! Grasses: set numbers to small values, too keep bdead at a minimum but still ! @@ -4238,7 +3517,7 @@ subroutine init_pft_alloc_params() ! WAI parameters, the choice depends on IALLOM. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !------------------------------------------------------------------------------------! ! WAI is defined as a fraction of (potential) LAI. This is just a refit of ! ! allometry 2 but using DBH*DBH*Height as predictor for consistency. ! @@ -4393,7 +3672,7 @@ subroutine init_pft_alloc_params() , +0.4223014 & , is_tropical(:) .and. (.not. is_liana(:)) ) !------------------------------------------------------------------------------------! - case (4) + case (4,5) !------------------------------------------------------------------------------------! ! Test allometry based on excavation data in Panama based on H. ! ! Multiply it by 2 so that a 40 m tree can get access to water below 5m depth ! @@ -4423,11 +3702,6 @@ subroutine init_pft_alloc_params() ! Hydrological niche segregation defines forest structure and drought tolerance ! ! strategies in a seasonal Amazonian forest. J. Ecol., in press. ! ! doi:10.1111/1365-2745.13022 (B18). ! - ! ! - ! Longo M, Keller M, dos-Santos MN, Leitold V, Pinage ER, Baccini A, Saatchi S, ! - ! Nogueira EM, Batistella M , Morton DC. 2016. Aboveground biomass variability ! - ! across intact and degraded forests in the Brazilian Amazon. Global Biogeochem. ! - ! Cycles, 30(11):1639-1660. doi:10.1002/2016GB005465 (L16). ! !---------------------------------------------------------------------------------------! d18O_ref(:) = -5.356 b1d18O (:) = 0.0516 @@ -4716,12 +3990,35 @@ subroutine init_pft_photo_params() !---------------------------------------------------------------------------------------! select case (iphysiol) case (0,2) - !----- Default parameters (Moorcroft et al. 2001; Longo 2014). ----------------------! + !------------------------------------------------------------------------------------! + ! Default parameters (M01/M09/L19). ! + ! ! + ! Longo M, Knox RG, Medvigy DM, Levine NM, Dietze MC, Kim Y, Swann ALS, Zhang K, ! + ! Rollinson CR, Bras RL et al. 2019. The biophysics, ecology, and biogeochemistry ! + ! of functionally diverse, vertically and horizontally heterogeneous ecosystems: ! + ! the Ecosystem Demography model, version 2.2 -- part 1: Model description. ! + ! Geosci. Model Dev., 12: 4309-4346. doi:10.5194/gmd-12-4309-2019 (L19). ! + ! ! + ! Medvigy DM, Wofsy SC, Munger JW, Hollinger DY , Moorcroft PR. 2009. Mechanistic ! + ! scaling of ecosystem function and dynamics in space and time: Ecosystem ! + ! demography model version 2. J. Geophys. Res.-Biogeosci., 114: G01002. ! + ! doi:10.1029/2008JG000812 (M09). ! + ! ! + ! Moorcroft PR, Hurtt GC , Pacala SW. 2001. A method for scaling vegetation ! + ! dynamics: The Ecosystem Demography model (ED). Ecol. Monogr., 71: 557-586. ! + ! doi:10.1890/0012- 9615(2001)071[0557:AMFSVD]2.0.CO;2 (M01). ! + !------------------------------------------------------------------------------------! vm_hor(:) = 3000. vm_q10(:) = merge(q10_c4,q10_c3,photosyn_pathway(:) == 4) !------------------------------------------------------------------------------------! case (1,3) - !----- Use values from von Caemmerer (2000). ----------------------------------------! + !------------------------------------------------------------------------------------! + ! Use values from vC00. ! + ! ! + ! von Caemmerer S. 2000. Biochemical models of leaf photosynthesis. No. 2 in ! + ! Techniques in Plant Sciences. CSIRO Publishing, Collingwood, VIC, Australia. ! + ! doi:10.1006/anbo.2000.1296 (vC00). ! + !------------------------------------------------------------------------------------! vm_hor(:) = 58520. * tphysref / (rmol * (t00+25.)) vm_q10(:) = 2.21 !------------------------------------------------------------------------------------! @@ -5218,7 +4515,7 @@ subroutine init_pft_resp_params() ! names already in use in c2n factors. ! !---------------------------------------------------------------------------------------! select case (iallom) - case (2,3,4) + case (2,3,4,5) !------------------------------------------------------------------------------------! ! For tropical leaves/fine roots, assume the metabolic/structural ratio obtained ! ! by B17. For grasses and temperate plants, use B17 equation and R96 values for ! @@ -6536,6 +5833,12 @@ subroutine init_pft_phen_params() !------------------------------------------------------------------------------! phenology(ipft) = 5 !------------------------------------------------------------------------------! + case (5) + !------------------------------------------------------------------------------! + ! Combined light and plant-hydraulics driven drought phenology. ! + !------------------------------------------------------------------------------! + phenology(ipft) = 6 + !------------------------------------------------------------------------------! end select !---------------------------------------------------------------------------------! end if @@ -8233,6 +7536,7 @@ subroutine init_derived_params_after_xml() , srf_hor & ! intent(inout) , srf_q10 & ! intent(inout) , bleaf_crit & ! intent(inout) + , ddh_allom & ! intent(out) , d1DBH_small & ! intent(out) , d2DBH_small & ! intent(out) , d1DBH_large & ! intent(out) @@ -8424,7 +7728,7 @@ subroutine init_derived_params_after_xml() !------ Make sure the soil carbon fractions add up to one. -----------------------------! if (f0_msc < 0. .or. f0_psc < 0.0 .or. (f0_msc + f0_psc) > 1.0) then write (unit=*,fmt='(a)') '-------------------------------------------------' - write (unit=*,fmt='(a)') ' F0_MSC and F0_SSC must be fractions (0-1)' + write (unit=*,fmt='(a)') ' F0_MSC and F0_PSC must be fractions (0-1)' write (unit=*,fmt='(a)') ' and their sum cannot exceed 1.0' write (unit=*,fmt='(a)') '' write (unit=*,fmt='(a)') ' Current values: ' @@ -8484,7 +7788,7 @@ subroutine init_derived_params_after_xml() ! both in case this simulation is not using light-controlled phenology. ! !---------------------------------------------------------------------------------------! select case (iphen_scheme) - case (3) + case (3,5) !------------------------------------------------------------------------------------! ! Light phenology is enabled. ! !------------------------------------------------------------------------------------! @@ -8561,7 +7865,7 @@ subroutine init_derived_params_after_xml() !---------------------------------------------------------------------------------------! ! Hgt_max of temperate trees cannot exceed b1Ht, and cannot exceed hgt_ref for ! - ! tropical trees (IALLOM=2 or IALLOM=3). ! + ! tropical trees (IALLOM = 2). ! !---------------------------------------------------------------------------------------! select case (iallom) case (2) @@ -8655,6 +7959,14 @@ subroutine init_derived_params_after_xml() !------------------------------------------------------------------------------------! + !----- Set allometric formula. ------------------------------------------------------! + select case (iallom) + case (3,4,5) + ddh_allom(ipft) = is_tropical(ipft) .and. (.not. is_liana(ipft)) + case default + ddh_allom(ipft) = .false. + end select + !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! @@ -8662,8 +7974,7 @@ subroutine init_derived_params_after_xml() ! the size2bd and size2bl functions, and to be consistent, they cannot be ! ! initialised through XML. ! !------------------------------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft)) ) then + if (ddh_allom(ipft)) then !---------------------------------------------------------------------------------! ! Incorporate both heartwood and height allometric equations to derive DBH. ! !---------------------------------------------------------------------------------! @@ -8680,7 +7991,7 @@ subroutine init_derived_params_after_xml() !------ Inverse of the leaf biomass function. ------------------------------------! l2DBH(ipft) = 1. / ( ( 2. + b2Ht(ipft) ) * b2Bl(ipft) ) - l1DBH(ipft) = ( C2B / (b1Bl(ipft) * exp(b1Ht(ipft) * b2Bl(ipft)) ) ) ** l2DBH(ipft) + l1DBH(ipft) = ( 1. / (b1Bl(ipft) * exp(b1Ht(ipft) * b2Bl(ipft)) ) ) ** l2DBH(ipft) !---------------------------------------------------------------------------------! else !---------------------------------------------------------------------------------! @@ -8769,7 +8080,7 @@ subroutine init_derived_params_after_xml() ! allometry sets define the minimum sizes as before, for back-compability. ! !------------------------------------------------------------------------------------! select case (iallom) - case (3,4) + case (3,4,5) !---------------------------------------------------------------------------------! ! New method, each PFT has a minimum resolvable density. The fraction ensures ! ! that plants start as resolvable. ! @@ -9665,41 +8976,43 @@ subroutine init_derived_params_after_xml() !----- Print allometric coefficients. --------------------------------------------------! if (print_zero_table) then open (unit=18,file=trim(allom_file),status='replace',action='write') - write(unit=18,fmt='(54(1x,a))') ' PFT',' TROPICAL',' GRASS' & + write(unit=18,fmt='(55(1x,a))') ' PFT',' TROPICAL',' GRASS' & ,' CONIFER',' SAVANNAH',' LIANA' & - ,' RHO',' B1HT',' B2HT' & - ,' HGT_REF',' B1BL',' B2BL' & - ,' B1BS_SMALL',' B2BS_SMALL',' B1BS_LARGE' & - ,' B2BS_LARGE',' D1DBH_SMALL',' D2DBH_SMALL' & - ,' D1DBH_LARGE',' D2DBH_LARGE',' L1DBH' & - ,' L2DBH',' B1CA',' B2CA' & - ,' B1WAI',' B2WAI',' B1SA' & - ,' B2SA',' B1RD',' B2RD' & - ,' B1XS',' B1XB',' HGT_MIN' & - ,' HGT_MAX',' MIN_DBH',' DBH_CRIT' & - ,' DBH_BIGLEAF',' BDEAD_CRIT',' BLEAF_CRIT' & - ,' BALIVE_CRIT',' BEVERY_CRIT',' INIT_DENS' & - ,' SLA',' F_BSTOR_INIT',' Q' & - ,' QSW',' QBARK',' QRHOB' & - ,' d18O_REF',' B1_D18O',' B2_D18O' & - ,' B1_EFRD',' B2_EFRD',' INIT_LAIMAX' - + ,' DDH_ALLOM',' RHO',' B1HT' & + ,' B2HT',' HGT_REF',' B1BL' & + ,' B2BL',' B1BS_SMALL',' B2BS_SMALL' & + ,' B1BS_LARGE',' B2BS_LARGE',' D1DBH_SMALL' & + ,' D2DBH_SMALL',' D1DBH_LARGE',' D2DBH_LARGE' & + ,' L1DBH',' L2DBH',' B1CA' & + ,' B2CA',' B1WAI',' B2WAI' & + ,' B1SA',' B2SA',' B1RD' & + ,' B2RD',' B1XS',' B1XB' & + ,' HGT_MIN',' HGT_MAX',' MIN_DBH' & + ,' DBH_CRIT',' DBH_BIGLEAF',' BDEAD_CRIT' & + ,' BLEAF_CRIT',' BALIVE_CRIT',' BEVERY_CRIT' & + ,' INIT_DENS',' SLA',' F_BSTOR_INIT' & + ,' Q',' QSW',' QBARK' & + ,' QRHOB',' d18O_REF',' B1_D18O' & + ,' B2_D18O',' B1_EFRD',' B2_EFRD' & + ,' INIT_LAIMAX' + do ipft=1,n_pft - write (unit=18,fmt='(9x,i5,5(13x,l1),47(1x,f13.6),1(1x,es13.6))') & + write (unit=18,fmt='(9x,i5,6(13x,l1),47(1x,f13.6),1(1x,es13.6))') & ipft,is_tropical(ipft),is_grass(ipft),is_conifer(ipft) & - ,is_savannah(ipft),is_liana(ipft),rho(ipft),b1Ht(ipft),b2Ht(ipft) & - ,hgt_ref(ipft),b1Bl(ipft),b2Bl(ipft),b1Bs_small(ipft) & - ,b2Bs_small(ipft),b1Bs_large(ipft),b2Bs_large(ipft) & - ,d1DBH_small(ipft),d2DBH_small(ipft),d1DBH_large(ipft) & - ,d2DBH_large(ipft),l1DBH(ipft),l2DBH(ipft),b1Ca(ipft),b2Ca(ipft) & - ,b1WAI(ipft),b2WAI(ipft),b1SA(ipft),b2SA(ipft),b1Rd(ipft) & - ,b2Rd(ipft),b1Xs(ipft),b1Xb(ipft),hgt_min(ipft),hgt_max(ipft) & - ,min_dbh(ipft),dbh_crit(ipft),dbh_bigleaf(ipft),bdead_crit(ipft) & - ,bleaf_crit(ipft),balive_crit(ipft),bevery_crit(ipft) & - ,init_density(ipft),sla(ipft),f_bstorage_init(ipft),q(ipft) & - ,qsw(ipft),qbark(ipft),qrhob(ipft),d18O_ref(ipft),b1d18O(ipft) & - ,b2d18O(ipft),b1Efrd(ipft),b2Efrd(ipft),init_laimax(ipft) + ,is_savannah(ipft),is_liana(ipft),ddh_allom(ipft),rho(ipft) & + ,b1Ht(ipft),b2Ht(ipft),hgt_ref(ipft),b1Bl(ipft),b2Bl(ipft) & + ,b1Bs_small(ipft),b2Bs_small(ipft),b1Bs_large(ipft) & + ,b2Bs_large(ipft),d1DBH_small(ipft),d2DBH_small(ipft) & + ,d1DBH_large(ipft),d2DBH_large(ipft),l1DBH(ipft),l2DBH(ipft) & + ,b1Ca(ipft),b2Ca(ipft),b1WAI(ipft),b2WAI(ipft),b1SA(ipft) & + ,b2SA(ipft),b1Rd(ipft),b2Rd(ipft),b1Xs(ipft),b1Xb(ipft) & + ,hgt_min(ipft),hgt_max(ipft),min_dbh(ipft),dbh_crit(ipft) & + ,dbh_bigleaf(ipft),bdead_crit(ipft),bleaf_crit(ipft) & + ,balive_crit(ipft),bevery_crit(ipft),init_density(ipft),sla(ipft) & + ,f_bstorage_init(ipft),q(ipft),qsw(ipft),qbark(ipft),qrhob(ipft) & + ,d18O_ref(ipft),b1d18O(ipft),b2d18O(ipft),b1Efrd(ipft),b2Efrd(ipft) & + ,init_laimax(ipft) end do close(unit=18,status='keep') end if diff --git a/ED/src/init/ed_type_init.f90 b/ED/src/init/ed_type_init.f90 index 456c93fd4..91822fa17 100644 --- a/ED/src/init/ed_type_init.f90 +++ b/ED/src/init/ed_type_init.f90 @@ -19,7 +19,8 @@ module ed_type_init !---------------------------------------------------------------------------------------! subroutine init_ed_cohort_vars(cpatch,ico, lsl,mzg,ntext_soil) use ed_state_vars , only : patchtype ! ! structure - use allometry , only : size2krdepth ! ! function + use allometry , only : size2krdepth & ! function + , distrib_root ! ! sub-routine use pft_coms , only : phenology & ! intent(in) , cuticular_cond & ! intent(in) , leaf_turnover_rate & ! intent(in) @@ -201,6 +202,12 @@ subroutine init_ed_cohort_vars(cpatch,ico, lsl,mzg,ntext_soil) !------------------------------------------------------------------------------------! + + !------ Find the root distribution. -------------------------------------------------! + call distrib_root(kroot,ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------------! ! Start variables related with plant hydraulics. ! !------------------------------------------------------------------------------------! @@ -1128,6 +1135,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%fmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%fmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%fmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%fmean_snowfac (ipaa:ipaz) = 0.0 csite%fmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%fmean_par_gnd (ipaa:ipaz) = 0.0 csite%fmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1210,6 +1218,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%dmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%dmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%dmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%dmean_snowfac (ipaa:ipaz) = 0.0 csite%dmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%dmean_par_gnd (ipaa:ipaz) = 0.0 csite%dmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1286,6 +1295,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%mmean_sfcw_mass (ipaa:ipaz) = 0.0 csite%mmean_sfcw_temp (ipaa:ipaz) = 0.0 csite%mmean_sfcw_fliq (ipaa:ipaz) = 0.0 + csite%mmean_snowfac (ipaa:ipaz) = 0.0 csite%mmean_rshort_gnd (ipaa:ipaz) = 0.0 csite%mmean_par_gnd (ipaa:ipaz) = 0.0 csite%mmean_rlong_gnd (ipaa:ipaz) = 0.0 @@ -1409,6 +1419,7 @@ subroutine init_ed_patch_vars(csite,ipaa,ipaz,lsl) csite%qmean_sfcw_mass (:,ipaa:ipaz) = 0.0 csite%qmean_sfcw_temp (:,ipaa:ipaz) = 0.0 csite%qmean_sfcw_fliq (:,ipaa:ipaz) = 0.0 + csite%qmean_snowfac (:,ipaa:ipaz) = 0.0 csite%qmean_rshort_gnd (:,ipaa:ipaz) = 0.0 csite%qmean_par_gnd (:,ipaa:ipaz) = 0.0 csite%qmean_rlong_gnd (:,ipaa:ipaz) = 0.0 @@ -1522,6 +1533,7 @@ subroutine init_ed_site_vars(cpoly) , writing_eorq & ! intent(in) , writing_dcyc & ! intent(in) , economics_scheme ! ! intent(in) + use consts_coms , only : huge_num ! ! intent(in) implicit none !----- Arguments. -------------------------------------------------------------------! type(polygontype), target :: cpoly @@ -1674,7 +1686,7 @@ subroutine init_ed_site_vars(cpoly) ! Initialise the minimum monthly temperature with a very large value, this is ! ! going to be reduced as the canopy temperature is updated. ! !------------------------------------------------------------------------------------! - cpoly%min_monthly_temp(:) = huge(1.) + cpoly%min_monthly_temp(:) = huge_num !------------------------------------------------------------------------------------! @@ -1684,7 +1696,7 @@ subroutine init_ed_site_vars(cpoly) ! by actual rainfall after 12 months. In the future we may initialise with climato- ! ! logical rainfall. ! !------------------------------------------------------------------------------------! - cpoly%avg_monthly_pcpg(:,:) = 500. + cpoly%avg_monthly_accp(:,:) = 500. !------------------------------------------------------------------------------------! @@ -2084,6 +2096,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%fmean_sfcw_mass (ipy) = 0.0 cgrid%fmean_sfcw_temp (ipy) = 0.0 cgrid%fmean_sfcw_fliq (ipy) = 0.0 + cgrid%fmean_snowfac (ipy) = 0.0 cgrid%fmean_rshort_gnd (ipy) = 0.0 cgrid%fmean_par_gnd (ipy) = 0.0 cgrid%fmean_rlong_gnd (ipy) = 0.0 @@ -2257,6 +2270,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = 0.0 cgrid%dmean_sfcw_temp (ipy) = 0.0 cgrid%dmean_sfcw_fliq (ipy) = 0.0 + cgrid%dmean_snowfac (ipy) = 0.0 cgrid%dmean_rshort_gnd (ipy) = 0.0 cgrid%dmean_par_gnd (ipy) = 0.0 cgrid%dmean_rlong_gnd (ipy) = 0.0 @@ -2414,6 +2428,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = 0.0 cgrid%mmean_sfcw_temp (ipy) = 0.0 cgrid%mmean_sfcw_fliq (ipy) = 0.0 + cgrid%mmean_snowfac (ipy) = 0.0 cgrid%mmean_rshort_gnd (ipy) = 0.0 cgrid%mmean_par_gnd (ipy) = 0.0 cgrid%mmean_rlong_gnd (ipy) = 0.0 @@ -2656,6 +2671,7 @@ subroutine init_ed_poly_vars(cgrid) cgrid%qmean_sfcw_mass (:,ipy) = 0.0 cgrid%qmean_sfcw_temp (:,ipy) = 0.0 cgrid%qmean_sfcw_fliq (:,ipy) = 0.0 + cgrid%qmean_snowfac (:,ipy) = 0.0 cgrid%qmean_rshort_gnd (:,ipy) = 0.0 cgrid%qmean_par_gnd (:,ipy) = 0.0 cgrid%qmean_rlong_gnd (:,ipy) = 0.0 diff --git a/ED/src/init/landuse_init.f90 b/ED/src/init/landuse_init.f90 index 77de83090..b2839475d 100644 --- a/ED/src/init/landuse_init.f90 +++ b/ED/src/init/landuse_init.f90 @@ -112,7 +112,7 @@ subroutine read_landuse_matrix write (unit=*,fmt='(a)') ' so MAX_LU_YEARS >= IYEARZ-IYEARA+1, then recompile' write (unit=*,fmt='(a)') ' your model.' call fatal_error ('Simulation is too long for anthropogenic disturbance.' & - ,'landuse_init','landuse_init.f90') + ,'read_landuse_matrix','landuse_init.f90') end if !------------------------------------------------------------------------------------! @@ -301,7 +301,7 @@ subroutine read_landuse_matrix write (unit=*,fmt='(a,1x,i6)') ' - Nharvest:',nharvest write (unit=*,fmt='(a)') '------------------------------------' call fatal_error('Land use area is zero, it doesn''t make any sense!' & - ,'landuse_init','landuse_init.f90') + ,'read_landuse_matrix','landuse_init.f90') else lu_area_i = 1. / lu_area end if diff --git a/ED/src/io/average_utils.f90 b/ED/src/io/average_utils.f90 index 152c09294..722b61051 100644 --- a/ED/src/io/average_utils.f90 +++ b/ED/src/io/average_utils.f90 @@ -493,6 +493,9 @@ subroutine aggregate_polygon_fmean(cgrid) cgrid%fmean_sfcw_mass (ipy) = cgrid%fmean_sfcw_mass (ipy) & + csite%fmean_sfcw_mass (ipa) & * patch_wgt + cgrid%fmean_snowfac (ipy) = cgrid%fmean_snowfac (ipy) & + + csite%fmean_snowfac (ipa) & + * patch_wgt cgrid%fmean_rshort_gnd (ipy) = cgrid%fmean_rshort_gnd (ipy) & + csite%fmean_rshort_gnd (ipa) & * patch_wgt @@ -1425,11 +1428,13 @@ subroutine zero_ed_fmean_vars(cgrid) cgrid%fmean_sfcw_mass ( ipy) = 0.0 cgrid%fmean_sfcw_temp ( ipy) = 0.0 cgrid%fmean_sfcw_fliq ( ipy) = 0.0 + cgrid%fmean_snowfac ( ipy) = 0.0 cgrid%fmean_soil_energy (:,ipy) = 0.0 cgrid%fmean_soil_mstpot (:,ipy) = 0.0 cgrid%fmean_soil_water (:,ipy) = 0.0 cgrid%fmean_soil_temp (:,ipy) = 0.0 cgrid%fmean_soil_fliq (:,ipy) = 0.0 + cgrid%fmean_snowfac ( ipy) = 0.0 cgrid%fmean_rshort_gnd ( ipy) = 0.0 cgrid%fmean_par_gnd ( ipy) = 0.0 cgrid%fmean_rlong_gnd ( ipy) = 0.0 @@ -1574,6 +1579,7 @@ subroutine zero_ed_fmean_vars(cgrid) csite%fmean_sfcw_mass ( ipa) = 0.0 csite%fmean_sfcw_temp ( ipa) = 0.0 csite%fmean_sfcw_fliq ( ipa) = 0.0 + csite%fmean_snowfac ( ipa) = 0.0 csite%fmean_soil_energy (:,ipa) = 0.0 csite%fmean_soil_mstpot (:,ipa) = 0.0 csite%fmean_soil_water (:,ipa) = 0.0 @@ -2059,6 +2065,9 @@ subroutine integrate_ed_dmean_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = cgrid%dmean_sfcw_mass (ipy) & + cgrid%fmean_sfcw_mass (ipy) & * frqsum_o_daysec + cgrid%dmean_snowfac (ipy) = cgrid%dmean_snowfac (ipy) & + + cgrid%fmean_snowfac (ipy) & + * frqsum_o_daysec cgrid%dmean_rshort_gnd (ipy) = cgrid%dmean_rshort_gnd (ipy) & + cgrid%fmean_rshort_gnd (ipy) & * frqsum_o_daysec @@ -2363,6 +2372,9 @@ subroutine integrate_ed_dmean_vars(cgrid) csite%dmean_sfcw_mass (ipa) = csite%dmean_sfcw_mass (ipa) & + csite%fmean_sfcw_mass (ipa) & * frqsum_o_daysec + csite%dmean_snowfac (ipa) = csite%dmean_snowfac (ipa) & + + csite%fmean_snowfac (ipa) & + * frqsum_o_daysec csite%dmean_rshort_gnd (ipa) = csite%dmean_rshort_gnd (ipa) & + csite%fmean_rshort_gnd (ipa) & * frqsum_o_daysec @@ -2812,10 +2824,11 @@ end subroutine normalize_ed_today_vars !=======================================================================================! !=======================================================================================! - ! SUBROUTINE: NORMALIZE_ED_TODAYNPP_VARS - !> \brief This subroutine will scale the daily NPP allocation terms + ! SUBROUTINE: COPY_TODAY_TO_DMEAN_VARS + !> \brief This subroutine scales the daily NPP allocation terms and transfer today + !! variables to dmean. !---------------------------------------------------------------------------------------! - subroutine normalize_ed_todayNPP_vars(cgrid) + subroutine copy_today_to_dmean_vars(cgrid) use ed_state_vars , only : edtype & ! structure , polygontype & ! structure , sitetype & ! structure @@ -2833,47 +2846,70 @@ subroutine normalize_ed_todayNPP_vars(cgrid) integer :: isi integer :: ipa integer :: ico + !------------------------------------------------------------------------------------! + + !------ Skip sub-routine and do nothing in case we are not writing daily averages. --! + if (.not. writing_long) return + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Loop through polygons. ! + !------------------------------------------------------------------------------------! polyloop: do ipy=1,cgrid%npolygons cpoly => cgrid%polygon(ipy) + + !---------------------------------------------------------------------------------! + ! Loop through sites. ! + !---------------------------------------------------------------------------------! siteloop: do isi=1,cpoly%nsites csite => cpoly%site(isi) - patchloop: do ipa=1,csite%npatches + !------------------------------------------------------------------------------! + ! Loop through patches. ! + !------------------------------------------------------------------------------! + patchloop: do ipa=1,csite%npatches cpatch => csite%patch(ipa) - - !----- Included a loop so it won't crash with empty cohorts... -------------! + + !---------------------------------------------------------------------------! + ! Loop through cohorts. This must be a loop, so it won't crash with ! + ! empty patches. ! + !---------------------------------------------------------------------------! cohortloop: do ico=1,cpatch%ncohorts !------------------------------------------------------------------------! ! We now update the daily means of NPP allocation terms ! ! and we convert them to kgC/plant/yr ! !------------------------------------------------------------------------! - if (writing_long) then - cpatch%dmean_nppleaf (ico) = cpatch%today_nppleaf (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppfroot (ico) = cpatch%today_nppfroot (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppsapwood(ico) = cpatch%today_nppsapwood(ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppbark (ico) = cpatch%today_nppbark (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppcroot (ico) = cpatch%today_nppcroot (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppseeds (ico) = cpatch%today_nppseeds (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppwood (ico) = cpatch%today_nppwood (ico) & - * yr_day / cpatch%nplant (ico) - cpatch%dmean_nppdaily (ico) = cpatch%today_nppdaily (ico) & - * yr_day / cpatch%nplant (ico) - end if + cpatch%dmean_nppleaf (ico) = cpatch%today_nppleaf (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppfroot (ico) = cpatch%today_nppfroot (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppsapwood(ico) = cpatch%today_nppsapwood(ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppbark (ico) = cpatch%today_nppbark (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppcroot (ico) = cpatch%today_nppcroot (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppseeds (ico) = cpatch%today_nppseeds (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppwood (ico) = cpatch%today_nppwood (ico) & + * yr_day / cpatch%nplant (ico) + cpatch%dmean_nppdaily (ico) = cpatch%today_nppdaily (ico) & + * yr_day / cpatch%nplant (ico) + !------------------------------------------------------------------------! end do cohortloop + !---------------------------------------------------------------------------! end do patchloop + !------------------------------------------------------------------------------! end do siteloop + !---------------------------------------------------------------------------------! end do polyloop + !------------------------------------------------------------------------------------! return - end subroutine normalize_ed_todayNPP_vars + end subroutine copy_today_to_dmean_vars !=======================================================================================! !=======================================================================================! @@ -3702,6 +3738,7 @@ subroutine zero_ed_dmean_vars(cgrid) cgrid%dmean_sfcw_mass (ipy) = 0.0 cgrid%dmean_sfcw_temp (ipy) = 0.0 cgrid%dmean_sfcw_fliq (ipy) = 0.0 + cgrid%dmean_snowfac (ipy) = 0.0 cgrid%dmean_soil_energy (:,ipy) = 0.0 cgrid%dmean_soil_mstpot (:,ipy) = 0.0 cgrid%dmean_soil_water (:,ipy) = 0.0 @@ -3824,6 +3861,7 @@ subroutine zero_ed_dmean_vars(cgrid) csite%dmean_sfcw_mass (ipa) = 0.0 csite%dmean_sfcw_temp (ipa) = 0.0 csite%dmean_sfcw_fliq (ipa) = 0.0 + csite%dmean_snowfac (ipa) = 0.0 csite%dmean_soil_energy (:,ipa) = 0.0 csite%dmean_soil_mstpot (:,ipa) = 0.0 csite%dmean_soil_water (:,ipa) = 0.0 @@ -4426,6 +4464,9 @@ subroutine integrate_ed_mmean_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = cgrid%mmean_sfcw_mass (ipy) & + cgrid%dmean_sfcw_mass (ipy) & * ndaysi + cgrid%mmean_snowfac (ipy) = cgrid%mmean_snowfac (ipy) & + + cgrid%dmean_snowfac (ipy) & + * ndaysi cgrid%mmean_soil_energy (:,ipy) = cgrid%mmean_soil_energy (:,ipy) & + cgrid%dmean_soil_energy (:,ipy) & * ndaysi @@ -4951,6 +4992,9 @@ subroutine integrate_ed_mmean_vars(cgrid) csite%mmean_sfcw_mass (ipa) = csite%mmean_sfcw_mass (ipa) & + csite%dmean_sfcw_mass (ipa) & * ndaysi + csite%mmean_snowfac (ipa) = csite%mmean_snowfac (ipa) & + + csite%dmean_snowfac (ipa) & + * ndaysi csite%mmean_soil_energy (:,ipa) = csite%mmean_soil_energy (:,ipa) & + csite%dmean_soil_energy (:,ipa) & * ndaysi @@ -6086,6 +6130,7 @@ subroutine zero_ed_mmean_vars(cgrid) cgrid%mmean_sfcw_mass (ipy) = 0.0 cgrid%mmean_sfcw_temp (ipy) = 0.0 cgrid%mmean_sfcw_fliq (ipy) = 0.0 + cgrid%mmean_snowfac (ipy) = 0.0 cgrid%mmean_soil_energy (:,ipy) = 0.0 cgrid%mmean_soil_mstpot (:,ipy) = 0.0 cgrid%mmean_soil_water (:,ipy) = 0.0 @@ -6274,6 +6319,7 @@ subroutine zero_ed_mmean_vars(cgrid) csite%mmean_sfcw_mass (ipa) = 0.0 csite%mmean_sfcw_temp (ipa) = 0.0 csite%mmean_sfcw_fliq (ipa) = 0.0 + csite%mmean_snowfac (ipa) = 0.0 csite%mmean_soil_energy (:,ipa) = 0.0 csite%mmean_soil_mstpot (:,ipa) = 0.0 csite%mmean_soil_water (:,ipa) = 0.0 @@ -6838,6 +6884,9 @@ subroutine integrate_ed_qmean_vars(cgrid) cgrid%qmean_sfcw_mass (t,ipy) = cgrid%qmean_sfcw_mass (t,ipy) & + cgrid%fmean_sfcw_mass (ipy) & * ndaysi + cgrid%qmean_snowfac (t,ipy) = cgrid%qmean_snowfac (t,ipy) & + + cgrid%fmean_snowfac (ipy) & + * ndaysi cgrid%qmean_soil_energy (:,t,ipy) = cgrid%qmean_soil_energy (:,t,ipy) & + cgrid%fmean_soil_energy (:,ipy) & * ndaysi @@ -7230,6 +7279,9 @@ subroutine integrate_ed_qmean_vars(cgrid) csite%qmean_sfcw_mass (t,ipa) = csite%qmean_sfcw_mass (t,ipa) & + csite%fmean_sfcw_mass (ipa) & * ndaysi + csite%qmean_snowfac (t,ipa) = csite%qmean_snowfac (t,ipa) & + + csite%fmean_snowfac (ipa) & + * ndaysi csite%qmean_soil_energy (:,t,ipa) = csite%qmean_soil_energy (:,t,ipa) & + csite%fmean_soil_energy (:,ipa) & * ndaysi @@ -7796,6 +7848,25 @@ subroutine normalize_ed_qmean_vars(cgrid) + !---------------------------------------------------------------------------! + ! Find the derived properties for the canopy air space. ! + !---------------------------------------------------------------------------! + do t=1,ndcycle + can_exner = press2exner ( csite%qmean_can_prss (t,ipa)) + csite%qmean_can_temp(t,ipa) = extheta2temp( can_exner & + , csite%qmean_can_theta(t,ipa)) + csite%qmean_can_rhos(t,ipa) = idealdenssh ( csite%qmean_can_prss (t,ipa) & + , csite%qmean_can_temp (t,ipa) & + , csite%qmean_can_shv (t,ipa)) + csite%qmean_can_dmol(t,ipa) = idealdmolsh ( csite%qmean_can_prss (t,ipa) & + , csite%qmean_can_temp (t,ipa) & + , csite%qmean_can_shv (t,ipa)) + end do + !---------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------! ! Soil matric potential, temperature, and liquid water. ! !---------------------------------------------------------------------------! @@ -8163,6 +8234,7 @@ subroutine zero_ed_qmean_vars(cgrid) cgrid%qmean_sfcw_mass (:,ipy) = 0.0 cgrid%qmean_sfcw_temp (:,ipy) = 0.0 cgrid%qmean_sfcw_fliq (:,ipy) = 0.0 + cgrid%qmean_snowfac (:,ipy) = 0.0 cgrid%qmean_soil_energy (:,:,ipy) = 0.0 cgrid%qmean_soil_mstpot (:,:,ipy) = 0.0 cgrid%qmean_soil_water (:,:,ipy) = 0.0 @@ -8309,6 +8381,7 @@ subroutine zero_ed_qmean_vars(cgrid) csite%qmean_sfcw_mass (:,ipa) = 0.0 csite%qmean_sfcw_temp (:,ipa) = 0.0 csite%qmean_sfcw_fliq (:,ipa) = 0.0 + csite%qmean_snowfac (:,ipa) = 0.0 csite%qmean_soil_energy (:,:,ipa) = 0.0 csite%qmean_soil_mstpot (:,:,ipa) = 0.0 csite%qmean_soil_water (:,:,ipa) = 0.0 diff --git a/ED/src/io/ed_init_history.f90 b/ED/src/io/ed_init_history.f90 index f4d91cc49..7453fb2f1 100644 --- a/ED/src/io/ed_init_history.f90 +++ b/ED/src/io/ed_init_history.f90 @@ -23,31 +23,48 @@ module ed_init_history ! polygons and populate the model states with what is found in the files tree. ! !---------------------------------------------------------------------------------------! subroutine resume_from_history() - use ed_max_dims , only : n_pft & ! intent(in) - , str_len ! ! intent(in) - use ed_misc_coms , only : sfilin & ! intent(in) - , current_time & ! intent(in) - , max_poihist_dist ! ! intent(in) - use ed_state_vars , only : polygontype & ! structure - , sitetype & ! structure - , patchtype & ! structure - , edtype & ! structure - , edgrid_g & ! structure - , allocate_sitetype & ! subroutine - , allocate_patchtype & ! subroutine - , allocate_polygontype ! ! subroutine - use soil_coms , only : alloc_soilgrid ! ! subroutine - use grid_coms , only : ngrids ! ! intent(in) - use phenology_startup, only : phenology_init ! ! subroutine - use ed_node_coms , only : mynum ! ! intent(in) + use ed_max_dims , only : n_pft & ! intent(in) + , str_len & ! intent(in) + , ed_nstyp & ! intent(in) + , undef_real ! ! intent(in) + use ed_misc_coms , only : sfilin & ! intent(in) + , current_time & ! intent(in) + , max_poihist_dist ! ! intent(in) + use ed_state_vars , only : polygontype & ! structure + , sitetype & ! structure + , patchtype & ! structure + , edtype & ! structure + , edgrid_g & ! structure + , allocate_sitetype & ! subroutine + , allocate_patchtype & ! subroutine + , allocate_polygontype ! ! subroutine + use grid_coms , only : ngrids & ! intent(in) + , nzg & ! intent(out) + , nzs ! ! intent(out) + use soil_coms , only : slz & ! intent(out) + , slhydro_ref & ! intent(out) + , slxclay_ref & ! intent(out) + , slxsilt_ref & ! intent(out) + , slxsand_ref & ! intent(out) + , slsoc_ref & ! intent(out) + , slph_ref & ! intent(out) + , slcec_ref & ! intent(out) + , sldbd_ref & ! intent(out) + , alloc_soilgrid ! ! sub-routine + use fusion_fission_coms, only : ff_nhgt & ! intent(in) + , hgt_class ! ! intent(in) + use phenology_startup , only : phenology_init ! ! subroutine + use ed_node_coms , only : mynum & ! intent(in) + , nnodetot ! ! intent(in) + use ed_init , only : sfcdata_ed ! ! sub-routine use hdf5 - use hdf5_coms , only : file_id & ! intent(inout) - , dset_id & ! intent(inout) - , dspace_id & ! intent(inout) - , globdims & ! intent(inout) - , chnkdims & ! intent(inout) - , chnkoffs ! ! intent(inout) - use landuse_init , only : read_landuse_matrix ! ! intent(in) + use hdf5_coms , only : file_id & ! intent(inout) + , dset_id & ! intent(inout) + , dspace_id & ! intent(inout) + , globdims & ! intent(inout) + , chnkdims & ! intent(inout) + , chnkoffs ! ! intent(inout) + use landuse_init , only : read_landuse_matrix ! ! sub-routine implicit none !------ Local variables. ------------------------------------------------------------! type(edtype) , pointer :: cgrid @@ -88,6 +105,7 @@ subroutine resume_from_history() write (unit=*,fmt='(a)') '-----------------------------------------------------' write (unit=*,fmt='(a)') ' Loading Full State (HISTORY)' + write (unit=*,fmt='(a)') '-----------------------------------------------------' !----- Open the HDF environment. ----------------------------------------------------! @@ -133,6 +151,182 @@ subroutine resume_from_history() ,'resume_from_history','ed_init_history.f90') end if end if + !---------------------------------------------------------------------------------! + + + + + !---------------------------------------------------------------------------------! + ! If this is the first grid, we read global dimensions and vectors. ! + !---------------------------------------------------------------------------------! + select case (ngr) + case (1) + if (mynum == nnodetot) write (unit=*,fmt='(a)') & + ' [-] Load global dimensions...' + + !------------------------------------------------------------------------------! + ! Retrieve global vector sizes. This includes the number of soil and snow ! + ! layers, and the number of height classes for patch fusion. ! + ! ! + ! Note: if running HISTORY, this will overwrite the ED2IN settings. It is ! + ! not anyway a good idea to change settings in simulations using ! + ! HISTORY (you can always have a "soft" initialisation for forest ! + ! structure only, using RUNTYPE='INITIAL' and IED_INIT_MODE=5, and this ! + ! would allow you to change as many settings as you want, and likely ! + ! even different versions of code if you dare. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = 1_8 + + call h5dopen_f(file_id,'NZG', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,nzg,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'NZS', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,nzs,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'FF_NHGT', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,ff_nhgt,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Retrieve soil layers. These will overwrite ED2IN settings if they are ! + ! different. It is very unwise to change the soil grid during a HISTORY run. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(nzg,8) + + slz(:) = undef_real + call h5dopen_f(file_id,'SLZ', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slz(1:nzg),globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Height classes for patch fusion. ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(ff_nhgt,8) + + if (allocated(hgt_class)) deallocate(hgt_class) + allocate(hgt_class(ff_nhgt)) + call h5dopen_f(file_id,'HGT_CLASS', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,hgt_class,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + + + !------------------------------------------------------------------------------! + ! Retrieve default soil characteristics (texture and approach). This will ! + ! effectively supersede the ISOIL_HYDRO settings (it's not wise to change ! + ! settings in the middle of a simulation). ! + !------------------------------------------------------------------------------! + globdims = 0_8 + chnkdims = 0_8 + chnkoffs = 0_8 + globdims(1) = int(ed_nstyp,8) + + call h5dopen_f(file_id,'SLHYDRO_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER,slhydro_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXSAND_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxsand_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXSILT_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxsilt_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLXCLAY_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slxclay_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLSOC_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slsoc_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLPH_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slph_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLCEC_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,slcec_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + + call h5dopen_f(file_id,'SLDBD_REF', dset_id, hdferr) + call h5dget_space_f(dset_id, dspace_id, hdferr) + call h5dread_f(dset_id, H5T_NATIVE_REAL,sldbd_ref,globdims, hdferr) + call h5sclose_f(dspace_id, hdferr) + call h5dclose_f(dset_id, hdferr) + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Allocate soil grid arrays. ! + !------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [-] Alloc_Soilgrid...' + call alloc_soilgrid() + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise variables that are related to soil layers. ! + !------------------------------------------------------------------------------! + if (mynum == nnodetot) write (unit=*,fmt='(a)') ' [-] Sfcdata_ED...' + call sfcdata_ed() + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! !---------------------------------------------------------------------------------! @@ -424,13 +618,13 @@ subroutine resume_from_history() !----- Load the anthropogenic disturbance (or set them all to zero). ----------------! - write(unit=*,fmt='(a,i2.2)') ' Checking anthropogenic disturbance. Node: ',mynum + write(unit=*,fmt='(a,i2.2)') ' Loading anthropogenic disturbance. Node: ',mynum call read_landuse_matrix() !------------------------------------------------------------------------------------! !----- Load phenology in case it is prescribed (or set them with defaults). ---------! - write(unit=*,fmt='(a,i2.2)') ' Checking prescribed phenology. Node: ',mynum + write(unit=*,fmt='(a,i2.2)') ' Loading prescribed phenology. Node: ',mynum call phenology_init() return @@ -1004,6 +1198,8 @@ subroutine fill_history_grid_p11dmean(cgrid,ipy,py_index) ,'DMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_sfcw_fliq (ipy:ipy) & ,'DMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%dmean_snowfac (ipy:ipy) & + ,'DMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_rshort_gnd (ipy:ipy) & ,'DMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%dmean_par_gnd (ipy:ipy) & @@ -1432,6 +1628,8 @@ subroutine fill_history_grid_p11mmean(cgrid,ipy,py_index) ,'MMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_sfcw_fliq (ipy:ipy) & ,'MMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%mmean_snowfac (ipy:ipy) & + ,'MMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_rshort_gnd (ipy:ipy) & ,'MMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%mmean_par_gnd (ipy:ipy) & @@ -2055,6 +2253,8 @@ subroutine fill_history_grid_m11(cgrid,ipy,py_index) ,'QMEAN_SFCW_TEMP_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_sfcw_fliq (:,ipy) & ,'QMEAN_SFCW_FLIQ_PY ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(cgrid%qmean_snowfac (:,ipy) & + ,'QMEAN_SNOWFAC_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_rshort_gnd (:,ipy) & ,'QMEAN_RSHORT_GND_PY ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(cgrid%qmean_par_gnd (:,ipy) & @@ -3257,8 +3457,8 @@ subroutine fill_history_polygon(cpoly,pysi_index,nsites_global,nsites_now,is_bur memoffs (2) = 0_8 call hdf_getslab_r(cpoly%lambda_fire & ,'LAMBDA_FIRE ',dsetrank,iparallel,.true.,foundvar) - call hdf_getslab_r(cpoly%avg_monthly_pcpg & - ,'AVG_MONTHLY_PCPG ',dsetrank,iparallel,.true.,foundvar) + call hdf_getslab_r(cpoly%avg_monthly_accp & + ,'AVG_MONTHLY_ACCP ',dsetrank,iparallel,.true.,foundvar) call hdf_getslab_r(cpoly%crop_yield & ,'CROP_YIELD_SI ',dsetrank,iparallel,.true.,foundvar) !------------------------------------------------------------------------------------! @@ -4069,6 +4269,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'DMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_sfcw_fliq & ,'DMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%dmean_snowfac & + ,'DMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_rshort_gnd & ,'DMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%dmean_par_gnd & @@ -4238,6 +4440,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'MMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_sfcw_fliq & ,'MMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%mmean_snowfac & + ,'MMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_rshort_gnd & ,'MMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%mmean_par_gnd & @@ -4443,6 +4647,8 @@ subroutine fill_history_site(csite,sipa_index,npatches_global,is_burnt) ,'QMEAN_SFCW_TEMP_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_sfcw_fliq & ,'QMEAN_SFCW_FLIQ_PA ',dsetrank,iparallel,.false.,foundvar) + call hdf_getslab_r(csite%qmean_snowfac & + ,'QMEAN_SNOWFAC_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_rshort_gnd & ,'QMEAN_RSHORT_GND_PA ',dsetrank,iparallel,.false.,foundvar) call hdf_getslab_r(csite%qmean_par_gnd & @@ -5691,6 +5897,8 @@ subroutine fill_history_patch(cpatch,paco_index,ncohorts_global) memdims (2) = int(cpatch%ncohorts,8) memsize (2) = int(cpatch%ncohorts,8) memoffs (2) = 0_8 + call hdf_getslab_r(cpatch%root_frac & + ,'ROOT_FRAC ',dsetrank,iparallel,.true. ,foundvar) call hdf_getslab_r(cpatch%wflux_gw_layer & ,'WFLUX_GW_LAYER ',dsetrank,iparallel,.true. ,foundvar) if (writing_long) then diff --git a/ED/src/io/ed_load_namelist.f90 b/ED/src/io/ed_load_namelist.f90 index 37a430c8b..e5967bc04 100644 --- a/ED/src/io/ed_load_namelist.f90 +++ b/ED/src/io/ed_load_namelist.f90 @@ -659,11 +659,6 @@ subroutine copy_nl(copy_type) imontha = nl%imontha iyeara = nl%iyeara - nzg = nl%nzg - nzs = nl%nzs - - slz(1:nzgmax) = nl%slz(1:nzgmax) - !------------------------------------------------------------------------------------! ! Set current time to initial time here. If this is a history run, reset ! ! current time in subroutine history_start. ! diff --git a/ED/src/io/ed_opspec.F90 b/ED/src/io/ed_opspec.F90 index 1011fcf90..44a52bce9 100644 --- a/ED/src/io/ed_opspec.F90 +++ b/ED/src/io/ed_opspec.F90 @@ -51,6 +51,7 @@ subroutine ed_opspec_grid , ed_reg_lonmin & ! intent(in) , ed_reg_lonmax ! ! intent(in) use soil_coms , only : slz ! ! intent(in) + use ed_misc_coms, only : runtype ! ! intent(in) implicit none !----- Local variables. ----------------------------------------------------------------! @@ -285,60 +286,67 @@ subroutine ed_opspec_grid end if !---------------------------------------------------------------------------------------! - ! Check whether ED soil layers are reasonable, i.e, enough layers, sorted from the ! - ! deepest to the shallowest. ! + ! The checks on surface and snow settings should be made only for INITIAL runs. ! !---------------------------------------------------------------------------------------! - if (nzg < 2) then - write (reason,'(a,1x,i4,a)') & - 'Too few soil layers. Set it to at least 2. Your nzg is currently set to' & - ,nzg,'...' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - elseif (nzg > nzgmax) then - write (reason,'(2(a,1x,i5,a))') & - 'The number of soil layers cannot be greater than ',nzgmax,'.' & - ,' Your nzg is currently set to',nzg,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - end if - do k=1,nzg - if (slz(k) > -.001) then - write (reason,'(a,1x,i4,1x,a,1x,es14.7,a)') & - 'Your soil level #',k,'is not enough below ground. It is currently set to' & - ,slz(k),', make it deeper than -0.001...' + select case (trim(runtype)) + case ('INITIAL') + !------------------------------------------------------------------------------------! + ! Check whether ED soil layers are reasonable, i.e, enough layers, sorted from ! + ! the deepest to the shallowest. ! + !------------------------------------------------------------------------------------! + if (nzg < 2) then + write (reason,'(a,1x,i4,a)') & + 'Too few soil layers. Set it to at least 2. Your nzg is currently set to' & + ,nzg,'...' call opspec_fatal(reason,'opspec_grid') ifaterr=ifaterr+1 + elseif (nzg > nzgmax) then + write (reason,'(2(a,1x,i5,a))') & + 'The number of soil layers cannot be greater than ',nzgmax,'.' & + ,' Your nzg is currently set to',nzg,'.' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 end if - end do + do k=1,nzg + if (slz(k) > -.001) then + write (reason,'(a,1x,i4,1x,a,1x,es14.7,a)') & + 'Your soil level #',k,'is too thin. It is currently set to',slz(k) & + ,', make it deeper than -0.001...' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 + end if + end do + + do k=1,nzg-1 + if (slz(k)-slz(k+1) > .001) then + write (reason,'(2(a,1x,i4,1x),a,2x,a,1x,es14.7,1x,a,1x,es14.7,a)') & + 'Soil layers #',k,'and',k+1,'are not enough apart (i.e. > 0.001).' & + ,'They are currently set as ',slz(k),'and',slz(k+1),'...' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 + end if + end do + - do k=1,nzg-1 - if (slz(k)-slz(k+1) > .001) then - write (reason,'(2(a,1x,i4,1x),a,2x,a,1x,es14.7,1x,a,1x,es14.7,a)') & - 'Soil layers #',k,'and',k+1,'are not enough apart (i.e. > 0.001).' & - ,'They are currently set as ',slz(k),'and',slz(k+1),'...' + !------------------------------------------------------------------------------------! + ! Check whether ED snow layers are well set, i.e., the number of soil levels is ! + ! within the allowed range. ! + !------------------------------------------------------------------------------------! + if (nzs < 1) then + write (reason,'(a,2x,a,1x,i4,a)') & + 'Too few maximum # of snow layers. Set it to at least 1.' & + ,'Your nzs is currently set to',nzs,'.' call opspec_fatal(reason,'opspec_grid') ifaterr=ifaterr+1 + elseif (nzs > nzsmax) then + write (reason,'(2(a,1x,i5,a))') & + 'The number of snow layers cannot be greater than ',nzsmax,'.' & + ,' Your nzs is currently set to',nzs,'.' + call opspec_fatal(reason,'opspec_grid') + ifaterr=ifaterr+1 end if - end do - - - !---------------------------------------------------------------------------------------! - ! Check whether ED snow layers are well set, i.e., the number of soil levels is ! - ! within the allowed range. ! - !---------------------------------------------------------------------------------------! - if (nzs < 1) then - write (reason,'(a,2x,a,1x,i4,a)') & - 'Too few maximum # of snow layers. Set it to at least 1.' & - ,'Your nzs is currently set to',nzs,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - elseif (nzs > nzsmax) then - write (reason,'(2(a,1x,i5,a))') & - 'The number of snow layers cannot be greater than ',nzsmax,'.' & - ,' Your nzs is currently set to',nzs,'.' - call opspec_fatal(reason,'opspec_grid') - ifaterr=ifaterr+1 - end if + !------------------------------------------------------------------------------------! + end select !---------------------------------------------------------------------------------------! @@ -1145,6 +1153,8 @@ end subroutine ed_opspec_times !------------------------------------------------------------------------------------------! subroutine ed_opspec_misc use ed_max_dims , only : n_pft & ! intent(in) + , ed_nstyp & ! intent(in) + , ed_nscol & ! intent(in) , str_len & ! intent(in) , skip_integer & ! intent(in) , skip_real ! ! intent(in) @@ -1189,9 +1199,7 @@ subroutine ed_opspec_misc , lwidth_nltree & ! intent(in) , ribmax & ! intent(in) , leaf_maxwhc ! ! intent(in) - use soil_coms , only : ed_nstyp & ! intent(in) - , ed_nscol & ! intent(in) - , isoilflg & ! intent(in) + use soil_coms , only : isoilflg & ! intent(in) , islcolflg & ! intent(in) , nslcon & ! intent(in) , isoilcol & ! intent(in) @@ -1440,7 +1448,8 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (ied_init_mode == -8) then + select case (ied_init_mode) + case (-8) !------------------------------------------------------------------------------------! ! The special 8-layer model works only in size- and age-structured runs. ! !------------------------------------------------------------------------------------! @@ -1471,20 +1480,22 @@ subroutine ed_opspec_misc write (unit=*,fmt='(a)') ' simulations only. If that''s not what you wanted, change ' write (unit=*,fmt='(a)') ' your IED_INIT_MODE variable on your ED2IN. ' write (unit=*,fmt='(a)') '===========================================================' - elseif ((ied_init_mode < -1 .or. ied_init_mode > 7) .and. & - (ied_init_mode /= 99 )) then + case (-1:8,99) + !----- Valid options, do nothing. ---------------------------------------------------! + continue + !------------------------------------------------------------------------------------! + case default write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IED_INIT_MODE, it must be between -1 and 7. Yours is set to' & + 'Invalid IED_INIT_MODE, it must be between -1 and 8. Yours is set to' & ,ied_init_mode,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 - end if + end select - if (ied_init_mode == 7 .and. isoilstateinit>0 ) then - write (reason,fmt='(a)') & - 'Please set ISOILSTATEINIT=0 if using IED_INIT_MODE=7' + if (ied_init_mode == 7 .and. isoilstateinit > 0) then + write (reason,fmt='(a)') 'Please set ISOILSTATEINIT = 0 if using IED_INIT_MODE = 7.' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 end if @@ -1631,9 +1642,9 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (isoilbc < 0 .or. isoilbc > 3) then + if (isoilbc < -1 .or. isoilbc > 3) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid ISOILBC, it must be between 0 and 3. Yours is set to',isoilbc,'...' + 'Invalid ISOILBC, it must be between -1 and 3. Yours is set to',isoilbc,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 else if(isoilbc == 2 .and. (sldrain < 0. .or. sldrain > 90.)) then @@ -1841,9 +1852,9 @@ subroutine ed_opspec_misc ifaterr = ifaterr +1 end if - if (iallom < 0 .or. iallom > 4) then + if (iallom < 0 .or. iallom > 5) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IALLOM, it must be between 0 and 4. Yours is set to' & + 'Invalid IALLOM, it must be between 0 and 5. Yours is set to' & ,iallom,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 @@ -1872,9 +1883,9 @@ subroutine ed_opspec_misc end if - if (iphen_scheme < -1 .or. iphen_scheme > 4) then + if (iphen_scheme < -1 .or. iphen_scheme > 5) then write (reason,fmt='(a,1x,i4,a)') & - 'Invalid IPHEN_SCHEME, it must be between -1 and 4. Yours is set to' & + 'Invalid IPHEN_SCHEME, it must be between -1 and 5. Yours is set to' & ,iphen_scheme,'...' call opspec_fatal(reason,'opspec_misc') ifaterr = ifaterr +1 @@ -1893,7 +1904,7 @@ subroutine ed_opspec_misc ! model may be linear or log-linear. Don't bother checking if IPHEN_SCHEME is not 3. ! !---------------------------------------------------------------------------------------! select case (iphen_scheme) - case (3) + case (3,5) !----- Light-driven phenology is enabled. Check settings. --------------------------! select case (economics_scheme) case (1) diff --git a/ED/src/io/ed_print.F90 b/ED/src/io/ed_print.F90 index aeb2115b8..33f5a51a7 100644 --- a/ED/src/io/ed_print.F90 +++ b/ED/src/io/ed_print.F90 @@ -30,6 +30,7 @@ module ed_print subroutine print_fields(ifm,cgrid) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , sendnum & ! intent(in) @@ -49,10 +50,6 @@ subroutine print_fields(ifm,cgrid) , num_var ! ! intent(in) use ed_max_dims , only : str_len_short ! ! intent(in) implicit none - !----- Standard common blocks. ------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. -------------------------------------------------------------------! integer , intent(in) :: ifm type(edtype) , target :: cgrid diff --git a/ED/src/io/ed_read_ed10_20_history.f90 b/ED/src/io/ed_read_ed10_20_history.f90 index 083c6e93e..e1b0ef959 100644 --- a/ED/src/io/ed_read_ed10_20_history.f90 +++ b/ED/src/io/ed_read_ed10_20_history.f90 @@ -881,12 +881,18 @@ subroutine read_ed10_ed20_history_file end select !------------------------------------------------------------------! + !------------------------------------------------------------------! - ! Initialise SLA with the look-up table value, this may be ! - ! updated during phenology initialisation, but an initial assign- ! - ! ment is needed to obtain area indices. ! + ! Initialise SLA, Vm0, Rd0, and with the look-up table value. ! + ! These variables may be updated during phenology initialisation, ! + ! or trait plasticity, but they must have an initial assignment so ! + ! we can even calculate the initial area indices and inicial trait ! + ! values needed for the trait update. ! !------------------------------------------------------------------! - cpatch%sla(ic2) = SLA(ipft(ic)) + cpatch%sla (ic2) = SLA (ipft(ic)) + cpatch%vm_bar(ic2) = Vm0 (ipft(ic)) + cpatch%rd_bar(ic2) = Rd0 (ipft(ic)) + cpatch%llspan(ic2) = leaf_lifespan(ipft(ic)) !------------------------------------------------------------------! diff --git a/ED/src/io/ed_read_ed21_history.f90 b/ED/src/io/ed_read_ed21_history.f90 index 3e84faf03..bba663ff7 100644 --- a/ED/src/io/ed_read_ed21_history.f90 +++ b/ED/src/io/ed_read_ed21_history.f90 @@ -691,36 +691,52 @@ subroutine read_ed21_history_file !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4)) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! @@ -2082,36 +2098,52 @@ subroutine read_ed21_history_unstruct !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if (iallom == 3 .or. iallom == 4) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! @@ -3456,36 +3488,52 @@ subroutine read_ed21_polyclone !---------------------------------------------------------------! ! Initialise size and structural pools. ! !---------------------------------------------------------------! - if (iallom == 3 .or. iallom == 4) then + select case (iallom) + case (3,4,5) !----- New allometry, initialise with DBH. ------------------! cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) bdeadx = size2bd(cpatch%dbh(ico) & ,cpatch%hite(ico),ipft) cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - elseif ( igrass == 1 .and. is_grass(ipft) & - .and. cpatch%bdeada(ico) > 0.0 ) then - !-- if the initial file was running with igrass = 0, bdead ! - ! should be nonzero. If the new run has igrass = 1, bdead ! - ! is set to zero and the mass is discarded ! - cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) - cpatch%bdeada(ico) = 0.0 - cpatch%bdeadb(ico) = 0.0 - - else if (bdeadx > 0.0 .and. igrass == 0) then - ! grasses have bdead in both input and current run (igrass=0) - cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & - ,cpatch%bdeadb(ico) ) - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) - else - ! it is either a new grass (igrass=1) in the initial file, ! - ! or the value for bdead is missing from the files ! - cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) - bdeadx = size2bd(cpatch%dbh(ico) & - ,cpatch%hite(ico),ipft) - cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx - cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx - end if + case default + if ( igrass == 1 .and. is_grass(ipft) & + .and. cpatch%bdeada(ico) > 0.0 ) then + !---------------------------------------------------------! + ! If the initial file was running with igrass = 0, ! + ! bdead should be nonzero. If the new run has ! + ! igrass = 1, bdead is set to zero and the mass is ! + ! discarded. This does not violate carbon conservation ! + ! because this is the initial state of a new run. ! + !---------------------------------------------------------! + cpatch%hite (ico) = dbh2h (ipft,cpatch%dbh (ico)) + cpatch%bdeada(ico) = 0.0 + cpatch%bdeadb(ico) = 0.0 + !---------------------------------------------------------! + + else if (bdeadx > 0.0 .and. igrass == 0) then + !---------------------------------------------------------! + ! Grasses have bdead in both input and current run ! + ! (igrass=0). ! + !---------------------------------------------------------! + cpatch%dbh(ico) = bd2dbh(ipft,cpatch%bdeada(ico) & + ,cpatch%bdeadb(ico) ) + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico) ) + !---------------------------------------------------------! + else + !---------------------------------------------------------! + ! It is either a new grass (igrass=1) in the initial ! + ! file, or the value for bdead is missing from the files. ! + !---------------------------------------------------------! + cpatch%hite(ico) = dbh2h (ipft,cpatch%dbh (ico)) + bdeadx = size2bd(cpatch%dbh(ico) & + ,cpatch%hite(ico),ipft) + cpatch%bdeada(ico) = agf_bs(ipft) * bdeadx + cpatch%bdeadb(ico) = (1.0 - agf_bs(ipft)) * bdeadx + !---------------------------------------------------------! + end if + !------------------------------------------------------------! + end select !---------------------------------------------------------------! diff --git a/ED/src/io/ed_read_ed22_initial.f90 b/ED/src/io/ed_read_ed22_initial.f90 new file mode 100644 index 000000000..bcdd1a5ef --- /dev/null +++ b/ED/src/io/ed_read_ed22_initial.f90 @@ -0,0 +1,1339 @@ +!==========================================================================================! +!==========================================================================================! +! This subroutine reads ED-2.2 initial files. The format is very similar to the ! +! ED-1.0/ED-2.0 "history" format, except that it has additional fields to initialise the ! +! necromass, and a site file. ! +!------------------------------------------------------------------------------------------! +subroutine read_ed22_initial_file + + use ed_max_dims , only : n_pft & ! intent(in) + , huge_site & ! intent(in) + , huge_patch & ! intent(in) + , huge_cohort & ! intent(in) + , max_water & ! intent(in) + , str_len & ! intent(in) + , maxfiles & ! intent(in) + , maxlist & ! intent(in) + , undef_character & ! intent(in) + , undef_integer & ! intent(in) + , undef_real ! ! intent(in) + use pft_coms , only : q & ! intent(in) + , qsw & ! intent(in) + , qbark & ! intent(in) + , SLA & ! intent(in) + , min_dbh & ! intent(in) + , is_grass & ! intent(in) + , include_pft & ! intent(in) + , include_pft_ag & ! intent(in) + , pft_1st_check & ! intent(in) + , agf_bs & ! intent(in) + , f_bstorage_init & ! intent(in) + , include_these_pft & ! intent(in) + , leaf_turnover_rate & ! intent(in) + , vm0 & ! intent(in) + , rd0 & ! intent(in) + , negligible_nplant ! ! intent(in) + use ed_misc_coms , only : sfilin ! ! intent(in) + use consts_coms , only : pio180 & ! intent(in) + , pio4 & ! intent(in) + , almost_zero & ! intent(in) + , tiny_num ! ! intent(in) + use ed_misc_coms , only : use_target_year & ! intent(in) + , restart_target_year ! ! intent(in) + use ed_state_vars , only : polygontype & ! variable type + , sitetype & ! variable type + , patchtype & ! variable type + , edtype & ! variable type + , edgrid_g & ! variable type + , allocate_polygontype & ! subroutine + , allocate_sitetype & ! subroutine + , allocate_patchtype ! ! subroutine + use grid_coms , only : ngrids & ! intent(in) + , nzg ! ! intent(in) + use soil_coms , only : soil_hydro_scheme & ! intent(in) + , slz & ! intent(in) + , slxkey_ref & ! intent(inout) + , slxsand_ref & ! intent(inout) + , slxsilt_ref & ! intent(inout) + , slxclay_ref & ! intent(inout) + , slhydro_ref & ! intent(inout) + , slsoc_ref & ! intent(inout) + , slph_ref & ! intent(inout) + , slcec_ref & ! intent(inout) + , sldbd_ref & ! intent(inout) + , ed_gen_soil_table ! ! subroutine + use allometry , only : bd2dbh & ! function + , dbh2h & ! function + , size2bd & ! function + , size2bl & ! function + , size2bt & ! function + , size2xb & ! function + , ed_balive & ! function + , ed_biomass & ! function + , area_indices ! ! subroutine + use fuse_fiss_utils , only : sort_cohorts & ! subroutine + , sort_patches ! ! subroutine + use decomp_coms , only : decomp_scheme & ! intent(in) + , c2n_structural ! ! intent(in) + use phenology_coms , only : llspan_inf ! ! intent(in) + use physiology_coms , only : iddmort_scheme & ! intent(in) + , trait_plasticity_scheme ! ! intent(in) + use update_derived_utils, only : update_cohort_plastic_trait ! ! subroutine + use ed_init , only : soil_default_fill & ! sub-routine + , sfcdata_ed ! ! sub-routine + use ed_type_init , only : init_ed_cohort_vars & ! subroutine + , init_ed_patch_vars & ! subroutine + , init_ed_site_vars & ! subroutine + , init_ed_poly_vars ! ! subroutine + use ed_init , only : calc_flow_routing ! ! subroutine + implicit none + + !----- Local constants. ----------------------------------------------------------------! + real(kind=8), parameter :: min_area = 1.d-7 ! Minimum acceptable area. + real(kind=8), parameter :: min_ok = 1.d-20 ! Minimum acceptable value for + ! any restart variable. + !----- Local variables. ----------------------------------------------------------------! + type(edtype) , pointer :: cgrid + type(polygontype) , pointer :: cpoly + type(sitetype) , pointer :: csite + type(patchtype) , pointer :: cpatch + character(len=str_len), dimension(maxlist) :: full_list + character(len=str_len), dimension(maxfiles) :: sss_list + character(len=str_len), dimension(maxfiles) :: pss_list + character(len=str_len), dimension(maxfiles) :: css_list + character(len=str_len), dimension(huge_site) :: sname + character(len=str_len), dimension(huge_patch) :: psname + character(len=str_len), dimension(huge_patch) :: pname + character(len=str_len), dimension(huge_cohort) :: csname + character(len=str_len), dimension(huge_cohort) :: cpname + character(len=str_len), dimension(huge_cohort) :: cname + character(len=str_len) :: sss_name + character(len=str_len) :: pss_name + character(len=str_len) :: css_name + character(len=str_len) :: cdum + integer , dimension(huge_site) :: nscol + integer , dimension(huge_site) :: ntext + integer , dimension(huge_site) :: lsl + integer , dimension(huge_site) :: patch_count + integer , dimension(huge_site) :: last_ipa + integer , dimension(huge_patch) :: dtype + integer , dimension(huge_patch) :: psite_id + integer , dimension(huge_patch) :: ppatch_id + integer , dimension(huge_patch) :: cohort_count + integer , dimension(huge_patch) :: last_ico + integer , dimension(huge_cohort) :: ipft + integer , dimension(huge_cohort) :: cpatch_id + integer , dimension(huge_cohort) :: csite_id + integer :: year + integer :: igr + integer :: ipy + integer :: gsi + integer :: gpa + integer :: gco + integer :: isi + integer :: ipa + integer :: ico + integer :: apa + integer :: aco + integer :: ierr + integer :: nf + integer :: nflist + integer :: nflsss + integer :: nflpss + integer :: nflcss + integer :: nclosest + integer :: ncohorts + integer :: npatches + integer :: nsites + logical , dimension(n_pft) :: discarded_pft + logical , dimension(:) , allocatable :: shmask + logical :: single_poi + real(kind=8) :: darea + real , dimension(huge_site) :: s_area + real , dimension(huge_site) :: depth + real , dimension(huge_site) :: sand + real , dimension(huge_site) :: clay + real , dimension(huge_site) :: slsoc + real , dimension(huge_site) :: slph + real , dimension(huge_site) :: slcec + real , dimension(huge_site) :: sldbd + real , dimension(huge_site) :: elevation + real , dimension(huge_site) :: slope + real , dimension(huge_site) :: aspect + real , dimension(huge_site) :: tci + real , dimension(huge_site) :: moist_f + real , dimension(huge_site) :: moist_w + real , dimension(huge_patch) :: time + real , dimension(huge_patch) :: age + real , dimension(huge_patch) :: p_area + real , dimension(huge_patch) :: fgc + real , dimension(huge_patch) :: fsc + real , dimension(huge_patch) :: stgc + real , dimension(huge_patch) :: stgl + real , dimension(huge_patch) :: stsc + real , dimension(huge_patch) :: stsl + real , dimension(huge_patch) :: msc + real , dimension(huge_patch) :: ssc + real , dimension(huge_patch) :: psc + real , dimension(huge_patch) :: fsn + real , dimension(huge_patch) :: msn + real , dimension(huge_cohort) :: balive + real , dimension(huge_cohort) :: bdead + real , dimension(huge_cohort) :: nplant + real , dimension(huge_cohort) :: hite + real , dimension(huge_cohort) :: dbh + real , dimension(huge_cohort) :: ctime + real , dimension(maxfiles) :: slon_list + real , dimension(maxfiles) :: slat_list + real , dimension(maxfiles) :: plon_list + real , dimension(maxfiles) :: plat_list + real , dimension(maxfiles) :: clon_list + real , dimension(maxfiles) :: clat_list + real , dimension(maxfiles) :: file_sdist + real , dimension(maxfiles) :: file_pdist + real , dimension(maxfiles) :: file_cdist + real , dimension(n_pft) :: leaf_lifespan + real , dimension(:) , allocatable :: ed_slz + real :: dummy + real :: area_sum + !----- External function. --------------------------------------------------------------! + real , external :: sngloff + real , external :: dist_gc + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Define PFT-dependent leaf life span, used for initialisation. ! + !---------------------------------------------------------------------------------------! + leaf_lifespan(:) = merge( 12.0 / leaf_turnover_rate(:) & + , llspan_inf & + , leaf_turnover_rate(:) > 0.0 ) + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Allocate temporary variables used during initialisation. ! + !---------------------------------------------------------------------------------------! + allocate(shmask(nzg)) + allocate(ed_slz(nzg)) + shmask(:) = .false. + ed_slz(:) = slz(1:nzg) + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Now we loop over all all grids and polygons, and fill them with patches and ! + ! cohorts from the closest polygon. ! + !---------------------------------------------------------------------------------------! + main_gridloop: do igr = 1,ngrids + cgrid => edgrid_g(igr) + + !----- Retrieve all files with the specified prefix. --------------------------------! + call ed_filelist(full_list,sfilin(igr),nflist) + !------------------------------------------------------------------------------------! + + !----- Retrieve LON/LAT information for sites, patches and cohorts ------------------! + call ed1_fileinfo('.sss',nflist,full_list,nflsss,sss_list,slon_list,slat_list) + call ed1_fileinfo('.pss',nflist,full_list,nflpss,pss_list,plon_list,plat_list) + call ed1_fileinfo('.css',nflist,full_list,nflcss,css_list,clon_list,clat_list) + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Save logical flag to decide whether or not this is a single-grid, single- ! + ! -polygon simulation. This information allows us to change the default soil ! + ! properties so they are site-specific. ! + !------------------------------------------------------------------------------------! + single_poi = (ngrids == 1) .and. (cgrid%npolygons == 1) + !------------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------------! + ! Loop through every polygon. ! + !------------------------------------------------------------------------------------! + main_polyloop: do ipy = 1,cgrid%npolygons + cpoly => cgrid%polygon(ipy) + + !----- Initialise load adjacency with dummy value. -------------------------------! + cgrid%load_adjacency(ipy) = 0 + cgrid%wbar (ipy) = 0.0 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Reset patch and cohort count. ! + !---------------------------------------------------------------------------------! + patch_count (:) = 0 + cohort_count(:) = 0 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Initialise the distances as very large numbers, so if we don't fill all the ! + ! patches and cohorts, we will not going to take non-sense as a valid polygon. ! + !---------------------------------------------------------------------------------! + file_sdist(:) = 1.e20 + file_pdist(:) = 1.e20 + file_cdist(:) = 1.e20 + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Reset the other placeholder variables. ! + !---------------------------------------------------------------------------------! + !------ Site-level variables. ----------------------------------------------------! + sname (:) = undef_character + nscol (:) = undef_integer + ntext (:) = undef_integer + lsl (:) = undef_integer + patch_count (:) = undef_integer + dtype (:) = undef_integer + s_area (:) = undef_real + depth (:) = undef_real + sand (:) = undef_real + clay (:) = undef_real + slsoc (:) = undef_real + slph (:) = undef_real + slcec (:) = undef_real + sldbd (:) = undef_real + elevation (:) = undef_real + slope (:) = undef_real + aspect (:) = undef_real + tci (:) = undef_real + moist_f (:) = undef_real + moist_w (:) = undef_real + !------ Patch-level variables. ---------------------------------------------------! + psname (:) = undef_character + pname (:) = undef_character + psite_id (:) = undef_integer + ppatch_id (:) = undef_integer + cohort_count (:) = undef_integer + time (:) = undef_real + age (:) = undef_real + p_area (:) = undef_real + fgc (:) = undef_real + fsc (:) = undef_real + stgc (:) = undef_real + stgl (:) = undef_real + stsc (:) = undef_real + stsl (:) = undef_real + msc (:) = undef_real + ssc (:) = undef_real + psc (:) = undef_real + fsn (:) = undef_real + msn (:) = undef_real + !------ Cohort-level variables. --------------------------------------------------! + csname (:) = undef_character + cpname (:) = undef_character + cname (:) = undef_character + csite_id (:) = undef_integer + cpatch_id (:) = undef_integer + ipft (:) = undef_integer + balive (:) = undef_real + bdead (:) = undef_real + nplant (:) = undef_real + hite (:) = undef_real + dbh (:) = undef_real + ctime (:) = undef_real + !---------------------------------------------------------------------------------! + + + + + + !---------------------------------------------------------------------------------! + ! Compute the distances between every polygon in the initial files and the ! + ! current polygon. ! + !---------------------------------------------------------------------------------! + do nf=1,nflsss + file_sdist(nf) = dist_gc(cgrid%lon(ipy),slon_list(nf) & + ,cgrid%lat(ipy),slat_list(nf) ) + end do + do nf=1,nflpss + file_pdist(nf) = dist_gc(cgrid%lon(ipy),plon_list(nf) & + ,cgrid%lat(ipy),plat_list(nf) ) + end do + do nf=1,nflcss + file_cdist(nf) = dist_gc(cgrid%lon(ipy),clon_list(nf) & + ,cgrid%lat(ipy),clat_list(nf) ) + end do + !---------------------------------------------------------------------------------! + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read site file. ! + !---------------------------------------------------------------------------------! + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(file_sdist,dim=1) + sss_name = trim(sss_list(nclosest)) + write (unit=*,fmt='(2a)') '+ Using site file: ',trim(sss_name) + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Open the patch file and read skip the header. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(sss_name),form='formatted',status='old',action='read') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Now we loop over all patches and decide whether they should be included or ! + ! not. ! + !---------------------------------------------------------------------------------! + gsi = 1 + read_sites: do + + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of sites ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gsi > huge_site) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(sss_name) + write (unit=*,fmt='(a)') ' Number of sites is > HUGE_SITE...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_SITE:',huge_site + write (unit=*,fmt='(a)') ' Increase HUGE_SITE to read this...' + call fatal_error('Too many patches to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + !----- Read line. Exit loop when finished reading sites. ---------------------! + read(unit=12,fmt=*,iostat=ierr) sname(gsi),darea,depth(gsi),nscol(gsi) & + ,ntext(gsi),sand(gsi),clay(gsi),slsoc(gsi) & + ,slph(gsi),slcec(gsi),sldbd(gsi),elevation(gsi) & + ,slope(gsi),aspect(gsi),tci(gsi),moist_f(gsi) & + ,moist_w(gsi) + if (ierr /= 0) exit read_sites + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Add site only if the area is above minimum, we avoid including ! + ! sites that are tiny since they will be overwritten by the next site. ! + !------------------------------------------------------------------------------! + s_area(gsi) = sngloff(darea, min_area) + if (s_area(gsi) > min_area) gsi = gsi + 1 + !------------------------------------------------------------------------------! + end do read_sites + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of sites. We also make sure that there is at ! + ! least one valid site, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + nsites = gsi - 1 + if (nsites <= 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(sss_name) + write (unit=*,fmt='(a)') ' Invalid number of sites: ',nsites + write (unit=*,fmt='(a)') ' File is probably corrupted...' + else + !------ Make sure the sum of site areas is 1. ---------------------------------! + area_sum = sum(s_area(1:nsites)) + s_area(1:nsites) = s_area(1:nsites) / area_sum + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read patch file. ! + !---------------------------------------------------------------------------------! + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(file_pdist,dim=1) + pss_name = trim(pss_list(nclosest)) + write (unit=*,fmt='(2a)') 'Using patch file: ',trim(pss_name) + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Open the patch file and skip the header. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(pss_name),form='formatted',status='old',action='read') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop over all patches and decide whether they should be included or not. ! + !---------------------------------------------------------------------------------! + gpa = 1 + read_patches: do + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of patches ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gpa > huge_patch) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Number of patches is > HUGE_PATCH...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_PATCH:',huge_patch + write (unit=*,fmt='(a)') ' Increase HUGE_PATCH to read this...' + call fatal_error('Too many patches to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + + !----- Read line. Exit loop when finished reading patches. -------------------! + read(unit=12,fmt=*,iostat=ierr) time(gpa),psname(gpa),pname(gpa),dtype(gpa) & + ,age(gpa),darea,fgc(gpa),fsc(gpa),stgc(gpa) & + ,stgl(gpa),stsc(gpa),stsl(gpa),msc(gpa) & + ,ssc(gpa),psc(gpa),fsn(gpa),msn(gpa) & + ,dummy,dummy,dummy,dummy + if (ierr /= 0) exit read_patches + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Add site only if the area is above minimum, we avoid including ! + ! sites that are tiny since they will be overwritten by the next site. ! + !------------------------------------------------------------------------------! + p_area(gpa) = sngloff(darea, min_area) + if (p_area(gpa) > min_area) gpa = gpa + 1 + !------------------------------------------------------------------------------! + end do read_patches + !---------------------------------------------------------------------------------! + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of patches. We also make sure that there is ! + ! at least one valid patch, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + npatches = gpa - 1 + if (npatches <= 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Invalid number of patches: ',npatches + write (unit=*,fmt='(a)') ' File is probably corrupted...' + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + ! Read cohort file. ! + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Find the file that is the closest to the current polygon, based on the ! + ! distance vector. ! + !---------------------------------------------------------------------------------! + nclosest = minloc(abs(file_pdist(nclosest)-file_cdist),dim=1) + css_name = trim(css_list(nclosest)) + write (unit=*,fmt='(2a)') 'Using cohort file: ',trim(css_name) + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Open the cohort file and read in all cohorts. ! + !---------------------------------------------------------------------------------! + open(unit=12,file=trim(css_name),form='formatted',status='old') + read(unit=12,fmt='(a4)') cdum + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop over all cohorts and decide whether they should be included or not. ! + !---------------------------------------------------------------------------------! + discarded_pft(:) = .false. + gco = 1 + read_cohorts: do + + !------------------------------------------------------------------------------! + ! We must check whether we are not exceeding the maximum number of patches ! + ! that we can read. ! + !------------------------------------------------------------------------------! + if (gco > huge_cohort) then + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a)') ' Number of cohorts is > HUGE_COHORT...' + write (unit=*,fmt='(a,1x,i7)') ' HUGE_COHORT:',huge_cohort + write (unit=*,fmt='(a)') ' Increase HUGE_COHORT to read this...' + call fatal_error('Too many cohorts to be read...' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + + + + + + !----- Read line. Exit loop when finished reading cohorts. -------------------! + read(unit=12,fmt=*,iostat=ierr) ctime(gco),csname(gco),cpname(gco),cname(gco) & + ,dbh(gco),hite(gco),ipft(gco),nplant(gco) & + ,bdead(gco),balive(gco),dummy,dummy + if (ierr /= 0) exit read_cohorts + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Make sure this cohort qualifies to be included (if not qualified, we ! + ! cycle the read_cohorts loop without updating gco. ! + !------------------------------------------------------------------------------! + year = int(ctime(gco)) + if (use_target_year == 1 .and. year /= restart_target_year) then + !----- User wants css year to match the restart target year. ---------------! + cycle read_cohorts + !---------------------------------------------------------------------------! + else if (nplant(gco) < negligible_nplant(ipft(gco))) then + !----- Cohort population is negligible. ------------------------------------! + cycle read_cohorts + !---------------------------------------------------------------------------! + else if (.not. include_pft(ipft(gco))) then + !---------------------------------------------------------------------------! + ! This PFT is not in the list of PFTs to include. Decide what to do ! + ! based on the PFT_1ST_CHECK settings. ! + !---------------------------------------------------------------------------! + select case (pft_1st_check) + case (0) + !----- Stop the run. ----------------------------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Either edit NL%INCLUDE_THESE_PFT or' & + ,'set NL%PFT_1ST_CHECK to 1 or 2.' + call fatal_error('Invalid PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !------------------------------------------------------------------------! + case (1) + !----- Warn user about the unexpected PFT. ------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Changing include_these_pft to' & + ,'incorporate the PFT.' + call warning('Unexpected PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !------------------------------------------------------------------------! + + + !----- Add the unexpected PFT to the list of possible PFTs. -------------! + include_pft(ipft(gco)) = .true. + include_these_pft(count(include_pft)) = ipft(gco) + call sort_up(include_these_pft,n_pft) + if (is_grass(ipft(gco))) include_pft_ag(ipft(gco)) = .true. + !------------------------------------------------------------------------! + case (2) + if (.not. discarded_pft(ipft(gco))) then + !---------------------------------------------------------------------! + ! In case this is the first time finding this unexpected PFT, ! + ! warn user. ! + !---------------------------------------------------------------------! + write (unit=*,fmt='(a,1x,a)' ) ' In file:',trim(css_name) + write (unit=*,fmt='(a,1x,i5,1x,a)') & + 'There are cohorts of PFT =',ipft(gco) & + ,', which are not defined in NL%INCLUDE_THESE_PFT.' + write (unit=*,fmt='(a,1x,a)') ' Discarding PFT.' + call warning('Unexpected PFT in initial file' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + !---------------------------------------------------------------------! + + + !------ Switch flag so we don't overwhelm the output with warnings. --! + discarded_pft(ipft(gco)) = .true. + !---------------------------------------------------------------------! + end if + !------------------------------------------------------------------------! + + !----- Skip the cohort. -------------------------------------------------! + cycle read_cohorts + !------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------! + else + !----- Keep the cohort. ----------------------------------------------------! + gco = gco + 1 + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + end do read_cohorts + !---------------------------------------------------------------------------------! + + + !------ Close the file. ----------------------------------------------------------! + close(unit=12,status='keep') + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Here we determine the number of sites. We also make sure that there is at ! + ! least one valid site, otherwise we issue an error. ! + !---------------------------------------------------------------------------------! + ncohorts = gco - 1 + if (npatches < 0) then + write (unit=*,fmt='(a,1x,a)') ' In file:',trim(pss_name) + write (unit=*,fmt='(a)') ' Invalid number of patches: ',npatches + write (unit=*,fmt='(a)') ' File is probably corrupted...' + end if + !---------------------------------------------------------------------------------! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! + + + + + !---------------------------------------------------------------------------------! + ! Link patches and cohorts to sites. To reduce the computational burden of ! + ! long patch/cohort files, we skip the beginning of the loop when all the initial ! + ! patches and cohorts have already been assigned. This will only be effective ! + ! if the files are organised (most of the time they are, but the code doesn't ! + ! assume they are). ! + !---------------------------------------------------------------------------------! + apa = 1 + aco = 1 + do gsi=1,nsites + !----- Flag all patches associated with this site. ----------------------------! + do gpa=apa,npatches + !----- Link patch to site if the names match. ------------------------------! + if (trim(psname(gpa)) == trim(sname(gsi))) then + psite_id(gpa) = gsi + + + !------------------------------------------------------------------------! + ! Update apa in case all patch elements up to this point have been ! + ! assigned to a site. ! + !------------------------------------------------------------------------! + if (gpa == apa) then + apa = apa + 1 + end if + !------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------! + ! Link cohorts to patches. ! + !---------------------------------------------------------------------------! + do gco=aco,ncohorts + !----- Flag all cohorts associated with this patch and site. ------------! + if ( (trim(cpname(gco)) == trim(pname (gpa))) .and. & + (trim(csname(gco)) == trim(psname(gpa))) .and. & + (trim(csname(gco)) == trim(sname (gsi))) ) then + cpatch_id(gco) = gpa + csite_id (gco) = gsi + + !---------------------------------------------------------------------! + ! Update apa in case all cohort elements up to this point have ! + ! been assigned to a patch/site. ! + !---------------------------------------------------------------------! + if (gco == aco) then + aco = aco + 1 + end if + !---------------------------------------------------------------------! + + end if + !------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------! + + + !----- Count cohorts belonging to this patch. ------------------------------! + cohort_count(gpa) = count(cpatch_id(:) == gpa) + !---------------------------------------------------------------------------! + end do + !------------------------------------------------------------------------------! + + + !----- Count patches belonging to this site. ----------------------------------! + patch_count(gsi) = count(psite_id(:) == gsi) + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! In case this site does not have any patch, issue an error. Sites should ! + ! always have at least one patch. ! + !------------------------------------------------------------------------------! + if (patch_count(gsi) == 0) then + write (unit=*,fmt='(a)' ) '==========================================' + write (unit=*,fmt='(a)' ) ' Site without patches found!' + write (unit=*,fmt='(a)' ) '==========================================' + write (unit=*,fmt='(a,1x,a)' ) ' Site file: ',trim(sss_name) + write (unit=*,fmt='(a,1x,a)' ) ' Patch file:',trim(pss_name) + write (unit=*,fmt='(a,1x,i5)') ' Site ID: ',gsi + write (unit=*,fmt='(a,1x,a)' ) ' Site name: ',sname(gsi) + write (unit=*,fmt='(a)' ) '==========================================' + call fatal_error('A site without corresponding patches was found!' & + ,'read_ed22_initial_file','ed_read_ed22_initial.f90') + end if + !------------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------------! + + + + + + !---------------------------------------------------------------------------------! + ! Allocate sites. ! + !---------------------------------------------------------------------------------! + call allocate_polygontype(cpoly,nsites) + call soil_default_fill(cgrid,igr,ipy) + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop through sites and allocate patches and cohorts. ! + !---------------------------------------------------------------------------------! + gsi = 0 + init_sites: do isi=1,cpoly%nsites + !------ Update pointers and counters. -----------------------------------------! + csite => cpoly%site(isi) + gsi = gsi + 1 + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! In case this is a single-grid, single-polygon simulation, we rewrite ! + ! the site properties of the first soil classes with the site-level ! + ! information. ! + !------------------------------------------------------------------------------! + if (single_poi) then + !----- Replace texture with the site ID. -----------------------------------! + ntext(gsi) = isi + !---------------------------------------------------------------------------! + + + !----- Overwrite reference properties of the isi-th site. ------------------! + slxkey_ref (isi) = 'Site' + slhydro_ref(isi) = soil_hydro_scheme + slxsand_ref(isi) = sand (gsi) + slxclay_ref(isi) = clay (gsi) + slxsilt_ref(isi) = 1. - slxsand_ref(isi) - slxclay_ref(isi) + slsoc_ref (isi) = slsoc(gsi) + slph_ref (isi) = slph (gsi) + slcec_ref (isi) = slcec(gsi) + sldbd_ref (isi) = sldbd(gsi) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! Initialise site variables. If TOPMODEL becomes again functional, this ! + ! list may need to be expanded. ! + !------------------------------------------------------------------------------! + cpoly%area (isi) = s_area (gsi) + cpoly%ntext_soil(:,isi) = ntext (gsi) + cpoly%ncol_soil (isi) = nscol (gsi) + cpoly%elevation (isi) = elevation(gsi) + cpoly%slope (isi) = slope (gsi) + cpoly%aspect (isi) = aspect (gsi) + cpoly%tci (isi) = tci (gsi) + cpoly%moist_f (isi) = moist_f (gsi) + cpoly%moist_w (isi) = moist_w (gsi) + !------------------------------------------------------------------------------! + + + !------ Dummy variables. ------------------------------------------------------! + cpoly%sitenum (isi) = isi + !------------------------------------------------------------------------------! + + + !------ Find the lowest soil level to simulate. -------------------------------! + shmask(:) = ed_slz(:) <= - abs(depth(gsi)) + cpoly%lsl(isi) = min(max(1,maxloc(ed_slz(:),dim=1,mask=shmask)),nzg-1) + !------------------------------------------------------------------------------! + + + !------ Copy patch count. -----------------------------------------------------! + cpoly%patch_count(isi) = patch_count(gsi) + !------------------------------------------------------------------------------! + + + !------ Update the polygon average topographic moisture index. ----------------! + cgrid%wbar(ipy) = cgrid%wbar(ipy) + cpoly%moist_w(isi) * cpoly%area(isi) + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! Allocate patches for this site. ! + !------------------------------------------------------------------------------! + call allocate_sitetype(csite,patch_count(gsi)) + !------------------------------------------------------------------------------! + end do init_sites + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Loop through all patches, and initialise them at the appropriate site. ! + !---------------------------------------------------------------------------------! + last_ipa(:) = 0 + init_patches: do gpa=1,npatches + !------------------------------------------------------------------------------! + ! Try setting the site. If the site had a tiny area, this patch may be ! + ! orphaned, in which case we skip it. ! + !------------------------------------------------------------------------------! + if (psite_id(gpa) == undef_integer) then + !----- Invalid patch, skip it. ---------------------------------------------! + cycle init_patches + !---------------------------------------------------------------------------! + else + !----- Valid patch, assign site. -------------------------------------------! + isi = psite_id(gpa) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Set other counters and pointers. ---------------------------------------! + ipa = last_ipa(isi) + 1 + ppatch_id(gpa) = ipa + csite => cpoly%site (isi) + cpatch => csite%patch(ipa) + !------------------------------------------------------------------------------! + + + + !------ Set patch-level variables. --------------------------------------------! + csite%pname (ipa) = trim(pname (gpa)) + csite%dist_type (ipa) = dtype (gpa) + csite%age (ipa) = age (gpa) + csite%area (ipa) = p_area (gpa) + csite%fast_grnd_C (ipa) = fgc (gpa) + csite%fast_soil_C (ipa) = fsc (gpa) + csite%structural_grnd_C (ipa) = stgc (gpa) + csite%structural_grnd_L (ipa) = stgl (gpa) + csite%structural_soil_C (ipa) = stsc (gpa) + csite%structural_soil_L (ipa) = stsl (gpa) + csite%mineralized_soil_N(ipa) = msn (gpa) + csite%cohort_count (ipa) = cohort_count(gpa) + !------------------------------------------------------------------------------! + + + + !------ Set fast nitrogen pools so they are proportional to the carbon pools. -! + if ( (fgc(gpa)+fsc(gpa)) > tiny_num) then + csite%fast_grnd_N (ipa) = fgc(gpa) * fsn(gpa) / (fgc(gpa)+fsc(gpa)) + csite%fast_soil_N (ipa) = fsc(gpa) * fsn(gpa) / (fgc(gpa)+fsc(gpa)) + else + csite%fast_grnd_C (ipa) = 0.0 + csite%fast_soil_C (ipa) = 0.0 + csite%fast_grnd_N (ipa) = 0.0 + csite%fast_soil_N (ipa) = 0.0 + end if + !------------------------------------------------------------------------------! + + + + !------ Use stoichiometry to derive structural N pools. -----------------------! + csite%structural_grnd_N (ipa) = csite%structural_grnd_C (ipa) / c2n_structural + csite%structural_soil_N (ipa) = csite%structural_soil_C (ipa) / c2n_structural + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Check decomposition scheme before assigning microbial carbon. ! + !------------------------------------------------------------------------------! + select case (decomp_scheme) + case (5) + csite%microbial_soil_C(ipa) = msc(gpa) + csite%slow_soil_C (ipa) = ssc(gpa) + csite%passive_soil_C (ipa) = psc(gpa) + case default + csite%microbial_soil_C(ipa) = 0.0 + csite%slow_soil_C (ipa) = msc(gpa) + ssc(gpa) + psc(gpa) + csite%passive_soil_C (ipa) = 0.0 + end select + !------------------------------------------------------------------------------! + + + !----- Initialise other properties. -------------------------------------------! + csite%fbeam (ipa) = 1.0 + csite%light_type (ipa) = 1 + csite%sum_dgd (ipa) = 0.0 + csite%sum_chd (ipa) = 0.0 + csite%plant_ag_biomass (ipa) = 0.0 + !------------------------------------------------------------------------------! + + + !------ Allocate cohorts for this patch. --------------------------------------! + if ( cohort_count(gpa) /= 0) then + call allocate_patchtype(cpatch,cohort_count(gpa)) + end if + !------------------------------------------------------------------------------! + + + !------ Update last_ipa for this site. ----------------------------------------! + last_ipa(isi) = ipa + !------------------------------------------------------------------------------! + end do init_patches + !---------------------------------------------------------------------------------! + + + + + !---------------------------------------------------------------------------------! + ! Loop through all cohort, and initialise them at the appropriate patch and ! + ! site. ! + !---------------------------------------------------------------------------------! + last_ico(:) = 0 + init_cohorts: do gco=1,ncohorts + !------------------------------------------------------------------------------! + ! Try setting the site and patch. If the site or the patch had a tiny ! + ! area, this cohort may be orphaned, in which case we skip it. ! + !------------------------------------------------------------------------------! + if (csite_id(gco) == undef_integer .or. cpatch_id(gco) == undef_integer) then + !----- Invalid cohort, skip it. --------------------------------------------! + cycle init_cohorts + !---------------------------------------------------------------------------! + else + !----- Valid cohort, assign site and global patch. -------------------------! + isi = csite_id (gco) + gpa = cpatch_id(gco) + !---------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------! + + + !----- Set other counters and pointers. ---------------------------------------! + ipa = ppatch_id(gpa) + ico = last_ico (gpa) + 1 + csite => cpoly%site(isi) + cpatch => csite%patch(ipa) + !------------------------------------------------------------------------------! + + + + + !------ Copy data from files to cohort. ---------------------------------------! + cpatch%nplant(ico) = nplant(gco) + cpatch%pft (ico) = ipft (gco) + cpatch%dbh (ico) = max(dbh(gco),min_dbh(ipft(gco))) + !------------------------------------------------------------------------------! + + + + + !------ Update allometry to define height and heartwood. ----------------------! + cpatch%hite (ico) = dbh2h(cpatch%pft(ico),cpatch%dbh(ico)) + bdead (gco) = size2bd(cpatch%dbh(ico),cpatch%hite(ico),cpatch%pft(ico)) + cpatch%bdeada(ico) = agf_bs(cpatch%pft(ico)) * bdead(gco) + cpatch%bdeadb(ico) = (1.0 - agf_bs(cpatch%pft(ico))) * bdead(gco) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise SLA, Vm0, Rd0, and with the look-up table value. These ! + ! variables may be updated during phenology initialisation, or trait ! + ! plasticity, but they must have an initial assignment so we can even ! + ! calculate the initial area indices and inicial trait values needed for the ! + ! trait update. ! + !------------------------------------------------------------------------------! + cpatch%sla (ico) = SLA (ipft(gco)) + cpatch%vm_bar(ico) = Vm0 (ipft(gco)) + cpatch%rd_bar(ico) = Rd0 (ipft(gco)) + cpatch%llspan(ico) = leaf_turnover_rate(ipft(gco)) + !------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------! + ! Use allometry to define leaf and the other live biomass pools. ! + !------------------------------------------------------------------------------! + cpatch%bleaf (ico) = size2bl(cpatch%dbh(ico),cpatch%hite(ico) & + ,cpatch%sla(ico),ipft(gco)) + cpatch%broot (ico) = cpatch%bleaf(ico) * q(ipft(gco)) + cpatch%bsapwooda(ico) = agf_bs(ipft(gco)) & + * cpatch%bleaf(ico) * qsw(ipft(gco)) * cpatch%hite(ico) + cpatch%bsapwoodb(ico) = (1.-agf_bs(ipft(gco))) & + * cpatch%bleaf(ico) * qsw(ipft(gco)) * cpatch%hite(ico) + cpatch%bbarka(ico) = agf_bs(ipft(gco)) & + * cpatch%bleaf(ico) * qbark(ipft(gco)) * cpatch%hite(ico) + cpatch%bbarkb(ico) = (1.-agf_bs(ipft(gco))) & + * cpatch%bleaf(ico) * qbark(ipft(gco)) * cpatch%hite(ico) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Start plants with full phenology, we will take care of phenology after ! + ! this sub-routine. ! + !------------------------------------------------------------------------------! + cpatch%phenology_status(ico) = 0 + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! In case we are representing trait plasticity, update traits (SLA, Vm0). ! + ! This must be done before calculating LAI and before ed_balive. ! + !------------------------------------------------------------------------------! + select case (trait_plasticity_scheme) + case (0) + continue + case default + call update_cohort_plastic_trait(cpatch,ico,.true. & + ,leaf_lifespan(ipft(gco)) & + ,vm0 (ipft(gco)) & + ,rd0 (ipft(gco)) & + ,sla (ipft(gco)) ) + end select + !------------------------------------------------------------------------------! + + + + + !----- Assign biomass of living tissues. --------------------------------------! + cpatch%balive(ico) = ed_balive(cpatch, ico) + !------------------------------------------------------------------------------! + + + !----- Initialise storage biomass (after setting balive). ---------------------! + cpatch%bstorage(ico) = max( almost_zero, f_bstorage_init(ipft(gco))) & + * cpatch%balive(ico) + !------------------------------------------------------------------------------! + + + + !----- Assign LAI, WAI, and CAI -----------------------------------------------! + call area_indices(cpatch, ico) + !------------------------------------------------------------------------------! + + + + !------------------------------------------------------------------------------! + ! Initialise the carbon balance. For initial conditions, we always assume ! + ! storage biomass for the previous months so the scale is correct (carbon ! + ! balance is given in kgC/pl). The current month carbon balance must be ! + ! initialised consistently with the iddmort_scheme we are using. ! + !------------------------------------------------------------------------------! + cpatch%cb (1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_lightmax(1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_moistmax(1:12,ico) = cpatch%bstorage(ico) + cpatch%cb_mlmax (1:12,ico) = cpatch%bstorage(ico) + select case (iddmort_scheme) + case (0) + !------ Storage is not accounted. ------------------------------------------! + cpatch%cb (13,ico) = 0.0 + cpatch%cb_lightmax(13,ico) = 0.0 + cpatch%cb_moistmax(13,ico) = 0.0 + cpatch%cb_mlmax (13,ico) = 0.0 + !---------------------------------------------------------------------------! + case (1) + !------ Storage is accounted. ----------------------------------------------! + cpatch%cb (13,ico) = cpatch%bstorage(ico) + cpatch%cb_lightmax(13,ico) = cpatch%bstorage(ico) + cpatch%cb_moistmax(13,ico) = cpatch%bstorage(ico) + cpatch%cb_mlmax (13,ico) = cpatch%bstorage(ico) + !---------------------------------------------------------------------------! + end select + cpatch%cbr_bar (ico) = 1.0 + !------------------------------------------------------------------------------! + + + + !----- Above ground biomass, use the allometry. -------------------------------! + cpatch%agb (ico) = ed_biomass(cpatch, ico) + cpatch%basarea(ico) = pio4 * cpatch%dbh(ico) * cpatch%dbh(ico) + cpatch%btimber(ico) = size2bt( cpatch%dbh (ico) & + , cpatch%hite (ico) & + , cpatch%bdeada (ico) & + , cpatch%bsapwooda (ico) & + , cpatch%bbarka (ico) & + , cpatch%pft (ico) ) + cpatch%thbark (ico) = size2xb( cpatch%dbh (ico) & + , cpatch%hite (ico) & + , cpatch%bbarka (ico) & + , cpatch%bbarkb (ico) & + , cpatch%sla (ico) & + , cpatch%pft (ico) ) + !------------------------------------------------------------------------------! + + + + !----- Growth rates, start with zero. -----------------------------------------! + cpatch%dagb_dt (ico) = 0. + cpatch%dlnagb_dt(ico) = 0. + cpatch%dba_dt (ico) = 0. + cpatch%dlnba_dt (ico) = 0. + cpatch%ddbh_dt (ico) = 0. + cpatch%dlndbh_dt(ico) = 0. + !------------------------------------------------------------------------------! + + !------------------------------------------------------------------------------! + ! Initialise other cohort variables. Some of them won't be updated ! + ! unless the lai exceeds lai_min. ! + !------------------------------------------------------------------------------! + cpatch%fsw(ico) = 1.0 + cpatch%gpp(ico) = 0.0 + cpatch%par_l(ico) = 0.0 + !------------------------------------------------------------------------------! + + + !----- Update the patch level above-ground biomass. ---------------------------! + csite%plant_ag_biomass(ipa) = csite%plant_ag_biomass(ipa) & + + cpatch%agb(ico) * cpatch%nplant(ico) + !------------------------------------------------------------------------------! + + + + !------ Update last_ico for this patch. ---------------------------------------! + last_ico(gpa) = ico + !------------------------------------------------------------------------------! + end do init_cohorts + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Find site adjacency (unlikely to be needed here). + !---------------------------------------------------------------------------------! + if (cgrid%load_adjacency(ipy) /= 0) then + call calc_flow_routing(cgrid,ipy) + end if + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Initialise additional site-, patch-, and cohort-level variables. ! + !---------------------------------------------------------------------------------! + init2_sites: do isi = 1,cpoly%nsites + + !----- Make sure that the total patch area is 1. ------------------------------! + csite => cpoly%site(isi) + area_sum = sum(csite%area(1:csite%npatches)) + csite%area(1:csite%npatches) = csite%area(1:csite%npatches) / area_sum + !------------------------------------------------------------------------------! + + + + + !----- Initialise the cohort variables, then sort them by size. ---------------! + init2_patches: do ipa = 1,csite%npatches + cpatch => csite%patch(ipa) + + !----- Initialise additional cohort variables. -----------------------------! + init2_cohorts: do ico = 1,cpatch%ncohorts + call init_ed_cohort_vars(cpatch,ico,cpoly%lsl(isi),nzg & + ,cpoly%ntext_soil(:,isi)) + end do init2_cohorts + !---------------------------------------------------------------------------! + + !----- Make sure that cohorts are organised from tallest to shortest. ------! + call sort_cohorts(cpatch) + !---------------------------------------------------------------------------! + end do init2_patches + !------------------------------------------------------------------------------! + + + + !----- Initialise the remaining patch-level variables. ------------------------! + call init_ed_patch_vars(csite,1,csite%npatches,cpoly%lsl(isi)) + !------------------------------------------------------------------------------! + + !----- Make sure that patches are organised from oldest to youngest. ----------! + call sort_patches(csite) + !------------------------------------------------------------------------------! + end do init2_sites + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! In case this is a single site simulation, we must update the soil ! + ! properties before initialising the site-level variables, because soil ! + ! characteristics are read from the site file. ! + !---------------------------------------------------------------------------------! + if (single_poi) then + call sfcdata_ed() + end if + !---------------------------------------------------------------------------------! + + + + !----- Initialise the remaining site-level variables. ----------------------------! + call init_ed_site_vars(cpoly) + !---------------------------------------------------------------------------------! + end do main_polyloop + !------------------------------------------------------------------------------------! + + + + !----- Initialise the polygon-level variables. --------------------------------------! + call init_ed_poly_vars(cgrid) + !------------------------------------------------------------------------------------! + end do main_gridloop + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Update the soil parameter table as soil properties have been overwritten for ! + ! a few sites. ! + !---------------------------------------------------------------------------------------! + call ed_gen_soil_table() + !---------------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------------! + ! Free memory. ! + !---------------------------------------------------------------------------------------! + deallocate(shmask) + deallocate(ed_slz) + !---------------------------------------------------------------------------------------! + + + return +end subroutine read_ed22_initial_file +!==========================================================================================! +!==========================================================================================! +!==========================================================================================! +!==========================================================================================! diff --git a/ED/src/io/ed_xml_config.f90 b/ED/src/io/ed_xml_config.f90 index 22e741ecd..6ac5a3cbd 100644 --- a/ED/src/io/ed_xml_config.f90 +++ b/ED/src/io/ed_xml_config.f90 @@ -1472,6 +1472,12 @@ recursive subroutine read_ed_xml_config(filename) if(texist) retained_carbon_fraction = sngloff(rval,tiny_offset) call getConfigREAL ('root_phen_factor','phenology',i,rval,texist) if(texist) root_phen_factor = sngloff(rval,tiny_offset) + call getConfigREAL ('f_psi_xdry','phenology',i,rval,texist) + if(texist) f_psi_xdry = sngloff(rval,tiny_offset) + call getConfigREAL ('elongf_min','phenology',i,rval,texist) + if(texist) elongf_min = sngloff(rval,tiny_offset) + call getConfigREAL ('elongf_flush','phenology',i,rval,texist) + if(texist) elongf_flush = sngloff(rval,tiny_offset) call getConfigREAL ('theta_crit','phenology',i,rval,texist) if(texist) thetacrit= sngloff(rval,tiny_offset) call getConfigREAL ('dl_tr','phenology',i,rval,texist) @@ -2431,6 +2437,9 @@ subroutine write_ed_xml_config call libxml2f90_ll_opentag("phenology") call putConfigREAL("retained_carbon_fraction",retained_carbon_fraction) call putConfigREAL("root_phen_factor" ,root_phen_factor ) + call putConfigREAL("f_psi_xdry" ,f_psi_xdry ) + call putConfigREAL("elongf_min" ,elongf_min ) + call putConfigREAL("elongf_flush" ,elongf_flush ) call putConfigREAL("theta_crit" ,thetacrit ) call putConfigREAL("dl_tr" ,dl_tr ) call putConfigREAL("st_tr1" ,st_tr1 ) diff --git a/ED/src/io/h5_output.F90 b/ED/src/io/h5_output.F90 index 209b184aa..e72fdcccf 100644 --- a/ED/src/io/h5_output.F90 +++ b/ED/src/io/h5_output.F90 @@ -30,6 +30,7 @@ subroutine h5_output(vtype) , stride & ! intent(in) , globdims ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : mynum & ! intent(in) , nnodetot & ! intent(in) , recvnum & ! intent(in) @@ -50,10 +51,6 @@ subroutine h5_output(vtype) , gdpy ! ! intent(in) implicit none - !------ Include standard common blocks. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !------ Arguments. ---------------------------------------------------------------------! character(len=*) , intent(in) :: vtype !------ Local variables. ---------------------------------------------------------------! @@ -879,8 +876,9 @@ subroutine geth5dims(idim_type,varlen,globid,var_len_global,dsetrank,varn,nrec,i !---------------------------------------------------------------------------------------! select case (idim_type) - case(90,91,92,96) ! No polygon-site-patch or cohort dimension, or single-dim. vector - + case(90,91,92,96,98,980) + ! No polygon-site-patch or cohort dimension, or single-dim. vector + dsetrank = 1 chnkdims(1) = int(varlen,8) chnkoffs(1) = int(globid,8) diff --git a/ED/src/memory/ed_max_dims.F90 b/ED/src/memory/ed_max_dims.F90 index 2996c71ca..9e581ab26 100644 --- a/ED/src/memory/ed_max_dims.F90 +++ b/ED/src/memory/ed_max_dims.F90 @@ -245,25 +245,32 @@ module ed_max_dims ! For restart runs, this is the maximum number of certain variables that can be ! ! read. ! ! HUGE_POLYGON - maximum number of input polygons. ! + ! HUGE_SITE - maximum number of input sites. ! ! HUGE_PATCH - maximum number of input patches. ! ! HUGE_COHORT - maximum number of input cohorts. ! ! MAX_WATER - maximum number of soil water levels (not assigned to polygons). ! !---------------------------------------------------------------------------------------! integer, parameter :: huge_polygon = nxpmax * nypmax + integer, parameter :: huge_site = ed_nstyp #if defined(MAC_OS_X) integer, parameter :: huge_patch = 200 - integer, parameter :: huge_cohort = 8000 + integer, parameter :: huge_cohort = 20000 + integer, parameter :: max_water = 5 #else - integer, parameter :: huge_patch = 10000 - integer, parameter :: huge_cohort = 250000 -#endif + integer, parameter :: huge_patch = 20000 + integer, parameter :: huge_cohort = 800000 integer, parameter :: max_water = 100 +#endif !---------------------------------------------------------------------------------------! !----- Maximum number of land use polygons that can be read by filelist. ---------------! +#if defined(MAC_OS_X) + integer, parameter :: huge_lu = 999 +#else integer, parameter :: huge_lu = 99999 +#endif !---------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ed_misc_coms.f90 b/ED/src/memory/ed_misc_coms.f90 index 79968322d..f6e496671 100644 --- a/ED/src/memory/ed_misc_coms.f90 +++ b/ED/src/memory/ed_misc_coms.f90 @@ -8,6 +8,11 @@ module ed_misc_coms implicit none + + !----- String for the output format of the restore file. -------------------------------! + character(len=26), parameter :: fmtrest = '(i4.4,2(1x,i2.2),1x,2i2.2)' + !---------------------------------------------------------------------------------------! + type simtime integer :: year integer :: month @@ -260,17 +265,40 @@ module ed_misc_coms !----- Namelist option for allometry scheme. -------------------------------------------! - integer :: iallom ! 0 -- Original ED-2.1 allometry - ! 1 -- DBH -> AGB Tree allometry based on Baker et al. (2004) - ! keep original ED-2.1 Bl/Bd ratio - ! 2 -- DBH -> AGB Tree allometry based on Baker et al. (2004) - ! keep original ED-2.1 Bl - ! 3 -- Updated allometric and trait-based parameters for tropical - ! PFTs. When available, parameters came from regional data - ! sets and regional studies, or from local studies when regional - ! ones were not found. Check ed_params.f90 for details and - ! references. - !---------------------------------------------------------------------------------------! + integer :: iallom ! 0 -- (Legacy) Original ED-1.0, included for back compatibility. + ! 1 -- (Legacy) ED-2.1 allometry, included for back compatibility. + ! a. The coefficients for structural biomass are set so the + ! total AGB is similar to Baker et al. (2004, Glob. Change + ! Biol.), equation 2. + ! b. Experimental root depth that makes canopy trees to have + ! root depths of 5m and grasses/seedlings at 0.5 to have root + ! depth of 0.5 m. + ! c. Crown area defined as in Poorter et al. (2006, Ecology), + ! imposing maximum crown area. + ! 2 -- (ED-2.2 default) Similar to 1, but with a few extra changes. + ! a. Height -> DBH allometry as in Poorter et al. (2006) + ! b. Balive is retuned, using a few leaf biomass allometric + ! equations for a few genera in Costa Rica. References: + ! Cole and Ewel (2006, Forest Ecol. Manag.), and + ! Calvo-Alvarado et al. (2008, Tree Physiol.). + ! 3 -- (Beta) Revised tropical PFT allometric (Longo et al. 2020, + ! J. Geophys. Res.-Biogeosci.). + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the + ! Sustainable Landscapes Dataset (Longo et al. 2016, Glob. + ! Biogeochem. Cycles). DBH-Height takes a simpler log-linear + ! form fitted using SMA so it can be inverted (useful for + ! airborne lidar initialisation). + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change + ! Biol.) + ! c. DBH^2*H -> Leaf area based on the BAAD data base: + ! Falster et al. (2015, Ecology). + ! 4 -- (Under Development) Similar to 3 but (a) leaf and height + ! allometric equations depend on wood density; (b) use + ! height-based root allometry from Smith-Martin et al. (2020, + ! New Phyt.). + ! 5 -- (Under Development) Similar to IALLOM = 3 but using the + ! rooting allometry from IALLOM = 4. + !---------------------------------------------------------------------------------------! diff --git a/ED/src/memory/ed_state_vars.F90 b/ED/src/memory/ed_state_vars.F90 index d27c9f9b2..1f45ada15 100644 --- a/ED/src/memory/ed_state_vars.F90 +++ b/ED/src/memory/ed_state_vars.F90 @@ -633,6 +633,8 @@ module ed_state_vars real, pointer, dimension(:) :: wflux_wl != 0.0) then + soil(s)%soilld = soil(s)%soilwp & + + thetacrit * (soil(s)%slmsts-soil(s)%soilwp) + soil(s)%slpotld = matric_potential(s,soil(s)%soilld) + else + soil(s)%slpotld = thetacrit * 1.e6 / (grav * wdns) + soil(s)%soilld = soil_moisture(s,soil(s)%slpotld) + end if + !----- Fire. ------------------------------------------------------------------! + if (sm_fire >= 0.0) then + soil(s)%soilfr = soil(s)%soilcp + sm_fire * (soil(s)%slmsts-soil(s)%soilcp) + soil(s)%slpotfr = matric_potential(s,soil(s)%soilfr) + else + soil(s)%slpotfr = sm_fire * 1.e6 / (grav * wdns) + soil(s)%soilfr = soil_moisture(s,soil(s)%slpotfr) + end if + !------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------! + ! Define hydraulic parameter decay, similar to TOPMODEL. We currently use ! + ! the default value of 2.0, following N05's SIMTOP model. ! + ! ! + ! Niu GY, Yang ZL, Dickinson RE , Gulden LE. 2005. A simple TOPMODEL-based ! + ! runoff parameterization (SIMTOP) for use in global climate models. ! + ! J. Geophys. Res.-Atmos., 110: D21106. doi:10.1029/2005JD006111 (N05). ! + !------------------------------------------------------------------------------! + soil(s)%fhydraul = 2.0 + !------------------------------------------------------------------------------! + end select + !---------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------! + ! Heat capacity (J/m3/K). Here we take the volume average amongst silt, ! + ! clay, and sand, and consider the contribution of air sitting in. In order to ! + ! keep it simple, we assume that the air fraction won't change, although in ! + ! reality its contribution should be a function of soil moisture. Here we use ! + ! the amount of air in case the soil moisture was halfway between dry air and ! + ! saturated, so the error is not too biased. ! + !---------------------------------------------------------------------------------! + soil(s)%slcpd = (1. - soil(s)%slmsts) & + * ( soil(s)%xsand * sand_hcapv + soil(s)%xsilt * silt_hcapv & + + soil(s)%xclay * clay_hcapv ) & + + 0.5 * ( soil(s)%slmsts - soil(s)%soilcp ) * air_hcapv + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Thermal conductivity is the weighted average of thermal conductivities of ! + ! all materials, although a further weighting factor due to thermal gradient of ! + ! different materials. We use the de Vries model described at: ! + ! ! + ! Camillo, P., T.J. Schmugge, 1981: A computer program for the simulation of heat ! + ! and moisture flow in soils, NASA-TM-82121, Greenbelt, MD, United States. ! + ! ! + ! Parlange, M.B., et al., 1998: Review of heat and water movement in field soils, ! + ! Soil Till. Res., 47(1-2), 5-10. ! + ! ! + !---------------------------------------------------------------------------------! + !---- The k-factors, assuming spherical particles. -------------------------------! + ksand = 3. * h2o_thcond / ( 2. * h2o_thcond + sand_thcond ) + ksilt = 3. * h2o_thcond / ( 2. * h2o_thcond + silt_thcond ) + kclay = 3. * h2o_thcond / ( 2. * h2o_thcond + clay_thcond ) + kair = 3. * h2o_thcond / ( 2. * h2o_thcond + air_thcond ) + !---- The conductivity coefficients. ---------------------------------------------! + soil(s)%thcond0 = (1. - soil(s)%slmsts ) & + * ( ksand * soil(s)%xsand * sand_thcond & + + ksilt * soil(s)%xsilt * silt_thcond & + + kclay * soil(s)%xclay * clay_thcond ) & + + soil(s)%slmsts * kair * air_thcond + soil(s)%thcond1 = h2o_thcond - kair * air_thcond + soil(s)%thcond2 = (1. - soil(s)%slmsts ) & + * ( ksand * soil(s)%xsand + ksilt * soil(s)%xsilt & + + kclay * soil(s)%xclay ) & + + soil(s)%slmsts * kair + soil(s)%thcond3 = 1. - kair + !---------------------------------------------------------------------------------! + + end do + !------------------------------------------------------------------------------------! + + + + !----- Here we fill soil8, which will be used in Runge-Kutta (double precision). ----! + do s=1,ed_nstyp + soil8(s)%key = soil(s)%key + soil8(s)%method = soil(s)%method + soil8(s)%xsand = dble(soil(s)%xsand ) + soil8(s)%xsilt = dble(soil(s)%xsilt ) + soil8(s)%xclay = dble(soil(s)%xclay ) + soil8(s)%slsoc = dble(soil(s)%slsoc ) + soil8(s)%slph = dble(soil(s)%slph ) + soil8(s)%slcec = dble(soil(s)%slcec ) + soil8(s)%sldbd = dble(soil(s)%sldbd ) + soil8(s)%soilre = dble(soil(s)%soilre ) + soil8(s)%soilcp = dble(soil(s)%soilcp ) + soil8(s)%soilwp = dble(soil(s)%soilwp ) + soil8(s)%soilfr = dble(soil(s)%soilfr ) + soil8(s)%soilld = dble(soil(s)%soilld ) + soil8(s)%sfldcap = dble(soil(s)%sfldcap ) + soil8(s)%soilbp = dble(soil(s)%soilbp ) + soil8(s)%slmsts = dble(soil(s)%slmsts ) + soil8(s)%soilpo = dble(soil(s)%soilpo ) + soil8(s)%slpotcp = dble(soil(s)%slpotcp ) + soil8(s)%slpotwp = dble(soil(s)%slpotwp ) + soil8(s)%slpotfr = dble(soil(s)%slpotfr ) + soil8(s)%slpotld = dble(soil(s)%slpotld ) + soil8(s)%slpotfc = dble(soil(s)%slpotfc ) + soil8(s)%slpotbp = dble(soil(s)%slpotbp ) + soil8(s)%slpots = dble(soil(s)%slpots ) + soil8(s)%slpotpo = dble(soil(s)%slpotpo ) + soil8(s)%sltt = dble(soil(s)%sltt ) + soil8(s)%slnm = dble(soil(s)%slnm ) + soil8(s)%slbs = dble(soil(s)%slbs ) + soil8(s)%slmm = dble(soil(s)%slmm ) + soil8(s)%slmu = dble(soil(s)%slmu ) + soil8(s)%malpha = dble(soil(s)%malpha ) + soil8(s)%slcons = dble(soil(s)%slcons ) + soil8(s)%fhydraul = dble(soil(s)%fhydraul) + soil8(s)%slcpd = dble(soil(s)%slcpd ) + soil8(s)%thcond0 = dble(soil(s)%thcond0 ) + soil8(s)%thcond1 = dble(soil(s)%thcond1 ) + soil8(s)%thcond2 = dble(soil(s)%thcond2 ) + soil8(s)%thcond3 = dble(soil(s)%thcond3 ) + end do + !------------------------------------------------------------------------------------! + + + + + !------------------------------------------------------------------------------------! + ! Decide whether to write the table with the soil properties. ! + !------------------------------------------------------------------------------------! + print_soil_table = btest(idetailed,5) + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Print the parameters in case the user wants it. ! + !------------------------------------------------------------------------------------! + if (print_soil_table) then + !----- Open and write header. ----------------------------------------------------! + open (unit=26,file=trim(soil_table_fn),status='replace',action='write') + write(unit=26,fmt='(38(a,1x))') 'ISOIL', ' KEY', 'TYPE' & + ,' XSAND',' XSILT',' XCLAY' & + ,' SLSOC',' SLPH',' SLCEC' & + ,' SLDBD',' SOILRE',' SOILCP' & + ,' SOILWP',' SOILFR',' SOILLD' & + ,' SOILFC',' SOILBP',' SOILPO' & + ,' SLPOTCP',' SLPOTWP',' SLPOTFR' & + ,' SLPOTLD',' SLPOTFC',' SLPOTBP' & + ,' SLPOTPO',' SLTT',' SLNM' & + ,' SLBS',' SLMM',' SLMU' & + ,' MALPHA',' SLCONS_MMHR',' FHYDRAUL' & + ,' SLCPD_MJm3K',' THCOND0',' THCOND1' & + ,' THCOND2',' THCOND3' + !---------------------------------------------------------------------------------! + + + !---------------------------------------------------------------------------------! + ! Loop over soil texture types. ! + !---------------------------------------------------------------------------------! + do s=1,ed_nstyp + !----- For some variables, we use different units to make them more legible. --! + slcons_mmhr = soil(s)%slcons*1000.*hr_sec + slcpd_mjm3k = soil(s)%slcpd*0.001 + !------------------------------------------------------------------------------! + + !----- Add soil characteristics. ----------------------------------------------! + write(unit=26,fmt='(i5,1x,2(a4,1x),35(f12.5,1x))') & + s,adjustr(soil(s)%key),adjustr(soil(s)%method) & + ,soil(s)%xsand ,soil(s)%xsilt ,soil(s)%xclay & + ,soil(s)%slsoc ,soil(s)%slph ,soil(s)%slcec & + ,soil(s)%sldbd ,soil(s)%soilre ,soil(s)%soilcp & + ,soil(s)%soilwp ,soil(s)%soilfr ,soil(s)%soilld & + ,soil(s)%sfldcap ,soil(s)%soilbp ,soil(s)%slmsts & + ,soil(s)%slpotcp ,soil(s)%slpotwp ,soil(s)%slpotfr & + ,soil(s)%slpotld ,soil(s)%slpotfc ,soil(s)%slpotbp & + ,soil(s)%slpots ,soil(s)%sltt ,soil(s)%slnm & + ,soil(s)%slbs ,soil(s)%slmm ,soil(s)%slmu & + ,soil(s)%malpha ,slcons_mmhr ,soil(s)%fhydraul & + ,slcpd_mjm3k ,soil(s)%thcond0 ,soil(s)%thcond1 & + ,soil(s)%thcond2 ,soil(s)%thcond3 + !------------------------------------------------------------------------------! + end do + !---------------------------------------------------------------------------------! + + + !----- Close table. --------------------------------------------------------------! + close(unit=26,status='keep') + !---------------------------------------------------------------------------------! + end if + !------------------------------------------------------------------------------------! + + + return + end subroutine ed_gen_soil_table + !=======================================================================================! + !=======================================================================================! + + + + + + !=======================================================================================! !=======================================================================================! ! This function determines the soil class based on the fraction of sand, clay, and ! diff --git a/ED/src/mpi/ed_mpass_init.F90 b/ED/src/mpi/ed_mpass_init.F90 index 2aebbf93b..6f29675af 100644 --- a/ED/src/mpi/ed_mpass_init.F90 +++ b/ED/src/mpi/ed_mpass_init.F90 @@ -16,6 +16,7 @@ subroutine ed_masterput_processid(nproc,headnode_num,masterworks,par_run) , recvnum & ! intent(out) , master_num & ! intent(out) , machs ! ! intent(out) + use mpi #else use ed_para_coms, only : nmachs & ! intent(in) , machsize & ! intent(in) @@ -38,7 +39,6 @@ subroutine ed_masterput_processid(nproc,headnode_num,masterworks,par_run) integer :: nm #if defined(RAMS_MPI) integer :: ierr - include 'mpif.h' !---------------------------------------------------------------------------------------! #endif @@ -101,6 +101,7 @@ end subroutine ed_masterput_processid !------------------------------------------------------------------------------------------! subroutine ed_masterput_nl(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) use ed_max_dims , only : str_len & ! intent(in) , max_poi & ! intent(in) @@ -368,8 +369,6 @@ subroutine ed_masterput_nl(par_run) !----- Local variables. ----------------------------------------------------------------! integer :: ierr integer :: n - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -706,6 +705,7 @@ end subroutine ed_masterput_nl !------------------------------------------------------------------------------------------! subroutine ed_masterput_met_header(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) use ed_max_dims , only : max_met_vars & ! intent(in) , str_len ! ! intent(in) @@ -736,8 +736,6 @@ subroutine ed_masterput_met_header(par_run) integer :: nsize integer :: f integer :: v - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' !---------------------------------------------------------------------------------------! #endif @@ -802,6 +800,7 @@ end subroutine ed_masterput_met_header !==========================================================================================! subroutine ed_masterput_poly_dims(par_run,masterworks) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : mainnum ! ! intent(in) #endif use ed_para_coms , only : nmachs & ! intent(in) @@ -838,7 +837,6 @@ subroutine ed_masterput_poly_dims(par_run,masterworks) real :: totalwork #if defined(RAMS_MPI) integer :: ierr - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -1107,6 +1105,7 @@ end subroutine ed_masterput_poly_dims !------------------------------------------------------------------------------------------! subroutine ed_masterput_worklist_info(par_run) #if defined(RAMS_MPI) + use mpi use ed_para_coms , only : machnum ! ! intent(in) #endif use ed_max_dims , only : maxmach @@ -1139,8 +1138,6 @@ subroutine ed_masterput_worklist_info(par_run) integer :: mpiid integer , dimension(:), allocatable :: iscratch real , dimension(:), allocatable :: rscratch - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' #endif !---------------------------------------------------------------------------------------! @@ -1300,6 +1297,7 @@ end subroutine ed_masterput_worklist_info !------------------------------------------------------------------------------------------! subroutine ed_nodeget_processid(init) #if defined(RAMS_MPI) + use mpi use ed_node_coms, only : master_num & ! intent(out) , mchnum & ! intent(out) , mynum & ! intent(out) @@ -1316,7 +1314,6 @@ subroutine ed_nodeget_processid(init) integer, intent(in) :: init !----- Local variables. ----------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' integer, dimension(MPI_STATUS_SIZE) :: status #endif integer :: ierr @@ -1361,6 +1358,7 @@ end subroutine ed_nodeget_processid !------------------------------------------------------------------------------------------! subroutine ed_nodeget_nl #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : master_num ! ! intent(in) use ed_max_dims , only : str_len & ! intent(in) , max_poi & ! intent(in) @@ -1622,7 +1620,6 @@ subroutine ed_nodeget_nl #endif implicit none #if defined(RAMS_MPI) - include 'mpif.h' !----- Local variables. ----------------------------------------------------------------! integer :: n #endif @@ -1975,6 +1972,7 @@ end subroutine ed_nodeget_nl !------------------------------------------------------------------------------------------! subroutine ed_nodeget_met_header() #if defined(RAMS_MPI) + use mpi use ed_node_coms , only : master_num ! ! intent(in) use ed_max_dims , only : max_met_vars & ! intent(in) , str_len ! ! intent(in) @@ -1998,7 +1996,6 @@ subroutine ed_nodeget_met_header() implicit none #if defined(RAMS_MPI) - include 'mpif.h' !---- Local variables. -----------------------------------------------------------------! integer :: ierr integer :: nsize @@ -2077,6 +2074,7 @@ end subroutine ed_nodeget_met_header !==========================================================================================! subroutine ed_nodeget_poly_dims #if defined(RAMS_MPI) + use mpi use ed_state_vars, only : gdpy & ! intent(out) , py_off ! ! intent(out) use ed_node_coms , only : master_num & ! intent(in) @@ -2091,8 +2089,6 @@ subroutine ed_nodeget_poly_dims integer :: ierr integer :: ifm integer :: nm - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' !---------------------------------------------------------------------------------------! do ifm=1,ngrids do nm=1,nmachs @@ -2127,15 +2123,12 @@ subroutine ed_nodeget_worklist_info use mem_polygons , only : maxsite ! ! intent(in) use ed_node_coms , only : mynum ! ! intent(in) #if defined(RAMS_MPI) + use mpi use ed_max_dims , only : maxmach ! ! intent(in) use ed_node_coms , only : master_num ! ! intent(in) #endif implicit none -#if defined(RAMS_MPI) - !------ Pre-compiled options. ----------------------------------------------------------! - include 'mpif.h' -#endif !------ Local variables. ---------------------------------------------------------------! integer :: npolygons integer :: ifm diff --git a/ED/src/mpi/ed_para_init.f90 b/ED/src/mpi/ed_para_init.f90 index b34a0f3dd..2037f5714 100644 --- a/ED/src/mpi/ed_para_init.f90 +++ b/ED/src/mpi/ed_para_init.f90 @@ -517,7 +517,6 @@ subroutine ed_parvec_work(ifm,nxp,nyp) , npolys_run & ! intent(out) , ed_alloc_work_vec & ! subroutine , ed_nullify_work_vec ! ! subroutine - use soil_coms , only : ed_nstyp ! ! intent(in) use mem_polygons , only : maxsite ! ! intent(in) implicit none !----- Arguments. ----------------------------------------------------------------------! @@ -659,7 +658,8 @@ subroutine ed_load_work_from_history() real , external :: dist_gc !---------------------------------------------------------------------------------------! - + write (unit=*,fmt='(a)') ' Welcome to ed_load_work_from_history!' + !---------------------------------------------------------------------------------------! ! Here we decide whether this is a history or an ED-2.1 restart run. In case none ! diff --git a/ED/src/utils/allometry.f90 b/ED/src/utils/allometry.f90 index 1be867ce1..ab95f50d4 100644 --- a/ED/src/utils/allometry.f90 +++ b/ED/src/utils/allometry.f90 @@ -142,10 +142,8 @@ real function size2bd(dbh,hite,ipft) , b1Bs_large & ! intent(in) , b2Bs_large & ! intent(in) , is_grass & ! intent(in) - , is_tropical & ! intent(in) - , is_liana ! ! intent(in) - use ed_misc_coms, only : igrass & ! intent(in) - , iallom ! ! intent(in) + , ddh_allom ! ! intent(in) + use ed_misc_coms, only : igrass ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -164,8 +162,7 @@ real function size2bd(dbh,hite,ipft) size2bd = 0.0 else !----- Depending on the allometry, size means DBH or DBH^2 * Height. -------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = dbh * dbh * hite else size = dbh @@ -305,10 +302,9 @@ real function size2bl(dbh,hite,sla_in,ipft) , b2Bl & ! intent(in) , is_liana & ! intent(in) , is_grass & ! intent(in) - , is_tropical & ! intent(in) + , ddh_allom & ! intent(in) , liana_dbh_crit ! ! intent(in) - use ed_misc_coms , only : igrass & ! intent(in) - , iallom ! ! intent(in) + use ed_misc_coms , only : igrass ! ! intent(in) use ed_state_vars, only : patchtype ! ! structure implicit none @@ -341,8 +337,7 @@ real function size2bl(dbh,hite,sla_in,ipft) ! Find leaf biomass depending on the allometry. The new allometry uses dbh and ! ! height, whereas the old allometry uses dbh only. ! !------------------------------------------------------------------------------------! - if ((iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * hite else size = mdbh @@ -352,10 +347,10 @@ real function size2bl(dbh,hite,sla_in,ipft) !------------------------------------------------------------------------------------! - ! For iallom == 4 (tropical trees), b1Bl and b2Bl represents leaf area based ! - ! allometry, we need to convert it to biomass using cohort-level SLA. ! + ! Currently, b1Bl/b2Bl are parameters for individual leaf area (as opposed to ! + ! individual leaf biomass) when using the D*D*H-based allometry. ! !------------------------------------------------------------------------------------! - if (iallom == 4 .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then !----- Use specific form (notice that C2B was cancelled out. ---------------------! size2bl = b1Bl(ipft) / sla_in * size ** b2Bl(ipft) !---------------------------------------------------------------------------------! @@ -452,10 +447,10 @@ end function ba2h ! DBH has no real meaning for grasses with the new allometry. ! !---------------------------------------------------------------------------------------! real function bl2dbh(bleaf,sla_in,ipft) - use pft_coms , only : dbh_crit & ! intent(in) + use pft_coms , only : ddh_allom & ! intent(in) + , dbh_crit & ! intent(in) , l1DBH & ! intent(in) , l2DBH ! ! intent(in) - use ed_misc_coms, only : iallom ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -468,17 +463,15 @@ real function bl2dbh(bleaf,sla_in,ipft) !------------------------------------------------------------------------------------! - ! The inverse function works for both DBH- and DBH^2*Hgt-based allometric ! - ! equations, because l1DBH and l2DBH already account for the different allometric ! - ! functions. However, for leaf-area-based allometry (IALLOM = 4), we need to multiply! - ! bleaf with sla_in to get leaf area because l1DBH and l2DBH are based on leaf area ! + ! The functional for is similar, but when using the D*D*H-allometry, we must ! + ! multiply leaf biomass with SLA, because b1Bl and b2Bl are coefficients for leaf ! + ! area, instead of leaf biomass. ! !------------------------------------------------------------------------------------! - select case (iallom) - case (4) + if (ddh_allom(ipft)) then mdbh = l1DBH(ipft) * (bleaf * sla_in) ** l2DBH(ipft) - case default + else mdbh = l1DBH(ipft) * bleaf ** l2DBH(ipft) - end select + end if !------------------------------------------------------------------------------------! @@ -539,7 +532,7 @@ real function size2ca(dbh,hite,sla,ipft,cap_crit) , hgt_max & ! intent(in) , is_grass & ! intent(in) , is_liana & ! intent(in) - , is_tropical & ! intent(in) + , ddh_allom & ! intent(in) , b1Ca & ! intent(in) , b2Ca & ! intent(in) , liana_dbh_crit ! ! intent(in) @@ -608,8 +601,7 @@ real function size2ca(dbh,hite,sla,ipft,cap_crit) !----- Find the nominal crown area. ----------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * hite else size = mdbh @@ -889,13 +881,6 @@ real function size2prd(hite,dbh,ipft) !------------------------------------------------------------------------------! size = dbh * dbh * hite !------------------------------------------------------------------------------! - case (1,2,4) - !------------------------------------------------------------------------------! - ! This is just a test allometry, that imposes root depth to be 0.5 m for ! - ! plants that are 0.15-m tall, and 5.0 m for plants that are 35-m tall. ! - !------------------------------------------------------------------------------! - size = hite - !------------------------------------------------------------------------------! case (3) !------------------------------------------------------------------------------! ! Test allometry, similar to 2, but based on D*D*H. The curve loosely fits ! @@ -920,6 +905,12 @@ real function size2prd(hite,dbh,ipft) size = hite end if !------------------------------------------------------------------------------! + case default + !------------------------------------------------------------------------------! + ! Size is always height, regardless of the PFT. ! + !------------------------------------------------------------------------------! + size = hite + !------------------------------------------------------------------------------! end select !---------------------------------------------------------------------------------! @@ -1401,14 +1392,13 @@ subroutine area_indices(cpatch, ico) use ed_state_vars, only : patchtype ! ! Structure use pft_coms , only : dbh_crit & ! intent(in) , is_liana & ! intent(in) - , is_tropical & ! intent(in) , is_grass & ! intent(in) + , ddh_allom & ! intent(in) , b1WAI & ! intent(in) , b2WAI & ! intent(in) , liana_dbh_crit ! ! intent(in) use rk4_coms , only : ibranch_thermo ! ! intent(in) - use ed_misc_coms , only : igrass & ! intent(in) - , iallom ! ! intent(in) + use ed_misc_coms , only : igrass ! ! intent(in) implicit none !----- Arguments --------------------------------------------------------------------! @@ -1422,7 +1412,9 @@ subroutine area_indices(cpatch, ico) !------------------------------------------------------------------------------------! + !----- Useful aliases. --------------------------------------------------------------! ipft = cpatch%pft(ico) + !------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------! @@ -1466,8 +1458,7 @@ subroutine area_indices(cpatch, ico) !-----Find WAI. ------------------------------------------------------------------! - if ( (iallom == 3 .or. iallom == 4) & - .and. is_tropical(ipft) .and. (.not. is_liana(ipft))) then + if (ddh_allom(ipft)) then size = mdbh * mdbh * cpatch%hite(ico) else size = mdbh @@ -1481,6 +1472,87 @@ subroutine area_indices(cpatch, ico) end subroutine area_indices !=======================================================================================! !=======================================================================================! + + + + + + + !=======================================================================================! + !=======================================================================================! + ! This function defines the vertical root distribution. ! + !---------------------------------------------------------------------------------------! + subroutine distrib_root(kroot,ipft,root_frac) + use grid_coms , only : nzg ! ! intent(in) + use soil_coms , only : slz ! ! intent(in) + use pft_coms , only : root_beta ! ! intent(in) + use physiology_coms, only : plant_hydro_scheme ! ! intent(in) + implicit none + !----- Arguments. -------------------------------------------------------------------! + integer , intent(in) :: kroot + integer , intent(in) :: ipft + real , dimension(nzg) , intent(out) :: root_frac + !----- Local variables. -------------------------------------------------------------! + integer :: k + real :: slzboti + real :: sbetai + real , dimension(nzg+1) :: root_cumul + !------------------------------------------------------------------------------------! + + + + !----- Useful short names. ----------------------------------------------------------! + slzboti = 1. / slz(kroot) + sbetai = 1. / (1. - root_beta(ipft)) + !------------------------------------------------------------------------------------! + + + + !----- Initialise the fractions. ----------------------------------------------------! + root_cumul(:) = 1. + root_frac (:) = 0. + root_cumul(nzg+1) = 0. + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! Decide how to split root fraction. Currently this is bound to plant hydro- ! + ! dynamics, but in the future we could make this a flag on its own, for testing ! + ! different hypotheses. ! + !------------------------------------------------------------------------------------! + select case (plant_hydro_scheme) + case (0) + !---------------------------------------------------------------------------------! + ! Default ED-2. Roots evenly distributed across depth. Currently this is ! + ! a diagnostic variable and not used anywhere in the code. ! + !---------------------------------------------------------------------------------! + do k=kroot+1,nzg + root_cumul(k) = slz(k) * slzboti + end do + !---------------------------------------------------------------------------------! + case default + !------ Plant hydrodynamics, assume a power decay. -------------------------------! + do k=kroot+1,nzg + root_cumul(k) = sbetai * ( 1. - root_beta(ipft) ** (slz(k) * slzboti) ) + end do + !---------------------------------------------------------------------------------! + end select + !------------------------------------------------------------------------------------! + + + !------------------------------------------------------------------------------------! + ! The rooting fraction is the difference in cumulative rooting density. ! + !------------------------------------------------------------------------------------! + do k=kroot,nzg + root_frac(k) = root_cumul(k) - root_cumul(k+1) + end do + !------------------------------------------------------------------------------------! + + + return + end subroutine distrib_root + !=======================================================================================! + !=======================================================================================! end module allometry !==========================================================================================! !==========================================================================================! diff --git a/ED/src/utils/ed_filelist.F90 b/ED/src/utils/ed_filelist.F90 index 88dd482bc..e4f81745a 100644 --- a/ED/src/utils/ed_filelist.F90 +++ b/ED/src/utils/ed_filelist.F90 @@ -198,10 +198,19 @@ subroutine ed1_fileinfo(text,nfiles,full_list,ntype,type_list,tlon_list,tlat_lis select case(text) case ('.site') okdot = 4 - case ('.pss','.css','.txt') + case ('.sss','.pss','.css','.txt') okdot = 3 case ('.lu') okdot = 2 + case default + write (unit=*,fmt='(a)' ) '----------------------------------------------' + write (unit=*,fmt='(a)' ) ' Unrecognised extension for ED1 file style! ' + write (unit=*,fmt='(a)' ) '----------------------------------------------' + write (unit=*,fmt='(a,1x,a)' ) ' TEXT = ',trim(text) + write (unit=*,fmt='(a,1x,i12)') ' NFILES = ',nfiles + write (unit=*,fmt='(a,1x,a)' ) ' FULL_LIST(1st) = ',trim(full_list(1)) + write (unit=*,fmt='(a)' ) '----------------------------------------------' + call fatal_error('Invalid file extension','ed1_fileinfo','ed_filelist.F90') end select diff --git a/ED/src/utils/fatal_error.F90 b/ED/src/utils/fatal_error.F90 index 18bf18a8c..e54335c03 100644 --- a/ED/src/utils/fatal_error.F90 +++ b/ED/src/utils/fatal_error.F90 @@ -8,6 +8,9 @@ subroutine fatal_error(reason,subr,file) use ed_node_coms , only : nnodetot & ! intent(in) , mynum ! ! intent(in) +#if defined(RAMS_MPI) + use mpi +#endif implicit none !----- Arguments. ----------------------------------------------------------------------! character(len=*), intent(in) :: reason @@ -18,9 +21,6 @@ subroutine fatal_error(reason,subr,file) logical :: slavenode !---------------------------------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! ! Check which type of end we should use. For the main program, this should never ! diff --git a/ED/src/utils/fuse_fiss_utils.f90 b/ED/src/utils/fuse_fiss_utils.f90 index 213f00572..caff9a989 100644 --- a/ED/src/utils/fuse_fiss_utils.f90 +++ b/ED/src/utils/fuse_fiss_utils.f90 @@ -1995,7 +1995,8 @@ subroutine fuse_2_cohorts(cpatch,donc,recc,can_prss,can_shv,lsl,fuse_initial) , bl2h & ! function , dbh2h & ! function , size2xb & ! function - , ed_balive ! ! function + , ed_balive & ! function + , distrib_root ! ! subroutine use ed_max_dims , only : n_mort ! ! intent(in) use ed_misc_coms , only : writing_long & ! intent(in) , writing_eorq & ! intent(in) @@ -2198,6 +2199,12 @@ subroutine fuse_2_cohorts(cpatch,donc,recc,can_prss,can_shv,lsl,fuse_initial) + !----- Update the vertical distribution of roots. -----------------------------------! + call distrib_root(cpatch%krdepth(recc),cpatch%pft(recc),cpatch%root_frac(:,recc)) + !------------------------------------------------------------------------------------! + + + !----- Maintenance costs. -----------------------------------------------------------! cpatch%leaf_maintenance (recc) = cpatch%leaf_maintenance (recc) * rnplant & @@ -7578,6 +7585,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%fmean_sfcw_mass (recp) * rawgt csite%fmean_sfcw_mass (recp) = csite%fmean_sfcw_mass (donp) * dawgt & + csite%fmean_sfcw_mass (recp) * rawgt + csite%fmean_snowfac (recp) = csite%fmean_snowfac (donp) * dawgt & + + csite%fmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ------------------------------! if (csite%fmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%fmean_sfcw_energy (recp) = csite%fmean_sfcw_energy (recp) & @@ -7775,6 +7784,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%dmean_sfcw_mass (recp) * rawgt csite%dmean_sfcw_mass (recp) = csite%dmean_sfcw_mass (donp) * dawgt & + csite%dmean_sfcw_mass (recp) * rawgt + csite%dmean_snowfac (recp) = csite%dmean_snowfac (donp) * dawgt & + + csite%dmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ---------------------------! if (csite%dmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%dmean_sfcw_energy (recp) = csite%dmean_sfcw_energy (recp) & @@ -8169,6 +8180,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%mmean_sfcw_mass (recp) * rawgt csite%mmean_sfcw_mass (recp) = csite%mmean_sfcw_mass (donp) * dawgt & + csite%mmean_sfcw_mass (recp) * rawgt + csite%mmean_snowfac (recp) = csite%mmean_snowfac (donp) * dawgt & + + csite%mmean_snowfac (recp) * rawgt !----- Check whether there is enough surface water. ---------------------------! if (csite%mmean_sfcw_mass(recp) > tiny_sfcwater_mass) then csite%mmean_sfcw_energy (recp) = csite%mmean_sfcw_energy (recp) & @@ -8520,6 +8533,8 @@ subroutine fuse_2_patches(csite,donp,recp,mzg,mzs,cmet,lsl,ntext_soil,green_leaf * csite%qmean_sfcw_mass (t,recp) * rawgt csite%qmean_sfcw_mass (t,recp) = csite%qmean_sfcw_mass (t,donp) * dawgt & + csite%qmean_sfcw_mass (t,recp) * rawgt + csite%qmean_snowfac (t,recp) = csite%qmean_snowfac (t,donp) * dawgt & + + csite%qmean_snowfac (t,recp) * rawgt !----- Check whether there is enough surface water. ------------------------! if (csite%qmean_sfcw_mass(t,recp) > tiny_sfcwater_mass) then csite%qmean_sfcw_energy (t,recp) = csite%qmean_sfcw_energy(t,recp) & diff --git a/ED/src/utils/numutils.f90 b/ED/src/utils/numutils.f90 index de2c50065..22c830115 100644 --- a/ED/src/utils/numutils.f90 +++ b/ED/src/utils/numutils.f90 @@ -906,3 +906,73 @@ end function fquant_mask !==========================================================================================! !==========================================================================================! + + + +!==========================================================================================! +!==========================================================================================! +! FUNCTION bpow01 +!\brief Safe power estimate to avoid floating point exceptions +!\author Marcos Longo 3 March 2021 +!\details This function to calculate power functions for numbers bounded between 0 and 1 +!! safely. It uses that y = x ** a = exp(a * ln(x)), and use the safe log limits +!! to avoid FPE errors. This function "should" work for values greater than 1 too, +!! but don't use if for negative numbers. +!------------------------------------------------------------------------------------------! +real(kind=4) function bpow01(x,a) + use consts_coms, only : lnexp_min & ! intent(in) + , lnexp_max ! ! intent(in) + implicit none + !----- Arguments. ----------------------------------------------------------------------! + real(kind=4), intent(in) :: x + real(kind=4), intent(in) :: a + !----- Internal variables. -------------------------------------------------------------! + real(kind=4) :: lnexp + !---------------------------------------------------------------------------------------! + + + + !---------------------------------------------------------------------------------------! + ! Check if x is greater than zero (if it is exactly zero, we cannot use the log ! + ! approach). ! + !---------------------------------------------------------------------------------------! + if (x > 0.) then + + + !----- Find the bounded term inside the exponential. --------------------------------! + lnexp = max(lnexp_min,min(lnexp_max,a * log(x))) + !------------------------------------------------------------------------------------! + + + !----- Report result. ---------------------------------------------------------------! + bpow01 = exp(lnexp) + !------------------------------------------------------------------------------------! + else if (x == 0. .and. a > 0.) then + !----- By definition 0^a = 0 as long as a > 0. --------------------------------------! + bpow01 = 0. + !------------------------------------------------------------------------------------! + else + !------------------------------------------------------------------------------------! + ! Invalid input data, stop everything. ! + !------------------------------------------------------------------------------------! + write(unit=*,fmt='(a)' ) '-----------------------------------------------' + write(unit=*,fmt='(a)' ) ' Invalid variables for bpow01!' + write(unit=*,fmt='(a)' ) '-----------------------------------------------' + write(unit=*,fmt='(a,1x,es12.5)') ' x = ',x + write(unit=*,fmt='(a,1x,es12.5)') ' a = ',a + write(unit=*,fmt='(a)' ) '-----------------------------------------------' + write(unit=*,fmt='(a)' ) ' If x >= 0., then make sure a >= 0. ' + write(unit=*,fmt='(a)' ) ' If x = 0., then make sure a > 0. ' + write(unit=*,fmt='(a)' ) ' Negative x values are not allowed. ' + write(unit=*,fmt='(a)' ) '-----------------------------------------------' + call fatal_error('Invalid values for x and/or a.','bpow01','numutils.f90') + !------------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------------! + + + return +end function bpow01 +!==========================================================================================! +!==========================================================================================! + diff --git a/ED/src/utils/rsys.F90 b/ED/src/utils/rsys.F90 index ca3ba998f..ff3b45567 100644 --- a/ED/src/utils/rsys.F90 +++ b/ED/src/utils/rsys.F90 @@ -117,7 +117,7 @@ logical function isnan_real(x) !---------------------------------------------------------------------------------------! #if defined(PGI) - isnan_real = x == x + isnan_real = x /= x #else isnan_real = isnan(x) #endif @@ -131,6 +131,31 @@ end function isnan_real +!==========================================================================================! +!==========================================================================================! +! Function that checks whether a number is NaN. This works with PGI, Intel, and GNU. ! +!------------------------------------------------------------------------------------------! +logical function isnan_dble(x) + implicit none + !------ Arguments. ---------------------------------------------------------------------! + real(kind=8), intent(in) :: x + !---------------------------------------------------------------------------------------! + +#if defined(PGI) + isnan_dble = x /= x +#else + isnan_dble = isnan(x) +#endif + + return +end function isnan_dble +!==========================================================================================! +!==========================================================================================! + + + + + !==========================================================================================! !==========================================================================================! ! Function that waits for a few seconds before moving on. This may be useful for OMP ! diff --git a/ED/src/utils/update_derived_utils.f90 b/ED/src/utils/update_derived_utils.f90 index 7ab3c2752..d465fdc88 100644 --- a/ED/src/utils/update_derived_utils.f90 +++ b/ED/src/utils/update_derived_utils.f90 @@ -65,7 +65,8 @@ subroutine update_cohort_derived_props(cpatch,ico,lsl,new_year,llspan_toc , size2xb & ! function , ed_balive & ! function , ed_biomass & ! function - , area_indices ! ! subroutine + , area_indices & ! sub-routine + , distrib_root ! ! sub-routine use physiology_coms, only : trait_plasticity_scheme ! ! intent(in) use consts_coms , only : pio4 ! ! intent(in) use ed_misc_coms , only : igrass & ! intent(in) @@ -193,6 +194,13 @@ subroutine update_cohort_derived_props(cpatch,ico,lsl,new_year,llspan_toc !----- Update rooting depth ---------------------------------------------------------! cpatch%krdepth(ico) = size2krdepth(cpatch%hite(ico),cpatch%dbh(ico),ipft,lsl) !if new root depth is smaller keep the old one + !------------------------------------------------------------------------------------! + + + !----- Update the vertical distribution of roots. -----------------------------------! + call distrib_root(cpatch%krdepth(ico),ipft,cpatch%root_frac(:,ico)) + !------------------------------------------------------------------------------------! + return end subroutine update_cohort_derived_props !=======================================================================================! @@ -390,27 +398,45 @@ subroutine update_cohort_plastic_trait(cpatch,ico,is_instant cpatch%sla (ico) = new_sla cpatch%psi_open (ico) = cpatch%psi_open (ico) * sla_scaler cpatch%psi_closed(ico) = cpatch%psi_closed(ico) * sla_scaler + !------------------------------------------------------------------------------------! - ! Since SLA is changed, we might need to adjust leaf biomass if leaf area based - ! allometry is used + + + !------------------------------------------------------------------------------------! + ! 6. SLA may have changed, therefore we must adjust leaf biomass if we are using ! + ! the leaf-area based allometry. ! + !------------------------------------------------------------------------------------! select case (iallom) - case (4) - bl_max = size2bl(cpatch%dbh(ico),cpatch%hite(ico),cpatch%sla(ico),cpatch%pft(ico)) + case (3,4,5) + !---- Maximum leaf biomass. ------------------------------------------------------! + bl_max = size2bl(cpatch%dbh(ico),cpatch%hite(ico),cpatch%sla(ico),cpatch%pft(ico)) + !---------------------------------------------------------------------------------! - if (cpatch%bleaf(ico) > bl_max) then - ! if the new bl_max is smaller than current bleaf, we need to dump - ! the extra carbon into bstorage and change phenology_status - cpatch%bstorage(ico) = cpatch%bstorage(ico) & - + (cpatch%bleaf(ico) - bl_max) - ! Water content will be updated later in structural_growth + + !---------------------------------------------------------------------------------! + ! Check that plasticity doesn't violate allometry. ! + !---------------------------------------------------------------------------------! + if (cpatch%bleaf(ico) > bl_max) then + !------------------------------------------------------------------------------! + ! If the new bl_max is smaller than current bleaf, we need to dump the ! + ! extra carbon into bstorage and change phenology_status. ! + !------------------------------------------------------------------------------! + cpatch%bstorage(ico) = cpatch%bstorage(ico) + (cpatch%bleaf(ico) - bl_max) + + !----- Water content will be updated later in structural_growth. --------------! cpatch%bleaf(ico) = bl_max + !------------------------------------------------------------------------------! - ! we also update balive since bleaf changed + !----- We also update balive since bleaf changed. -----------------------------! cpatch%balive(ico) = ed_balive(cpatch,ico) + !------------------------------------------------------------------------------! + !----- Leaves are at maximum elongation, update phenology flag accordingly. ---! cpatch%phenology_status(ico) = 0 - endif + !------------------------------------------------------------------------------! + end if + !---------------------------------------------------------------------------------! end select !------------------------------------------------------------------------------------! @@ -794,7 +820,7 @@ end subroutine update_patch_derived_props !=======================================================================================! ! This subroutine will take care of some diagnostic thermodynamic properties. ! !---------------------------------------------------------------------------------------! - subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) + subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,lsl,ntext_soil) use ed_state_vars, only : sitetype ! ! structure use therm_lib , only : idealdenssh & ! function @@ -815,6 +841,7 @@ subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) integer , intent(in) :: ipaz integer , intent(in) :: mzg integer , intent(in) :: mzs + integer , intent(in) :: lsl integer , dimension(mzg), intent(in) :: ntext_soil !----- Local variables. -------------------------------------------------------------! integer :: ipa @@ -841,7 +868,7 @@ subroutine update_patch_thermo_props(csite,ipaa,ipaz,mzg,mzs,ntext_soil) !----- Update soil temperature and liquid water fraction. ------------------------! - do k = 1, mzg + do k = lsl, mzg nsoil = ntext_soil(k) soilhcap = soil(nsoil)%slcpd call uextcm2tl(csite%soil_energy(k,ipa),csite%soil_water(k,ipa)*wdns,soilhcap & @@ -890,7 +917,7 @@ end subroutine update_patch_thermo_props ! This subroutine will update the fast mean properties, similarly to the routine ! ! above. ! !---------------------------------------------------------------------------------------! - subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) + subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,lsl,ntext_soil) use ed_state_vars, only : sitetype ! ! structure use therm_lib , only : idealdenssh & ! function @@ -911,6 +938,7 @@ subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) integer , intent(in) :: ipaa integer , intent(in) :: ipaz integer , intent(in) :: mzg + integer , intent(in) :: lsl integer , dimension(mzg), intent(in) :: ntext_soil !----- Local variables. -------------------------------------------------------------! integer :: ipa @@ -937,7 +965,7 @@ subroutine update_patch_thermo_fmean(csite,ipaa,ipaz,mzg,ntext_soil) !----- Update soil temperature and liquid water fraction. ------------------------! - do k = 1, mzg + do k = lsl, mzg nsoil = ntext_soil(k) soilhcap = soil(nsoil)%slcpd call uextcm2tl( csite%fmean_soil_energy(k,ipa) & diff --git a/EDR/src/driver/ed_1st.F90 b/EDR/src/driver/ed_1st.F90 index 571477f54..9ac94dcaa 100644 --- a/EDR/src/driver/ed_1st.F90 +++ b/EDR/src/driver/ed_1st.F90 @@ -22,13 +22,12 @@ subroutine ed_1st_master (ipara, nnodestotal,nslaves, headnode_num, max_threads, use ed_misc_coms , only : runtype ! ! intent(inout) use ed_state_vars, only : allocate_edglobals & ! subroutine , filltab_alltypes ! ! subroutine +#if defined(RAMS_MPI) + use mpi +#endif implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !----- Arguments. ----------------------------------------------------------------------! integer , intent(in) :: ipara ! 0 if sequential run; 1 if parallel run integer , intent(in) :: nnodestotal ! total number of nodes on any run @@ -170,10 +169,10 @@ end subroutine ed_1st_master !------------------------------------------------------------------------------------------! subroutine ed_1st_node() use ed_mem_alloc, only : ed_memory_allocation ! ! subroutine - implicit none - !----- Pre-compiled variables from MPI. ------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi +#endif + implicit none !----- Local variable (MPI only). ------------------------------------------------------! integer :: ierr #endif diff --git a/EDR/src/driver/ed_driver.F90 b/EDR/src/driver/ed_driver.F90 index b9fc14731..58a8759a5 100644 --- a/EDR/src/driver/ed_driver.F90 +++ b/EDR/src/driver/ed_driver.F90 @@ -30,11 +30,10 @@ subroutine ed_driver() use detailed_coms , only : idetailed & ! intent(in) , patch_keep ! ! intent(in) use phenology_aux , only : first_phenology ! ! subroutine - implicit none - !----- Included variables. -------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' ! MPI commons + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! character(len=12) :: c0 character(len=12) :: c1 diff --git a/EDR/src/driver/ed_model.F90 b/EDR/src/driver/ed_model.F90 index fe00a6003..aa23d598e 100644 --- a/EDR/src/driver/ed_model.F90 +++ b/EDR/src/driver/ed_model.F90 @@ -85,11 +85,10 @@ subroutine ed_model() , zero_ed_fmean_vars & ! sub-routine , integrate_ed_fmean_met_vars & ! sub-routine , zero_ed_yearly_vars ! ! sub-routine - implicit none - !----- Common blocks. ------------------------------------------------------------------! #if defined(RAMS_MPI) - include 'mpif.h' + use mpi #endif + implicit none !----- Local variables. ----------------------------------------------------------------! character(len=28) :: fmthead character(len=32) :: fmtcntr diff --git a/EDR/src/driver/edmain.F90 b/EDR/src/driver/edmain.F90 index f5b8c1f44..33614086d 100644 --- a/EDR/src/driver/edmain.F90 +++ b/EDR/src/driver/edmain.F90 @@ -14,6 +14,9 @@ !------------------------------------------------------------------------------------------! program main !$ use omp_lib +#if defined(RAMS_MPI) + use mpi +#endif implicit none !---------------------------------------------------------------------------------------! @@ -46,10 +49,6 @@ program main integer, dimension(64) :: thread_use integer, dimension(64) :: cpu_use integer, external :: findmycpu - !------ MPI interface. -----------------------------------------------------------------! -#if defined(RAMS_MPI) - include 'mpif.h' -#endif !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-TEST b/EDTS/Templates/ED2IN-TEST index 64f489146..e36f75f7c 100644 --- a/EDTS/Templates/ED2IN-TEST +++ b/EDTS/Templates/ED2IN-TEST @@ -887,13 +887,19 @@ $ED_NL ! a few genera in Costa Rica. References: ! ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! ! (2008, Tree Physiol.). ! - ! 3. (Beta) Updated allometric for tropical PFTs based on data from ! - ! Sustainable Landscapes Brazil (Height and crown area), Chave et al. ! - ! (2014, Glob. Change Biol.) (biomass) and the BAAD data base, Falster et ! - ! al. (2015, Ecology) (leaf area). Both leaf and structural biomass take ! - ! DBH and Height as dependent variables, and DBH-Height takes a simpler ! - ! log-linear form fitted using SMA so it can be inverted (useful for ! - ! airborne lidar initialisation). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 3 !---------------------------------------------------------------------------------------! @@ -964,10 +970,25 @@ $ED_NL ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-tonzi b/EDTS/Templates/ED2IN-tonzi index 06ed7ff22..667687714 100644 --- a/EDTS/Templates/ED2IN-tonzi +++ b/EDTS/Templates/ED2IN-tonzi @@ -788,27 +788,36 @@ $ED_NL !---------------------------------------------------------------------------------------! - ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs. Temperate PFTs ! - ! will use the new root allometry and the maximum crown area if IALLOM is set ! - ! to 1 or 2). ! - ! 0. Original ED-2.1 ! - ! 1. a. The coefficients for structural biomass are set so the total AGB ! - ! is similar to Baker et al. (2004), equation 2. Balive is the ! - ! default ED-2.1; ! + ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs). Temperate PFTs ! + ! will use the new root allometry and the maximum crown area unless IALLOM is ! + ! set to 0). ! + ! 0. (Legacy) Original ED-1.0, included for back compatibility. ! + ! 1. (Legacy) ! + ! a. The coefficients for structural biomass are set so the total AGB ! + ! is similar to Baker et al. (2004, Glob. Change Biol.), equation 2. ! ! b. Experimental root depth that makes canopy trees to have root depths ! ! of 5m and grasses/seedlings at 0.5 to have root depth of 0.5 m. ! - ! c. Crown area defined as in Poorter et al. (2006), imposing maximum ! - ! crown area ! - ! 2. Similar to 1, but with a few extra changes. ! + ! c. Crown area defined as in Poorter et al. (2006, Ecology), imposing ! + ! maximum crown area. ! + ! 2. (ED-2.2 default) Similar to 1, but with a few extra changes. ! ! a. Height -> DBH allometry as in Poorter et al. (2006) ! ! b. Balive is retuned, using a few leaf biomass allometric equations for ! - ! a few genuses in Costa Rica. References: ! - ! Cole and Ewel (2006), and Calvo Alvarado et al. (2008). ! - ! 3. Similar to 2, except that tropical leaf biomass is estimated from ! - ! Lescure et al. (1983), and PFT differences on bleaf are based on SLA ! - ! instead of wood density. Also, the leaf allometry is split into ! - ! small classes ("saplings") and large classes ("trees"), like in Cole ! - ! and Ewel (2006). ! + ! a few genera in Costa Rica. References: ! + ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! + ! (2008, Tree Physiol.). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 2 !---------------------------------------------------------------------------------------! @@ -848,37 +857,52 @@ $ED_NL ! IPHEN_SCHEME -- It controls the phenology scheme. Even within each scheme, the ! ! actual phenology will be different depending on the PFT. ! ! ! - ! -1: grasses - evergreen; ! + ! -1: (ED-2.2 default for evergreen tropical). ! + ! grasses - evergreen; ! ! tropical - evergreen; ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous (Botta et al.); ! ! ! - ! 0: grasses - drought-deciduous (old scheme); ! + ! 0: (Deprecated). ! + ! grasses - drought-deciduous (old scheme); ! ! tropical - drought-deciduous (old scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 1: prescribed phenology ! + ! 1: (ED-2.2 default for prescribed phenology; deprecated for tropical PFTs). ! + ! phenology is prescribed for cold-deciduous broadleaf trees. ! ! ! - ! 2: grasses - drought-deciduous (new scheme); ! + ! 2: (ED-2.2 default). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (new scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 3: grasses - drought-deciduous (new scheme); ! + ! 3: (Beta). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 4: grasses - drought-deciduous (plant hydraulics); ! - ! tropical - drought-deciduous (plant hydraulics; ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! diff --git a/EDTS/Templates/ED2IN-tonzi.harvest b/EDTS/Templates/ED2IN-tonzi.harvest index fed665436..faac10ca0 100644 --- a/EDTS/Templates/ED2IN-tonzi.harvest +++ b/EDTS/Templates/ED2IN-tonzi.harvest @@ -788,27 +788,36 @@ $ED_NL !---------------------------------------------------------------------------------------! - ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs. Temperate PFTs ! - ! will use the new root allometry and the maximum crown area if IALLOM is set ! - ! to 1 or 2). ! - ! 0. Original ED-2.1 ! - ! 1. a. The coefficients for structural biomass are set so the total AGB ! - ! is similar to Baker et al. (2004), equation 2. Balive is the ! - ! default ED-2.1; ! + ! IALLOM -- Which allometry to use (this mostly affects tropical PFTs). Temperate PFTs ! + ! will use the new root allometry and the maximum crown area unless IALLOM is ! + ! set to 0). ! + ! 0. (Legacy) Original ED-1.0, included for back compatibility. ! + ! 1. (Legacy) ! + ! a. The coefficients for structural biomass are set so the total AGB ! + ! is similar to Baker et al. (2004, Glob. Change Biol.), equation 2. ! ! b. Experimental root depth that makes canopy trees to have root depths ! ! of 5m and grasses/seedlings at 0.5 to have root depth of 0.5 m. ! - ! c. Crown area defined as in Poorter et al. (2006), imposing maximum ! - ! crown area ! - ! 2. Similar to 1, but with a few extra changes. ! + ! c. Crown area defined as in Poorter et al. (2006, Ecology), imposing ! + ! maximum crown area. ! + ! 2. (ED-2.2 default) Similar to 1, but with a few extra changes. ! ! a. Height -> DBH allometry as in Poorter et al. (2006) ! ! b. Balive is retuned, using a few leaf biomass allometric equations for ! - ! a few genuses in Costa Rica. References: ! - ! Cole and Ewel (2006), and Calvo Alvarado et al. (2008). ! - ! 3. Similar to 2, except that tropical leaf biomass is estimated from ! - ! Lescure et al. (1983), and PFT differences on bleaf are based on SLA ! - ! instead of wood density. Also, the leaf allometry is split into ! - ! small classes ("saplings") and large classes ("trees"), like in Cole ! - ! and Ewel (2006). ! + ! a few genera in Costa Rica. References: ! + ! Cole and Ewel (2006, Forest Ecol. Manag.), and Calvo-Alvarado et al. ! + ! (2008, Tree Physiol.). ! + ! 3. (Beta) Revised tropical PFT allometric (Longo et al. 2020, JGR-B). ! + ! a. Height -> DBH and DBH^2*H -> CA. Model fitting using the Sustainable ! + ! Landscapes Dataset (Longo et al. 2016, Glob. Biogeochem. Cycles). ! + ! DBH-Height takes a simpler log-linear form fitted using SMA so it can ! + ! be inverted (useful for airborne lidar initialisation). ! + ! b. DBH^2*H -> AGB. Based on Chave et al. (2014, Glob. Change Biol.) ! + ! c. DBH^2*H -> Leaf area based on the BAAD data base: ! + ! Falster et al. (2015, Ecology). ! + ! 4. (Under Development) Similar to 3 but (a) leaf and height allometric ! + ! equations depend on wood density; (b) use height-based root allometry ! + ! from Smith-Martin et al. (2020, New Phyt.). ! + ! 5. (Under Development) Similar to IALLOM = 3 but using the rooting ! + ! allometry from IALLOM = 4. ! !---------------------------------------------------------------------------------------! NL%IALLOM = 2 !---------------------------------------------------------------------------------------! @@ -848,37 +857,52 @@ $ED_NL ! IPHEN_SCHEME -- It controls the phenology scheme. Even within each scheme, the ! ! actual phenology will be different depending on the PFT. ! ! ! - ! -1: grasses - evergreen; ! + ! -1: (ED-2.2 default for evergreen tropical). ! + ! grasses - evergreen; ! ! tropical - evergreen; ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous (Botta et al.); ! ! ! - ! 0: grasses - drought-deciduous (old scheme); ! + ! 0: (Deprecated). ! + ! grasses - drought-deciduous (old scheme); ! ! tropical - drought-deciduous (old scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 1: prescribed phenology ! + ! 1: (ED-2.2 default for prescribed phenology; deprecated for tropical PFTs). ! + ! phenology is prescribed for cold-deciduous broadleaf trees. ! ! ! - ! 2: grasses - drought-deciduous (new scheme); ! + ! 2: (ED-2.2 default). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (new scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 3: grasses - drought-deciduous (new scheme); ! + ! 3: (Beta). ! + ! grasses - drought-deciduous (new scheme); ! ! tropical - drought-deciduous (light phenology); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! - ! 4: grasses - drought-deciduous (plant hydraulics); ! - ! tropical - drought-deciduous (plant hydraulics; ! + ! 4: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme); ! ! conifers - evergreen; ! ! hardwoods - cold-deciduous; ! ! ! + ! 5: (Beta). ! + ! grasses - drought-deciduous (hydraulics scheme); ! + ! tropical - drought-deciduous (hydraulics scheme + light phenology); ! + ! conifers - evergreen; ! + ! hardwoods - cold-deciduous; ! + ! ! + ! ! ! Old scheme: plants shed their leaves once instantaneous amount of available water ! ! becomes less than a critical value. ! ! New scheme: plants shed their leaves once a 10-day running average of available ! ! water becomes less than a critical value. ! + ! Hydraulics scheme: plants shed their leaves once predawn leaf water potential is ! + ! lower than tugor loss point for 10 consecutive days ! !---------------------------------------------------------------------------------------! NL%IPHEN_SCHEME = 2 !---------------------------------------------------------------------------------------! diff --git a/R-utils/Ft.ustar.r b/R-utils/Ft.ustar.r index e63c53fc9..1374e08d9 100644 --- a/R-utils/Ft.ustar.r +++ b/R-utils/Ft.ustar.r @@ -19,7 +19,18 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ #---------------------------------------------------------------------------------------# - #----- Delete data that is missing. ----------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case storage is always NA, it means storage was not measured. In this case, we # + # assume zero storage whenever the CO2 flux is not missing. # + #---------------------------------------------------------------------------------------# + if ( all(! is.finite(cflxst)) && any(is.finite(cflxca)) ){ + cflxst = ifelse( test = is.finite(cflxca), yes = 0., no = NA_real_ ) + }#end if ( all(! is.finite(cflxst)) && any(is.finite(cflxca)) ) + #---------------------------------------------------------------------------------------# + + + + #----- Delete missing data. ------------------------------------------------------------# keep = is.finite(ustar) & is.finite(cflxca) & is.finite(cflxst) & nighttime keep = ifelse(is.na(keep),FALSE,keep) ustar = ustar [keep] @@ -80,7 +91,7 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ while (iterate){ b = b + 1 ttt = t.test(x=sp.cflxca[[b]],y=sp.cflxst[[b]],alternative="greater") - iterate = b < nbins && ttt$p.value %>=% 0.01 + iterate = b < nbins && ttt$p.value %ge% 0.01 }#end for #---------------------------------------------------------------------------------------# @@ -129,8 +140,8 @@ Ft.ustar <<- function(ustar,cflxca,cflxst,nighttime,delta=0.01,nmin=10){ #---- Check whether the p.value is sufficiently large. ------------------------------# - success = ( ( p.ft %<=% p.lm && p.lm %>=% 0.10 && p.ft %>=% 0.10 ) - || ( p.ft %>=% 0.50 && p.lm %>=% 0.50 ) ) + success = ( ( p.ft %le% p.lm && p.lm %ge% 0.10 && p.ft %ge% 0.10 ) + || ( p.ft %ge% 0.50 && p.lm %ge% 0.50 ) ) iterate = ( ! success ) && (b < (nbins - 2)) cat(" u* = ",ustar.breaks[b],"; p.lm = ",sprintf("%.2f",p.lm) ,"; p.ft = ",sprintf("%.2f",p.ft) diff --git a/R-utils/allometry.r b/R-utils/allometry.r index ea350baec..13e98f355 100644 --- a/R-utils/allometry.r +++ b/R-utils/allometry.r @@ -8,7 +8,7 @@ h2dbh <<- function(h,ipft){ zpft = ipft }#end if - tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4) + tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4,5) tropn = pft$tropical[zpft] & iallom %in% c(2) tempe = ! pft$tropical[zpft] @@ -54,7 +54,7 @@ dbh2h <<- function(dbh,ipft,use.crit=TRUE){ dbhuse = dbh }#end if (use.crit) - tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4) + tropo = pft$tropical[zpft] & iallom %in% c(0,1,3,4,5) tropn = pft$tropical[zpft] & iallom %in% c(2) tempe = ! pft$tropical[zpft] @@ -102,7 +102,7 @@ size2bl <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -113,7 +113,7 @@ size2bl <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ # For iallom == 4 (tropical trees), b1Bl and b2Bl represents leaf area based # # allometry, we need to convert it to biomass using cohort-level SLA. # #---------------------------------------------------------------------------------------# - bleaf = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(4)) + bleaf = ifelse( test = pft$ddh.allom[zpft] , yes = pft$b1Bl[zpft] / sla * size ^ pft$b2Bl[zpft] , no = pft$b1Bl[zpft] / C2B * size ^ pft$b2Bl[zpft] )#end ifelse @@ -182,7 +182,7 @@ size2bd <<- function(dbh,hgt,ipft){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbh * dbh * dbh2h(dbh,ipft=zpft) , no = dbh )#end ifelse @@ -191,7 +191,7 @@ size2bd <<- function(dbh,hgt,ipft){ #----- Select allometric parameters based on the size. ---------------------------------# - bdead = ifelse( test = dbh %<% pft$dbh.crit[zpft] + bdead = ifelse( test = dbh %lt% pft$dbh.crit[zpft] , yes = pft$b1Bs.small[zpft] / C2B * size ^ pft$b2Bs.small[zpft] , no = pft$b1Bs.large[zpft] / C2B * size ^ pft$b2Bs.large[zpft] )#end ifelse @@ -249,8 +249,8 @@ size2de <<- function(dbh,hgt,ipft,dbh.by=0.1,...){ #----- Identify cohorts with size that outside resolvable height range. ----------------# - large = (dbh*dbh*hgt) %>=% (pft$dbh.crit[zpft]*pft$dbh.crit[zpft]*pft$hgt.max[zpft]) - small = (dbh*dbh*hgt) %<=% (pft$dbh.min [zpft]*pft$dbh.min [zpft]*pft$hgt.min[zpft]) + large = (dbh*dbh*hgt) %ge% (pft$dbh.crit[zpft]*pft$dbh.crit[zpft]*pft$hgt.max[zpft]) + small = (dbh*dbh*hgt) %le% (pft$dbh.min [zpft]*pft$dbh.min [zpft]*pft$hgt.min[zpft]) heq = ifelse( test = large , yes = pft$hgt.max[zpft] , no = ifelse(test = small,yes=pft$hgt.min[zpft],no=NA_real_) @@ -321,7 +321,7 @@ size2ca <<- function(dbh,hgt,sla,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -368,7 +368,7 @@ size2wai <<- function(dbh,hgt,ipft,use.crit=TRUE){ #----- Decide which variable to use as dependent variable (DBH or DBH^2*Hgt). ----------# - size = ifelse( test = pft$tropical[zpft] & (! pft$liana[zpft]) & (iallom %in% c(3,4)) + size = ifelse( test = pft$ddh.allom[zpft] , yes = dbhuse * dbhuse * hgt , no = dbhuse )#end ifelse @@ -505,7 +505,7 @@ size2rd <<- function(hgt,dbh,ipft){ #------------------------------------------------------------------------------------# vol = size2vol(hgt=hgt,dbh=dbh,ipft=zpft) rd = pft$b1Rd[zpft] * (hgt * dbh * dbh) ^ pft$b2Rd[zpft] - }else if (iallom %in% c(1,2,4)){ + }else if (iallom %in% c(1,2,4,5)){ #------------------------------------------------------------------------------------# # This is just a test allometry, that imposes root depth to be 0.5 m for # # plants that are 0.15-m tall, and 5.0 m for plants that are 35-m tall. # diff --git a/R-utils/amzbr_poi.csv b/R-utils/amzbr_poi.csv new file mode 100644 index 000000000..92c63a1a2 --- /dev/null +++ b/R-utils/amzbr_poi.csv @@ -0,0 +1,351 @@ +short,iata,longname,lon,lat,alt,wmo,isoilflg,istext,sand,clay,slsoc,slph,slcec,sldbd,depth,isoilbc,sldrain,scolour,met.driver,yeara,yearz,iphen,iage +AMZBR_0001,a0001,Amazon Polygon 0001,-61.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0002,a0002,Amazon Polygon 0002,-60.5,-13.5,NA,NA,2,3,0.614,0.173,0.0179,5.2,0.099,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0003,a0003,Amazon Polygon 0003,-63.5,-12.5,NA,NA,2,6,0.495,0.262,0.016,5,0.086,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0004,a0004,Amazon Polygon 0004,-62.5,-12.5,NA,NA,2,6,0.532827158181877,0.223343203931085,0.0151842159320799,4.81890525820088,0.0924997073894,1223.15593565532,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0005,a0005,Amazon Polygon 0005,-61.5,-12.5,NA,NA,2,6,0.450731520182141,0.306403635818869,0.0183703078468289,4.88934097681909,0.0847669342966816,1220.75569914233,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0006,a0006,Amazon Polygon 0006,-60.5,-12.5,NA,NA,2,6,0.558696336870935,0.25565491270113,0.0175133858267717,5.01828141047586,0.0786268401232455,1228.952413557,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0007,a0007,Amazon Polygon 0007,-57.5,-12.5,NA,NA,2,3,0.709133718829057,0.193535598120708,0.0181794000722805,4.42490061438381,0.117891217925551,1208.67003975425,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0008,a0008,Amazon Polygon 0008,-56.5,-12.5,NA,NA,2,3,0.606,0.148,0.0193,4.8,0.119,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0009,a0009,Amazon Polygon 0009,-55.5,-12.5,NA,NA,2,3,0.589,0.157,0.0202,4.9,0.103,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0010,a0010,Amazon Polygon 0010,-54.5,-12.5,NA,NA,2,6,0.588931216931217,0.262272927689594,0.0225351851851852,4.77416225749559,0.0949766313932981,1217.7557319224,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0011,a0011,Amazon Polygon 0011,-53.5,-12.5,NA,NA,2,6,0.599319673617407,0.255952493200363,0.0254086854034451,4.85642792384406,0.0997787851314597,1223.12420670898,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0012,a0012,Amazon Polygon 0012,-52.5,-12.5,NA,NA,2,6,0.612817371143214,0.240545211342964,0.0232944533618691,4.87788478687355,0.0945580524344569,1232.01533797039,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0013,a0013,Amazon Polygon 0013,-64.5,-11.5,NA,NA,2,6,0.479828543080773,0.284419945311968,0.0166047393115583,4.81936043008105,0.100291496056211,1195.82545471844,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0014,a0014,Amazon Polygon 0014,-63.5,-11.5,NA,NA,2,6,0.485,0.257,0.0158,4.9,0.106,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0015,a0015,Amazon Polygon 0015,-62.5,-11.5,NA,NA,2,6,0.501,0.249,0.0156,4.8,0.097,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0016,a0016,Amazon Polygon 0016,-61.5,-11.5,NA,NA,2,6,0.523848657024793,0.226321280991736,0.0169982954545455,4.49927685950413,0.124055785123967,1184.70041322314,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0017,a0017,Amazon Polygon 0017,-60.5,-11.5,NA,NA,2,6,0.497783881692461,0.240416956240693,0.0196677284365722,4.45150152401207,0.126352349579395,1200.16621915694,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0018,a0018,Amazon Polygon 0018,-58.5,-11.5,NA,NA,2,3,0.693155778355077,0.173519040956307,0.0190220585730911,4.49683832001874,0.093880134066002,1204.17132873688,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0019,a0019,Amazon Polygon 0019,-57.5,-11.5,NA,NA,2,6,0.63242030075188,0.211000751879699,0.018783984962406,4.40165413533835,0.118276315789474,1200.62781954887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0020,a0020,Amazon Polygon 0020,-56.5,-11.5,NA,NA,2,6,0.57516957605985,0.227517278232989,0.018230067687923,4.47965799786249,0.108535447096544,1183.00320627004,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0021,a0021,Amazon Polygon 0021,-55.5,-11.5,NA,NA,2,6,0.510825076502976,0.257880298023357,0.0184726919460603,4.49994209822324,0.0874274582138211,1220.57710949869,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0022,a0022,Amazon Polygon 0022,-54.5,-11.5,NA,NA,2,6,0.487881694188864,0.278034703205448,0.0195147338426058,4.46274694902791,0.0922889434748252,1212.0752010889,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0023,a0023,Amazon Polygon 0023,-53.5,-11.5,NA,NA,2,6,0.555425406611463,0.24867891830051,0.0224132015084607,4.54773858860616,0.10696034121807,1202.62595041515,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0024,a0024,Amazon Polygon 0024,-52.5,-11.5,NA,NA,2,6,0.590901915708812,0.240373946360153,0.0237653256704981,4.7,0.0953348659003831,1219.11111111111,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0025,a0025,Amazon Polygon 0025,-51.5,-11.5,NA,NA,2,6,0.570771587743732,0.269424592120971,0.0249384003183446,4.80632709908476,0.0955849582172702,1250.71627536809,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0026,a0026,Amazon Polygon 0026,-70.5,-10.5,NA,NA,2,5,0.268586573884568,0.273290216946377,0.0155534588620549,5.11150225133033,0.137365534179288,1232.50511665984,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0027,a0027,Amazon Polygon 0027,-69.5,-10.5,NA,NA,2,5,0.255309546902415,0.270967242632211,0.0138333107995789,4.98478570186679,0.108638683442099,1228.99132282708,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0028,a0028,Amazon Polygon 0028,-68.5,-10.5,NA,NA,2,5,0.375535984392639,0.257547019074892,0.014790658312192,4.94065469673704,0.0907140872889422,1197.26259706581,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0029,a0029,Amazon Polygon 0029,-67.5,-10.5,NA,NA,2,8,0.35,0.376,0.01775,4.9,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0030,a0030,Amazon Polygon 0030,-64.5,-10.5,NA,NA,2,6,0.529973709369025,0.283845602294455,0.0171866156787763,4.35984703632887,0.100737571701721,1192.34703632887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0031,a0031,Amazon Polygon 0031,-63.5,-10.5,NA,NA,2,8,0.432643394648829,0.299053929765886,0.0166405936454849,4.67403846153846,0.112194816053512,1210.72324414716,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0032,a0032,Amazon Polygon 0032,-62.5,-10.5,NA,NA,2,6,0.494,0.243,0.016,4.7,0.105,1260,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0033,a0033,Amazon Polygon 0033,-61.5,-10.5,NA,NA,2,6,0.49244186594181,0.238797371096574,0.014983443469425,4.43026238832619,0.111291163568836,1186.34065867886,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0034,a0034,Amazon Polygon 0034,-60.5,-10.5,NA,NA,2,6,0.491073476702509,0.23670394265233,0.01958,4.50075268817204,0.163920788530466,1192.56630824373,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0035,a0035,Amazon Polygon 0035,-59.5,-10.5,NA,NA,2,5,0.461174165897482,0.210466248712498,0.0178801675803811,4.24772576654593,0.127716360263101,1188.02454954436,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0036,a0036,Amazon Polygon 0036,-58.5,-10.5,NA,NA,2,6,0.514599857223987,0.252289045767123,0.0188627956798313,4.21694322049529,0.13539388654222,1190.54806387158,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0037,a0037,Amazon Polygon 0037,-57.5,-10.5,NA,NA,2,6,0.465125610607118,0.267740753663643,0.0236287508722959,4.52194696441033,0.153891835310537,1182.19818562456,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0038,a0038,Amazon Polygon 0038,-56.5,-10.5,NA,NA,2,5,0.464903981264637,0.250442232630757,0.0205060109289617,4.61795472287276,0.125676034348165,1156.95940671351,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0039,a0039,Amazon Polygon 0039,-55.5,-10.5,NA,NA,2,6,0.505,0.253,0.0235,4.7,0.103,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0040,a0040,Amazon Polygon 0040,-54.5,-10.5,NA,NA,2,5,0.393729058561898,0.264852853965901,0.0252414751667902,4.57464788732394,0.121721645663454,1179.52928094885,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0041,a0041,Amazon Polygon 0041,-53.5,-10.5,NA,NA,2,5,0.401815985879695,0.245247932799796,0.0253594807000572,4.60263405422378,0.150477803500267,1194.09328244205,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0042,a0042,Amazon Polygon 0042,-52.5,-10.5,NA,NA,2,5,0.399637471243974,0.242709380581886,0.0238326686745709,4.72583446003614,0.150625690337864,1210.92894080837,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0043,a0043,Amazon Polygon 0043,-51.5,-10.5,NA,NA,2,6,0.618858166616901,0.205634219169901,0.0287937593311436,4.66846819946253,0.107021200358316,1230.14034040012,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0044,a0044,Amazon Polygon 0044,-71.5,-9.5,NA,NA,2,5,0.2943,0.259934782608696,0.0158695652173913,4.95608695652174,0.112786956521739,1235.52173913043,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0045,a0045,Amazon Polygon 0045,-70.5,-9.5,NA,NA,2,5,0.305387091805691,0.261167482153038,0.0162427374391191,5.02855481083927,0.136660936118321,1231.51185619382,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0046,a0046,Amazon Polygon 0046,-69.5,-9.5,NA,NA,2,7,0.179644132168629,0.313389669578428,0.0173817698442841,4.66532472464869,0.112062666160273,1175.17280668439,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0047,a0047,Amazon Polygon 0047,-68.5,-9.5,NA,NA,2,8,0.212696200292891,0.282547400081515,0.015953183856051,4.48167131689039,0.0964868885524467,1194.66360484659,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0048,a0048,Amazon Polygon 0048,-67.5,-9.5,NA,NA,2,17,0.294,0.401,0.016,4.4,0.103,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0049,a0049,Amazon Polygon 0049,-66.5,-9.5,NA,NA,2,8,0.390965537390559,0.326264148863619,0.0155160579886473,4.10831258032794,0.110196527696416,1181.08181612982,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0050,a0050,Amazon Polygon 0050,-65.5,-9.5,NA,NA,2,6,0.502480310179564,0.292924625920026,0.0149670508436175,4.08581239331415,0.0987440934990041,1196.04507161374,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0051,a0051,Amazon Polygon 0051,-64.5,-9.5,NA,NA,2,6,0.494187799505387,0.312813945287714,0.0149187115745389,4.11208667279386,0.106490502680508,1191.6781646651,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0052,a0052,Amazon Polygon 0052,-63.5,-9.5,NA,NA,2,5,0.422,0.228,0.0154,4.2,0.112,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0053,a0053,Amazon Polygon 0053,-62.5,-9.5,NA,NA,2,6,0.526723673792557,0.304761678543151,0.0146926365795724,4.13927157561362,0.135636579572447,1158.82026920032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0054,a0054,Amazon Polygon 0054,-61.5,-9.5,NA,NA,2,6,0.475837709065701,0.29394519942737,0.015715992691971,4.3700175457831,0.116479974835913,1164.29444036872,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0055,a0055,Amazon Polygon 0055,-60.5,-9.5,NA,NA,2,5,0.447614974910265,0.253068502357162,0.01506097630202,4.41817571496863,0.118908089626355,1188.45530971388,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0056,a0056,Amazon Polygon 0056,-59.5,-9.5,NA,NA,2,8,0.436,0.293,0.0156,4.4,0.119,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0057,a0057,Amazon Polygon 0057,-58.5,-9.5,NA,NA,2,8,0.373190780945213,0.311429482796364,0.0175689428738517,4.2942220707985,0.0995860169035956,1174.96904734837,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0058,a0058,Amazon Polygon 0058,-57.5,-9.5,NA,NA,2,8,0.307440996390111,0.317666280594289,0.0225546361273277,4.21207162666504,0.119468748654608,1167.99140995435,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0059,a0059,Amazon Polygon 0059,-56.5,-9.5,NA,NA,2,6,0.506473550552617,0.24092955085447,0.0195003808627664,4.56988751127002,0.117750887984349,1147.19256543143,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0060,a0060,Amazon Polygon 0060,-55.5,-9.5,NA,NA,2,8,0.361656974459725,0.309918271119843,0.0260042043222004,4.72495088408644,0.127231827111984,1144.39685658153,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0061,a0061,Amazon Polygon 0061,-54.5,-9.5,NA,NA,2,8,0.349,0.362,0.025,4.7,0.11,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0062,a0062,Amazon Polygon 0062,-53.5,-9.5,NA,NA,2,5,0.349855406244037,0.264574030049878,0.0247361279049624,4.79534808484788,0.114095044355591,1180.68561139773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0063,a0063,Amazon Polygon 0063,-52.5,-9.5,NA,NA,2,5,0.33865035510691,0.261535925271796,0.0256825678221337,4.87961449338954,0.129706389892549,1199.54266478572,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0064,a0064,Amazon Polygon 0064,-51.5,-9.5,NA,NA,2,6,0.498,0.268,0.0245,4.9,0.104,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0065,a0065,Amazon Polygon 0065,-50.5,-9.5,NA,NA,2,6,0.525777332900562,0.208962055089023,0.0241504218658141,4.83680823227603,0.101601278318499,1216.26059760822,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0066,a0066,Amazon Polygon 0066,-72.5,-8.5,NA,NA,2,8,0.308196101665935,0.278748366544917,0.0183815152392838,4.86620001626734,0.134061153724777,1229.3862292831,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0067,a0067,Amazon Polygon 0067,-71.5,-8.5,NA,NA,2,8,0.264883241943049,0.300300623375535,0.0162334923811684,5.03047408913002,0.119286187412714,1219.72116159341,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0068,a0068,Amazon Polygon 0068,-70.5,-8.5,NA,NA,2,5,0.234465406275141,0.272731697506034,0.0144447304907482,4.65398230088496,0.125496781979083,1213.52373290426,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0069,a0069,Amazon Polygon 0069,-69.5,-8.5,NA,NA,2,17,0.195,0.475,0.0187,4.5,0.129,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0070,a0070,Amazon Polygon 0070,-68.5,-8.5,NA,NA,2,8,0.284172835164074,0.310147088504925,0.0167848071918792,4.19720324027838,0.125654576915696,1182.77061513042,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0071,a0071,Amazon Polygon 0071,-67.5,-8.5,NA,NA,2,8,0.292415094339623,0.280952830188679,0.0174801886792453,4.00471698113208,0.128358490566038,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0072,a0072,Amazon Polygon 0072,-66.5,-8.5,NA,NA,2,5,0.333994414551417,0.273713230915524,0.0166014804391806,4.00638898330226,0.124824917685918,1182.2743102262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0073,a0073,Amazon Polygon 0073,-65.5,-8.5,NA,NA,2,5,0.391689886228156,0.270636335410864,0.016295352637965,4.07896382826861,0.126661592497729,1179.22209455998,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0074,a0074,Amazon Polygon 0074,-64.5,-8.5,NA,NA,2,8,0.275761382799325,0.305858347386172,0.0152971753794266,4.03537099494098,0.131158094435076,1168.42327150084,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0075,a0075,Amazon Polygon 0075,-63.5,-8.5,NA,NA,2,5,0.446589841795909,0.230337786650386,0.0158791607766828,4.09768862141198,0.136847354038952,1157.19072304322,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0076,a0076,Amazon Polygon 0076,-62.5,-8.5,NA,NA,2,6,0.485391852708602,0.303511448010119,0.0159982613780063,4.07286673656322,0.142600464137334,1155.32594619365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0077,a0077,Amazon Polygon 0077,-61.5,-8.5,NA,NA,2,8,0.39032962633452,0.345288256227758,0.0164452846975089,4.03171708185053,0.159075622775801,1152.02846975089,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0078,a0078,Amazon Polygon 0078,-60.5,-8.5,NA,NA,2,8,0.449616911764706,0.296716911764706,0.0162023897058824,4.20419117647059,0.125605882352941,1148.41544117647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0079,a0079,Amazon Polygon 0079,-59.5,-8.5,NA,NA,2,8,0.430033564013841,0.302976124567474,0.0164828719723183,4.30847750865052,0.119707958477509,1179.83737024221,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0080,a0080,Amazon Polygon 0080,-58.5,-8.5,NA,NA,2,8,0.394577675922117,0.296017847845743,0.0219717984785969,4.16831558112525,0.111375879436032,1158.48458933164,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0081,a0081,Amazon Polygon 0081,-57.5,-8.5,NA,NA,2,8,0.315638539518452,0.296398497272827,0.0217040873252256,4.25230282100439,0.125653331708667,1186.68046425431,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0082,a0082,Amazon Polygon 0082,-56.5,-8.5,NA,NA,2,6,0.483814907575956,0.273005780648467,0.020767937415412,4.37064210130148,0.124972786107768,1144.58596627468,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0083,a0083,Amazon Polygon 0083,-55.5,-8.5,NA,NA,2,8,0.421587032842893,0.290319392737938,0.0241565207003981,4.52127644933888,0.126940318506445,1121.21486336916,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0084,a0084,Amazon Polygon 0084,-54.5,-8.5,NA,NA,2,5,0.458282146473169,0.246636854539318,0.0201726628417145,4.65366182922713,0.111901788727641,1171.96085048937,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0085,a0085,Amazon Polygon 0085,-53.5,-8.5,NA,NA,2,5,0.431616948300138,0.244417809042943,0.0215428077825752,4.86602068162482,0.112193635844849,1174.86039365359,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0086,a0086,Amazon Polygon 0086,-52.5,-8.5,NA,NA,2,8,0.308990110529378,0.277067481093659,0.0239304828388598,4.89464805119255,0.109695753344968,1182.61780104712,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0087,a0087,Amazon Polygon 0087,-51.5,-8.5,NA,NA,2,8,0.406,0.338,0.0222,4.9,0.108,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0088,a0088,Amazon Polygon 0088,-50.5,-8.5,NA,NA,2,6,0.4685,0.295,0.0185,4.9,0.1,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0089,a0089,Amazon Polygon 0089,-49.5,-8.5,NA,NA,2,8,0.431,0.339,0.0169,5,0.092,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0090,a0090,Amazon Polygon 0090,-73.5,-7.5,NA,NA,2,8,0.391,0.324,0.0224,4.5,0.136,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0091,a0091,Amazon Polygon 0091,-72.5,-7.5,NA,NA,2,5,0.444441610513001,0.204659918732888,0.0266572703059183,4.3666707129805,0.118013108343385,1215.66088118286,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0092,a0092,Amazon Polygon 0092,-71.5,-7.5,NA,NA,2,5,0.386658737850952,0.272557957864953,0.0199268460635044,4.31066929344001,0.124357484483654,1219.21429426263,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0093,a0093,Amazon Polygon 0093,-70.5,-7.5,NA,NA,2,5,0.366125589077417,0.253766524780332,0.0181243697535265,4.48917334601188,0.136852753442216,1221.44094531756,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0094,a0094,Amazon Polygon 0094,-69.5,-7.5,NA,NA,2,8,0.253972444637277,0.312403365737154,0.0178998208380468,4.34265742362901,0.136120903769662,1182.20953369047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0095,a0095,Amazon Polygon 0095,-68.5,-7.5,NA,NA,2,8,0.200743368179314,0.301632325090516,0.0172303795472488,4.22280023851364,0.137691803984821,1181.03801223613,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0096,a0096,Amazon Polygon 0096,-67.5,-7.5,NA,NA,2,5,0.381922800638101,0.255151761226465,0.0196085375387342,4.09823179411313,0.135412690661849,1175.34945814459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0097,a0097,Amazon Polygon 0097,-66.5,-7.5,NA,NA,2,5,0.348184485006519,0.23294035202086,0.024803520208605,4.04439374185137,0.191614732724902,1177.87157757497,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0098,a0098,Amazon Polygon 0098,-65.5,-7.5,NA,NA,2,8,0.308420070011669,0.321481135744846,0.0307659665499806,3.96472189809413,0.169152080902373,1180.05056398289,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0099,a0099,Amazon Polygon 0099,-64.5,-7.5,NA,NA,2,5,0.351106795659845,0.254051741535766,0.0203675119637823,4.07047266919123,0.136158306477854,1174.39542714777,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0100,a0100,Amazon Polygon 0100,-63.5,-7.5,NA,NA,2,5,0.348967213114754,0.26909079445145,0.0190341740226986,4.06746532156368,0.141581336696091,1157.49054224464,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0101,a0101,Amazon Polygon 0101,-62.5,-7.5,NA,NA,2,5,0.378444493006993,0.260364073426573,0.0191657342657343,3.94291958041958,0.134450174825175,1164.74213286713,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0102,a0102,Amazon Polygon 0102,-61.5,-7.5,NA,NA,2,6,0.453149367351377,0.28299968276548,0.0227161959982204,3.88057940082181,0.151093734890761,1143.15157711345,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0103,a0103,Amazon Polygon 0103,-60.5,-7.5,NA,NA,2,8,0.373584675406836,0.329590782847593,0.0207403994178037,3.96982038909162,0.145212434772781,1148.79399666279,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0104,a0104,Amazon Polygon 0104,-59.5,-7.5,NA,NA,2,8,0.405411632262946,0.327696254382808,0.018126229491516,4.09238941624413,0.110656700148928,1151.25093690372,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0105,a0105,Amazon Polygon 0105,-58.5,-7.5,NA,NA,2,8,0.428718387571201,0.29752014655824,0.0203812926641996,4.06013174998406,0.114318209045183,1142.86488831388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0106,a0106,Amazon Polygon 0106,-57.5,-7.5,NA,NA,2,6,0.472673811569476,0.27488861900762,0.0187833172623552,4.1798953546306,0.11831492959481,1142.06634486178,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0107,a0107,Amazon Polygon 0107,-56.5,-7.5,NA,NA,2,6,0.500921888020872,0.288057685256937,0.0208270270845811,4.2068280147721,0.12062062271103,1146.91242218899,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0108,a0108,Amazon Polygon 0108,-55.5,-7.5,NA,NA,2,6,0.502766601941748,0.260951067961165,0.0187345242718447,4.44784466019418,0.126612815533981,1148.86990291262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0109,a0109,Amazon Polygon 0109,-54.5,-7.5,NA,NA,2,8,0.448037156462829,0.279485268453837,0.0204603661946344,4.58734200570774,0.123710238224751,1141.20139248498,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0110,a0110,Amazon Polygon 0110,-53.5,-7.5,NA,NA,2,5,0.405870414394448,0.272369805154135,0.023213342243383,4.74567721897063,0.121075053077005,1161.26218937101,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0111,a0111,Amazon Polygon 0111,-52.5,-7.5,NA,NA,2,5,0.423161031407032,0.260672216314762,0.0215711442273108,4.91259080863187,0.123516537823892,1174.36324277597,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0112,a0112,Amazon Polygon 0112,-51.5,-7.5,NA,NA,2,5,0.41030231838826,0.239494717325198,0.0220526448879972,4.92635660676482,0.126257567676888,1171.95394064303,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0113,a0113,Amazon Polygon 0113,-50.5,-7.5,NA,NA,2,5,0.412344678552134,0.26009508373852,0.0203463533225284,4.9,0.116281469475959,1174.65694219341,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0114,a0114,Amazon Polygon 0114,-49.5,-7.5,NA,NA,2,8,0.419,0.312,0.0186,5,0.091,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0115,a0115,Amazon Polygon 0115,-72.5,-6.5,NA,NA,2,8,0.345939206079485,0.303633795622216,0.0243704137723336,4.17603294844803,0.150050279166451,1196.53872861361,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0116,a0116,Amazon Polygon 0116,-71.5,-6.5,NA,NA,2,8,0.365716493645615,0.300526175467609,0.0226478336799038,4.22261301260796,0.147174307282635,1182.35775502717,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0117,a0117,Amazon Polygon 0117,-70.5,-6.5,NA,NA,2,8,0.305412541254125,0.315392326732673,0.0216017326732673,4.21839933993399,0.150901402640264,1205.20627062706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0118,a0118,Amazon Polygon 0118,-69.5,-6.5,NA,NA,2,8,0.34921965818152,0.289604052229818,0.0203178301890008,4.18135129314014,0.145573370106932,1184.21751984388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0119,a0119,Amazon Polygon 0119,-68.5,-6.5,NA,NA,2,5,0.348604688763137,0.253696038803557,0.0206685529506871,4.08164915117219,0.167421180274859,1176.0064672595,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0120,a0120,Amazon Polygon 0120,-67.5,-6.5,NA,NA,2,5,0.365728348805189,0.260591566985573,0.0227778287695533,4.02753760229251,0.14967491544859,1183.13628939597,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0121,a0121,Amazon Polygon 0121,-66.5,-6.5,NA,NA,2,8,0.363994422005904,0.287466842724147,0.0256279680184059,4.03136513463336,0.162374574213007,1172.78109534152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0122,a0122,Amazon Polygon 0122,-65.5,-6.5,NA,NA,2,8,0.289125427594071,0.328168757126568,0.0314795515013303,3.91022424933485,0.261543139490688,1155.68985176739,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0123,a0123,Amazon Polygon 0123,-64.5,-6.5,NA,NA,2,8,0.249266584145497,0.284162360328903,0.020971189741879,4.08993166317843,0.14584038391267,1174.72197515196,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0124,a0124,Amazon Polygon 0124,-63.5,-6.5,NA,NA,2,7,0.196579547290917,0.275370295899876,0.0199282736771132,4.11996596514939,0.150321114510502,1171.63357395483,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0125,a0125,Amazon Polygon 0125,-62.5,-6.5,NA,NA,2,5,0.244662535410765,0.274032577903683,0.0191499291784703,4.13445467422096,0.117794971671388,1159.95042492918,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0126,a0126,Amazon Polygon 0126,-61.5,-6.5,NA,NA,2,3,0.560114285714286,0.1922,0.0275228571428571,3.88285714285714,0.1474,1111.71428571429,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0127,a0127,Amazon Polygon 0127,-60.5,-6.5,NA,NA,2,8,0.388485111813259,0.358129854186806,0.0245543343694118,3.92201855126991,0.129592882908742,1138.78255735462,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0128,a0128,Amazon Polygon 0128,-59.5,-6.5,NA,NA,2,8,0.329346531302876,0.337793570219966,0.0191165143824027,4.04602368866328,0.109199323181049,1143.87140439932,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0129,a0129,Amazon Polygon 0129,-58.5,-6.5,NA,NA,2,8,0.401046897022193,0.331684073736919,0.0208013602676036,4.02297069725274,0.107369580881748,1162.37055629501,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0130,a0130,Amazon Polygon 0130,-57.5,-6.5,NA,NA,2,8,0.402082448308531,0.329085118646906,0.0205117771282756,4.05679704007993,0.120642426752595,1147.70319656278,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0131,a0131,Amazon Polygon 0131,-56.5,-6.5,NA,NA,2,8,0.403477622136805,0.311749766298696,0.0207805693787863,4.07391789389225,0.135365797214032,1141.82167733301,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0132,a0132,Amazon Polygon 0132,-55.5,-6.5,NA,NA,2,8,0.315060023085802,0.307880723355137,0.021293420546364,4.02181608310889,0.15152558676414,1134.78260869565,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0133,a0133,Amazon Polygon 0133,-54.5,-6.5,NA,NA,2,5,0.472456509042975,0.232519024079735,0.0184966023346652,4.39294157816014,0.120887602741927,1139.14116702345,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0134,a0134,Amazon Polygon 0134,-53.5,-6.5,NA,NA,2,5,0.433865380282771,0.260146140656473,0.020582968267837,4.68518820884446,0.114179586990585,1161.35344960581,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0135,a0135,Amazon Polygon 0135,-52.5,-6.5,NA,NA,2,8,0.398,0.302,0.0219,4.7,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0136,a0136,Amazon Polygon 0136,-51.5,-6.5,NA,NA,2,8,0.399,0.3,0.0223,4.7,0.11,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0137,a0137,Amazon Polygon 0137,-50.5,-6.5,NA,NA,2,8,0.375477076859613,0.293679840673366,0.0243680114404698,4.8353155320134,0.117020456632055,1162.96801551463,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0138,a0138,Amazon Polygon 0138,-49.5,-6.5,NA,NA,2,8,0.41,0.305,0.0195,4.9,0.102,1240,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0139,a0139,Amazon Polygon 0139,-48.5,-6.5,NA,NA,2,8,0.438,0.295,0.0163,5,0.084,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0140,a0140,Amazon Polygon 0140,-72.5,-5.5,NA,NA,2,8,0.316631318267378,0.293731070052168,0.0212564050324336,4.03435012014072,0.133540200221238,1204.23283989838,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0141,a0141,Amazon Polygon 0141,-71.5,-5.5,NA,NA,2,8,0.261831067264059,0.331674853274107,0.0242969500923943,4.13961911542858,0.144168750466063,1175.89916503948,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0142,a0142,Amazon Polygon 0142,-70.5,-5.5,NA,NA,2,8,0.343382487520799,0.321202787021631,0.0223361064891847,4.14968801996672,0.135537853577371,1182.25457570715,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0143,a0143,Amazon Polygon 0143,-69.5,-5.5,NA,NA,2,8,0.274067385416902,0.372217615069417,0.0230286438385721,4.12630420864217,0.1318701219462,1184.8735444809,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0144,a0144,Amazon Polygon 0144,-68.5,-5.5,NA,NA,2,8,0.376389945078158,0.339515842839037,0.0280085762568652,4.00566117448247,0.167994930291508,1190.59146599071,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0145,a0145,Amazon Polygon 0145,-67.5,-5.5,NA,NA,2,8,0.356222727272727,0.306647159090909,0.0269543181818182,4.03232954545455,0.150550568181818,1144.60227272727,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0146,a0146,Amazon Polygon 0146,-66.5,-5.5,NA,NA,2,8,0.371920323009405,0.315239792837457,0.0268064244874011,4.08748153937897,0.153513564625017,1163.25080116365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0147,a0147,Amazon Polygon 0147,-65.5,-5.5,NA,NA,2,8,0.320175685557587,0.328858500914077,0.0264373126142596,4.2209689213894,0.152609140767825,1175.46252285192,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0148,a0148,Amazon Polygon 0148,-64.5,-5.5,NA,NA,2,17,0.19,0.501,0.0244,4.1,0.15,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0149,a0149,Amazon Polygon 0149,-63.5,-5.5,NA,NA,2,17,0.151,0.531,0.021,4.2,0.148,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0150,a0150,Amazon Polygon 0150,-62.5,-5.5,NA,NA,2,7,0.162319696146734,0.283881096617385,0.02113330578884,4.10775040297384,0.137642820829614,1171.37074442068,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0151,a0151,Amazon Polygon 0151,-61.5,-5.5,NA,NA,2,17,0.231,0.456,0.0193,4,0.114,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0152,a0152,Amazon Polygon 0152,-60.5,-5.5,NA,NA,2,8,0.341970195896916,0.374434081407434,0.020952469499411,3.94210630242548,0.116940004238079,1151.01613736737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0153,a0153,Amazon Polygon 0153,-59.5,-5.5,NA,NA,2,8,0.232390243902439,0.348792682926829,0.0172573170731707,4.04268292682927,0.110219512195122,1142.19512195122,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0154,a0154,Amazon Polygon 0154,-58.5,-5.5,NA,NA,2,8,0.367328599477271,0.346718543401378,0.0163035298076339,4.16878166280633,0.105175781723714,1141.87391642773,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0155,a0155,Amazon Polygon 0155,-57.5,-5.5,NA,NA,2,8,0.357098701250047,0.3620339573164,0.0193660672959784,4.19626448101776,0.112960418923554,1149.06354993779,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0156,a0156,Amazon Polygon 0156,-56.5,-5.5,NA,NA,2,8,0.34612741653184,0.3127191263931,0.0202685715388804,4.02263168324212,0.137436727117829,1138.13882752506,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0157,a0157,Amazon Polygon 0157,-55.5,-5.5,NA,NA,2,8,0.278051742100947,0.33339098713427,0.0196052091300199,4.09188828089866,0.140839386752368,1140.87748074938,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0158,a0158,Amazon Polygon 0158,-54.5,-5.5,NA,NA,2,8,0.39464608371322,0.283622461665976,0.0203793203481144,4.24243680066308,0.117186904268545,1158.15167840862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0159,a0159,Amazon Polygon 0159,-53.5,-5.5,NA,NA,2,8,0.394302088079942,0.287042205311682,0.0185841949886112,4.44558374069444,0.104233757115698,1159.35239376196,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0160,a0160,Amazon Polygon 0160,-52.5,-5.5,NA,NA,2,8,0.398610950414417,0.285193127551434,0.0168288526619137,4.49620860509732,0.0943560255317985,1160.68634924208,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0161,a0161,Amazon Polygon 0161,-51.5,-5.5,NA,NA,2,8,0.422262532563853,0.301807108592407,0.0167985824585007,4.4886403343559,0.0944742243282384,1159.71514316469,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0162,a0162,Amazon Polygon 0162,-50.5,-5.5,NA,NA,2,8,0.370207576953433,0.318092344119968,0.0235119968429361,4.78003157063931,0.117884767166535,1167.6637726914,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0163,a0163,Amazon Polygon 0163,-49.5,-5.5,NA,NA,2,8,0.428,0.3,0.0182,4.7,0.096,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0164,a0164,Amazon Polygon 0164,-48.5,-5.5,NA,NA,2,8,0.449983009708738,0.306681692094313,0.018595665742025,4.73065187239945,0.0946463245492372,1188.93203883495,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0165,a0165,Amazon Polygon 0165,-71.5,-4.5,NA,NA,2,17,0.172,0.46,0.0438,4.2,0.119,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0166,a0166,Amazon Polygon 0166,-70.5,-4.5,NA,NA,2,7,0.180844339539162,0.326875672395628,0.0378916021208374,4.25120446069311,0.119021785409909,1183.58017266654,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0167,a0167,Amazon Polygon 0167,-69.5,-4.5,NA,NA,2,8,0.273516734693877,0.343818775510204,0.0231362448979592,4.19681632653061,0.121054285714286,1186.53469387755,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0168,a0168,Amazon Polygon 0168,-68.5,-4.5,NA,NA,2,8,0.342060798209623,0.358166728832525,0.0194925400969787,4.27907497202536,0.12147034688549,1193.32711674748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0169,a0169,Amazon Polygon 0169,-67.5,-4.5,NA,NA,2,8,0.348771046735434,0.306365616648273,0.0239883688631256,4.10847593744122,0.141212122899216,1154.67484644238,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0170,a0170,Amazon Polygon 0170,-66.5,-4.5,NA,NA,2,8,0.324960698490132,0.3012612351484,0.0265792256374342,4.20402743720121,0.142542745427422,1141.99287086459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0171,a0171,Amazon Polygon 0171,-65.5,-4.5,NA,NA,2,8,0.282513583441138,0.297124838292367,0.0212324062095731,3.95873221216041,0.128265847347995,1179.42432082794,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0172,a0172,Amazon Polygon 0172,-64.5,-4.5,NA,NA,2,7,0.19746709470305,0.290691813804173,0.01776886035313,3.97512038523274,0.137132423756019,1192.31942215088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0173,a0173,Amazon Polygon 0173,-63.5,-4.5,NA,NA,2,7,0.126954475308642,0.292680941358025,0.0181841820987654,3.78769290123457,0.126659722222222,1189.32098765432,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0174,a0174,Amazon Polygon 0174,-62.5,-4.5,NA,NA,2,4,0.163475716064757,0.273605230386052,0.0177661270236613,4.15230386052304,0.136013698630137,1161.02117061021,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0175,a0175,Amazon Polygon 0175,-61.5,-4.5,NA,NA,2,7,0.13280727212721,0.302809712941324,0.0262820949943889,3.94619143567497,0.113322670499445,1165.89946168109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0176,a0176,Amazon Polygon 0176,-60.5,-4.5,NA,NA,2,7,0.179919421487603,0.312974690082645,0.0183882747933884,4.09395661157025,0.127867768595041,1160.86260330579,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0177,a0177,Amazon Polygon 0177,-59.5,-4.5,NA,NA,2,8,0.336,0.318,0.0166,4.1,0.105,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0178,a0178,Amazon Polygon 0178,-58.5,-4.5,NA,NA,2,8,0.321262204059056,0.375463295514598,0.0144652699143677,4.09469339482078,0.104014310235251,1156.80443887106,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0179,a0179,Amazon Polygon 0179,-57.5,-4.5,NA,NA,2,8,0.415331305303557,0.366601371168554,0.0171815995710085,4.11656375020538,0.104339695117783,1157.63684320586,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0180,a0180,Amazon Polygon 0180,-56.5,-4.5,NA,NA,2,8,0.355593315895006,0.393720972354411,0.0162704985607786,4.19262089454544,0.105047794626876,1155.94914097185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0181,a0181,Amazon Polygon 0181,-55.5,-4.5,NA,NA,2,8,0.333254551700447,0.356485056681553,0.0200386808656819,4.18979732050842,0.100683613878392,1147.5334936448,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0182,a0182,Amazon Polygon 0182,-54.5,-4.5,NA,NA,2,8,0.36203836952556,0.363111520041128,0.0200708210486965,4.38380479003491,0.0977894594579951,1168.20588858607,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0183,a0183,Amazon Polygon 0183,-53.5,-4.5,NA,NA,2,8,0.412961517904864,0.307752004275788,0.0185749331908071,4.39567076429717,0.0942057723142704,1164.0994120791,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0184,a0184,Amazon Polygon 0184,-52.5,-4.5,NA,NA,2,8,0.411855537435268,0.337758914280448,0.0158014482785004,4.33425209540328,0.10255163071051,1179.34930849609,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0185,a0185,Amazon Polygon 0185,-51.5,-4.5,NA,NA,2,8,0.407422168172342,0.365154968728284,0.016791000694927,4.45868658790827,0.101891938846421,1185.28492008339,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0186,a0186,Amazon Polygon 0186,-50.5,-4.5,NA,NA,2,8,0.441613636363636,0.297163961038961,0.0201332792207792,4.79350649350649,0.102337662337662,1174.59415584416,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0187,a0187,Amazon Polygon 0187,-49.5,-4.5,NA,NA,2,8,0.444267904509284,0.319212201591512,0.0194294429708223,4.61007957559682,0.0989336870026525,1171.29973474801,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0188,a0188,Amazon Polygon 0188,-48.5,-4.5,NA,NA,2,6,0.472237000640531,0.301920428836852,0.0192040664945198,4.53387164472268,0.081042653742603,1191.18135010809,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0189,a0189,Amazon Polygon 0189,-47.5,-4.5,NA,NA,2,5,0.382,0.245,0.0164,4.9,0.075,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0190,a0190,Amazon Polygon 0190,-46.5,-4.5,NA,NA,2,8,0.439428484011334,0.358171322892075,0.0173332375996905,4.93920405875888,0.0900584877584942,1245.42093411732,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0191,a0191,Amazon Polygon 0191,-45.5,-4.5,NA,NA,2,5,0.448,0.259,0.0159,5.2,0.081,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0192,a0192,Amazon Polygon 0192,-69.5,-3.5,NA,NA,2,5,0.318452568295237,0.27335013367275,0.0429284412195275,4.30292278054564,0.131592159120715,1180.0924575863,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0193,a0193,Amazon Polygon 0193,-68.5,-3.5,NA,NA,2,8,0.289615166039776,0.302296043277158,0.0243809465206284,4.28969269797309,0.112370333047237,1179.8274509834,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0194,a0194,Amazon Polygon 0194,-67.5,-3.5,NA,NA,2,8,0.2700686321647,0.311963459336089,0.0251306205205177,4.14459388065387,0.133479905527406,1150.91269511748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0195,a0195,Amazon Polygon 0195,-66.5,-3.5,NA,NA,2,8,0.302732084799917,0.317106665959767,0.0257642142408992,4.19155826315183,0.137826048525465,1135.74955305385,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0196,a0196,Amazon Polygon 0196,-65.5,-3.5,NA,NA,2,8,0.258101936799185,0.303352701325178,0.0245166666666667,4.09964322120285,0.127257900101937,1130.76962283384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0197,a0197,Amazon Polygon 0197,-64.5,-3.5,NA,NA,2,8,0.277105975197294,0.314315670800451,0.024867305524239,4.07733934611048,0.104762495302518,1133.91206313416,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0198,a0198,Amazon Polygon 0198,-63.5,-3.5,NA,NA,2,7,0.173980475688053,0.284462404732551,0.0183109889017527,4.06681640015756,0.112112878079992,1197.74383952955,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0199,a0199,Amazon Polygon 0199,-62.5,-3.5,NA,NA,2,8,0.205569367108256,0.279964966850437,0.0228394088267051,4.11279350923955,0.113313215921889,1169.96765862445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0200,a0200,Amazon Polygon 0200,-61.5,-3.5,NA,NA,2,8,0.207130391278045,0.297064415803823,0.0195096321133073,4.07966417615082,0.105054381826692,1165.84000418523,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0201,a0201,Amazon Polygon 0201,-60.5,-3.5,NA,NA,2,7,0.174480848187578,0.33643972382086,0.0177493920338391,4.14915719674249,0.0951833241015492,1161.88606016416,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0202,a0202,Amazon Polygon 0202,-59.5,-3.5,NA,NA,2,17,0.206,0.445,0.0185,4.2,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0203,a0203,Amazon Polygon 0203,-58.5,-3.5,NA,NA,2,8,0.324809022354477,0.397831643474228,0.0147858549279727,4.12196836513106,0.103717253738994,1167.54251025312,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0204,a0204,Amazon Polygon 0204,-57.5,-3.5,NA,NA,2,16,0.360496891737772,0.400771151258777,0.0195854962555674,4.21449828935962,0.113981802402827,1182.22045084109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0205,a0205,Amazon Polygon 0205,-56.5,-3.5,NA,NA,2,9,0.466265704196725,0.359033669562661,0.0156241671891566,4.09684359417543,0.0942319636252154,1176.10157498244,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0206,a0206,Amazon Polygon 0206,-55.5,-3.5,NA,NA,2,6,0.48989805511363,0.342665064851515,0.014674402617952,4.11786563803893,0.097472504212456,1188.98461685856,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0207,a0207,Amazon Polygon 0207,-54.5,-3.5,NA,NA,2,6,0.450073758865248,0.343052482269504,0.0156248226950355,4.2090780141844,0.0934992907801418,1177.39007092199,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0208,a0208,Amazon Polygon 0208,-53.5,-3.5,NA,NA,2,16,0.370784294070405,0.401918467590509,0.0164540809953716,4.49237763605096,0.106611387152024,1179.96542957844,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0209,a0209,Amazon Polygon 0209,-52.5,-3.5,NA,NA,2,16,0.411803245436105,0.406446653144016,0.0191922515212982,4.45204868154158,0.0970085192697769,1165.39553752535,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0210,a0210,Amazon Polygon 0210,-51.5,-3.5,NA,NA,2,5,0.439,0.205,0.0184,4.6,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0211,a0211,Amazon Polygon 0211,-50.5,-3.5,NA,NA,2,8,0.444111894273128,0.336293392070485,0.0183740528634361,4.54718061674009,0.0998828193832599,1169.46696035242,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0212,a0212,Amazon Polygon 0212,-49.5,-3.5,NA,NA,2,6,0.479633160621762,0.308116062176166,0.0217348186528497,4.69139896373057,0.104853367875648,1165,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0213,a0213,Amazon Polygon 0213,-48.5,-3.5,NA,NA,2,6,0.468818388864697,0.311223015158725,0.0176027987542047,4.44463898577152,0.0863382558718974,1190.26577691576,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0214,a0214,Amazon Polygon 0214,-47.5,-3.5,NA,NA,2,5,0.467,0.207,0.0157,4.8,0.071,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0215,a0215,Amazon Polygon 0215,-46.5,-3.5,NA,NA,2,6,0.45541505595117,0.345739572736521,0.016979518480841,4.61631061376738,0.0877416073245168,1190.91217361818,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0216,a0216,Amazon Polygon 0216,-45.5,-3.5,NA,NA,2,8,0.376,0.314,0.014,5.1,0.091,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0217,a0217,Amazon Polygon 0217,-69.5,-2.5,NA,NA,2,5,0.501084205518554,0.186823977164605,0.039562226450999,4.30428163653663,0.152717411988582,1153.55851569933,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0218,a0218,Amazon Polygon 0218,-68.5,-2.5,NA,NA,2,5,0.474578107885745,0.225788409727348,0.0350460210800488,4.24778382175107,0.157631583701463,1120.71969737027,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0219,a0219,Amazon Polygon 0219,-67.5,-2.5,NA,NA,2,7,0.196220794392523,0.317254672897196,0.0251533878504673,4.2,0.134580607476636,1137.23130841121,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0220,a0220,Amazon Polygon 0220,-66.5,-2.5,NA,NA,2,8,0.226691168376192,0.320084291935551,0.030027757405747,4.18836586183917,0.142762258213817,1132.93145452059,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0221,a0221,Amazon Polygon 0221,-65.5,-2.5,NA,NA,2,7,0.185346839867306,0.290991858339675,0.0266765038387251,4.2015748646035,0.14271704441742,1105.73817449625,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0222,a0222,Amazon Polygon 0222,-64.5,-2.5,NA,NA,2,17,0.22,0.477,0.0261,4.1,0.136,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0223,a0223,Amazon Polygon 0223,-63.5,-2.5,NA,NA,2,8,0.238802126881665,0.28627569123884,0.0242921620325804,4.12534833508294,0.121304591884166,1157.52515713517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0224,a0224,Amazon Polygon 0224,-62.5,-2.5,NA,NA,2,8,0.303226557975135,0.323876468990194,0.0221805349432241,4.32238435161985,0.102009606543295,1175.28861746452,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0225,a0225,Amazon Polygon 0225,-61.5,-2.5,NA,NA,2,8,0.384794096355573,0.322833529555224,0.0162511491983126,4.58697499306154,0.103769225769498,1178.56654731473,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0226,a0226,Amazon Polygon 0226,-60.5,-2.5,NA,NA,2,8,0.391387837747938,0.333180572612777,0.0151653244823465,4.14886476578854,0.0976049802387028,1190.23849846549,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0227,a0227,Amazon Polygon 0227,-59.5,-2.5,NA,NA,2,16,0.39368801431127,0.41897030411449,0.0159848658318426,4.05656529516995,0.0781792486583184,1165.52772808587,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0228,a0228,Amazon Polygon 0228,-58.5,-2.5,NA,NA,2,16,0.436608137421665,0.40402770637311,0.0160778985219255,4.14956738462942,0.0944311173872009,1165.84296631185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0229,a0229,Amazon Polygon 0229,-57.5,-2.5,NA,NA,2,6,0.479282903641197,0.346625089658027,0.0156348479275412,4.12573829897359,0.098496227238243,1166.06664423999,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0230,a0230,Amazon Polygon 0230,-56.5,-2.5,NA,NA,2,6,0.568451904758393,0.287509378431131,0.0137057084578839,4.03121116079173,0.083103354371674,1176.84889973747,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0231,a0231,Amazon Polygon 0231,-55.5,-2.5,NA,NA,2,16,0.412741742088074,0.41123452200969,0.0159234345366853,4.10431978283066,0.100178754600689,1166.25327145647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0232,a0232,Amazon Polygon 0232,-54.5,-2.5,NA,NA,2,5,0.369,0.222,0.0165,4.6,0.124,1160,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0233,a0233,Amazon Polygon 0233,-53.5,-2.5,NA,NA,2,11,0.258783928069683,0.487778870469233,0.0174272548468671,4.49269457712841,0.107891261590334,1169.15987636977,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0234,a0234,Amazon Polygon 0234,-52.5,-2.5,NA,NA,2,5,0.47,0.243,0.0154,4.4,0.104,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0235,a0235,Amazon Polygon 0235,-51.5,-2.5,NA,NA,2,6,0.486723228995058,0.296668314113125,0.0166360241625481,4.37144426139484,0.0979077429983525,1190.0823723229,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0236,a0236,Amazon Polygon 0236,-50.5,-2.5,NA,NA,2,6,0.455851878847693,0.305996691233648,0.0185474019218788,4.43283007888501,0.109237515123583,1178.0902214773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0237,a0237,Amazon Polygon 0237,-49.5,-2.5,NA,NA,2,8,0.416494,0.330832,0.0206422,4.5,0.125394,1182.88,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0238,a0238,Amazon Polygon 0238,-48.5,-2.5,NA,NA,2,5,0.456,0.241,0.0165,4.7,0.093,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0239,a0239,Amazon Polygon 0239,-47.5,-2.5,NA,NA,2,5,0.395,0.246,0.0157,4.9,0.076,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0240,a0240,Amazon Polygon 0240,-46.5,-2.5,NA,NA,2,8,0.366523568668258,0.366549613332243,0.016339490616958,4.55215271258003,0.08033462738003,1174.40768787318,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0241,a0241,Amazon Polygon 0241,-45.5,-2.5,NA,NA,2,8,0.412,0.291,0.0167,5,0.095,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0242,a0242,Amazon Polygon 0242,-44.5,-2.5,NA,NA,2,8,0.349,0.314,0.0197,5.1,0.148,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0243,a0243,Amazon Polygon 0243,-68.5,-1.5,NA,NA,2,3,0.583286919831224,0.191196905766526,0.0204880450070324,4.24838255977496,0.147434599156118,1174.75386779184,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0244,a0244,Amazon Polygon 0244,-67.5,-1.5,NA,NA,2,8,0.359,0.338,0.0251,4.3,0.14,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0245,a0245,Amazon Polygon 0245,-66.5,-1.5,NA,NA,2,6,0.484,0.261,0.0216,4.3,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0246,a0246,Amazon Polygon 0246,-65.5,-1.5,NA,NA,2,5,0.483153846153846,0.217,0.0222769230769231,4.3,0.101076923076923,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0247,a0247,Amazon Polygon 0247,-64.5,-1.5,NA,NA,2,5,0.332199570164771,0.226728347704738,0.0229433604016956,4.15299560886021,0.109355631266316,1140.07653008428,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0248,a0248,Amazon Polygon 0248,-63.5,-1.5,NA,NA,2,8,0.283137652629851,0.275732067246036,0.0222419811718623,4.10356431250998,0.126085245743094,1156.30507181702,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0249,a0249,Amazon Polygon 0249,-62.5,-1.5,NA,NA,2,8,0.278494276944493,0.278303735285365,0.0259597767751026,4.04693747670087,0.114247037965245,1161.43611359252,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0250,a0250,Amazon Polygon 0250,-61.5,-1.5,NA,NA,2,8,0.293022662889518,0.344461756373938,0.0409393767705382,4.03371104815864,0.137597733711048,1130.22662889518,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0251,a0251,Amazon Polygon 0251,-60.5,-1.5,NA,NA,2,8,0.306637396681003,0.37073806896197,0.0180052615048106,4.13085875382976,0.0963526754981705,1179.21859014325,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0252,a0252,Amazon Polygon 0252,-59.5,-1.5,NA,NA,2,16,0.300556308615255,0.401741069547032,0.0184511341679462,4.21649253416002,0.0842416870038793,1174.29416581795,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0253,a0253,Amazon Polygon 0253,-58.5,-1.5,NA,NA,2,17,0.249196236234406,0.409889027806853,0.0169219522241721,4.25042630421649,0.0909396671003949,1176.75135849828,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0254,a0254,Amazon Polygon 0254,-57.5,-1.5,NA,NA,2,8,0.353953296510074,0.356318795150176,0.0162318951959305,4.16127921138137,0.0921185700147406,1169.03315845088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0255,a0255,Amazon Polygon 0255,-56.5,-1.5,NA,NA,2,8,0.428561397205884,0.357890819191029,0.0170443708892477,4.07668184177044,0.102229315858188,1172.03342349047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0256,a0256,Amazon Polygon 0256,-55.5,-1.5,NA,NA,2,8,0.394724258319037,0.285435050554816,0.0174574132596345,4.58042111599446,0.120983760700622,1140.94614837231,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0257,a0257,Amazon Polygon 0257,-54.5,-1.5,NA,NA,2,6,0.453466860183841,0.30700145137881,0.0147157232704403,4.44944363812288,0.0934358974358974,1168.24383164006,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0258,a0258,Amazon Polygon 0258,-53.5,-1.5,NA,NA,2,8,0.358051985792703,0.375059412334517,0.0217846625766871,4.69667420083952,0.102369066838876,1149.43816596706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0259,a0259,Amazon Polygon 0259,-52.5,-1.5,NA,NA,2,6,0.489193198804185,0.267949177877429,0.0144534379671151,4.48789237668161,0.104897608370703,1180.63153961136,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0260,a0260,Amazon Polygon 0260,-51.5,-1.5,NA,NA,2,8,0.4179221017771,0.328776241876915,0.0169746115109358,4.50445071598713,0.105085291270001,1176.97838613175,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0261,a0261,Amazon Polygon 0261,-50.5,-1.5,NA,NA,2,6,0.547492846393835,0.282247721731745,0.0208268214779869,4.51611375009776,0.101198815924279,1198.09744113304,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0262,a0262,Amazon Polygon 0262,-49.5,-1.5,NA,NA,2,6,0.4680421384336,0.314970467602685,0.0255416866979813,4.57188082717456,0.127847153682839,1192.2391132314,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0263,a0263,Amazon Polygon 0263,-48.5,-1.5,NA,NA,2,8,0.391037326388889,0.327946180555556,0.0201565972222222,4.671875,0.141463541666667,1194.19270833333,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0264,a0264,Amazon Polygon 0264,-47.5,-1.5,NA,NA,2,5,0.383,0.249,0.0161,4.9,0.102,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0265,a0265,Amazon Polygon 0265,-46.5,-1.5,NA,NA,2,5,0.365,0.271,0.0168,4.9,0.107,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0266,a0266,Amazon Polygon 0266,-45.5,-1.5,NA,NA,2,8,0.372681588447653,0.363571119133574,0.0232038989169675,4.83451263537906,0.140849097472924,1191.12635379061,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0267,a0267,Amazon Polygon 0267,-69.5,-0.5,NA,NA,2,6,0.513583189169413,0.245977740531898,0.0276737157238781,4.58843583440703,0.12858002948712,1194.93803226348,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0268,a0268,Amazon Polygon 0268,-68.5,-0.5,NA,NA,2,3,0.600080368544563,0.184909434794784,0.0266536832169823,4.45450123700453,0.13408238057271,1160.05935057225,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0269,a0269,Amazon Polygon 0269,-67.5,-0.5,NA,NA,2,6,0.497991462671745,0.274257998162199,0.0237007313136071,4.41340109443275,0.129521088572825,1136.4929430812,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0270,a0270,Amazon Polygon 0270,-66.5,-0.5,NA,NA,2,6,0.487163751757489,0.259332591217498,0.0247852706061505,4.28013241098742,0.11444026279783,1143.40517343133,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0271,a0271,Amazon Polygon 0271,-65.5,-0.5,NA,NA,2,5,0.479092105263158,0.217730263157895,0.0217730263157895,4.2,0.0977763157894737,1173.88157894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0272,a0272,Amazon Polygon 0272,-64.5,-0.5,NA,NA,2,5,0.472669608463471,0.249291511524267,0.02087983621479,4.13056551181114,0.106210734138445,1160.99596029531,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0273,a0273,Amazon Polygon 0273,-63.5,-0.5,NA,NA,2,6,0.46518007761852,0.262138086454371,0.0250127829843773,4.11123340189234,0.11280515756391,1155.37493870311,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0274,a0274,Amazon Polygon 0274,-62.5,-0.5,NA,NA,2,8,0.399849910285365,0.303517220341941,0.0301553996969191,4.09137312319897,0.116908159627452,1150.9291358209,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0275,a0275,Amazon Polygon 0275,-61.5,-0.5,NA,NA,2,8,0.401,0.296,0.0293,4.1,0.121,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0276,a0276,Amazon Polygon 0276,-60.5,-0.5,NA,NA,2,8,0.43759229436722,0.327765854198416,0.0239312319665031,4.07425046342091,0.103975187414491,1182.26604116517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0277,a0277,Amazon Polygon 0277,-59.5,-0.5,NA,NA,2,17,0.239715351812367,0.418997334754797,0.0188569829424307,4.20442430703625,0.0887681236673774,1185.07995735608,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0278,a0278,Amazon Polygon 0278,-58.5,-0.5,NA,NA,2,8,0.232,0.367,0.017,4.2,0.091,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0279,a0279,Amazon Polygon 0279,-57.5,-0.5,NA,NA,2,8,0.281511182108626,0.395685126020589,0.020892225772098,4.02744053958112,0.0987724529641463,1147.54348597799,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0280,a0280,Amazon Polygon 0280,-56.5,-0.5,NA,NA,2,8,0.333425168387214,0.385573036348581,0.0181079429907979,4.08479599600034,0.111452773708574,1167.16959626952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0281,a0281,Amazon Polygon 0281,-55.5,-0.5,NA,NA,2,8,0.367863167567993,0.389374358579361,0.0202798785670844,4.13969965062452,0.111505103338343,1159.92937182343,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0282,a0282,Amazon Polygon 0282,-54.5,-0.5,NA,NA,2,8,0.338900020480741,0.347237539346446,0.024187092972358,4.39643822949762,0.105208915705631,1174.61851509937,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0283,a0283,Amazon Polygon 0283,-53.5,-0.5,NA,NA,2,8,0.355,0.28,0.0153,4.5,0.098,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0284,a0284,Amazon Polygon 0284,-52.5,-0.5,NA,NA,2,8,0.339034131922173,0.374604688011251,0.0156990635612464,4.42961377701112,0.103277610183329,1204.46796846706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0285,a0285,Amazon Polygon 0285,-51.5,-0.5,NA,NA,2,8,0.372166159029789,0.380014992408354,0.0220836014901674,4.63160218234417,0.146076665566285,1177.6541729892,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0286,a0286,Amazon Polygon 0286,-50.5,-0.5,NA,NA,2,6,0.487482056944867,0.322890399180772,0.0234138451341345,4.56961782065618,0.120102198797205,1192.29829864262,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0287,a0287,Amazon Polygon 0287,-49.5,-0.5,NA,NA,2,5,0.4075,0.242,0.0301,5,0.17,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0288,a0288,Amazon Polygon 0288,-48.5,-0.5,NA,NA,2,8,0.410034389140271,0.337929411764706,0.0235811764705882,4.7020814479638,0.14496742081448,1174.00904977376,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0289,a0289,Amazon Polygon 0289,-69.5,0.5,NA,NA,2,6,0.518,0.244,0.024,4.5,0.124,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0290,a0290,Amazon Polygon 0290,-68.5,0.5,NA,NA,2,6,0.556031275302543,0.213491255142449,0.0269094765332795,4.77052293091954,0.128356794829367,1199.06133779691,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0291,a0291,Amazon Polygon 0291,-67.5,0.5,NA,NA,2,6,0.531345964496635,0.243997191584387,0.0252805275869034,4.58959693238905,0.12274820262963,1138.82061016445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0292,a0292,Amazon Polygon 0292,-66.5,0.5,NA,NA,2,6,0.548215196717419,0.224407028928467,0.0271229074631325,4.43939775224795,0.109745421821456,1113.94872134619,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0293,a0293,Amazon Polygon 0293,-65.5,0.5,NA,NA,2,6,0.484765179678734,0.256514100828391,0.0282823256655113,4.14867339135671,0.114060992235232,1143.58311648962,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0294,a0294,Amazon Polygon 0294,-64.5,0.5,NA,NA,2,6,0.487010403492551,0.258904649364713,0.0268010597810063,4.10729350353887,0.118673620957919,1124.26391973434,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0295,a0295,Amazon Polygon 0295,-63.5,0.5,NA,NA,2,5,0.490013881177124,0.223543586896169,0.0233667962243198,4.29244863964464,0.111192670738479,1171.7157134925,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0296,a0296,Amazon Polygon 0296,-62.5,0.5,NA,NA,2,6,0.483,0.261,0.0177,4.8,0.127,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0297,a0297,Amazon Polygon 0297,-61.5,0.5,NA,NA,2,6,0.490005479452055,0.286574429223744,0.0155687671232877,4.6,0.115645662100457,1239.25114155251,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0298,a0298,Amazon Polygon 0298,-60.5,0.5,NA,NA,2,8,0.422827388919844,0.29860800842063,0.0148668648048191,4.45877357340052,0.10206694774671,1226.64877103883,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0299,a0299,Amazon Polygon 0299,-59.5,0.5,NA,NA,2,8,0.35218276921012,0.332975825521394,0.0176846653881449,4.36719699243703,0.103102231226806,1209.98824400904,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0300,a0300,Amazon Polygon 0300,-58.5,0.5,NA,NA,2,8,0.363830388886367,0.307647710465354,0.0175809224486845,4.43911678729251,0.103051225392196,1189.58270236001,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0301,a0301,Amazon Polygon 0301,-57.5,0.5,NA,NA,2,8,0.354931842769564,0.343516768842409,0.0181821853588172,4.35708618824378,0.100027046520014,1219.78723404255,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0302,a0302,Amazon Polygon 0302,-56.5,0.5,NA,NA,2,8,0.377,0.279,0.0156,4.5,0.098,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0303,a0303,Amazon Polygon 0303,-55.5,0.5,NA,NA,2,8,0.35,0.292,0.0178,4.5,0.1,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0304,a0304,Amazon Polygon 0304,-54.5,0.5,NA,NA,2,8,0.326,0.309,0.0184,4.5,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0305,a0305,Amazon Polygon 0305,-53.5,0.5,NA,NA,2,8,0.323365210127657,0.370095805707387,0.0187482045535554,4.48093786377005,0.0996940546590494,1195.62742007063,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0306,a0306,Amazon Polygon 0306,-52.5,0.5,NA,NA,2,8,0.292867015931683,0.397491722254934,0.0192186303907941,4.4352519463437,0.103649205072188,1202.97149068891,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0307,a0307,Amazon Polygon 0307,-51.5,0.5,NA,NA,2,8,0.354676744608013,0.342080412276782,0.0198860758037557,4.59291576539618,0.104769497337053,1216.29109710547,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0308,a0308,Amazon Polygon 0308,-69.5,1.5,NA,NA,2,6,0.526,0.24,0.024,4.5,0.097,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0309,a0309,Amazon Polygon 0309,-68.5,1.5,NA,NA,2,6,0.52253906795127,0.205054553070751,0.0427814812837994,4.66687109294238,0.126099018640665,1194.61921079365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0310,a0310,Amazon Polygon 0310,-67.5,1.5,NA,NA,2,6,0.561091043671355,0.20421021465581,0.0270715025906736,4.8,0.125521835677276,1167.21687638786,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0311,a0311,Amazon Polygon 0311,-63.5,1.5,NA,NA,2,8,0.42494387755102,0.300469023323615,0.0162231413994169,4.46344752186589,0.11184584548105,1160.36807580175,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0312,a0312,Amazon Polygon 0312,-62.5,1.5,NA,NA,2,5,0.461726939264444,0.258288962317539,0.0154604370768904,4.66603356058363,0.108984270747554,1194.30671490346,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0313,a0313,Amazon Polygon 0313,-61.5,1.5,NA,NA,2,6,0.491579346398351,0.244625519219408,0.0134864468276648,4.76323965635835,0.117913015594765,1223.94573462479,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0314,a0314,Amazon Polygon 0314,-60.5,1.5,NA,NA,2,6,0.504332049917661,0.253297503740243,0.0135588157703226,4.78218311497323,0.0964585250071972,1215.72461292972,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0315,a0315,Amazon Polygon 0315,-59.5,1.5,NA,NA,2,6,0.481927994873695,0.255205541384766,0.0150356642601167,4.74670830089643,0.103511291584974,1207.44096428706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0316,a0316,Amazon Polygon 0316,-57.5,1.5,NA,NA,2,8,0.320494450050454,0.381883955600404,0.0240853683148335,4.43296333669694,0.130706020854356,1230.91153716784,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0317,a0317,Amazon Polygon 0317,-56.5,1.5,NA,NA,2,8,0.379,0.278,0.0166,4.6,0.102,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0318,a0318,Amazon Polygon 0318,-55.5,1.5,NA,NA,2,5,0.392,0.263,0.0161,4.6,0.101,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0319,a0319,Amazon Polygon 0319,-54.5,1.5,NA,NA,2,8,0.350395925297114,0.379331069609508,0.0170010526315789,4.57011884550085,0.100765365025467,1205.64006791171,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0320,a0320,Amazon Polygon 0320,-53.5,1.5,NA,NA,2,8,0.33561267805929,0.378876602523137,0.017076443885941,4.53922886608355,0.0972183506159432,1210.01906683005,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0321,a0321,Amazon Polygon 0321,-52.5,1.5,NA,NA,2,8,0.335149100257069,0.374988982739625,0.0183976496511201,4.54168196841719,0.117102093279471,1219.54829232464,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0322,a0322,Amazon Polygon 0322,-51.5,1.5,NA,NA,2,8,0.342559043915282,0.375207384619859,0.0198429336435915,4.53589145059832,0.111399201408253,1218.60642701711,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0323,a0323,Amazon Polygon 0323,-50.5,1.5,NA,NA,2,8,0.334285904255319,0.309539893617021,0.0247304521276596,4.85345744680851,0.195167553191489,747.114361702128,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0324,a0324,Amazon Polygon 0324,-63.5,2.5,NA,NA,2,5,0.394,0.267,0.0229,4.2,0.106,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0325,a0325,Amazon Polygon 0325,-62.5,2.5,NA,NA,2,8,0.373555616051848,0.347475527485543,0.0166705535882847,4.47090601554171,0.110173448007595,1154.31042803282,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0326,a0326,Amazon Polygon 0326,-61.5,2.5,NA,NA,2,6,0.474488977350501,0.284508323716426,0.0158915215631065,4.71459515869303,0.0970353676585795,1191.61066134685,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0327,a0327,Amazon Polygon 0327,-60.5,2.5,NA,NA,2,6,0.595486028789162,0.217139712108383,0.0127133361558002,4.97417442845047,0.0982561388653683,1264.29297205758,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0328,a0328,Amazon Polygon 0328,-52.5,2.5,NA,NA,2,8,0.363187161639598,0.365375870069606,0.0310636117556071,4.62965970610982,0.129161252900232,1214.36194895592,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0329,a0329,Amazon Polygon 0329,-51.5,2.5,NA,NA,2,8,0.357012872350827,0.354746872110307,0.0213451569559534,4.58902910482537,0.143151406767849,1205.39553680222,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0330,a0330,Amazon Polygon 0330,-63.5,3.5,NA,NA,2,8,0.361,0.281,0.0224,4.1,0.117,1120,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0331,a0331,Amazon Polygon 0331,-62.5,3.5,NA,NA,2,8,0.346073414671842,0.369487859609459,0.0177165198541867,4.37372537735457,0.10968214765377,1131.10602529551,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0332,a0332,Amazon Polygon 0332,-61.5,3.5,NA,NA,2,6,0.479615694573823,0.293875810816361,0.0152221313921233,4.85439423856933,0.110973840211288,1214.41237963628,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0333,a0333,Amazon Polygon 0333,-60.5,3.5,NA,NA,2,6,0.498,0.26,0.0101,5.3,0.153,1320,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0334,a0334,Amazon Polygon 0334,-51.5,3.5,NA,NA,2,8,0.359,0.366,0.0225,4.6,0.123,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0335,a0335,Amazon Polygon 0335,-60.5,4.5,NA,NA,2,5,0.442668521094112,0.255291608715809,0.0228799258229022,5.36764024107557,0.13246314325452,1224.35790449699,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0336,a0336,Amazon Polygon 0336,-59.5,-11.5,NA,NA,2,6,0.531965811840757,0.243728325972639,0.0187127669238973,4.4686539658477,0.108225292926799,1211.32454358169,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0337,a0337,Amazon Polygon 0337,-58.5,-12.5,NA,NA,2,3,0.754084244600303,0.15137239297781,0.0138599813936637,4.61700499339524,0.094790242484175,1221.66075690442,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0338,a0338,Amazon Polygon 0338,-51.5,-12.5,NA,NA,2,6,0.604934210526316,0.241301619433198,0.0233360829959514,4.81376518218624,0.092747975708502,1230.43016194332,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0339,a0339,Amazon Polygon 0339,-54.5,-13.5,NA,NA,2,6,0.604719512195122,0.254965447154472,0.0216197154471545,4.8,0.106475609756098,1225.91463414634,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZBR_0340,a0340,Amazon Polygon 0340,-46.5,-5.5,NA,NA,2,6,0.568910083727703,0.251582089552239,0.0157911175828176,4.90910083727703,0.0982085911903895,1276.40698944303,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0341,a0341,Amazon Polygon 0341,-59.5,-12.5,NA,NA,2,3,0.668453719723183,0.181541522491349,0.0159257352941176,4.6780276816609,0.103732698961938,1216.35813148789,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0342,a0342,Amazon Polygon 0342,-59.5,-13.5,NA,NA,2,3,0.699488842211707,0.186988779988865,0.0157302321721259,4.91277867918269,0.087079116612656,1214.97471074384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0343,a0343,Amazon Polygon 0343,-53.5,-13.5,NA,NA,2,6,0.556761283851555,0.280124373119358,0.0183568706118355,5.03019057171515,0.0786880641925777,1240.33099297894,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0344,a0344,Amazon Polygon 0344,-53.5,2.5,NA,NA,2,8,0.307401814058957,0.396586848072562,0.0224716553287982,4.62208616780045,0.108532426303855,1201.46031746032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0345,a0345,Amazon Polygon 0345,-73.5,-6.5,NA,NA,2,8,0.38418927140332,0.323272575377048,0.0253926179596497,4.18006928075437,0.134395888997171,1213.40132840139,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0346,a0346,Amazon Polygon 0346,-65.5,-11.5,NA,NA,2,8,0.436925311203319,0.291680497925311,0.0164742738589212,4.73112033195021,0.10660857538036,1211.53526970954,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0347,a0347,Amazon Polygon 0347,-69.5,-1.5,NA,NA,2,3,0.566508552631579,0.187552631578947,0.02448125,4.32605263157895,0.137514473684211,1178.75657894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZBR_0348,a0348,Amazon Polygon 0348,-59.5,4.5,NA,NA,2,8,0.41111091393079,0.277334516415262,0.0196432120674357,5.4318544809228,0.129808340727595,1221.20674356699,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZBR_0349,a0349,Amazon Polygon 0349,-50.5,-10.5,NA,NA,2,6,0.568891694352159,0.229058803986711,0.025399634551495,4.89614617940199,0.106660465116279,1234.76079734219,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZBR_0350,a0350,Amazon Polygon 0350,-50.5,0.5,NA,NA,2,8,0.339461871069182,0.341968553459119,0.0205159591194969,4.81088836477987,0.145310927672956,1209.13128930818,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 diff --git a/R-utils/amzif_poi.csv b/R-utils/amzif_poi.csv new file mode 100644 index 000000000..3b569db43 --- /dev/null +++ b/R-utils/amzif_poi.csv @@ -0,0 +1,351 @@ +short,iata,longname,lon,lat,alt,wmo,isoilflg,istext,sand,clay,slsoc,slph,slcec,sldbd,depth,isoilbc,sldrain,scolour,met.driver,yeara,yearz,iphen,iage +AMZIF_0001,i0001,Amazon Intact 0001,-61.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0002,i0002,Amazon Intact 0002,-60.5,-13.5,NA,NA,2,3,0.614,0.173,0.0179,5.2,0.099,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0003,i0003,Amazon Intact 0003,-63.5,-12.5,NA,NA,2,6,0.495,0.262,0.016,5,0.086,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0004,i0004,Amazon Intact 0004,-62.5,-12.5,NA,NA,2,6,0.532827158181877,0.223343203931085,0.0151842159320799,4.81890525820088,0.0924997073894,1223.15593565532,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0005,i0005,Amazon Intact 0005,-61.5,-12.5,NA,NA,2,6,0.450731520182141,0.306403635818869,0.0183703078468289,4.88934097681909,0.0847669342966816,1220.75569914233,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0006,i0006,Amazon Intact 0006,-60.5,-12.5,NA,NA,2,3,0.612,0.161,0.017,5,0.083,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0007,i0007,Amazon Intact 0007,-57.5,-12.5,NA,NA,2,3,0.688,0.106,0.0165,4.5,0.101,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0008,i0008,Amazon Intact 0008,-56.5,-12.5,NA,NA,2,3,0.606,0.148,0.0193,4.8,0.119,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0009,i0009,Amazon Intact 0009,-55.5,-12.5,NA,NA,2,3,0.589,0.157,0.0202,4.9,0.103,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0010,i0010,Amazon Intact 0010,-54.5,-12.5,NA,NA,2,6,0.588931216931217,0.262272927689594,0.0225351851851852,4.77416225749559,0.0949766313932981,1217.7557319224,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0011,i0011,Amazon Intact 0011,-53.5,-12.5,NA,NA,2,6,0.599319673617407,0.255952493200363,0.0254086854034451,4.85642792384406,0.0997787851314597,1223.12420670898,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0012,i0012,Amazon Intact 0012,-52.5,-12.5,NA,NA,2,6,0.612817371143214,0.240545211342964,0.0232944533618691,4.87788478687355,0.0945580524344569,1232.01533797039,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0013,i0013,Amazon Intact 0013,-64.5,-11.5,NA,NA,2,6,0.479828543080773,0.284419945311968,0.0166047393115583,4.81936043008105,0.100291496056211,1195.82545471844,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0014,i0014,Amazon Intact 0014,-63.5,-11.5,NA,NA,2,6,0.485,0.257,0.0158,4.9,0.106,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0015,i0015,Amazon Intact 0015,-62.5,-11.5,NA,NA,2,6,0.501,0.249,0.0156,4.8,0.097,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0016,i0016,Amazon Intact 0016,-61.5,-11.5,NA,NA,2,6,0.523848657024793,0.226321280991736,0.0169982954545455,4.49927685950413,0.124055785123967,1184.70041322314,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0017,i0017,Amazon Intact 0017,-60.5,-11.5,NA,NA,2,6,0.497783881692461,0.240416956240693,0.0196677284365722,4.45150152401207,0.126352349579395,1200.16621915694,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0018,i0018,Amazon Intact 0018,-58.5,-11.5,NA,NA,2,3,0.693155778355077,0.173519040956307,0.0190220585730911,4.49683832001874,0.093880134066002,1204.17132873688,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0019,i0019,Amazon Intact 0019,-57.5,-11.5,NA,NA,2,3,0.645,0.148,0.0169,4.6,0.108,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0020,i0020,Amazon Intact 0020,-56.5,-11.5,NA,NA,2,3,0.604,0.168,0.0182,4.6,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0021,i0021,Amazon Intact 0021,-55.5,-11.5,NA,NA,2,3,0.569,0.193,0.0185,4.6,0.094,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0022,i0022,Amazon Intact 0022,-54.5,-11.5,NA,NA,2,6,0.492119074281448,0.276775662560657,0.0195657334826428,4.45733482642777,0.0928402388951101,1212.03807390817,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0023,i0023,Amazon Intact 0023,-53.5,-11.5,NA,NA,2,6,0.556383399980493,0.248132351506876,0.0224636399102702,4.54969277284697,0.106959816639032,1202.66068467766,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0024,i0024,Amazon Intact 0024,-52.5,-11.5,NA,NA,2,6,0.590901915708812,0.240373946360153,0.0237653256704981,4.7,0.0953348659003831,1219.11111111111,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0025,i0025,Amazon Intact 0025,-51.5,-11.5,NA,NA,2,3,0.577,0.185,0.0223,5,0.098,1280,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0026,i0026,Amazon Intact 0026,-70.5,-10.5,NA,NA,2,5,0.268586573884568,0.273290216946377,0.0155534588620549,5.11150225133033,0.137365534179288,1232.50511665984,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0027,i0027,Amazon Intact 0027,-69.5,-10.5,NA,NA,2,5,0.255309546902415,0.270967242632211,0.0138333107995789,4.98478570186679,0.108638683442099,1228.99132282708,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0028,i0028,Amazon Intact 0028,-68.5,-10.5,NA,NA,2,8,0.406,0.381,0.0143,4.8,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0029,i0029,Amazon Intact 0029,-67.5,-10.5,NA,NA,2,8,0.35,0.376,0.01775,4.9,0.091,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0030,i0030,Amazon Intact 0030,-64.5,-10.5,NA,NA,2,6,0.529973709369025,0.283845602294455,0.0171866156787763,4.35984703632887,0.100737571701721,1192.34703632887,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0031,i0031,Amazon Intact 0031,-63.5,-10.5,NA,NA,2,8,0.432643394648829,0.299053929765886,0.0166405936454849,4.67403846153846,0.112194816053512,1210.72324414716,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0032,i0032,Amazon Intact 0032,-62.5,-10.5,NA,NA,2,6,0.494,0.243,0.016,4.7,0.105,1260,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0033,i0033,Amazon Intact 0033,-61.5,-10.5,NA,NA,2,6,0.49244186594181,0.238797371096574,0.014983443469425,4.43026238832619,0.111291163568836,1186.34065867886,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0034,i0034,Amazon Intact 0034,-60.5,-10.5,NA,NA,2,6,0.491073476702509,0.23670394265233,0.01958,4.50075268817204,0.163920788530466,1192.56630824373,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0035,i0035,Amazon Intact 0035,-59.5,-10.5,NA,NA,2,5,0.461174165897482,0.210466248712498,0.0178801675803811,4.24772576654593,0.127716360263101,1188.02454954436,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0036,i0036,Amazon Intact 0036,-58.5,-10.5,NA,NA,2,6,0.496,0.262,0.0189,4.4,0.113,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0037,i0037,Amazon Intact 0037,-57.5,-10.5,NA,NA,2,6,0.512,0.238,0.0209,4.6,0.144,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0038,i0038,Amazon Intact 0038,-56.5,-10.5,NA,NA,2,6,0.502,0.251,0.0217,4.7,0.118,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0039,i0039,Amazon Intact 0039,-55.5,-10.5,NA,NA,2,6,0.505,0.253,0.0235,4.7,0.103,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0040,i0040,Amazon Intact 0040,-54.5,-10.5,NA,NA,2,8,0.436,0.299,0.0229,4.7,0.107,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0041,i0041,Amazon Intact 0041,-53.5,-10.5,NA,NA,2,5,0.402522463234624,0.243850803832543,0.025400373492383,4.59887601936764,0.150494617704104,1194.2512709253,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0042,i0042,Amazon Intact 0042,-52.5,-10.5,NA,NA,2,5,0.399637471243974,0.242709380581886,0.0238326686745709,4.72583446003614,0.150625690337864,1210.92894080837,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0043,i0043,Amazon Intact 0043,-51.5,-10.5,NA,NA,2,6,0.549,0.238,0.0247,5,0.104,1280,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0044,i0044,Amazon Intact 0044,-71.5,-9.5,NA,NA,2,11,0.281,0.455,0.017,5.3,0.14,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0045,i0045,Amazon Intact 0045,-70.5,-9.5,NA,NA,2,5,0.305348457483086,0.261165160140003,0.0162451771355698,5.03126122777269,0.137244831040208,1230.80489335802,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0046,i0046,Amazon Intact 0046,-69.5,-9.5,NA,NA,2,7,0.179644132168629,0.313389669578428,0.0173817698442841,4.66532472464869,0.112062666160273,1175.17280668439,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0047,i0047,Amazon Intact 0047,-68.5,-9.5,NA,NA,2,11,0.247,0.466,0.0157,4.5,0.1,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0048,i0048,Amazon Intact 0048,-67.5,-9.5,NA,NA,2,17,0.294,0.401,0.016,4.4,0.103,1210,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0049,i0049,Amazon Intact 0049,-66.5,-9.5,NA,NA,2,8,0.390965537390559,0.326264148863619,0.0155160579886473,4.10831258032794,0.110196527696416,1181.08181612982,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0050,i0050,Amazon Intact 0050,-65.5,-9.5,NA,NA,2,6,0.502480310179564,0.292924625920026,0.0149670508436175,4.08581239331415,0.0987440934990041,1196.04507161374,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0051,i0051,Amazon Intact 0051,-64.5,-9.5,NA,NA,2,6,0.494187799505387,0.312813945287714,0.0149187115745389,4.11208667279386,0.106490502680508,1191.6781646651,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0052,i0052,Amazon Intact 0052,-63.5,-9.5,NA,NA,2,5,0.422,0.228,0.0154,4.2,0.112,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0053,i0053,Amazon Intact 0053,-62.5,-9.5,NA,NA,2,6,0.526723673792557,0.304761678543151,0.0146926365795724,4.13927157561362,0.135636579572447,1158.82026920032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0054,i0054,Amazon Intact 0054,-61.5,-9.5,NA,NA,2,6,0.475837709065701,0.29394519942737,0.015715992691971,4.3700175457831,0.116479974835913,1164.29444036872,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0055,i0055,Amazon Intact 0055,-60.5,-9.5,NA,NA,2,5,0.442820171430543,0.255906432266955,0.0147556308949299,4.41158322892077,0.11992612198258,1187.18252216066,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0056,i0056,Amazon Intact 0056,-59.5,-9.5,NA,NA,2,8,0.436,0.293,0.0156,4.4,0.119,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0057,i0057,Amazon Intact 0057,-58.5,-9.5,NA,NA,2,8,0.426,0.303,0.0174,4.5,0.109,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0058,i0058,Amazon Intact 0058,-57.5,-9.5,NA,NA,2,8,0.415,0.282,0.0209,4.5,0.116,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0059,i0059,Amazon Intact 0059,-56.5,-9.5,NA,NA,2,6,0.473,0.254,0.022,4.6,0.115,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0060,i0060,Amazon Intact 0060,-55.5,-9.5,NA,NA,2,8,0.361656974459725,0.309918271119843,0.0260042043222004,4.72495088408644,0.127231827111984,1144.39685658153,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0061,i0061,Amazon Intact 0061,-54.5,-9.5,NA,NA,2,8,0.349,0.362,0.025,4.7,0.11,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0062,i0062,Amazon Intact 0062,-53.5,-9.5,NA,NA,2,5,0.349855406244037,0.264574030049878,0.0247361279049624,4.79534808484788,0.114095044355591,1180.68561139773,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0063,i0063,Amazon Intact 0063,-52.5,-9.5,NA,NA,2,5,0.33865035510691,0.261535925271796,0.0256825678221337,4.87961449338954,0.129706389892549,1199.54266478572,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0064,i0064,Amazon Intact 0064,-51.5,-9.5,NA,NA,2,6,0.498,0.268,0.0245,4.9,0.104,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0065,i0065,Amazon Intact 0065,-50.5,-9.5,NA,NA,2,6,0.507,0.274,0.0237,4.8,0.096,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0066,i0066,Amazon Intact 0066,-72.5,-8.5,NA,NA,2,8,0.308196101665935,0.278748366544917,0.0183815152392838,4.86620001626734,0.134061153724777,1229.3862292831,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0067,i0067,Amazon Intact 0067,-71.5,-8.5,NA,NA,2,8,0.264883241943049,0.300300623375535,0.0162334923811684,5.03047408913002,0.119286187412714,1219.72116159341,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0068,i0068,Amazon Intact 0068,-70.5,-8.5,NA,NA,2,11,0.235,0.473,0.0154,4.7,0.125,1200,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0069,i0069,Amazon Intact 0069,-69.5,-8.5,NA,NA,2,17,0.195,0.475,0.0187,4.5,0.129,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0070,i0070,Amazon Intact 0070,-68.5,-8.5,NA,NA,2,8,0.284172835164074,0.310147088504925,0.0167848071918792,4.19720324027838,0.125654576915696,1182.77061513042,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0071,i0071,Amazon Intact 0071,-67.5,-8.5,NA,NA,2,8,0.292415094339623,0.280952830188679,0.0174801886792453,4.00471698113208,0.128358490566038,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0072,i0072,Amazon Intact 0072,-66.5,-8.5,NA,NA,2,5,0.333994414551417,0.273713230915524,0.0166014804391806,4.00638898330226,0.124824917685918,1182.2743102262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0073,i0073,Amazon Intact 0073,-65.5,-8.5,NA,NA,2,5,0.391689886228156,0.270636335410864,0.016295352637965,4.07896382826861,0.126661592497729,1179.22209455998,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0074,i0074,Amazon Intact 0074,-64.5,-8.5,NA,NA,2,8,0.275761382799325,0.305858347386172,0.0152971753794266,4.03537099494098,0.131158094435076,1168.42327150084,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0075,i0075,Amazon Intact 0075,-63.5,-8.5,NA,NA,2,5,0.44463884957865,0.229491292024114,0.0159032543220568,4.10166668675833,0.137151642422065,1157.3308357903,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0076,i0076,Amazon Intact 0076,-62.5,-8.5,NA,NA,2,6,0.485391852708602,0.303511448010119,0.0159982613780063,4.07286673656322,0.142600464137334,1155.32594619365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0077,i0077,Amazon Intact 0077,-61.5,-8.5,NA,NA,2,8,0.39032962633452,0.345288256227758,0.0164452846975089,4.03171708185053,0.159075622775801,1152.02846975089,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0078,i0078,Amazon Intact 0078,-60.5,-8.5,NA,NA,2,8,0.449616911764706,0.296716911764706,0.0162023897058824,4.20419117647059,0.125605882352941,1148.41544117647,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0079,i0079,Amazon Intact 0079,-59.5,-8.5,NA,NA,2,8,0.430033564013841,0.302976124567474,0.0164828719723183,4.30847750865052,0.119707958477509,1179.83737024221,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0080,i0080,Amazon Intact 0080,-58.5,-8.5,NA,NA,2,8,0.394577675922117,0.296017847845743,0.0219717984785969,4.16831558112525,0.111375879436032,1158.48458933164,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0081,i0081,Amazon Intact 0081,-57.5,-8.5,NA,NA,2,8,0.315638539518452,0.296398497272827,0.0217040873252256,4.25230282100439,0.125653331708667,1186.68046425431,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0082,i0082,Amazon Intact 0082,-56.5,-8.5,NA,NA,2,6,0.483814907575956,0.273005780648467,0.020767937415412,4.37064210130148,0.124972786107768,1144.58596627468,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0083,i0083,Amazon Intact 0083,-55.5,-8.5,NA,NA,2,8,0.421587032842893,0.290319392737938,0.0241565207003981,4.52127644933888,0.126940318506445,1121.21486336916,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0084,i0084,Amazon Intact 0084,-54.5,-8.5,NA,NA,2,5,0.458282146473169,0.246636854539318,0.0201726628417145,4.65366182922713,0.111901788727641,1171.96085048937,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0085,i0085,Amazon Intact 0085,-53.5,-8.5,NA,NA,2,5,0.431616948300138,0.244417809042943,0.0215428077825752,4.86602068162482,0.112193635844849,1174.86039365359,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0086,i0086,Amazon Intact 0086,-52.5,-8.5,NA,NA,2,8,0.308990110529378,0.277067481093659,0.0239304828388598,4.89464805119255,0.109695753344968,1182.61780104712,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0087,i0087,Amazon Intact 0087,-51.5,-8.5,NA,NA,2,8,0.406,0.338,0.0222,4.9,0.108,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0088,i0088,Amazon Intact 0088,-50.5,-8.5,NA,NA,2,6,0.4685,0.295,0.0185,4.9,0.1,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0089,i0089,Amazon Intact 0089,-49.5,-8.5,NA,NA,2,8,0.431,0.339,0.0169,5,0.092,1230,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0090,i0090,Amazon Intact 0090,-73.5,-7.5,NA,NA,2,8,0.391,0.324,0.0224,4.5,0.136,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0091,i0091,Amazon Intact 0091,-72.5,-7.5,NA,NA,2,5,0.444441610513001,0.204659918732888,0.0266572703059183,4.3666707129805,0.118013108343385,1215.66088118286,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0092,i0092,Amazon Intact 0092,-71.5,-7.5,NA,NA,2,5,0.386658737850952,0.272557957864953,0.0199268460635044,4.31066929344001,0.124357484483654,1219.21429426263,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0093,i0093,Amazon Intact 0093,-70.5,-7.5,NA,NA,2,5,0.366125589077417,0.253766524780332,0.0181243697535265,4.48917334601188,0.136852753442216,1221.44094531756,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0094,i0094,Amazon Intact 0094,-69.5,-7.5,NA,NA,2,8,0.253972444637277,0.312403365737154,0.0178998208380468,4.34265742362901,0.136120903769662,1182.20953369047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0095,i0095,Amazon Intact 0095,-68.5,-7.5,NA,NA,2,8,0.200743368179314,0.301632325090516,0.0172303795472488,4.22280023851364,0.137691803984821,1181.03801223613,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0096,i0096,Amazon Intact 0096,-67.5,-7.5,NA,NA,2,5,0.381922800638101,0.255151761226465,0.0196085375387342,4.09823179411313,0.135412690661849,1175.34945814459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0097,i0097,Amazon Intact 0097,-66.5,-7.5,NA,NA,2,5,0.348184485006519,0.23294035202086,0.024803520208605,4.04439374185137,0.191614732724902,1177.87157757497,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0098,i0098,Amazon Intact 0098,-65.5,-7.5,NA,NA,2,8,0.308420070011669,0.321481135744846,0.0307659665499806,3.96472189809413,0.169152080902373,1180.05056398289,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0099,i0099,Amazon Intact 0099,-64.5,-7.5,NA,NA,2,5,0.351106795659845,0.254051741535766,0.0203675119637823,4.07047266919123,0.136158306477854,1174.39542714777,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0100,i0100,Amazon Intact 0100,-63.5,-7.5,NA,NA,2,5,0.348967213114754,0.26909079445145,0.0190341740226986,4.06746532156368,0.141581336696091,1157.49054224464,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0101,i0101,Amazon Intact 0101,-62.5,-7.5,NA,NA,2,5,0.378444493006993,0.260364073426573,0.0191657342657343,3.94291958041958,0.134450174825175,1164.74213286713,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0102,i0102,Amazon Intact 0102,-61.5,-7.5,NA,NA,2,6,0.453149367351377,0.28299968276548,0.0227161959982204,3.88057940082181,0.151093734890761,1143.15157711345,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0103,i0103,Amazon Intact 0103,-60.5,-7.5,NA,NA,2,8,0.373584675406836,0.329590782847593,0.0207403994178037,3.96982038909162,0.145212434772781,1148.79399666279,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0104,i0104,Amazon Intact 0104,-59.5,-7.5,NA,NA,2,8,0.405411632262946,0.327696254382808,0.018126229491516,4.09238941624413,0.110656700148928,1151.25093690372,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0105,i0105,Amazon Intact 0105,-58.5,-7.5,NA,NA,2,8,0.428718387571201,0.29752014655824,0.0203812926641996,4.06013174998406,0.114318209045183,1142.86488831388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0106,i0106,Amazon Intact 0106,-57.5,-7.5,NA,NA,2,6,0.472673811569476,0.27488861900762,0.0187833172623552,4.1798953546306,0.11831492959481,1142.06634486178,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0107,i0107,Amazon Intact 0107,-56.5,-7.5,NA,NA,2,6,0.500921888020872,0.288057685256937,0.0208270270845811,4.2068280147721,0.12062062271103,1146.91242218899,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0108,i0108,Amazon Intact 0108,-55.5,-7.5,NA,NA,2,6,0.502766601941748,0.260951067961165,0.0187345242718447,4.44784466019418,0.126612815533981,1148.86990291262,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0109,i0109,Amazon Intact 0109,-54.5,-7.5,NA,NA,2,8,0.448037156462829,0.279485268453837,0.0204603661946344,4.58734200570774,0.123710238224751,1141.20139248498,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0110,i0110,Amazon Intact 0110,-53.5,-7.5,NA,NA,2,5,0.405870414394448,0.272369805154135,0.023213342243383,4.74567721897063,0.121075053077005,1161.26218937101,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0111,i0111,Amazon Intact 0111,-52.5,-7.5,NA,NA,2,5,0.423161031407032,0.260672216314762,0.0215711442273108,4.91259080863187,0.123516537823892,1174.36324277597,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0112,i0112,Amazon Intact 0112,-51.5,-7.5,NA,NA,2,5,0.41030231838826,0.239494717325198,0.0220526448879972,4.92635660676482,0.126257567676888,1171.95394064303,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0113,i0113,Amazon Intact 0113,-50.5,-7.5,NA,NA,2,8,0.423,0.313,0.0219,4.9,0.105,1220,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0114,i0114,Amazon Intact 0114,-49.5,-7.5,NA,NA,2,8,0.419,0.312,0.0186,5,0.091,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0115,i0115,Amazon Intact 0115,-72.5,-6.5,NA,NA,2,8,0.345939206079485,0.303633795622216,0.0243704137723336,4.17603294844803,0.150050279166451,1196.53872861361,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0116,i0116,Amazon Intact 0116,-71.5,-6.5,NA,NA,2,8,0.365716493645615,0.300526175467609,0.0226478336799038,4.22261301260796,0.147174307282635,1182.35775502717,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0117,i0117,Amazon Intact 0117,-70.5,-6.5,NA,NA,2,8,0.305412541254125,0.315392326732673,0.0216017326732673,4.21839933993399,0.150901402640264,1205.20627062706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0118,i0118,Amazon Intact 0118,-69.5,-6.5,NA,NA,2,8,0.34921965818152,0.289604052229818,0.0203178301890008,4.18135129314014,0.145573370106932,1184.21751984388,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0119,i0119,Amazon Intact 0119,-68.5,-6.5,NA,NA,2,5,0.348604688763137,0.253696038803557,0.0206685529506871,4.08164915117219,0.167421180274859,1176.0064672595,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0120,i0120,Amazon Intact 0120,-67.5,-6.5,NA,NA,2,5,0.365728348805189,0.260591566985573,0.0227778287695533,4.02753760229251,0.14967491544859,1183.13628939597,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0121,i0121,Amazon Intact 0121,-66.5,-6.5,NA,NA,2,8,0.363994422005904,0.287466842724147,0.0256279680184059,4.03136513463336,0.162374574213007,1172.78109534152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0122,i0122,Amazon Intact 0122,-65.5,-6.5,NA,NA,2,8,0.289125427594071,0.328168757126568,0.0314795515013303,3.91022424933485,0.261543139490688,1155.68985176739,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0123,i0123,Amazon Intact 0123,-64.5,-6.5,NA,NA,2,8,0.249266584145497,0.284162360328903,0.020971189741879,4.08993166317843,0.14584038391267,1174.72197515196,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0124,i0124,Amazon Intact 0124,-63.5,-6.5,NA,NA,2,7,0.196579547290917,0.275370295899876,0.0199282736771132,4.11996596514939,0.150321114510502,1171.63357395483,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0125,i0125,Amazon Intact 0125,-62.5,-6.5,NA,NA,2,5,0.244662535410765,0.274032577903683,0.0191499291784703,4.13445467422096,0.117794971671388,1159.95042492918,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0126,i0126,Amazon Intact 0126,-61.5,-6.5,NA,NA,2,3,0.560114285714286,0.1922,0.0275228571428571,3.88285714285714,0.1474,1111.71428571429,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0127,i0127,Amazon Intact 0127,-60.5,-6.5,NA,NA,2,8,0.388485111813259,0.358129854186806,0.0245543343694118,3.92201855126991,0.129592882908742,1138.78255735462,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0128,i0128,Amazon Intact 0128,-59.5,-6.5,NA,NA,2,8,0.329346531302876,0.337793570219966,0.0191165143824027,4.04602368866328,0.109199323181049,1143.87140439932,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0129,i0129,Amazon Intact 0129,-58.5,-6.5,NA,NA,2,8,0.401046897022193,0.331684073736919,0.0208013602676036,4.02297069725274,0.107369580881748,1162.37055629501,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0130,i0130,Amazon Intact 0130,-57.5,-6.5,NA,NA,2,8,0.402082448308531,0.329085118646906,0.0205117771282756,4.05679704007993,0.120642426752595,1147.70319656278,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0131,i0131,Amazon Intact 0131,-56.5,-6.5,NA,NA,2,8,0.403477622136805,0.311749766298696,0.0207805693787863,4.07391789389225,0.135365797214032,1141.82167733301,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0132,i0132,Amazon Intact 0132,-55.5,-6.5,NA,NA,2,8,0.407,0.289,0.0207,4.2,0.127,1140,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0133,i0133,Amazon Intact 0133,-54.5,-6.5,NA,NA,2,5,0.472456509042975,0.232519024079735,0.0184966023346652,4.39294157816014,0.120887602741927,1139.14116702345,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0134,i0134,Amazon Intact 0134,-53.5,-6.5,NA,NA,2,5,0.433865380282771,0.260146140656473,0.020582968267837,4.68518820884446,0.114179586990585,1161.35344960581,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0135,i0135,Amazon Intact 0135,-52.5,-6.5,NA,NA,2,8,0.398,0.302,0.0219,4.7,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0136,i0136,Amazon Intact 0136,-51.5,-6.5,NA,NA,2,8,0.399,0.3,0.0223,4.7,0.11,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0137,i0137,Amazon Intact 0137,-50.5,-6.5,NA,NA,2,8,0.369625296536983,0.299049618502065,0.0250926362147123,4.83620161647673,0.117865077193322,1161.80329672384,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0138,i0138,Amazon Intact 0138,-49.5,-6.5,NA,NA,2,8,0.41,0.305,0.0195,4.9,0.102,1240,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0139,i0139,Amazon Intact 0139,-48.5,-6.5,NA,NA,2,8,0.438,0.295,0.0163,5,0.084,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0140,i0140,Amazon Intact 0140,-72.5,-5.5,NA,NA,2,8,0.316631318267378,0.293731070052168,0.0212564050324336,4.03435012014072,0.133540200221238,1204.23283989838,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0141,i0141,Amazon Intact 0141,-71.5,-5.5,NA,NA,2,8,0.261831067264059,0.331674853274107,0.0242969500923943,4.13961911542858,0.144168750466063,1175.89916503948,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0142,i0142,Amazon Intact 0142,-70.5,-5.5,NA,NA,2,8,0.343382487520799,0.321202787021631,0.0223361064891847,4.14968801996672,0.135537853577371,1182.25457570715,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0143,i0143,Amazon Intact 0143,-69.5,-5.5,NA,NA,2,8,0.274067385416902,0.372217615069417,0.0230286438385721,4.12630420864217,0.1318701219462,1184.8735444809,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0144,i0144,Amazon Intact 0144,-68.5,-5.5,NA,NA,2,8,0.376389945078158,0.339515842839037,0.0280085762568652,4.00566117448247,0.167994930291508,1190.59146599071,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0145,i0145,Amazon Intact 0145,-67.5,-5.5,NA,NA,2,8,0.356222727272727,0.306647159090909,0.0269543181818182,4.03232954545455,0.150550568181818,1144.60227272727,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0146,i0146,Amazon Intact 0146,-66.5,-5.5,NA,NA,2,8,0.371920323009405,0.315239792837457,0.0268064244874011,4.08748153937897,0.153513564625017,1163.25080116365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0147,i0147,Amazon Intact 0147,-65.5,-5.5,NA,NA,2,8,0.320175685557587,0.328858500914077,0.0264373126142596,4.2209689213894,0.152609140767825,1175.46252285192,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0148,i0148,Amazon Intact 0148,-64.5,-5.5,NA,NA,2,17,0.19,0.501,0.0244,4.1,0.15,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0149,i0149,Amazon Intact 0149,-63.5,-5.5,NA,NA,2,17,0.151,0.531,0.021,4.2,0.148,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0150,i0150,Amazon Intact 0150,-62.5,-5.5,NA,NA,2,7,0.162319696146735,0.283881096617385,0.02113330578884,4.10775040297384,0.137642820829614,1171.37074442068,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0151,i0151,Amazon Intact 0151,-61.5,-5.5,NA,NA,2,17,0.231,0.456,0.0193,4,0.114,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0152,i0152,Amazon Intact 0152,-60.5,-5.5,NA,NA,2,8,0.341970195896916,0.374434081407434,0.020952469499411,3.94210630242548,0.116940004238079,1151.01613736737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0153,i0153,Amazon Intact 0153,-59.5,-5.5,NA,NA,2,8,0.338,0.298,0.0169,4.1,0.111,1150,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0154,i0154,Amazon Intact 0154,-58.5,-5.5,NA,NA,2,8,0.367328599477271,0.346718543401378,0.0163035298076339,4.16878166280633,0.105175781723714,1141.87391642773,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0155,i0155,Amazon Intact 0155,-57.5,-5.5,NA,NA,2,8,0.357098701250047,0.3620339573164,0.0193660672959784,4.19626448101776,0.112960418923554,1149.06354993779,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0156,i0156,Amazon Intact 0156,-56.5,-5.5,NA,NA,2,8,0.34612741653184,0.3127191263931,0.0202685715388804,4.02263168324212,0.137436727117829,1138.13882752506,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0157,i0157,Amazon Intact 0157,-55.5,-5.5,NA,NA,2,8,0.278051742100947,0.33339098713427,0.0196052091300199,4.09188828089866,0.140839386752368,1140.87748074938,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0158,i0158,Amazon Intact 0158,-54.5,-5.5,NA,NA,2,8,0.39464608371322,0.283622461665976,0.0203793203481144,4.24243680066308,0.117186904268545,1158.15167840862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0159,i0159,Amazon Intact 0159,-53.5,-5.5,NA,NA,2,8,0.394302088079942,0.287042205311682,0.0185841949886112,4.44558374069444,0.104233757115698,1159.35239376196,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0160,i0160,Amazon Intact 0160,-52.5,-5.5,NA,NA,2,8,0.398610950414417,0.285193127551434,0.0168288526619137,4.49620860509732,0.0943560255317985,1160.68634924208,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0161,i0161,Amazon Intact 0161,-51.5,-5.5,NA,NA,2,8,0.422262532563853,0.301807108592407,0.0167985824585007,4.4886403343559,0.0944742243282384,1159.71514316469,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0162,i0162,Amazon Intact 0162,-50.5,-5.5,NA,NA,2,8,0.370207576953433,0.318092344119968,0.0235119968429361,4.78003157063931,0.117884767166535,1167.6637726914,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0163,i0163,Amazon Intact 0163,-49.5,-5.5,NA,NA,2,8,0.428,0.3,0.0182,4.7,0.096,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0164,i0164,Amazon Intact 0164,-48.5,-5.5,NA,NA,2,5,0.445,0.272,0.0158,4.9,0.084,1220,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0165,i0165,Amazon Intact 0165,-71.5,-4.5,NA,NA,2,17,0.172,0.46,0.0438,4.2,0.119,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0166,i0166,Amazon Intact 0166,-70.5,-4.5,NA,NA,2,7,0.180844339539162,0.326875672395628,0.0378916021208374,4.25120446069311,0.119021785409909,1183.58017266654,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0167,i0167,Amazon Intact 0167,-69.5,-4.5,NA,NA,2,8,0.273516734693878,0.343818775510204,0.0231362448979592,4.19681632653061,0.121054285714286,1186.53469387755,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0168,i0168,Amazon Intact 0168,-68.5,-4.5,NA,NA,2,8,0.342060798209623,0.358166728832525,0.0194925400969787,4.27907497202536,0.12147034688549,1193.32711674748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0169,i0169,Amazon Intact 0169,-67.5,-4.5,NA,NA,2,8,0.348771046735434,0.306365616648273,0.0239883688631256,4.10847593744122,0.141212122899216,1154.67484644238,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0170,i0170,Amazon Intact 0170,-66.5,-4.5,NA,NA,2,8,0.324960698490132,0.3012612351484,0.0265792256374342,4.20402743720121,0.142542745427422,1141.99287086459,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0171,i0171,Amazon Intact 0171,-65.5,-4.5,NA,NA,2,8,0.282513583441138,0.297124838292367,0.0212324062095731,3.95873221216041,0.128265847347995,1179.42432082794,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0172,i0172,Amazon Intact 0172,-64.5,-4.5,NA,NA,2,7,0.19746709470305,0.290691813804173,0.01776886035313,3.97512038523274,0.137132423756019,1192.31942215088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0173,i0173,Amazon Intact 0173,-63.5,-4.5,NA,NA,2,7,0.126954475308642,0.292680941358025,0.0181841820987654,3.78769290123457,0.126659722222222,1189.32098765432,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0174,i0174,Amazon Intact 0174,-62.5,-4.5,NA,NA,2,4,0.163475716064757,0.273605230386052,0.0177661270236613,4.15230386052304,0.136013698630137,1161.02117061021,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0175,i0175,Amazon Intact 0175,-61.5,-4.5,NA,NA,2,7,0.13280727212721,0.302809712941324,0.0262820949943889,3.94619143567497,0.113322670499445,1165.89946168109,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0176,i0176,Amazon Intact 0176,-60.5,-4.5,NA,NA,2,7,0.179919421487603,0.312974690082645,0.0183882747933884,4.09395661157025,0.127867768595041,1160.86260330579,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0177,i0177,Amazon Intact 0177,-59.5,-4.5,NA,NA,2,8,0.336,0.318,0.0166,4.1,0.105,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0178,i0178,Amazon Intact 0178,-58.5,-4.5,NA,NA,2,8,0.321354241129811,0.375408567922717,0.0144654642733048,4.09468715420435,0.104033143211168,1156.81244095367,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0179,i0179,Amazon Intact 0179,-57.5,-4.5,NA,NA,2,8,0.415331305303557,0.366601371168554,0.0171815995710085,4.11656375020538,0.104339695117783,1157.63684320586,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0180,i0180,Amazon Intact 0180,-56.5,-4.5,NA,NA,2,8,0.355593315895006,0.393720972354411,0.0162704985607786,4.19262089454544,0.105047794626876,1155.94914097185,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0181,i0181,Amazon Intact 0181,-55.5,-4.5,NA,NA,2,8,0.333254551700447,0.356485056681553,0.0200386808656819,4.18979732050842,0.100683613878392,1147.5334936448,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0182,i0182,Amazon Intact 0182,-54.5,-4.5,NA,NA,2,8,0.36203836952556,0.363111520041128,0.0200708210486965,4.38380479003491,0.0977894594579951,1168.20588858607,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0183,i0183,Amazon Intact 0183,-53.5,-4.5,NA,NA,2,8,0.412961517904864,0.307752004275788,0.0185749331908071,4.39567076429717,0.0942057723142704,1164.0994120791,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0184,i0184,Amazon Intact 0184,-52.5,-4.5,NA,NA,2,8,0.411855537435268,0.337758914280448,0.0158014482785004,4.33425209540328,0.10255163071051,1179.34930849609,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0185,i0185,Amazon Intact 0185,-51.5,-4.5,NA,NA,2,8,0.407422168172342,0.365154968728284,0.016791000694927,4.45868658790827,0.101891938846421,1185.28492008339,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0186,i0186,Amazon Intact 0186,-50.5,-4.5,NA,NA,2,5,0.428,0.239,0.0181,4.6,0.093,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0187,i0187,Amazon Intact 0187,-49.5,-4.5,NA,NA,2,5,0.441,0.267,0.0193,4.7,0.093,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0188,i0188,Amazon Intact 0188,-48.5,-4.5,NA,NA,2,5,0.43,0.25,0.0182,4.7,0.078,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0189,i0189,Amazon Intact 0189,-47.5,-4.5,NA,NA,2,5,0.382,0.245,0.0164,4.9,0.075,1240,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0190,i0190,Amazon Intact 0190,-46.5,-4.5,NA,NA,2,8,0.439428484011334,0.358171322892075,0.0173332375996905,4.93920405875888,0.0900584877584942,1245.42093411732,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0191,i0191,Amazon Intact 0191,-45.5,-4.5,NA,NA,2,5,0.448,0.259,0.0159,5.2,0.081,1250,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0192,i0192,Amazon Intact 0192,-69.5,-3.5,NA,NA,2,5,0.318452568295237,0.27335013367275,0.0429284412195275,4.30292278054564,0.131592159120715,1180.0924575863,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0193,i0193,Amazon Intact 0193,-68.5,-3.5,NA,NA,2,8,0.289615166039776,0.302296043277158,0.0243809465206284,4.28969269797309,0.112370333047237,1179.8274509834,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0194,i0194,Amazon Intact 0194,-67.5,-3.5,NA,NA,2,8,0.2700686321647,0.311963459336089,0.0251306205205177,4.14459388065387,0.133479905527406,1150.91269511748,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0195,i0195,Amazon Intact 0195,-66.5,-3.5,NA,NA,2,8,0.302732084799917,0.317106665959767,0.0257642142408992,4.19155826315183,0.137826048525465,1135.74955305385,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0196,i0196,Amazon Intact 0196,-65.5,-3.5,NA,NA,2,8,0.258101936799184,0.303352701325178,0.0245166666666667,4.09964322120285,0.127257900101937,1130.76962283384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0197,i0197,Amazon Intact 0197,-64.5,-3.5,NA,NA,2,11,0.191,0.511,0.023,4.1,0.113,1150,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0198,i0198,Amazon Intact 0198,-63.5,-3.5,NA,NA,2,7,0.173980475688053,0.284462404732551,0.0183109889017527,4.06681640015756,0.112112878079992,1197.74383952955,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0199,i0199,Amazon Intact 0199,-62.5,-3.5,NA,NA,2,8,0.205569367108256,0.279964966850437,0.0228394088267051,4.11279350923955,0.113313215921889,1169.96765862445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0200,i0200,Amazon Intact 0200,-61.5,-3.5,NA,NA,2,17,0.209,0.486,0.0198,4.2,0.111,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0201,i0201,Amazon Intact 0201,-60.5,-3.5,NA,NA,2,7,0.164556952081697,0.335710919088767,0.0174515318146112,4.1420005236973,0.0925653312385441,1158.56245090338,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0202,i0202,Amazon Intact 0202,-59.5,-3.5,NA,NA,2,17,0.206,0.445,0.0185,4.2,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0203,i0203,Amazon Intact 0203,-58.5,-3.5,NA,NA,2,8,0.256,0.36,0.0165,4.2,0.109,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0204,i0204,Amazon Intact 0204,-57.5,-3.5,NA,NA,2,16,0.361287001225935,0.400896875184196,0.0195501365989632,4.21184136529572,0.11345984693712,1182.29455769475,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0205,i0205,Amazon Intact 0205,-56.5,-3.5,NA,NA,2,9,0.466265704196725,0.359033669562661,0.0156241671891566,4.09684359417543,0.0942319636252154,1176.10157498244,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0206,i0206,Amazon Intact 0206,-55.5,-3.5,NA,NA,2,6,0.48989805511363,0.342665064851515,0.014674402617952,4.11786563803893,0.097472504212456,1188.98461685856,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0207,i0207,Amazon Intact 0207,-54.5,-3.5,NA,NA,2,6,0.450073758865248,0.343052482269504,0.0156248226950355,4.2090780141844,0.0934992907801418,1177.39007092199,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0208,i0208,Amazon Intact 0208,-53.5,-3.5,NA,NA,2,8,0.388478597880332,0.386833348638904,0.0167795303617296,4.47863495593655,0.107195153680423,1181.71986743304,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0209,i0209,Amazon Intact 0209,-52.5,-3.5,NA,NA,2,5,0.382,0.208,0.0179,4.7,0.098,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0210,i0210,Amazon Intact 0210,-51.5,-3.5,NA,NA,2,5,0.439,0.205,0.0184,4.6,0.106,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0211,i0211,Amazon Intact 0211,-50.5,-3.5,NA,NA,2,5,0.455,0.219,0.0174,4.6,0.099,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0212,i0212,Amazon Intact 0212,-49.5,-3.5,NA,NA,2,5,0.4545,0.235,0.0202,4.7,0.092,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0213,i0213,Amazon Intact 0213,-48.5,-3.5,NA,NA,2,5,0.481,0.217,0.0169,4.5,0.078,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0214,i0214,Amazon Intact 0214,-47.5,-3.5,NA,NA,2,5,0.467,0.207,0.0157,4.8,0.071,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0215,i0215,Amazon Intact 0215,-46.5,-3.5,NA,NA,2,6,0.45541505595117,0.345739572736521,0.016979518480841,4.61631061376738,0.0877416073245168,1190.91217361818,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0216,i0216,Amazon Intact 0216,-45.5,-3.5,NA,NA,2,8,0.376,0.314,0.014,5.1,0.091,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0217,i0217,Amazon Intact 0217,-69.5,-2.5,NA,NA,2,5,0.501084205518554,0.186823977164605,0.039562226450999,4.30428163653663,0.152717411988582,1153.55851569933,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0218,i0218,Amazon Intact 0218,-68.5,-2.5,NA,NA,2,5,0.474578107885745,0.225788409727348,0.0350460210800488,4.24778382175107,0.157631583701463,1120.71969737027,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0219,i0219,Amazon Intact 0219,-67.5,-2.5,NA,NA,2,7,0.196220794392523,0.317254672897196,0.0251533878504673,4.2,0.134580607476636,1137.23130841121,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0220,i0220,Amazon Intact 0220,-66.5,-2.5,NA,NA,2,8,0.263612791702679,0.311148660328436,0.0280566119273984,4.19273984442524,0.152225583405359,1142.05704407952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0221,i0221,Amazon Intact 0221,-65.5,-2.5,NA,NA,2,7,0.185346839867306,0.290991858339675,0.0266765038387251,4.2015748646035,0.14271704441742,1105.73817449625,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0222,i0222,Amazon Intact 0222,-64.5,-2.5,NA,NA,2,17,0.22,0.477,0.0261,4.1,0.136,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0223,i0223,Amazon Intact 0223,-63.5,-2.5,NA,NA,2,8,0.238802126881665,0.28627569123884,0.0242921620325804,4.12534833508294,0.121304591884166,1157.52515713517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0224,i0224,Amazon Intact 0224,-62.5,-2.5,NA,NA,2,8,0.303226557975135,0.323876468990194,0.0221805349432241,4.32238435161985,0.102009606543295,1175.28861746452,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0225,i0225,Amazon Intact 0225,-61.5,-2.5,NA,NA,2,8,0.384794096355573,0.322833529555224,0.0162511491983126,4.58697499306154,0.103769225769498,1178.56654731473,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0226,i0226,Amazon Intact 0226,-60.5,-2.5,NA,NA,2,8,0.369814850494501,0.33377306007965,0.0152474823558628,4.13446662775592,0.0976310729886332,1188.5430997087,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0227,i0227,Amazon Intact 0227,-59.5,-2.5,NA,NA,2,16,0.39368801431127,0.41897030411449,0.0159848658318426,4.05656529516995,0.0781792486583184,1165.52772808587,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0228,i0228,Amazon Intact 0228,-58.5,-2.5,NA,NA,2,5,0.42,0.194,0.0155,4.1,0.091,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0229,i0229,Amazon Intact 0229,-57.5,-2.5,NA,NA,2,6,0.479282903641197,0.346625089658027,0.0156348479275412,4.12573829897359,0.098496227238243,1166.06664423999,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0230,i0230,Amazon Intact 0230,-56.5,-2.5,NA,NA,2,6,0.568451904758393,0.287509378431131,0.0137057084578839,4.03121116079173,0.083103354371674,1176.84889973747,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0231,i0231,Amazon Intact 0231,-55.5,-2.5,NA,NA,2,3,0.548,0.169,0.0143,4.1,0.107,1160,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0232,i0232,Amazon Intact 0232,-54.5,-2.5,NA,NA,2,5,0.369,0.222,0.0165,4.6,0.124,1160,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0233,i0233,Amazon Intact 0233,-53.5,-2.5,NA,NA,2,11,0.258783928069683,0.487778870469233,0.0174272548468671,4.49269457712841,0.107891261590334,1169.15987636977,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0234,i0234,Amazon Intact 0234,-52.5,-2.5,NA,NA,2,5,0.47,0.243,0.0154,4.4,0.104,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0235,i0235,Amazon Intact 0235,-51.5,-2.5,NA,NA,2,6,0.486723228995058,0.296668314113125,0.0166360241625481,4.37144426139484,0.0979077429983525,1190.0823723229,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0236,i0236,Amazon Intact 0236,-50.5,-2.5,NA,NA,2,6,0.466559221658206,0.302565989847716,0.0178413705583756,4.42301184433164,0.10463282571912,1181.5820642978,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0237,i0237,Amazon Intact 0237,-49.5,-2.5,NA,NA,2,5,0.472,0.242,0.0186,4.6,0.107,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0238,i0238,Amazon Intact 0238,-48.5,-2.5,NA,NA,2,5,0.456,0.241,0.0165,4.7,0.093,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0239,i0239,Amazon Intact 0239,-47.5,-2.5,NA,NA,2,5,0.395,0.246,0.0157,4.9,0.076,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0240,i0240,Amazon Intact 0240,-46.5,-2.5,NA,NA,2,8,0.366523568668258,0.366549613332243,0.016339490616958,4.55215271258003,0.08033462738003,1174.40768787318,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0241,i0241,Amazon Intact 0241,-45.5,-2.5,NA,NA,2,8,0.412,0.291,0.0167,5,0.095,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0242,i0242,Amazon Intact 0242,-44.5,-2.5,NA,NA,2,8,0.349,0.314,0.0197,5.1,0.148,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0243,i0243,Amazon Intact 0243,-68.5,-1.5,NA,NA,2,3,0.583286919831224,0.191196905766526,0.0204880450070324,4.24838255977496,0.147434599156118,1174.75386779184,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0244,i0244,Amazon Intact 0244,-67.5,-1.5,NA,NA,2,8,0.359,0.338,0.0251,4.3,0.14,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0245,i0245,Amazon Intact 0245,-66.5,-1.5,NA,NA,2,6,0.484,0.261,0.0216,4.3,0.107,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0246,i0246,Amazon Intact 0246,-65.5,-1.5,NA,NA,2,5,0.483153846153846,0.217,0.0222769230769231,4.3,0.101076923076923,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0247,i0247,Amazon Intact 0247,-64.5,-1.5,NA,NA,2,5,0.332199570164771,0.226728347704738,0.0229433604016956,4.15299560886021,0.109355631266316,1140.07653008428,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0248,i0248,Amazon Intact 0248,-63.5,-1.5,NA,NA,2,8,0.283137652629851,0.275732067246036,0.0222419811718623,4.10356431250998,0.126085245743094,1156.30507181702,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0249,i0249,Amazon Intact 0249,-62.5,-1.5,NA,NA,2,8,0.278494276944493,0.278303735285365,0.0259597767751026,4.04693747670087,0.114247037965245,1161.43611359252,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0250,i0250,Amazon Intact 0250,-61.5,-1.5,NA,NA,2,8,0.293022662889518,0.344461756373938,0.0409393767705382,4.03371104815864,0.137597733711048,1130.22662889518,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0251,i0251,Amazon Intact 0251,-60.5,-1.5,NA,NA,2,8,0.306637396681003,0.37073806896197,0.0180052615048106,4.13085875382976,0.0963526754981705,1179.21859014325,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0252,i0252,Amazon Intact 0252,-59.5,-1.5,NA,NA,2,16,0.300556308615255,0.401741069547032,0.0184511341679462,4.21649253416002,0.0842416870038793,1174.29416581795,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0253,i0253,Amazon Intact 0253,-58.5,-1.5,NA,NA,2,17,0.249196236234406,0.409889027806853,0.0169219522241721,4.25042630421649,0.0909396671003949,1176.75135849828,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0254,i0254,Amazon Intact 0254,-57.5,-1.5,NA,NA,2,8,0.353953296510074,0.356318795150176,0.0162318951959305,4.16127921138137,0.0921185700147406,1169.03315845088,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0255,i0255,Amazon Intact 0255,-56.5,-1.5,NA,NA,2,8,0.428561397205884,0.357890819191029,0.0170443708892477,4.07668184177044,0.102229315858188,1172.03342349047,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0256,i0256,Amazon Intact 0256,-55.5,-1.5,NA,NA,2,8,0.326753267119707,0.365852064819655,0.0162360690015682,4.17762676424464,0.109025614218505,1155.24307370622,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0257,i0257,Amazon Intact 0257,-54.5,-1.5,NA,NA,2,6,0.453466860183841,0.30700145137881,0.0147157232704403,4.44944363812288,0.0934358974358974,1168.24383164006,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0258,i0258,Amazon Intact 0258,-53.5,-1.5,NA,NA,2,8,0.358051985792703,0.375059412334517,0.0217846625766871,4.69667420083952,0.102369066838876,1149.43816596706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0259,i0259,Amazon Intact 0259,-52.5,-1.5,NA,NA,2,5,0.425,0.266,0.0211,4.7,0.13,1170,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0260,i0260,Amazon Intact 0260,-51.5,-1.5,NA,NA,2,8,0.422570366881509,0.324241067101816,0.0166373957360906,4.5004522363151,0.103892049038098,1177.00228423286,K,1,90,15,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0261,i0261,Amazon Intact 0261,-50.5,-1.5,NA,NA,2,6,0.561072147239264,0.28404981595092,0.0209613987730061,4.51754601226994,0.0997418404907976,1198.81717791411,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0262,i0262,Amazon Intact 0262,-49.5,-1.5,NA,NA,2,6,0.538880931837791,0.296545297670406,0.024327868852459,4.54831751509922,0.110910267471959,1196.7558239862,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0263,i0263,Amazon Intact 0263,-48.5,-1.5,NA,NA,2,5,0.393,0.274,0.0242,4.7,0.144,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0264,i0264,Amazon Intact 0264,-47.5,-1.5,NA,NA,2,5,0.383,0.249,0.0161,4.9,0.102,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0265,i0265,Amazon Intact 0265,-46.5,-1.5,NA,NA,2,5,0.365,0.271,0.0168,4.9,0.107,1200,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0266,i0266,Amazon Intact 0266,-45.5,-1.5,NA,NA,2,5,0.386,0.266,0.0217,4.9,0.127,1190,K,1,90,14,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0267,i0267,Amazon Intact 0267,-69.5,-0.5,NA,NA,2,6,0.513583189169413,0.245977740531898,0.0276737157238781,4.58843583440703,0.12858002948712,1194.93803226348,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0268,i0268,Amazon Intact 0268,-68.5,-0.5,NA,NA,2,3,0.600080368544563,0.184909434794784,0.0266536832169823,4.45450123700453,0.13408238057271,1160.05935057225,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0269,i0269,Amazon Intact 0269,-67.5,-0.5,NA,NA,2,6,0.497991462671745,0.274257998162199,0.0237007313136071,4.41340109443275,0.129521088572825,1136.4929430812,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0270,i0270,Amazon Intact 0270,-66.5,-0.5,NA,NA,2,6,0.487163751757489,0.259332591217498,0.0247852706061505,4.28013241098742,0.11444026279783,1143.40517343133,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0271,i0271,Amazon Intact 0271,-65.5,-0.5,NA,NA,2,5,0.479092105263158,0.217730263157895,0.0217730263157895,4.2,0.0977763157894737,1173.88157894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0272,i0272,Amazon Intact 0272,-64.5,-0.5,NA,NA,2,5,0.472669608463471,0.249291511524267,0.02087983621479,4.13056551181114,0.106210734138445,1160.99596029531,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0273,i0273,Amazon Intact 0273,-63.5,-0.5,NA,NA,2,6,0.46518007761852,0.262138086454371,0.0250127829843773,4.11123340189234,0.11280515756391,1155.37493870311,K,1,90,16,ERA5_CHIRPS,1981,2019,5,40 +AMZIF_0274,i0274,Amazon Intact 0274,-62.5,-0.5,NA,NA,2,8,0.399849910285365,0.303517220341941,0.0301553996969191,4.09137312319897,0.116908159627452,1150.9291358209,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0275,i0275,Amazon Intact 0275,-61.5,-0.5,NA,NA,2,8,0.401,0.296,0.0293,4.1,0.121,1170,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0276,i0276,Amazon Intact 0276,-60.5,-0.5,NA,NA,2,8,0.43759229436722,0.327765854198416,0.0239312319665031,4.07425046342091,0.103975187414491,1182.26604116517,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0277,i0277,Amazon Intact 0277,-59.5,-0.5,NA,NA,2,17,0.239715351812367,0.418997334754797,0.0188569829424307,4.20442430703625,0.0887681236673774,1185.07995735608,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0278,i0278,Amazon Intact 0278,-58.5,-0.5,NA,NA,2,8,0.232,0.367,0.017,4.2,0.091,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0279,i0279,Amazon Intact 0279,-57.5,-0.5,NA,NA,2,8,0.281511182108626,0.395685126020589,0.020892225772098,4.02744053958112,0.0987724529641463,1147.54348597799,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0280,i0280,Amazon Intact 0280,-56.5,-0.5,NA,NA,2,8,0.333425168387214,0.385573036348581,0.0181079429907979,4.08479599600034,0.111452773708574,1167.16959626952,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0281,i0281,Amazon Intact 0281,-55.5,-0.5,NA,NA,2,8,0.367863167567993,0.389374358579361,0.0202798785670844,4.13969965062452,0.111505103338343,1159.92937182343,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0282,i0282,Amazon Intact 0282,-54.5,-0.5,NA,NA,2,8,0.338900020480741,0.347237539346446,0.024187092972358,4.39643822949762,0.105208915705631,1174.61851509937,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0283,i0283,Amazon Intact 0283,-53.5,-0.5,NA,NA,2,8,0.355,0.28,0.0153,4.5,0.098,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0284,i0284,Amazon Intact 0284,-52.5,-0.5,NA,NA,2,8,0.339034131922173,0.374604688011251,0.0156990635612464,4.42961377701112,0.103277610183329,1204.46796846706,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0285,i0285,Amazon Intact 0285,-51.5,-0.5,NA,NA,2,8,0.372166159029789,0.380014992408354,0.0220836014901674,4.63160218234417,0.146076665566285,1177.6541729892,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0286,i0286,Amazon Intact 0286,-50.5,-0.5,NA,NA,2,5,0.445,0.222,0.0262,4.6,0.133,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0287,i0287,Amazon Intact 0287,-49.5,-0.5,NA,NA,2,5,0.4075,0.242,0.0301,5,0.17,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0288,i0288,Amazon Intact 0288,-48.5,-0.5,NA,NA,2,8,0.314,0.304,0.0325,5.2,0.173,1190,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0289,i0289,Amazon Intact 0289,-69.5,0.5,NA,NA,2,6,0.518,0.244,0.024,4.5,0.124,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0290,i0290,Amazon Intact 0290,-68.5,0.5,NA,NA,2,6,0.556031275302543,0.213491255142449,0.0269094765332795,4.77052293091954,0.128356794829367,1199.06133779691,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0291,i0291,Amazon Intact 0291,-67.5,0.5,NA,NA,2,6,0.531345964496635,0.243997191584387,0.0252805275869034,4.58959693238905,0.12274820262963,1138.82061016445,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0292,i0292,Amazon Intact 0292,-66.5,0.5,NA,NA,2,6,0.548215196717419,0.224407028928467,0.0271229074631325,4.43939775224795,0.109745421821456,1113.94872134619,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0293,i0293,Amazon Intact 0293,-65.5,0.5,NA,NA,2,6,0.484765179678734,0.256514100828391,0.0282823256655113,4.14867339135671,0.114060992235232,1143.58311648962,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0294,i0294,Amazon Intact 0294,-64.5,0.5,NA,NA,2,6,0.487010403492551,0.258904649364713,0.0268010597810063,4.10729350353887,0.118673620957919,1124.26391973434,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0295,i0295,Amazon Intact 0295,-63.5,0.5,NA,NA,2,5,0.490013881177124,0.223543586896169,0.0233667962243198,4.29244863964464,0.111192670738479,1171.7157134925,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0296,i0296,Amazon Intact 0296,-62.5,0.5,NA,NA,2,6,0.483,0.261,0.0177,4.8,0.127,1240,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0297,i0297,Amazon Intact 0297,-61.5,0.5,NA,NA,2,6,0.490005479452055,0.286574429223744,0.0155687671232877,4.6,0.115645662100457,1239.25114155251,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0298,i0298,Amazon Intact 0298,-60.5,0.5,NA,NA,2,8,0.422827388919844,0.29860800842063,0.0148668648048191,4.45877357340052,0.10206694774671,1226.64877103883,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0299,i0299,Amazon Intact 0299,-59.5,0.5,NA,NA,2,8,0.35218276921012,0.332975825521394,0.0176846653881449,4.36719699243703,0.103102231226806,1209.98824400904,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0300,i0300,Amazon Intact 0300,-58.5,0.5,NA,NA,2,8,0.363830388886367,0.307647710465354,0.0175809224486845,4.43911678729251,0.103051225392196,1189.58270236001,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0301,i0301,Amazon Intact 0301,-57.5,0.5,NA,NA,2,8,0.354931842769564,0.343516768842409,0.0181821853588172,4.35708618824378,0.100027046520014,1219.78723404255,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0302,i0302,Amazon Intact 0302,-56.5,0.5,NA,NA,2,8,0.377,0.279,0.0156,4.5,0.098,1180,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0303,i0303,Amazon Intact 0303,-55.5,0.5,NA,NA,2,8,0.35,0.292,0.0178,4.5,0.1,1190,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0304,i0304,Amazon Intact 0304,-54.5,0.5,NA,NA,2,8,0.326,0.309,0.0184,4.5,0.1,1200,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0305,i0305,Amazon Intact 0305,-53.5,0.5,NA,NA,2,8,0.323365210127657,0.370095805707387,0.0187482045535554,4.48093786377005,0.0996940546590494,1195.62742007063,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0306,i0306,Amazon Intact 0306,-52.5,0.5,NA,NA,2,8,0.292867015931683,0.397491722254934,0.0192186303907941,4.4352519463437,0.103649205072188,1202.97149068891,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0307,i0307,Amazon Intact 0307,-51.5,0.5,NA,NA,2,8,0.354676744608013,0.342080412276782,0.0198860758037557,4.59291576539618,0.104769497337053,1216.29109710547,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0308,i0308,Amazon Intact 0308,-69.5,1.5,NA,NA,2,6,0.526,0.24,0.024,4.5,0.097,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0309,i0309,Amazon Intact 0309,-68.5,1.5,NA,NA,2,6,0.52253906795127,0.205054553070751,0.0427814812837994,4.66687109294238,0.126099018640665,1194.61921079365,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0310,i0310,Amazon Intact 0310,-67.5,1.5,NA,NA,2,6,0.561091043671355,0.20421021465581,0.0270715025906736,4.8,0.125521835677276,1167.21687638786,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0311,i0311,Amazon Intact 0311,-63.5,1.5,NA,NA,2,8,0.42494387755102,0.300469023323615,0.0162231413994169,4.46344752186589,0.11184584548105,1160.36807580175,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0312,i0312,Amazon Intact 0312,-62.5,1.5,NA,NA,2,5,0.461726939264444,0.258288962317539,0.0154604370768904,4.66603356058363,0.108984270747554,1194.30671490346,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0313,i0313,Amazon Intact 0313,-61.5,1.5,NA,NA,2,6,0.491579346398351,0.244625519219408,0.0134864468276648,4.76323965635835,0.117913015594765,1223.94573462479,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0314,i0314,Amazon Intact 0314,-60.5,1.5,NA,NA,2,6,0.549014345688791,0.230570332291842,0.013304077377855,4.86755000506628,0.0961091934521206,1208.56740319152,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0315,i0315,Amazon Intact 0315,-59.5,1.5,NA,NA,2,6,0.481927994873695,0.255205541384766,0.0150356642601167,4.74670830089643,0.103511291584974,1207.44096428706,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0316,i0316,Amazon Intact 0316,-57.5,1.5,NA,NA,2,8,0.320494450050454,0.381883955600404,0.0240853683148335,4.43296333669694,0.130706020854356,1230.91153716784,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0317,i0317,Amazon Intact 0317,-56.5,1.5,NA,NA,2,8,0.379,0.278,0.0166,4.6,0.102,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0318,i0318,Amazon Intact 0318,-55.5,1.5,NA,NA,2,5,0.392,0.263,0.0161,4.6,0.101,1220,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0319,i0319,Amazon Intact 0319,-54.5,1.5,NA,NA,2,8,0.350395925297114,0.379331069609508,0.0170010526315789,4.57011884550085,0.100765365025467,1205.64006791171,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0320,i0320,Amazon Intact 0320,-53.5,1.5,NA,NA,2,8,0.33561267805929,0.378876602523137,0.017076443885941,4.53922886608355,0.0972183506159432,1210.01906683005,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0321,i0321,Amazon Intact 0321,-52.5,1.5,NA,NA,2,8,0.335149100257069,0.374988982739625,0.0183976496511201,4.54168196841719,0.117102093279471,1219.54829232464,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0322,i0322,Amazon Intact 0322,-51.5,1.5,NA,NA,2,8,0.342559043915282,0.375207384619859,0.0198429336435915,4.53589145059832,0.111399201408253,1218.60642701711,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0323,i0323,Amazon Intact 0323,-50.5,1.5,NA,NA,2,8,0.334285904255319,0.309539893617021,0.0247304521276596,4.85345744680851,0.195167553191489,747.114361702128,K,1,90,15,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0324,i0324,Amazon Intact 0324,-63.5,2.5,NA,NA,2,5,0.394,0.267,0.0229,4.2,0.106,1110,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0325,i0325,Amazon Intact 0325,-62.5,2.5,NA,NA,2,8,0.373555616051848,0.347475527485543,0.0166705535882847,4.47090601554171,0.110173448007595,1154.31042803282,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0326,i0326,Amazon Intact 0326,-61.5,2.5,NA,NA,2,6,0.474488977350501,0.284508323716426,0.0158915215631065,4.71459515869303,0.0970353676585795,1191.61066134685,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0327,i0327,Amazon Intact 0327,-60.5,2.5,NA,NA,2,3,0.582,0.197,0.0137,5.1,0.106,1270,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0328,i0328,Amazon Intact 0328,-52.5,2.5,NA,NA,2,8,0.363187161639598,0.365375870069606,0.0310636117556071,4.62965970610982,0.129161252900232,1214.36194895592,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0329,i0329,Amazon Intact 0329,-51.5,2.5,NA,NA,2,8,0.357012872350827,0.354746872110307,0.0213451569559534,4.58902910482537,0.143151406767849,1205.39553680222,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0330,i0330,Amazon Intact 0330,-63.5,3.5,NA,NA,2,8,0.361,0.281,0.0224,4.1,0.117,1120,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0331,i0331,Amazon Intact 0331,-62.5,3.5,NA,NA,2,8,0.346073414671842,0.369487859609459,0.0177165198541867,4.37372537735457,0.10968214765377,1131.10602529551,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0332,i0332,Amazon Intact 0332,-61.5,3.5,NA,NA,2,6,0.479615694573823,0.293875810816361,0.0152221313921233,4.85439423856933,0.110973840211288,1214.41237963628,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0333,i0333,Amazon Intact 0333,-60.5,3.5,NA,NA,2,6,0.498,0.26,0.0101,5.3,0.153,1320,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0334,i0334,Amazon Intact 0334,-51.5,3.5,NA,NA,2,8,0.307,0.331,0.0258,4.7,0.171,1180,K,1,90,15,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0335,i0335,Amazon Intact 0335,-60.5,4.5,NA,NA,2,8,0.348,0.334,0.0249,5.3,0.151,1230,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0336,i0336,Amazon Intact 0336,-59.5,-11.5,NA,NA,2,6,0.531965811840757,0.243728325972639,0.0187127669238973,4.4686539658477,0.108225292926799,1211.32454358169,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0337,i0337,Amazon Intact 0337,-58.5,-12.5,NA,NA,2,3,0.754084244600303,0.15137239297781,0.0138599813936637,4.61700499339524,0.094790242484175,1221.66075690442,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0338,i0338,Amazon Intact 0338,-51.5,-12.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0339,i0339,Amazon Intact 0339,-54.5,-13.5,NA,NA,2,6,0.604719512195122,0.254965447154472,0.0216197154471545,4.8,0.106475609756098,1225.91463414634,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0340,i0340,Amazon Intact 0340,-46.5,-5.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0341,i0341,Amazon Intact 0341,-59.5,-12.5,NA,NA,2,3,0.668453719723183,0.181541522491349,0.0159257352941176,4.6780276816609,0.103732698961938,1216.35813148789,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0342,i0342,Amazon Intact 0342,-59.5,-13.5,NA,NA,2,3,0.699488842211707,0.186988779988865,0.0157302321721259,4.91277867918269,0.087079116612656,1214.97471074384,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0343,i0343,Amazon Intact 0343,-53.5,-13.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,120 +AMZIF_0344,i0344,Amazon Intact 0344,-53.5,2.5,NA,NA,2,8,0.307401814058957,0.396586848072562,0.0224716553287982,4.62208616780045,0.108532426303855,1201.46031746032,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0345,i0345,Amazon Intact 0345,-73.5,-6.5,NA,NA,2,8,0.38418927140332,0.323272575377048,0.0253926179596497,4.18006928075437,0.134395888997171,1213.40132840139,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0346,i0346,Amazon Intact 0346,-65.5,-11.5,NA,NA,2,8,0.436925311203319,0.291680497925311,0.0164742738589212,4.73112033195021,0.10660857538036,1211.53526970954,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0347,i0347,Amazon Intact 0347,-69.5,-1.5,NA,NA,2,3,0.566508552631579,0.187552631578947,0.02448125,4.32605263157895,0.137514473684211,1178.75657894737,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0348,i0348,Amazon Intact 0348,-59.5,4.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 +AMZIF_0349,i0349,Amazon Intact 0349,-50.5,-10.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,60 +AMZIF_0350,i0350,Amazon Intact 0350,-50.5,0.5,NA,NA,2,6,0.521,0.251,0.0158,5,0.084,1250,K,1,90,16,ERA5_CHIRPS,1981,2019,5,30 diff --git a/R-utils/assign.pft.r b/R-utils/assign.pft.r index 4567345dc..5d22144da 100644 --- a/R-utils/assign.pft.r +++ b/R-utils/assign.pft.r @@ -333,7 +333,7 @@ assign.pft <<- function(datum,path=srcdir,approach=c("rho","cluster"),verbose=FA #==========================================================================================# #==========================================================================================# -# This function finds the most similar group to the data in +# This function finds the most similar group to the data input. #------------------------------------------------------------------------------------------# which.pft <<- function(datum,medoid,trait,wcluster){ diff --git a/R-utils/cci.lieberman.r b/R-utils/cci.lieberman.r index df17f632a..f8cde7212 100644 --- a/R-utils/cci.lieberman.r +++ b/R-utils/cci.lieberman.r @@ -167,7 +167,7 @@ cci.lieberman <<- function( xyz, dxy = 1, radius = 10, undef = -9999., closure }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! grepl("^cci.lieberman",wcm[[n]]) #---------------------------------------------------------------------------------# }#end if diff --git a/R-utils/charutils.r b/R-utils/charutils.r index 9d4a86944..2f9283c37 100644 --- a/R-utils/charutils.r +++ b/R-utils/charutils.r @@ -36,7 +36,7 @@ capwords <<- function(s, strict = FALSE) { #--------------------------------------------------------------------------------------# #---- Force NAs to remain NAs. --------------------------------------------------------# - ans[sel] = NA + ans[sel] = NA_character_ return(ans) #--------------------------------------------------------------------------------------# }#end if @@ -178,7 +178,7 @@ nregexpr <<- function(pattern,text,...){ }else{ #---- Use gregexpr to identifiy the number of occurrences. --------------------------# ans = gregexpr(pattern=pattern,text=text,...)[[1]] - ans = length(ans[ans %>% 0]) + ans = length(ans[ans %gt% 0]) #------------------------------------------------------------------------------------# }#end if (length(text) > 1) #---------------------------------------------------------------------------------------# diff --git a/R-utils/closest.r b/R-utils/closest.r index 4c56982f9..9a5537698 100644 --- a/R-utils/closest.r +++ b/R-utils/closest.r @@ -33,12 +33,12 @@ which.closest <<- function(x,A,mask=rep(TRUE,length(A)) ){ if (! any(is.finite(x)) || ! any(mask,na.rm=TRUE)){ #----- x is invalid, return NA. -----------------------------------------------------# idx = NA - }else if(sum(x %==% A,na.rm=TRUE) > 1){ + }else if(sum(x %eq% A,na.rm=TRUE) > 1){ #------------------------------------------------------------------------------------# # If there are multiple values of x that are the same as x, we randomly sample # # one value. # #------------------------------------------------------------------------------------# - idx = sample(A.idx[x %==% A],size=1) + idx = sample(A.idx[x %eq% A],size=1) #------------------------------------------------------------------------------------# }else{ #------------------------------------------------------------------------------------# diff --git a/R-utils/cloud.metrics.r b/R-utils/cloud.metrics.r index 881dd1ff5..d1256e6cc 100644 --- a/R-utils/cloud.metrics.r +++ b/R-utils/cloud.metrics.r @@ -389,7 +389,7 @@ cloud.metrics <<- function( x #-------------------------------------------------------------------------------------# # Keep only the last returns. # #-------------------------------------------------------------------------------------# - sellast = x$retn.number %==% x$number.retn.gp + sellast = x$retn.number %eq% x$number.retn.gp #----- Check whether to use the subset or the entire thing (to generate NA). ---------# if (sum(sellast) >= min.pts){ zlast = x$z[sellast] @@ -496,7 +496,7 @@ cloud.metrics <<- function( x }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! ( grepl("cloud.metrics",wcm[[n]]) || grepl("grid.metrics" ,wcm[[n]]) ) #---------------------------------------------------------------------------------# @@ -585,7 +585,7 @@ cloud.metrics <<- function( x zdens = data.frame(x=zzdens$x,y=zzdens$y) if (any(is.finite(zzdens$y))){ dz = mean(diff(zdens$x)) - spk = peaks(zdens$y) & zdens$y %>% 1.e-10 + spk = peaks(zdens$y) & zdens$y %gt% 1.e-10 zpeaks = zdens[spk,] o = order(zpeaks$y,decreasing=TRUE) zpeaks = zpeaks[o,] @@ -727,7 +727,7 @@ cloud.metrics <<- function( x }else{ #----- Not an error. Check whether this has been called by a friend function. ---# wcm[[n]] = paste(wcm[[n]],collapse="") - top = substring(wcm[[n]],1,4) %==% "NULL" + top = substring(wcm[[n]],1,4) %eq% "NULL" mess = mess && ! ( grepl("cloud.metrics",wcm[[n]]) || grepl("grid.metrics" ,wcm[[n]]) ) #---------------------------------------------------------------------------------# @@ -824,7 +824,7 @@ open.fcan <<- function( pt.cloud ans = rep(NA,times=length(zabove)) }else{ #----- Discard data that are not classified as vegetation. --------------------------# - zveg = ifelse( pt.cloud$pt.class %in% c(0,1,3,4,5) & pt.cloud$z %>=% zabove[1] + zveg = ifelse( pt.cloud$pt.class %in% c(0,1,3,4,5) & pt.cloud$z %ge% zabove[1] , pt.cloud$z , NA )#end ifelse diff --git a/R-utils/colour.palettes.r b/R-utils/colour.palettes.r new file mode 100644 index 000000000..34fcb9d9a --- /dev/null +++ b/R-utils/colour.palettes.r @@ -0,0 +1,410 @@ +#==========================================================================================# +#==========================================================================================# +# List of functions that generate colour palettes. They all call a single inter- # +# polation function. Most functions are derived from QGIS colour palettes. # +#------------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Blues. # + #---------------------------------------------------------------------------------------# + blues <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F7FBFF", "#DEEBF7", "#C6DBEF", "#9ECAE1", "#6BAED6", "#4292C6" + , "#2171B5", "#08519C", "#08306B") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function blues + #----- Inverse colour palette. ---------------------------------------------------------# + iblues <- function(n,alpha=1.0){ rev(blues(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + #---------------------------------------------------------------------------------------# + # BrBG. # + #---------------------------------------------------------------------------------------# + brbg <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#A6611A", "#DFC27D", "#F5F5F5", "#80CDC1", "#018571") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function brbg + #----- Inverse colour palette. ---------------------------------------------------------# + ibrbg <- function(n,alpha=1.0){ rev(brbg(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuGn. # + #---------------------------------------------------------------------------------------# + bugn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#C2D2F2", "#7AB1CC", "#63A6A6", "#338066", "#115929", "#003300") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bugn + #----- Inverse colour palette. ---------------------------------------------------------# + ibugn <- function(n,alpha=1.0){ rev(bugn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuGy. # + #---------------------------------------------------------------------------------------# + bugy <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#0050CE", "#1E64FF", "#2896FF", "#78D2FF", "#B4E6FF", "#FDFDFD" + , "#DEDEDE", "#B6B6B6", "#8E8E8E", "#666666", "#3E3E3E") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bugy + #----- Inverse colour palette. ---------------------------------------------------------# + ibugy <- function(n,alpha=1.0){ rev(bugy(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # BuPu. # + #---------------------------------------------------------------------------------------# + bupu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#EDF8FB", "#CCE0EE", "#AEC5DF", "#97A6CF", "#8B84BD", "#895FAC" + , "#853795", "#810F7C") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function bupu + #----- Inverse colour palette. ---------------------------------------------------------# + ibupu <- function(n,alpha=1.0){ rev(bupu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # Greys. # + #---------------------------------------------------------------------------------------# + greys <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#fafafa","#050505") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function greys + #----- Inverse colour palette. ---------------------------------------------------------# + igreys <- function(n,alpha=1.0){ rev(greys(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # OrRd. # + #---------------------------------------------------------------------------------------# + orrd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FEFAE4", "#FEE7B7", "#F2BB83", "#CC7549", "#A6341E", "#800000") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function orrd + #----- Inverse colour palette. ---------------------------------------------------------# + iorrd <- function(n,alpha=1.0){ rev(orrd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PiYG. # + #---------------------------------------------------------------------------------------# + piyg <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#D01C8B", "#F1B6DA", "#F7F7F7", "#B8E186", "#4DAC26") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function piyg + #----- Inverse colour palette. ---------------------------------------------------------# + ipiyg <- function(n,alpha=1.0){ rev(piyg(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PRGn. # + #---------------------------------------------------------------------------------------# + prgn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#7B3294", "#C2A5CF", "#F7F7F7", "#A6DBA0", "#008837") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function prgn + #----- Inverse colour palette. ---------------------------------------------------------# + iprgn <- function(n,alpha=1.0){ rev(prgn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuOr. # + #---------------------------------------------------------------------------------------# + puor <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#5E3C99", "#B2ABD2", "#F7F7F7", "#FDB863", "#E66101") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function puor + #----- Inverse colour palette. ---------------------------------------------------------# + ipuor <- function(n,alpha=1.0){ rev(puor(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuRd. # + #---------------------------------------------------------------------------------------# + purd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F1EEF6", "#D7B5D8", "#DF65B0", "#DD1C77", "#980043") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function purd + #----- Inverse colour palette. ---------------------------------------------------------# + ipurd <- function(n,alpha=1.0){ rev(purd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # PuBuGn. # + #---------------------------------------------------------------------------------------# + pubugn <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#F6EFF7", "#D6DAEB", "#B1C5DF", "#80B2D4", "#51A2C0", "#2694A1" + , "#10817E", "#016C59") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function pubugn + #----- Inverse colour palette. ---------------------------------------------------------# + ipubugn <- function(n,alpha=1.0){ rev(pubugn(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # RdBu. # + #---------------------------------------------------------------------------------------# + rdbu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c("#CA0020", "#F4A582", "#F7F7F7", "#92C5DE", "#0571B0") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function rdbu + #----- Inverse colour palette. ---------------------------------------------------------# + irdbu <- function(n,alpha=1.0){ rev(rdbu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # RdGy. # + #---------------------------------------------------------------------------------------# + rdgy <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = C( "#CA0020", "#F4A582", "#FFFFFF", "#BABABA", "#404040") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function rdgy + #----- Inverse colour palette. ---------------------------------------------------------# + irdgy <- function(n,alpha=1.0){ rev(rdgy(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # YlGnBu. # + #---------------------------------------------------------------------------------------# + ylgnbu <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FFFFCC", "#CAEABF", "#93D5B6", "#5CC1C0", "#3BA6C1", "#2F87BA" + , "#295FA9", "#253494") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function ylgnbu + #----- Inverse colour palette. ---------------------------------------------------------# + iylgnbu <- function(n,alpha=1.0){ rev(ylgnbu(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # YlOrRd. # + #---------------------------------------------------------------------------------------# + ylorrd <<- function(n,alpha=1.0){ + #----- Color entries. ---------------------------------------------------------------# + nodes = c( "#FFFFB2", "#FECC5C", "#FD8D3C", "#F03B20", "#BD0026") + #------------------------------------------------------------------------------------# + + #----- Call the interpolator. -------------------------------------------------------# + ans = colour.interpol(nodes=nodes,n=n) + ans = scales::alpha(colour=ans,alpha=alpha) + return(ans) + #------------------------------------------------------------------------------------# + }#end function ylorrd + #----- Inverse colour palette. ---------------------------------------------------------# + iylorrd <- function(n,alpha=1.0){ rev(ylorrd(n=n,alpha=alpha))} + #---------------------------------------------------------------------------------------# + + + + + + + + #---------------------------------------------------------------------------------------# + # For the following palettes, we use the default from package "viridis". We only # + # define the inverse functions for convenience. # + #---------------------------------------------------------------------------------------# + iinferno <- function(n,alpha=1.0){ inferno(n=n,alpha=alpha,direction=-1)} + imagma <- function(n,alpha=1.0){ magma (n=n,alpha=alpha,direction=-1)} + iviridis <- function(n,alpha=1.0){ viridis(n=n,alpha=alpha,direction=-1)} + #---------------------------------------------------------------------------------------# + + + + + +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/colour.utils.r b/R-utils/colour.utils.r index 6998de6c9..2d11c65a9 100644 --- a/R-utils/colour.utils.r +++ b/R-utils/colour.utils.r @@ -172,3 +172,45 @@ blacken <<- function(colour,f=c(s=0.50,v=0.50),...){ }#end function blacken #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# General function that interpolates nodes by using HSV. # +#------------------------------------------------------------------------------------------# +colour.interpol <<- function(nodes,n){ + #----- Decompose colours. --------------------------------------------------------------# + rgbmat = data.table(t(col2rgb(nodes))) + #---------------------------------------------------------------------------------------# + + + #----- Find the reference points for the interpolation functions. ----------------------# + rgbmat$x = seq(from=0,to=1,length.out=nrow(rgbmat)) + #---------------------------------------------------------------------------------------# + + + #----- Create functions to interpolate. ------------------------------------------------# + f.red = splinefun(x=rgbmat$x,y=rgbmat$red ,method="monoH.FC") + f.green = splinefun(x=rgbmat$x,y=rgbmat$green,method="monoH.FC") + f.blue = splinefun(x=rgbmat$x,y=rgbmat$blue ,method="monoH.FC") + #---------------------------------------------------------------------------------------# + + + #----- Create output table. ------------------------------------------------------------# + rgbout = data.table( x = seq(from=0,to=1,length.out=n) ) + rgbout$red = round(pmax(0,pmin(255,f.red (rgbout$x)))) + rgbout$green = round(pmax(0,pmin(255,f.green(rgbout$x)))) + rgbout$blue = round(pmax(0,pmin(255,f.blue (rgbout$x)))) + #---------------------------------------------------------------------------------------# + + + #------ Colour rainbow. ----------------------------------------------------------------# + ans = with(rgbout,rgb(red=red,green=green,blue=blue,maxColorValue=255)) + return(ans) + #---------------------------------------------------------------------------------------# +}#end colour.interpol +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/commonest.r b/R-utils/commonest.r index 5431722fa..57b82a993 100644 --- a/R-utils/commonest.r +++ b/R-utils/commonest.r @@ -8,7 +8,7 @@ commonest <<- function(x,na.rm=FALSE) { unique.x = unique(x) nu = length(unique.x) idx = which.max(tabulate(match(x, unique.x))) - fine = is.finite(idx) && idx %>=% 1 && idx %<=% nu + fine = is.finite(idx) && idx %ge% 1 && idx %le% nu if (fine){ often = unique.x[idx] }else{ @@ -30,9 +30,9 @@ commonest <<- function(x,na.rm=FALSE) { weighted.commonest <<- function(x,w,na.rm=FALSE) { #------ Discard NA entries. ------------------------------------------------------------# if (na.rm){ - keep = (! is.na(x)) & (w %>% 0) + keep = (! is.na(x)) & (w %gt% 0) }else{ - keep = w %>% 0 + keep = w %gt% 0 }#end if (na.rm) #---------------------------------------------------------------------------------------# diff --git a/R-utils/coord.utils.r b/R-utils/coord.utils.r index 9583dde7e..1314931b5 100644 --- a/R-utils/coord.utils.r +++ b/R-utils/coord.utils.r @@ -471,7 +471,7 @@ dec2dms <<- function(lon=NULL,lat=NULL){ degree = sprintf("%3i" ,floor(abs(lon)) ) minute = sprintf("%2.2i",floor(abs(lon) %% 1 * 60) ) second = sprintf("%2.2i",floor((abs(lon) %% 1 * 60) %% 1 * 60)) - hemisf = ifelse(lon %>=% 0,"E","W") + hemisf = ifelse(lon %ge% 0,"E","W") olon = paste0(degree,"-",minute,"\'",second,"\"",hemisf) olon = ifelse(is.finite(lon),olon,NA_character_) }else{ @@ -486,7 +486,7 @@ dec2dms <<- function(lon=NULL,lat=NULL){ degree = sprintf("%2i" ,floor(abs(lat)) ) minute = sprintf("%2.2i",floor(abs(lat) %% 1 * 60) ) second = sprintf("%2.2i",floor((abs(lat) %% 1 * 60) %% 1 * 60)) - hemisf = ifelse(lat %>=% 0,"N","S") + hemisf = ifelse(lat %ge% 0,"N","S") olat = paste0(degree,"-",minute,"\'",second,"\"",hemisf) olat = ifelse(is.finite(lat),olat,NA_character_) }else{ diff --git a/R-utils/curve.features.r b/R-utils/curve.features.r index 4a4fdf080..a8b48d358 100644 --- a/R-utils/curve.features.r +++ b/R-utils/curve.features.r @@ -15,14 +15,13 @@ curve.features <<- function( x , span = 3L , do.pad = TRUE , xscale = max(abs(x),na.rm=TRUE) - , toler = 10000. * .Machine$double.eps - , toler2 = 100. * .Machine$double.eps + , toler = 1.e-4 ){ #----- Make sure span is odd. ----------------------------------------------------------# span = as.integer(span) - if ( ! ((span %% 2) %==% 1 && span %>=% 3L)){ + if ( ! ((span %% 2) %eq% 1 && span %ge% 3L)){ stop(paste0(" Invalid span (",span,")! It must be an odd number (3 or greater)!")) - }#end if ( ! ((span %% 2) %==% 1)) + }#end if ( ! ((span %% 2) %eq% 1)) #---------------------------------------------------------------------------------------# @@ -41,7 +40,7 @@ curve.features <<- function( x #---------------------------------------------------------------------------------------# # Make sure that x can be normalised by the given scale. # #---------------------------------------------------------------------------------------# - if (xscale %>% 0.){ + if (xscale %gt% 0.){ x = x / xscale }else{ stop(paste0("Invalid xscale (",xscale,"). It must be positive.")) @@ -57,12 +56,22 @@ curve.features <<- function( x im1 = pmax(i-1, 1) #----- First derivative. ---------------------------------------------------------------# xp = x[ip1] - x[im1] - xp = ifelse(test=abs(xp) %>=% toler, yes=xp, no = 0.) + xpscale = max(abs(xp),na.rm=TRUE) + if (xpscale %gt% 0.){ + xp = ifelse(test= abs( xp / xpscale ) %ge% toler, yes= xp / xpscale, no = 0.) + }else{ + xp = 0. * xp + }#end if (xpscale %gt% 0.) #----- Second derivative. --------------------------------------------------------------# - xpp = x[ip1] - 2.*x[i] + x[im1] - xpp[1] = xpp[2] - xpp[nx] = xpp[nx-1] - xpp = ifelse(test=abs(xpp) %>=% toler2, yes=xpp, no = 0.) + xpp = x[ip1] - 2.*x[i] + x[im1] + xpp[1] = xpp[2] + xpp[nx] = xpp[nx-1] + xppscale = max(abs(xpp),na.rm=TRUE) + if (xppscale %gt% 0.){ + xpp = ifelse(test= abs( xpp / xppscale ) %ge% toler, yes= xpp / xppscale, no = 0.) + }else{ + xpp = 0. * xpp + }#end if (xppscale %gt% 0.) #---------------------------------------------------------------------------------------# @@ -79,6 +88,7 @@ curve.features <<- function( x # Create an zero matrix to pad the answers. # #---------------------------------------------------------------------------------------# zero = matrix(data=0.,nrow=soff,ncol=span) + x.mat = t(apply(X=rbind(zero,embed(x=x ,dimension=span),zero),MARGIN=1,FUN=rev)) xp.mat = t(apply(X=rbind(zero,embed(x=xp ,dimension=span),zero),MARGIN=1,FUN=rev)) xpp.mat = t(apply(X=rbind(zero,embed(x=xpp,dimension=span),zero),MARGIN=1,FUN=rev)) #---------------------------------------------------------------------------------------# @@ -102,30 +112,83 @@ curve.features <<- function( x xpp.left = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "left" ) xpp.right = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "right" ) xpp.both = apply( X = xpp.mat, MARGIN = 1, FUN = signblock, block = "all" ) - #----- Make sure we only select one element in the neighbourhood. ----------------------# - xp.zeroest = apply( X = abs(xp.mat[,smid]) < abs(xp.mat[,-smid,drop=FALSE]) - , MARGIN = 1 - , FUN = all - )#end apply - xpp.zeroest = apply( X = abs(xpp.mat[,smid]) < abs(xpp.mat[,-smid,drop=FALSE]) - , MARGIN = 1 - , FUN = all - )#end apply #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # Find maxima. # + # Find features. # #---------------------------------------------------------------------------------------# - ans = data.frame( max = xp.zeroest & xp.left*xp.right == -1 & xpp.both == -1 - , min = xp.zeroest & xp.left*xp.right == -1 & xpp.both == +1 - , iph = xpp.zeroest & xpp.left*xpp.right == -1 & xpp.left*xp.both == -1 - , ipv = xpp.zeroest & xpp.left*xpp.right == -1 & xpp.left*xp.both == +1 + ans = data.frame( max = xp.left*xp.right == -1 & xpp.both == -1 + , min = xp.left*xp.right == -1 & xpp.both == +1 + , iph = xpp.left*xpp.right == -1 & xpp.left*xp.both == -1 + , ipv = xpp.left*xpp.right == -1 & xpp.left*xp.both == +1 )#end data.frame #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # It is often the case that neighbouring cells are selected. In this case we # + # only keep one in the neighbourhood. # + #---------------------------------------------------------------------------------------# + #---- Maximum. Pick the maximum in the immediate vicinity. -----------------------------# + imax = which(ans$max) + if (length(imax) > 1){ + xtest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xoff = x[imax+o] + xoff = ifelse(test=(imax+o) %in% imax,yes=xoff,no=-Inf) + xtest = cbind(xtest,xoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xrefr = apply(X=xtest[,-smid],MARGIN=1,FUN=max) + iskip = xtest[,smid] < xrefr + ans$max[imax[iskip]] = FALSE + }#end if (length(imax) > 1) + #---- Minimum. Pick the minimum in the immediate vicinity. -----------------------------# + imin = which(ans$min) + if (length(imin) > 1){ + xtest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xoff = x[imin+o] + xoff = ifelse(test=(imin+o) %in% imin,yes=xoff,no=+Inf) + xtest = cbind(xtest,xoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xrefr = apply(X=xtest[,-smid],MARGIN=1,FUN=min) + iskip = xtest[,smid] > xrefr + ans$min[imin[iskip]] = FALSE + }#end if (length(imin) > 1) + #---- Horizontal inflection point. Pick the flattest point in the immediate vicinity. -# + iiph = which(ans$iph) + if (length(iiph) > 1){ + xptest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xpoff = xp[iiph+o] + xpoff = ifelse(test=(iiph+o) %in% iiph,yes=xpoff,no=+Inf) + xptest = cbind(xptest,xpoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xprefr = apply(X=abs(xptest[,-smid]),MARGIN=1,FUN=min) + iskip = abs(xptest[,smid]) > xprefr + ans$iph[iiph[iskip]] = FALSE + }#end if (length(iiph) > 1) + #---- Vertical inflection point. Pick the steepest point in the immediate vicinity. ---# + iipv = which(ans$ipv) + if (length(iipv) > 1){ + xptest = NULL + for (o in seq(from=-soff,to=soff,by=1)){ + xpoff = xp[iipv+o] + xpoff = ifelse(test=(iipv+o) %in% iipv,yes=xpoff,no=0.) + xptest = cbind(xptest,xpoff) + }#end for (o in seq(from=-soff,to=soff,by=1)) + xprefr = apply(X=abs(xptest[,-smid]),MARGIN=1,FUN=max) + iskip = abs(xptest[,smid]) < xprefr + ans$ipv[iipv[iskip]] = FALSE + }#end if (length(iipv) > 1) + #---------------------------------------------------------------------------------------# + + + + #----- Flag edges as inflection points in case their first derivative is not zero. -----# ans$iph[ 1] = ans$max[ 1] || (xp.right[ 1] == -1) ans$iph[nx] = ans$max[nx] || (xp.left [nx] == +1) diff --git a/R-utils/del.bad.rshort.r b/R-utils/del.bad.rshort.r index 4e5383ecb..0e4f95287 100644 --- a/R-utils/del.bad.rshort.r +++ b/R-utils/del.bad.rshort.r @@ -115,7 +115,7 @@ del.bad.rshort <<- function(dat,rshort.day.min=0.,par.frac.min=0.80,alb.max=0.30 #---------------------------------------------------------------------------------------# # We don't let radiation exceed maximum. # #---------------------------------------------------------------------------------------# - cat (" - Ensure daytime radiation does not exceed maximum.") + cat0(" - Ensure daytime radiation does not exceed maximum.") dat$rshort.in[dat$daytime] = pmin(dat$rshort.in[dat$daytime],dat$rshort.pot[dat$daytime]) dat$par.in [dat$daytime] = pmin(dat$par.in [dat$daytime],dat$par.pot [dat$daytime]) #---------------------------------------------------------------------------------------# diff --git a/R-utils/del.outliers.r b/R-utils/del.outliers.r index 7749fd482..99d206fa9 100644 --- a/R-utils/del.outliers.r +++ b/R-utils/del.outliers.r @@ -102,9 +102,9 @@ del.outliers <<- function( x # Vector to be evaluated # Discard suspicious data. # #---------------------------------------------------------------------------------# is.infty = is.infinite(thisnorm) - is.unreal = abs(thisnorm ) %>% max.real - is.outlier = abs(thisnorm ) %>% max.fine - is.spike = abs(thisnorm-neigh.norm) %>=% spike.min + is.unreal = abs(thisnorm ) %gt% max.real + is.outlier = abs(thisnorm ) %gt% max.fine + is.spike = abs(thisnorm-neigh.norm) %ge% spike.min weird = is.infty | is.unreal | (is.outlier & is.spike) thisvar[weird] = NA_real_ nweird = sum(weird) @@ -191,9 +191,9 @@ del.outliers <<- function( x # Vector to be evaluated # Discard suspicious data. # #---------------------------------------------------------------------------------# is.infty = is.infinite(thisnorm) - is.unreal = abs(thisnorm ) %>% max.real - is.outlier = abs(thisnorm ) %>% max.fine - is.spike = abs(thisnorm-neigh.norm) %>=% spike.min + is.unreal = abs(thisnorm ) %gt% max.real + is.outlier = abs(thisnorm ) %gt% max.fine + is.spike = abs(thisnorm-neigh.norm) %ge% spike.min weird = is.infty | is.unreal | (is.outlier & is.spike) thisvar[weird] = NA_real_ nweird = sum(weird) diff --git a/R-utils/demography.rates.r b/R-utils/demography.rates.r index e421197b0..deacd47c2 100644 --- a/R-utils/demography.rates.r +++ b/R-utils/demography.rates.r @@ -834,7 +834,7 @@ acc.recruitment.rate <<- function( property expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -886,7 +886,7 @@ acc.recruitment.rate <<- function( property expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1061,7 +1061,7 @@ acc.mortality.rate <<- function( property expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1113,7 +1113,7 @@ acc.mortality.rate <<- function( property expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1188,7 +1188,7 @@ acc.growth.rate <<- function(nok,lok,pop,gpop=pop,dtime,taxon,R=100,itb.max=50){ expected.tx = unlist(sapply(X=boot.tx,FUN=c)["t0",]) q025.tx = sapply(X= boot.tx ,FUN=boot.ci.lower,conf=0.95,type="perc") q975.tx = sapply(X= boot.tx ,FUN=boot.ci.upper,conf=0.95,type="perc") - fine = all(expected.tx %>=% q025.tx) && all(expected.tx %<=% q975.tx) + fine = all(expected.tx %ge% q025.tx) && all(expected.tx %le% q975.tx) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# @@ -1218,7 +1218,7 @@ acc.growth.rate <<- function(nok,lok,pop,gpop=pop,dtime,taxon,R=100,itb.max=50){ expected.gb = boot.gb$t0 q025.gb = boot.ci.lower(boot.out=boot.gb,conf=0.95,type="perc") q975.gb = boot.ci.upper(boot.out=boot.gb,conf=0.95,type="perc") - fine = all(expected.gb %>=% q025.gb) && all(expected.gb %<=% q975.gb) + fine = all(expected.gb %ge% q025.gb) && all(expected.gb %le% q975.gb) }#end while ((! fine) && (it < itb.max)) if (it == itb.max) browser() #---------------------------------------------------------------------------------------# diff --git a/R-utils/density.safe.r b/R-utils/density.safe.r index 58702a79e..7c0601d3f 100644 --- a/R-utils/density.safe.r +++ b/R-utils/density.safe.r @@ -49,7 +49,7 @@ density.safe <<- function( x }else{ #----- Select the valid x and e values. ---------------------------------------------# - sel = x %>% 0 & e %>=% 0 + sel = (x %gt% 0) & (e %ge% 0) n.x.use = sum(sel) #------------------------------------------------------------------------------------# @@ -104,16 +104,16 @@ density.safe <<- function( x # (for example, negative CO2 concentration). # #---------------------------------------------------------------------------------------# if (is.finite(xmin)){ - bye = ans$x %<% xmin + bye = ans$x %lt% xmin xadd = min(ans$x[! bye],na.rm=TRUE) - iadd = which(ans$x %==% xadd) + iadd = which(ans$x %eq% xadd) ans$y[iadd] = ans$y[iadd] + sum(ans$y[bye]) ans$y[bye ] = 0. }#end if(is.finite(xmin)) if (is.finite(xmax)){ - bye = ans$x %>% xmax + bye = ans$x %gt% xmax xadd = max(ans$x[! bye],na.rm=TRUE) - iadd = which(ans$x %==% xadd) + iadd = which(ans$x %eq% xadd) ans$y[iadd] = ans$y[iadd] + sum(ans$y[bye]) ans$y[bye ] = 0. }#end if(is.finite(xmax)) diff --git a/R-utils/desc.unit.r b/R-utils/desc.unit.r index ca646d470..fa52af9c3 100644 --- a/R-utils/desc.unit.r +++ b/R-utils/desc.unit.r @@ -3,7 +3,7 @@ # This function creates an expression object that has the description and the units # # with sub-scripts, superscripts and stuff. # #------------------------------------------------------------------------------------------# -desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE){ +desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE,twolines=FALSE){ if (missing(desc) | missing(unit)){ cat(" - Missing \"desc\": ",missing(desc),"\n") cat(" - Missing \"unit\": ",missing(unit),"\n") @@ -26,14 +26,25 @@ desc.unit <<- function(desc,unit,bracket=TRUE,dxpr=FALSE){ }#end if }else{ if (dxpr){ - if (bracket){ + if (bracket && twolines){ + answer = parse(text=paste0("atop(",desc,",paste(\"[\",",unit,",\"]\"))")) + }else if (bracket){ answer = parse(text=paste0("paste(",desc,",\" [\",",unit,",\"]\")")) + }else if (twolines){ + answer = parse(text=paste0("atop(",desc,",",unit,")")) }else{ answer = parse(text=paste0("paste(",desc,",\" \",",unit,",\"\")")) }#end if }else{ - if (bracket){ + if (bracket && twolines){ + answer = parse( text=paste0( "atop(paste(\"",desc,"\")," + , "paste(\"[\",",unit,",\"]\"))" + )#end paste0 + )#end paste + }else if (bracket){ answer = parse(text=paste0("paste(\"",desc,"\",\" [\",",unit,",\"]\")")) + }else if (twolines){ + answer = parse(text=paste0("atop(paste(\"",desc,"\"),paste(\"",unit,"\"))")) }else{ answer = parse(text=paste0("paste(\"",desc,"\",\" \",",unit,",\"\")")) }#end if diff --git a/R-utils/dynamics.proofer.r b/R-utils/dynamics.proofer.r index 7a9e9dd0e..4981c883a 100644 --- a/R-utils/dynamics.proofer.r +++ b/R-utils/dynamics.proofer.r @@ -84,7 +84,7 @@ death.proofer <<- function( datum # Forest inventory data set for (y in sequence(n.years)){ this.dead = paste(dead.pref,year4[y],sep=vsep) if (this.dead %in% names(datum)){ - sel = as.numeric(datum[[this.dead]]) %==% 1 + sel = as.numeric(datum[[this.dead]]) %eq% 1 datum$year.death[sel] = pmin(datum$year.death[sel],year4[y]) }#end if (this.dead %in% names(datum)) #---------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ death.proofer <<- function( datum # Forest inventory data set for (y in sequence(n.years)){ this.dbh = paste(dbh.pref ,year4[y],sep=vsep) alive = ( is.finite(datum[[this.dbh]]) - & datum$year.death %<=% year4[y] + & datum$year.death %le% year4[y] )#end alive datum$year.death[alive] = next.year[y] #---------------------------------------------------------------------------------# @@ -966,7 +966,7 @@ dbh.gap.filler <<- function( datum #----- Find out whether to fill the data. -------------------------------------------# - dbh.miss = is.na(datum[[dbh.label]]) | datum[[dbh.label]] %<% 0 + dbh.miss = is.na(datum[[dbh.label]]) | datum[[dbh.label]] %lt% 0 if (any(is.na(dbh.miss))){ cat0(" dbh.miss has NA!") }#end if @@ -979,7 +979,7 @@ dbh.gap.filler <<- function( datum # been taken care of before, but after discarding some bad measurements a few other # # pre-recruitment points may appear. # #------------------------------------------------------------------------------------# - bye = datum[[dbh.label]] %>% 0 & is.na(dbh.table[,y]) + bye = datum[[dbh.label]] %gt% 0 & is.na(dbh.table[,y]) message = paste0(dbh.label,"=",abs(datum[[dbh.label]]) ," is pre-recruitment thus removed",sep="") datum[[notes.label]][bye] = concatenate.message(datum[[notes.label]][bye] @@ -1045,8 +1045,8 @@ dbh.gap.filler <<- function( datum # Choose the years to update. It has to be NA and it has to be post- # # recruitment to be accepted. # #------------------------------------------------------------------------------------# - is.recruited = ( dbh.guess %>% ( dbh.min + dbh.min.toler ) - | datum[[dbh.label]] %>=% dbh.min + is.recruited = ( dbh.guess %gt% ( dbh.min + dbh.min.toler ) + | datum[[dbh.label]] %ge% dbh.min | datum$year.recruit <= year4[y] ) is.alive = datum$year.death > year4[y] update.year = dbh.miss & is.recruited & is.alive diff --git a/R-utils/elliptical.utils.r b/R-utils/elliptical.utils.r index f321a9772..a048d6d92 100644 --- a/R-utils/elliptical.utils.r +++ b/R-utils/elliptical.utils.r @@ -5,16 +5,16 @@ elliptical.radius <<- function(x,y,theta,degrees=FALSE){ if (degrees) theta = theta * pio180 - both.zero = x %==% 0 & y %==% 0 - x.zero = x %==% 0 & y %!=% 0 - y.zero = x %!=% 0 & y %==% 0 + both.zero = (x %eq% 0) & (y %eq% 0) + x.zero = (x %eq% 0) & (y %ne% 0) + y.zero = (x %ne% 0) & (y %eq% 0) x[x.zero] = sqrt(.Machine$double.eps) * y[x.zero] y[y.zero] = sqrt(.Machine$double.eps) * x[y.zero] - ans = ifelse( both.zero - , 0 - , x*y / sqrt(y*y*(cos(theta))^2+x*x*(sin(theta))^2) + ans = ifelse( test = both.zero + , yes = 0 + , no = x*y / sqrt(y*y*(cos(theta))^2+x*x*(sin(theta))^2) )#end ifelse return(ans) @@ -36,9 +36,9 @@ elliptical.area <<- function(x,y,theta0=0,theta1=2*pi,degrees=FALSE){ theta1 = theta1 * pio180 }#end if - both.zero = x %==% 0 & y %==% 0 - x.zero = x %==% 0 & y %!=% 0 - y.zero = x %!=% 0 & y %==% 0 + both.zero = ( x %eq% 0 ) & ( y %eq% 0 ) + x.zero = ( x %eq% 0 ) & ( y %ne% 0 ) + y.zero = ( x %ne% 0 ) & ( y %eq% 0 ) x[x.zero] = sqrt(.Machine$double.eps) * y[x.zero] y[y.zero] = sqrt(.Machine$double.eps) * x[y.zero] diff --git a/R-utils/entropy.r b/R-utils/entropy.r new file mode 100644 index 000000000..a795ab0bd --- /dev/null +++ b/R-utils/entropy.r @@ -0,0 +1,142 @@ +#==========================================================================================# +#==========================================================================================# +# Functions to help computing entropy fluxes. Most of the theory can be found in the # +# following papers. # +# # +# Quijano JC , Lin H. 2015. Is spatially integrated entropy production useful to predict # +# the dynamics of ecosystems? Ecol. Model., 313: 341-354. # +# doi:10.1016/j.ecolmodel.2015.06.012 (QJ15). # +# # +# Wright SE, Scott DS, Haddow JB , Rosen MA. 2001. On the entropy of radiative heat # +# transfer in engineering thermodynamics. Int. J. Eng. Sci., 39: 1691-1706. # +# doi:10.1016/S0020-7225(01)00024-6 (W01). # +# # +# Wu W , Liu Y. 2010. Radiation entropy flux and entropy production of the Earth system. # +# Rev. Geophys., 48: RG2003. doi:10.1029/2008RG000275 (WL10). # +# # +#------------------------------------------------------------------------------------------# + + +#------ Handy constants. ------------------------------------------------------------------# +w01.rf.sbeam <<- 2.31e-4 * tsun +w01.c0 <<- -45 / (4. * pi^4) +w01.c1 <<- +2.336 +w01.c2 <<- -0.260 +w01.rpfac <<- 4./3. +emis.atm <<- 0.85 # From Brunsell et al. (2011) +emis.sfc <<- 0.98 # From ED2 +#------------------------------------------------------------------------------------------# + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to shortwave radiation, following Q15, # +# who base their formulation on WL10 (which is done for the top of the atmosphere). This # +# assumes that albedo is the same for direct and diffuse radiation, and that all reflected # +# radiation is diffuse. # +#------------------------------------------------------------------------------------------# +fxentropy.rshort <<- function(rsdnwd,rswnet,rsbeam){ + + #----- Find derived radiation properties. ----------------------------------------------# + rsdiff = 0. * rsdnwd + pmax(0.,rsdnwd - rsbeam) # Diffuse radiation as residual + rsupwd = pmax(0.,rsdnwd - rswnet) # Upward radiation + albedo = 0. * rsdnwd + ifelse( test = rsdnwd %gt% 0. # Albedo + , yes = rsupwd / rsdnwd # + , no = 0.1 # + )#end ifelse # + #---------------------------------------------------------------------------------------# + + + + #----- Entropy due to direct radiation. ------------------------------------------------# + fs.rsbeam = w01.rf.sbeam * (1. - albedo) * rsbeam / tsun + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation. -----------------------------------------------# + delta = rsdiff / pi / radsol + rf.rsdiff = ifelse( test = delta %gt% 0. + , yes = ( w01.c0 * ( w01.c1 + w01.c2 * delta) * log(delta) + 1. ) + * w01.rpfac + , no = 0. + )#end ifelse + fs.rsdiff = rf.rsdiff * (1. - albedo) * rsdiff / tsun + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Total entropy flux due to solar radiation. # + #---------------------------------------------------------------------------------------# + ans = fs.rsbeam + fs.rsdiff + return(ans) + #---------------------------------------------------------------------------------------# +}#end sflux.rshort +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to downwelling longwave radiation, follow- # +# ing Q15, who base their formulation on WL10 and W01. Two differences from their # +# approach: # +# 1. We don't use the air temperature, but the equivalent atmospheric temperature, similar # +# to H10 (unless the user provides atmospheric temperature, in which case their values # +# take priority). # +# 2. We also account for the small amount of downwelling LW irradiance that is not # +# absorbed, using Kirchhoff's law. # +#------------------------------------------------------------------------------------------# +fxentropy.rldnwd <<- function(rldnwd,tatm.k){ + + #----- Find derived radiation properties. ----------------------------------------------# + if (missing(tatm.k)){ + tatm.k = sqrt(sqrt(rldnwd / (emis.atm * stefan))) + }#end if (missing(tsfc.k)) + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation (note we add the "LW albedo"). -----------------# + epsil = emis.atm + rf.rldnwd = ( w01.c0 * ( w01.c1 + w01.c2 * epsil) * log(epsil) + 1. ) * w01.rpfac + fs.rldnwd = rf.rldnwd * emis.sfc * rldnwd / tatm.k + #---------------------------------------------------------------------------------------# + + return(fs.rldnwd) + #---------------------------------------------------------------------------------------# +}#end sflux.rldnwd +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# This function finds the entropy flux due to upwelling longwave radiation, following # +# Q15, who base their formulation on WL10 and W01. Because skin temperature may be # +# available, we use that instead of calculating in here (unless skin temperature is not # +# provided). # +#------------------------------------------------------------------------------------------# +fxentropy.rlupwd <<- function(rlupwd,tsfc.k){ + + #----- Find derived radiation properties. ----------------------------------------------# + if (missing(tsfc.k)){ + tsfc.k = sqrt(sqrt(rlupwd / (emis.sfc * stefan))) + }#end if (missing(tsfc.k)) + #---------------------------------------------------------------------------------------# + + + #----- Entropy due to diffuse radiation (note we add the "LW albedo"). -----------------# + epsil = emis.sfc + rf.rlupwd = ( w01.c0 * ( w01.c1 + w01.c2 * epsil) * log(epsil) + 1. ) * w01.rpfac + fs.rlupwd = rf.rlupwd * rlupwd / tsfc.k + #---------------------------------------------------------------------------------------# + + return(fs.rlupwd) + #---------------------------------------------------------------------------------------# +}#end sflux.rlupwd +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/epolygon.r b/R-utils/epolygon.r index df955beb2..e0dec5726 100644 --- a/R-utils/epolygon.r +++ b/R-utils/epolygon.r @@ -47,19 +47,14 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL if (end > start) { den = density[i] if (is.na(den) || den < 0){ - if (R.Version()$major == "3"){ - polygon( x = xy$x[start:(end - 1)] - , y = xy$y[start:(end - 1)] - , col = col[i] - , border = NA - , density = den - , lty = lty[i] - , ... - )#end polygon - }else{ - .Internal(polygon( xy$x[start:(end - 1)] - , xy$y[start:(end - 1)], col[i], NA, lty[i], ...)) - }#end if + polygon( x = xy$x[start:(end - 1)] + , y = xy$y[start:(end - 1)] + , col = col[i] + , border = NA + , density = den + , lty = lty[i] + , ... + )#end polygon }else if (den > 0) { epolygon.fullhatch( x = xy$x[start:(end - 1)] , y = xy$y[start:(end - 1)] @@ -77,18 +72,16 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL }#end if start = end + 1 }#end for - if (R.Version()$major == "3"){ - polygon( x = xy$x - , y = xy$y - , density = 0 - , col = NA - , border = border - , lty = lty - , ... - )#end polygon - }else{ - .Internal(polygon(xy$x, xy$y, NA, border, lty, ...)) - }#end if + + polygon( x = xy$x + , y = xy$y + , density = 0 + , col = NA + , border = border + , lty = lty + , ... + )#end polygon + }else{ if (is.logical(border)) { if (!is.na(border) && border){ @@ -98,18 +91,15 @@ epolygon <<- function(x, y = NULL, density = NULL, angle = 45, border = NULL }#end if }#end if - if (R.Version()$major == "3"){ - polygon( x = xy$x - , y = xy$y - , density = NULL - , col = col - , border = border - , lty = lty - , ... - )#end polygon - }else{ - .Internal(polygon(xy$x, xy$y, col, border, lty, ...)) - }#end if + polygon( x = xy$x + , y = xy$y + , density = NULL + , col = col + , border = border + , lty = lty + , ... + )#end polygon + }#end if }#end function #==========================================================================================# diff --git a/R-utils/fuse.fiss.utils.r b/R-utils/fuse.fiss.utils.r index 12d330bc4..4224c50d4 100644 --- a/R-utils/fuse.fiss.utils.r +++ b/R-utils/fuse.fiss.utils.r @@ -250,15 +250,21 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ #---------------------------------------------------------------------------------# - }else if ( length(grep(pattern="dead." ,x=vname)) > 0 - || length(grep(pattern="canopy." ,x=vname)) > 0 - || length(grep(pattern="height." ,x=vname)) > 0 - || length(grep(pattern="band." ,x=vname)) > 0 - || length(grep(pattern="pom." ,x=vname)) > 0 - || length(grep(pattern="ladder" ,x=vname)) > 0 - || length(grep(pattern="cnpj" ,x=vname)) > 0 - || length(grep(pattern="soil" ,x=vname)) > 0 - || length(grep(pattern="code" ,x=vname)) > 0 + }else if ( any(grepl(pattern="dead." ,x=vname)) + || any(grepl(pattern="canopy." ,x=vname)) + || any(grepl(pattern="height." ,x=vname)) + || any(grepl(pattern="band." ,x=vname)) + || any(grepl(pattern="pom." ,x=vname)) + || any(grepl(pattern="ladder" ,x=vname)) + || any(grepl(pattern="cnpj" ,x=vname)) + || any(grepl(pattern="soil" ,x=vname)) + || any(grepl(pattern="code" ,x=vname)) + || any(grepl(pattern="plant.ID" ,x=vname)) + || any(grepl(pattern="voucher.number",x=vname)) + || any(grepl(pattern="status" ,x=vname)) + || any(grepl(pattern="tax.reliab" ,x=vname)) + || any(grepl(pattern="flag" ,x=vname)) + || any(grepl(pattern="n.tag" ,x=vname)) ){ #---- Variables that we update only if they have NA. -----------------------------# sel = ( is.na(receptor[[vname]]) @@ -332,7 +338,7 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ }else{ #----- Missing instructions, quit... ---------------------------------------------# - cat (" * VARIABLE: ",vname," has no instrucion!","\n") + cat (" * VARIABLE: ",vname," has no instruction!","\n") stop("Could not process the variable, sorry!") #---------------------------------------------------------------------------------# }#end if @@ -351,19 +357,25 @@ fuse.trees <<- function(receptor,donor,don.2.rec,survey.years,sci.strict=TRUE){ #==========================================================================================# #==========================================================================================# -# Function blend.trees # +# Function merge.trees # # # -# This function blends one tree to the other. This is slightly different from the # -# fusion routine above because blending adds information but compares the periods for # +# This function merges one tree to the other. This is slightly different from the # +# fusion routine above because merging adds information but compares the periods for # # which information is to be added. The other difference is that IT CANNOT BE USED IN # # VECTOR MODE: it works between one donor and one receptor only. # # # # receptor -- The data frame that will receive the data # # donor -- The data frame that will send the data # -# don.2.rec -- The indices of the receptor that will receive the data. # -# update.yr.notes -- Should we use notes.orig to make year notes? (TRUE/FALSE). # +# years.merge -- Years to merge data. # +# use.xy -- Variable to force using either donor ("from") or receptor ("to") # +# coordinate information. Default (NA_character_) is to check for # +# merged year and data availability. # +# use.tag -- Variable to force using either donor ("from") or receptor ("to") # +# tag information. Default (NA_character_) is to check for # +# merged year and data availability. # #------------------------------------------------------------------------------------------# -blend.trees = function(receptor,donor,years.blend){ +merge.trees = function(receptor,donor,years.merge + ,use.xy=NA_character_,use.tag=NA_character_){ #---------------------------------------------------------------------------------------# # Get the list of all variables. # @@ -394,7 +406,7 @@ blend.trees = function(receptor,donor,years.blend){ vname = variables[nv] old = paste("old",vname,sep=".") first = paste(vname,"1st",sep=".") - blend.input = paste(substring(vname,1,nchar(vname)-5),years.blend,sep=".") + merge.input = paste(substring(vname,1,nchar(vname)-5),years.merge,sep=".") #------------------------------------------------------------------------------------# @@ -402,16 +414,17 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------------# # Decide what to do based on the variable. # #------------------------------------------------------------------------------------# - if ( length(grep(pattern="trans" ,x=vname)) > 0 || - length(grep(pattern="full.tag" ,x=vname)) > 0 || - length(grep(pattern="old." ,x=vname)) > 0 || - length(grep(pattern=".1st" ,x=vname)) > 0 || - length(grep(pattern="scientific",x=vname)) > 0 || - length(grep(pattern="genus" ,x=vname)) > 0 || - length(grep(pattern="family" ,x=vname)) > 0 || - length(grep(pattern="year.last" ,x=vname)) > 0 || - length(grep(pattern="cnpj" ,x=vname)) > 0 || - length(grep(pattern="conflict." ,x=vname)) > 0){ + if ( any(grepl(pattern="trans" ,x=vname)) || + any(grepl(pattern="full.tag" ,x=vname)) || + any(grepl(pattern="old." ,x=vname)) || + any(grepl(pattern=".1st" ,x=vname)) || + any(grepl(pattern="scientific",x=vname)) || + any(grepl(pattern="genus" ,x=vname)) || + any(grepl(pattern="family" ,x=vname)) || + any(grepl(pattern="year.last" ,x=vname)) || + any(grepl(pattern="cnpj" ,x=vname)) || + any(grepl(pattern="conflict." ,x=vname)) + ){ #---------------------------------------------------------------------------------# # We skip these variables. # #---------------------------------------------------------------------------------# @@ -422,7 +435,7 @@ blend.trees = function(receptor,donor,years.blend){ }else if (vname %in% c("year.added")){ #---- We always keep the lowest value. -------------------------------------------# - receptor$year.added = min(receptor$year.added,min(years.blend)) + receptor$year.added = min(receptor$year.added,min(years.merge)) #---------------------------------------------------------------------------------# @@ -440,16 +453,17 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# - }else if (vname %in% c("tag","x","y")){ + }else if (vname %in% c("x","y")){ #---------------------------------------------------------------------------------# - # We will consider changing the values only if the donor has information. # + # We will consider changing the values only if the donor has information or # + # if we have clear instructions of what to do. # #---------------------------------------------------------------------------------# - if (! is.na(donor[[vname]])){ + if (is.na(use.xy) && (! is.na(donor[[vname]]))){ #------------------------------------------------------------------------------# # We update coordinates only if the last year of the original dataset was # - # less than the years we are blending. # + # less than the years we are merging. # #------------------------------------------------------------------------------# - if ( ( ( max(years.blend) > receptor$year.last ) + if ( ( ( max(years.merge) > receptor$year.last ) && ( receptor[[vname]] != donor[[vname]] ) ) || is.na(receptor[[vname]]) ){ receptor[[old ]] = receptor[[vname]] @@ -459,16 +473,83 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# - # We don't change the "1st" variables unless the data we are blending is # + # We don't change the "1st" variables unless the data we are merging is # # older than the first year the receptor has data. # #------------------------------------------------------------------------------# - if ( ( ( min(years.blend) < receptor$year.1st ) + if ( ( ( min(years.merge) < receptor$year.1st ) && ( receptor[[vname]] != donor[[vname]] ) ) || is.na(receptor[[vname]]) ){ receptor[[first]] = donor[[first]] }#end if #------------------------------------------------------------------------------# - }#end if + }else if (use.xy %in% "from"){ + #------------------------------------------------------------------------------# + # Set coordinates based on donor. # + #------------------------------------------------------------------------------# + receptor[[vname]] = donor[[vname]] + receptor[[old ]] = donor[[old ]] + receptor[[first]] = donor[[first]] + #------------------------------------------------------------------------------# + }else if (use.xy %in% "to"){ + #------------------------------------------------------------------------------# + # Set coordinates based on receptor. Dummy commands, no need to do # + # anything. # + #------------------------------------------------------------------------------# + receptor[[vname]] = receptor[[vname]] + receptor[[old ]] = receptor[[old ]] + receptor[[first]] = receptor[[first]] + #------------------------------------------------------------------------------# + }#end if (is.na(use.xy) && (! is.na(donor[[vname]]))) + #---------------------------------------------------------------------------------# + + + }else if (vname %in% c("tag")){ + #---------------------------------------------------------------------------------# + # We will consider changing the values only if the donor has information or # + # if we have clear instructions of what to do. # + #---------------------------------------------------------------------------------# + if (is.na(use.tag) && (! is.na(donor[[vname]]))){ + #------------------------------------------------------------------------------# + # We update coordinates only if the last year of the original dataset was # + # less than the years we are merging. # + #------------------------------------------------------------------------------# + if ( ( ( max(years.merge) > receptor$year.last ) + && ( receptor[[vname]] != donor[[vname]] ) ) + || is.na(receptor[[vname]]) ){ + receptor[[old ]] = receptor[[vname]] + receptor[[vname]] = donor [[vname]] + }#end if + #------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------# + # We don't change the "1st" variables unless the data we are merging is # + # older than the first year the receptor has data. # + #------------------------------------------------------------------------------# + if ( ( ( min(years.merge) < receptor$year.1st ) + && ( receptor[[vname]] != donor[[vname]] ) ) + || is.na(receptor[[vname]]) ){ + receptor[[first]] = donor[[first]] + }#end if + #------------------------------------------------------------------------------# + }else if (use.tag %in% "from"){ + #------------------------------------------------------------------------------# + # Set coordinates based on donor. # + #------------------------------------------------------------------------------# + receptor[[vname]] = donor[[vname]] + receptor[[old ]] = donor[[old ]] + receptor[[first]] = donor[[first]] + #------------------------------------------------------------------------------# + }else if (use.tag %in% "to"){ + #------------------------------------------------------------------------------# + # Set coordinates based on receptor. Dummy commands, no need to do # + # anything. # + #------------------------------------------------------------------------------# + receptor[[vname]] = receptor[[vname]] + receptor[[old ]] = receptor[[old ]] + receptor[[first]] = receptor[[first]] + #------------------------------------------------------------------------------# + }#end if (is.na(use.tag) && (! is.na(donor[[vname]]))) #---------------------------------------------------------------------------------# @@ -528,7 +609,7 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# # Check whether we update the common name. # #------------------------------------------------------------------------------# - if ( receptor$year.last < max(years.blend) ){ + if ( receptor$year.last < max(years.merge) ){ copy.common = ! donor.c.ignotum update.old = ( copy.common && (! receptor.c.ignotum) && receptor$common != donor$common ) @@ -541,7 +622,7 @@ blend.trees = function(receptor,donor,years.blend){ #------------------------------------------------------------------------------# # Check whether the donor first name is older than the receptor one. # #------------------------------------------------------------------------------# - if ( receptor$year.1st > min(years.blend) ){ + if ( receptor$year.1st > min(years.merge) ){ if ( ! donor.f.ignotum ){ receptor$common.1st = donor$common.1st }#end if @@ -600,9 +681,9 @@ blend.trees = function(receptor,donor,years.blend){ || ( length(grep(pattern="notes.",x=vname)) > 0 && ! vname %in% c("notes.orig","notes.qaqc") ) ){ #---------------------------------------------------------------------------------# - # Variables that we update only if this is the blending year. # + # Variables that we update only if this is the merging year. # #---------------------------------------------------------------------------------# - if (vname %in% blend.input && (! is.na(donor[[vname]]))){ + if (vname %in% merge.input && (! is.na(donor[[vname]]))){ #----- Copy only the cells that had no info before. ---------------------------# receptor[[vname]] = donor[[vname]] #------------------------------------------------------------------------------# @@ -612,7 +693,7 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# # For DBH, we also check whether they match in case of overlap, and flag any # - # mismatch for blending years. # + # mismatch for merging years. # #---------------------------------------------------------------------------------# if ( length(grep(pattern="dbh." ,x=vname)) > 0){ dbh.vars = c(dbh.vars,vname) @@ -624,11 +705,18 @@ blend.trees = function(receptor,donor,years.blend){ #---------------------------------------------------------------------------------# - }else if ( length(grep(pattern="canopy." ,x=vname)) > 0 - || length(grep(pattern="height." ,x=vname)) > 0 - || length(grep(pattern="band." ,x=vname)) > 0 - || length(grep(pattern="pom." ,x=vname)) > 0 - || length(grep(pattern="ladder" ,x=vname)) > 0 + }else if ( any(grepl(pattern="canopy." ,x=vname)) + || any(grepl(pattern="height." ,x=vname)) + || any(grepl(pattern="band." ,x=vname)) + || any(grepl(pattern="pom." ,x=vname)) + || any(grepl(pattern="ladder" ,x=vname)) + || any(grepl(pattern="plant.ID" ,x=vname)) + || any(grepl(pattern="voucher.number",x=vname)) + || any(grepl(pattern="status" ,x=vname)) + || any(grepl(pattern="tax.reliab" ,x=vname)) + || any(grepl(pattern="flag" ,x=vname)) + || any(grepl(pattern="n.tag" ,x=vname)) + ){ #---- Variables that we update only if they have NA. -----------------------------# sel = ( is.na(receptor[[vname]]) @@ -645,7 +733,7 @@ blend.trees = function(receptor,donor,years.blend){ }else{ #----- Missing instructions, quit... ---------------------------------------------# - cat (" * VARIABLE: ",vname," has no instrucion!","\n") + cat (" * VARIABLE: ",vname," has no instruction!","\n") stop("Could not process the variable, sorry!") #---------------------------------------------------------------------------------# }#end if diff --git a/R-utils/globdims.r b/R-utils/globdims.r index 17bf676f4..35a4a64d6 100644 --- a/R-utils/globdims.r +++ b/R-utils/globdims.r @@ -7,7 +7,7 @@ nstyp <<- 17 # Number of default soil types #----- Radiation thresholds. --------------------------------------------------------------# -cosz.min <<- 0.03 # cos(89*pi/180) # Minimum cosine of zenith angle +cosz.min <<- 0.0001 # 0.03 # cos(89*pi/180) # Minimum cosine of zenith angle cosz.highsun <<- cos(84*pi/180) # Zenith angle to not be called sunrise or sunset cosz.twilight <<- cos(96*pi/180) # Cosine of the end of civil twilight fvis.beam.def <<- 0.43 diff --git a/R-utils/gridded.plot.r b/R-utils/gridded.plot.r index 15b91019d..357ff9b31 100644 --- a/R-utils/gridded.plot.r +++ b/R-utils/gridded.plot.r @@ -88,7 +88,7 @@ gridded.plot <<- function( x = seq(from=0,to=1,len=nrow(z)) #----- No messed-up axes are allowed, they must increase. ------------------------------# - if (any(diff(x) %<=% 0) || any(diff(y) %<=% 0)){ + if (any(diff(x) %le% 0) || any(diff(y) %le% 0)){ stop("increasing x and y values expected") }#end if #---------------------------------------------------------------------------------------# @@ -246,7 +246,19 @@ gridded.plot <<- function( x = seq(from=0,to=1,len=nrow(z)) #----- Plot the title. --------------------------------------------------------------# - if (! is.null(key.title)) do.call(what="title",args=key.title) + if (! is.null(key.title)){ + #---- Make sure that the key title will work with multiple configurations. -------# + if (! is.list(key.title)){ + key.title=list(main=key.title) + }else if (! "main" %in% names(key.title)){ + names(key.title)[[1]] = "main" + }#end if + #---------------------------------------------------------------------------------# + + #----- Call the command. ---------------------------------------------------------# + do.call(what="title",args=key.title) + #---------------------------------------------------------------------------------# + }#end if (! is.null(key.title)) #------------------------------------------------------------------------------------# #=======================================================================================# #=======================================================================================# diff --git a/R-utils/image.map.r b/R-utils/image.map.r index 40c99efbe..969f0f4b1 100644 --- a/R-utils/image.map.r +++ b/R-utils/image.map.r @@ -506,8 +506,8 @@ image.map <<- function( x zzz = tapply(X=zzz,INDEX=iii,FUN=mean,na.rm=TRUE) sss = tapply(X=sss,INDEX=iii,FUN=any ,na.rm=TRUE) #----- Generate output mesh. -----------------------------------------------------# - if (! (nx.interp %>% 0)) nx.interp = 10*length(unique(xx)) - if (! (ny.interp %>% 0)) ny.interp = 10*length(unique(yy)) + if (! (nx.interp %gt% 0)) nx.interp = 10*length(unique(xx)) + if (! (ny.interp %gt% 0)) ny.interp = 10*length(unique(yy)) xo = seq(from=0,to=1,length.out=nx.interp) yo = seq(from=0,to=1,length.out=ny.interp) xoyo = expand.grid(xo,yo) diff --git a/R-utils/is.peak.r b/R-utils/is.peak.r index fc89a9eea..eac2a33ee 100644 --- a/R-utils/is.peak.r +++ b/R-utils/is.peak.r @@ -12,7 +12,7 @@ is.peak <<- function( pt.cloud #----- Check whether to use only first returns or all returns. -------------------------# idx.retn = with(pt.cloud, which(retn.number %in% retn.use)) idx.clss = with(pt.cloud, which(pt.class %in% clss.use)) - idx.agnd = with(pt.cloud, which(z %>=% zmin)) + idx.agnd = with(pt.cloud, which(z %ge% zmin)) idx.keep = intersect(idx.clss,intersect(idx.retn,idx.agnd)) #---------------------------------------------------------------------------------------# diff --git a/R-utils/licorfun.r b/R-utils/licorfun.r index 663e1c6da..1b9dc986b 100644 --- a/R-utils/licorfun.r +++ b/R-utils/licorfun.r @@ -154,7 +154,7 @@ comp.photo.tempfun <<- function(thispft,met,quantum.t=FALSE){ ipsII.max = ( aparms$jm * ( 2.0 * thispft$curvpar - 1. - 2.0 * sqrt(thispft$curvpar * (thispft$curvpar-1.0) ) ) ) }else{ - ipsII.max = discard + ipsII.max = huge.num }#end if (thispft$curvpar > 1.) ipsII = min(0.5 * thispft$phi.psII * met$par,ipsII.max) aterm = thispft$curvpar @@ -390,14 +390,14 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # make the other negative, which will make the guess discarded. # #---------------------------------------------------------------------------------# ciroot1 = - bquad / (2.0 * aquad) - ciroot2 = - discard + ciroot2 = - huge.num }else if (discr > 0.0){ ciroot1 = (- bquad + sqrt(discr)) / (2.0 * aquad) ciroot2 = (- bquad - sqrt(discr)) / (2.0 * aquad) }else{ #----- Discriminant is negative. Impossible to solve. ---------------------------# - ciroot1 = - discard - ciroot2 = - discard + ciroot1 = - huge.num + ciroot2 = - huge.num }# end if }else{ #------------------------------------------------------------------------------------# @@ -405,7 +405,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # works for this case. # #------------------------------------------------------------------------------------# ciroot1 = - cquad / bquad - ciroot2 = - discard + ciroot2 = - huge.num #----- Not used, just for the debugging process. ------------------------------------# discr = bquad * bquad }# end if @@ -414,7 +414,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # the positive discard so this will never be chosen. # #---------------------------------------------------------------------------------------# cigsw=max(ciroot1, ciroot2) - if (cigsw == -discard) cigsw = discard + if (cigsw == -huge.num) cigsw = huge.num #---------------------------------------------------------------------------------------# @@ -446,14 +446,14 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # make the other negative, which will make the guess discarded. # #---------------------------------------------------------------------------------# ciroot1 = - bquad / (2.0 * aquad) - ciroot2 = -discard + ciroot2 = -huge.num }else if (discr > 0.0){ ciroot1 = (- bquad + sqrt(discr)) / (2.0 * aquad) ciroot2 = (- bquad - sqrt(discr)) / (2.0 * aquad) }else{ #----- Discriminant is negative. Impossible to solve. ---------------------------# - ciroot1 = -discard - ciroot2 = -discard + ciroot1 = -huge.num + ciroot2 = -huge.num }#end if }else{ #------------------------------------------------------------------------------------# @@ -461,7 +461,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # that works for this case. # #------------------------------------------------------------------------------------# ciroot1 = - cquad / bquad - ciroot2 = -discard + ciroot2 = -huge.num #----- Not used, just for the debugging process. ------------------------------------# discr = bquad * bquad }# end if @@ -470,7 +470,7 @@ find.lint.co2.bounds <<- function(met,thispft,aparms){ # the positive discard so this will never be chosen. # #---------------------------------------------------------------------------------------# ciQ=max(ciroot1, ciroot2) - if (ciQ == -discard) ciQ = discard + if (ciQ == -huge.num) ciQ = huge.num #---------------------------------------------------------------------------------------# @@ -959,7 +959,7 @@ solve.aofixed.case <<- function(met,thispft,aparms){ if (aquad == 0.0){ #----- Not really a quadratic equation. ------------------------------------------# gswroot1 = -cquad / bquad - gswroot2 = discard + gswroot2 = huge.num }else{ #----- A quadratic equation, find the discriminant. ------------------------------# discr = bquad * bquad - 4.0 * aquad * cquad @@ -967,7 +967,7 @@ solve.aofixed.case <<- function(met,thispft,aparms){ if (discr == 0.0){ #----- Double root. -----------------------------------------------------------# gswroot1 = - bquad / (2.0 * aquad) - gswroot2 = discard + gswroot2 = huge.num }else if (discr > 0.0){ #----- Two distinct roots. ----------------------------------------------------# gswroot1 = (- bquad - sqrt(discr)) / (2.0 * aquad) diff --git a/R-utils/load.everything.r b/R-utils/load.everything.r index bc900c4f0..5683a0ab8 100644 --- a/R-utils/load.everything.r +++ b/R-utils/load.everything.r @@ -222,7 +222,6 @@ discreet.require <<- function(...){ #------------------------------------------------------------------------------------------# loaded.package = list() loaded.package[["abind" ]] = discreet.require(abind ) -loaded.package[["agricolae" ]] = discreet.require(agricolae ) loaded.package[["akima" ]] = discreet.require(akima ) loaded.package[["beanplot" ]] = discreet.require(beanplot ) loaded.package[["boot" ]] = discreet.require(boot ) @@ -236,15 +235,14 @@ loaded.package[["data.table" ]] = discreet.require(data.table ) loaded.package[["devtools" ]] = discreet.require(devtools ) loaded.package[["FAdist" ]] = discreet.require(FAdist ) loaded.package[["fields" ]] = discreet.require(fields ) +loaded.package[["foto" ]] = discreet.require(foto ) loaded.package[["gbm" ]] = discreet.require(gbm ) -loaded.package[["gdalUtils" ]] = discreet.require(gdalUtils ) -loaded.package[["geoR" ]] = discreet.require(geoR ) +#loaded.package[["geoR" ]] = discreet.require(geoR ) +loaded.package[["ggplot2" ]] = discreet.require(ggplot2 ) loaded.package[["gpclib" ]] = discreet.require(gpclib ) loaded.package[["grDevices" ]] = discreet.require(grDevices ) loaded.package[["gstat" ]] = discreet.require(gstat ) -loaded.package[["hdf5" ]] = discreet.require(hdf5 ) loaded.package[["Hmisc" ]] = discreet.require(Hmisc ) -loaded.package[["klaR" ]] = discreet.require(klaR ) loaded.package[["kriging" ]] = discreet.require(kriging ) loaded.package[["leaps" ]] = discreet.require(leaps ) loaded.package[["maps" ]] = discreet.require(maps ) @@ -252,20 +250,25 @@ loaded.package[["mapdata" ]] = discreet.require(mapdata ) loaded.package[["maptools" ]] = discreet.require(maptools ) loaded.package[["MASS" ]] = discreet.require(MASS ) loaded.package[["MCMCpack" ]] = discreet.require(MCMCpack ) +loaded.package[["nat.utils" ]] = discreet.require(nat.utils ) loaded.package[["nlme" ]] = discreet.require(nlme ) loaded.package[["numDeriv" ]] = discreet.require(numDeriv ) loaded.package[["onls" ]] = discreet.require(onls ) loaded.package[["PBSmapping" ]] = discreet.require(PBSmapping ) loaded.package[["plotrix" ]] = discreet.require(plotrix ) loaded.package[["pls" ]] = discreet.require(pls ) +loaded.package[["ppcor" ]] = discreet.require(ppcor ) loaded.package[["proto" ]] = discreet.require(proto ) loaded.package[["randomForest"]] = discreet.require(randomForest) loaded.package[["raster" ]] = discreet.require(raster ) +loaded.package[["reshape2" ]] = discreet.require(reshape2 ) loaded.package[["rgdal" ]] = discreet.require(rgdal ) loaded.package[["rgeos" ]] = discreet.require(rgeos ) +loaded.package[["rhdf5" ]] = discreet.require(rhdf5 ) loaded.package[["rlas" ]] = discreet.require(rlas ) loaded.package[["robustbase" ]] = discreet.require(robustbase ) loaded.package[["rworldmap" ]] = discreet.require(rworldmap ) +loaded.package[["RColorBrewer"]] = discreet.require(RColorBrewer) loaded.package[["RSEIS" ]] = discreet.require(RSEIS ) loaded.package[["R.utils" ]] = discreet.require(R.utils ) loaded.package[["shapefiles" ]] = discreet.require(shapefiles ) @@ -275,10 +278,12 @@ loaded.package[["sn" ]] = discreet.require(sn ) loaded.package[["sp" ]] = discreet.require(sp ) loaded.package[["stats4" ]] = discreet.require(stats4 ) loaded.package[["vioplot" ]] = discreet.require(vioplot ) -loaded.package[["VoxR" ]] = discreet.require(VoxR ) +loaded.package[["viridis" ]] = discreet.require(viridis ) loaded.package[["zoo" ]] = discreet.require(zoo ) #---- Packages that must be loaded at the end. --------------------------------------------# loaded.package[["forecast" ]] = discreet.require(forecast ) +loaded.package[["klaR" ]] = discreet.require(klaR ) +loaded.package[["agricolae" ]] = discreet.require(agricolae ) #------------------------------------------------------------------------------------------# @@ -368,16 +373,6 @@ try(unlockBinding("theme",envir),silent=TRUE) -#------------------------------------------------------------------------------------------# -# SHADY BUSINESS... We must unlock %>% from package forecast and replace by our # -# function. # -#------------------------------------------------------------------------------------------# -envir = as.environment("package:forecast") -try(unlockBinding("%>%",envir),silent=TRUE) -#------------------------------------------------------------------------------------------# - - - #------------------------------------------------------------------------------------------# # Organise the files so we load them in the right order. # #------------------------------------------------------------------------------------------# @@ -461,7 +456,9 @@ for (if90 in sequence(nall.f90)){ dummy = if (file.exists(flib.so)){file.remove(flib.so)}else{character(0)} dummy = if (file.exists(flib.sl)){file.remove(flib.sl)}else{character(0)} dummy = if (file.exists(flib.o )){file.remove(flib.o )}else{character(0)} - dummy = rcmd(cmd="SHLIB",cmdargs=fnow,libpath=srcdir) + dummy = rcmd(cmd="SHLIB",cmdargs=fnow ) + dummy = rcmd(cmd="SHLIB",cmdargs=flib.o) + #------------------------------------------------------------------------------------# }#end if ("try-error" %in% is(dummy)) #---------------------------------------------------------------------------------------# }#end for (if90 in sequence(nall.f90)) diff --git a/R-utils/locations.r b/R-utils/locations.r index 8fdfc7cb8..1c2fe4309 100644 --- a/R-utils/locations.r +++ b/R-utils/locations.r @@ -61,6 +61,33 @@ locations <<- function(where,here=getwd(),yearbeg=1500,yearend=2008,monthbeg=1,d pathrst = file.path(here,ici,"histo",ici) pathout = file.path(pathroot,"epost") + }else if( ( substring(ici,1,2) %in% c("ta","ti","tl") ) + & ( ( substring(ici,7,7) %in% "_" ) | ( nchar(ici) == 6 ) ) + ){ + #---- Regional based name. ----------------------------------------------------------# + metflag = substring(ici,1) + if (tolower(metflag) %in% "ta"){ + thismet = "(ERA5)" + }else{ + thismet = "" + }#end if + + #----- Grab the IATA code. ----------------------------------------------------------# + iata = substring(ici,2,6) + pp = which(poilist$iata %in% iata) + + #----- Put the name of the place and the meteorological forcing. --------------------# + testpoi = paste0(poilist$longname[pp]," ",thismet) + lon = poilist$lon[pp] + lat = poilist$lat[pp] + wmo = poilist$wmo[pp] + + lieu = simul.description(ici,testpoi,iata=FALSE) + pathroot = file.path(here,ici) + pathin = file.path(pathroot,"analy",ici) + pathrst = file.path(here,ici,"histo",ici) + pathout = file.path(pathroot,"epost") + }else if( substring(ici,4,4) == "_" & substring(ici,9,9) == "_"){ #---- Convert back to upper case. ---------------------------------------------------# ici = paste0(toupper(substring(ici,1,3)),substring(ici,4)) @@ -543,8 +570,8 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ #----- ivegt.dynamics is the flag for vegetation dynamics. -----------------------------# flagvar[["ivegt.dynamics"]] = list( descr = "Vegetation dynamics" , numeric = TRUE - , values = seq(from=0,to=2,by=1) - , names = c("OFF","ON","Multi") + , values = c(0,1,2,99) + , names = c("OFF","ON","Multi","Bare") )#end list #----- iphen.scheme is the phenology scheme for tropical broadleaf trees. --------------# flagvar[["iphen.scheme"]] = list( descr = "Phenology scheme" @@ -607,13 +634,13 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- irad.drought is the rainfall response. ------------------------------------------# flagvar[["irain.drought"]] = list( descr = "Rainfall" - , numeric = TRUE + , numeric = TRUE , values = seq(from=0,to=1,by=1) , names = c("Normal","2010 drought") )#end list #----- Photosynthesis parameters. ------------------------------------------------------# flagvar[["iphysiol"]] = list( descr = "Photosynthesis" - , numeric = TRUE + , numeric = TRUE , values = seq(from=0,to=3,by=1) , names = c("Arrhenius (no Jmax/TPmax)" ,"Arrenhius (with Jmax/TPmax)" @@ -623,13 +650,13 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["igrass"]] = list( descr = "Grass scheme" - , numeric = TRUE + , numeric = TRUE , values = c(0,1) , names = c("ED-1","Swann") )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["isoilbc"]] = list( descr = "Soil Bnd. Cond." - , numeric = TRUE + , numeric = TRUE , values = c(0,1,2,3,4) , names = c( "Bedrock" , "Free drainage" @@ -640,7 +667,7 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ )#end list #----- Grass type. ---------------------------------------------------------------------# flagvar[["ipercol"]] = list( descr = "Percolation" - , numeric = TRUE + , numeric = TRUE , values = c(0,1,2) , names = c( "Walko et al. (2000)" , "Anderson (1976)" @@ -655,11 +682,12 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ #----- Fire model. ---------------------------------------------------------------------# flagvar[["include.fire"]] = list( descr = "Fire model" , numeric = TRUE - , values = c(0,1,2,3) + , values = c(0,1,2,3,4) , names = c( "Off" , "ED-1.0 type" , "Default ED-2.1" - , "Water-deficit based" + , "EMBERFIRE" + , "FIRESTARTER" )#end c )#end list #----- Energy budget type. -------------------------------------------------------------# @@ -961,14 +989,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ , values = c(0,1) , names = c("OFF","ON") )#end list - flagvar[["soil.hydro"]] = list( descr = "Soil hydraulics" - , numeric = TRUE - , values = c(0,1,2) - , names = c( "Brooks-Corey-Cosby" - , "Brooks-Cory-Tomasella" - , "van Genuchten-Hodnett" - )#end c - )#end list flagvar[["dhist" ]] = list( descr = "LCLU history" , numeric = FALSE , values = c("int","ril","cl1","cl2","lt1" @@ -1536,11 +1556,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("iphen.scheme","d0","include.fire") na = c( 10, 16, 24) nz = c( 12, 18, 25) - }else if (lenici == 26 & grep(pattern="islhydro",x=ici)){ - nparms = 2 - param = c("ivegt.dynamics","soil.hydro") - na = c( 14, 25) - nz = c( 15, 26) }else if (lenici == 26){ nparms = 3 param = c("ianth.disturb","logging.type", "bharvest") @@ -1631,11 +1646,6 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("yeara","iphen.scheme","isoil.text","treefall") na = c( 9, 18, 27, 35) nz = c( 11, 20, 28, 37) - }else if (lenici == 38 & grep(pattern="islhydro",x=ici)){ - nparms = 3 - param = c("ivegt.dynamics","soil.hydro","hydrodyn.set") - na = c( 14, 25, 37) - nz = c( 15, 26, 38) }else if (lenici == 39){ nparms = 3 param = c("struct","iphen.scheme","include.fire") @@ -1677,6 +1687,16 @@ simul.description <<- function(ici,testpoi,iata=TRUE,max.char=66){ param = c("lon","lat") na = c( 13, 23) nz = c( 18, 28) + }else if(lenici == 34 && grepl(pattern="ifire",x=ici)){ + nparms = 3 + param = c("lon","lat","include.fire") + na = c( 11, 21, 33) + nz = c( 16, 26, 34) + }else if(lenici == 46 && grepl(pattern="ifire",x=ici)){ + nparms = 4 + param = c("lon","lat","include.fire","sm.fire") + na = c( 11, 21, 33, 42) + nz = c( 16, 26, 34, 46) }#end if }#end if #---------------------------------------------------------------------------------------# @@ -1757,6 +1777,28 @@ poilist <<- read.csv( file = file.path(srcdir,"poilist.csv") , header = TRUE , stringsAsFactors = FALSE )#end read.csv +if (file.exists(file.path(srcdir,"amzbr_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzbr_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzbr_poi.csv"))) +if (file.exists(file.path(srcdir,"amzif_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzif_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzif_poi.csv"))) +npoi <<- nrow(poilist) +if (file.exists(file.path(srcdir,"amzlu_poi.csv"))){ + amzlist <<- read.csv( file = file.path(srcdir,"amzlu_poi.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + poilist <<- merge(poilist,amzlist,all=TRUE) +}#end if (file.exists(file.path(srcdir,"amzif_poi.csv"))) npoi <<- nrow(poilist) #==========================================================================================# #==========================================================================================# diff --git a/R-utils/lt.weibull.r b/R-utils/lt.weibull.r index e929cf8f9..0b9c0ded3 100644 --- a/R-utils/lt.weibull.r +++ b/R-utils/lt.weibull.r @@ -8,7 +8,7 @@ dlt.weibull <<- function(x,left=0,shape,scale=1,log=FALSE){ lnorm = left / scale #---------------------------------------------------------------------------------------# - dens = ifelse( x %<% left + dens = ifelse( x %lt% left , 0. , shape / scale * xnorm ^ (shape-1) * exp( lnorm ^ shape - xnorm ^ shape ) )#end ifelse @@ -34,7 +34,7 @@ plt.weibull <<- function(q,left=0,shape,scale=1,lower.tail=TRUE,log.p=FALSE){ #---------------------------------------------------------------------------------------# - prob = ifelse( q %<% left, 0., 1. - exp( lnorm^shape - qnorm^shape ) ) + prob = ifelse( q %lt% left, 0., 1. - exp( lnorm^shape - qnorm^shape ) ) if (lower.tail) prob = 1. - prob if (log.p ) prob = log(prob) return(prob) diff --git a/R-utils/macarthur.horn.r b/R-utils/macarthur.horn.r index da9deb26c..e83971d9d 100644 --- a/R-utils/macarthur.horn.r +++ b/R-utils/macarthur.horn.r @@ -64,15 +64,15 @@ macarthur.horn <<- function( pt.cloud # Make sure the settings make sense. # #---------------------------------------------------------------------------------------# #----- Check additional values. --------------------------------------------------------# - if (! ( zh %>% 0 && - nz %>% 0 && - zh %>% zo && - zo %>=% 0 && - ( is.na(rvorg) || rvorg %>% 0 ) && - ( out.lai %>% 0 ) && + if (! ( zh %gt% 0 && + nz %gt% 0 && + zh %gt% zo && + zo %ge% 0 && + ( is.na(rvorg) || rvorg %gt% 0 ) && + ( out.lai %gt% 0 ) && ( is.logical(tall.at.zh) ) && - ( (sigma.z %>% 0) || (! wfsim) ) && - Gmu %>%0 + ( (sigma.z %gt% 0) || (! wfsim) ) && + Gmu %gt%0 ) ){ cat0("------------------------------------------------------------------") cat0(" MacArthur and Horn won't run due to problems with your settings:" ) @@ -191,12 +191,12 @@ macarthur.horn <<- function( pt.cloud #----- Assume that everything with height zero is ground. ------------------------------# - pt.cloud$pt.class[pt.cloud$z %<=% 0] = 2 + pt.cloud$pt.class[pt.cloud$z %le% 0] = 2 #---------------------------------------------------------------------------------------# #----- Keep only the points that are within bounds. ------------------------------------# - keep = pt.cloud$z %>=% 0 & pt.cloud$z %<% zh & pt.cloud$pt.class %in% c(0,1,2,3,4,5) + keep = pt.cloud$z %ge% 0 & pt.cloud$z %lt% zh & pt.cloud$pt.class %in% c(0,1,2,3,4,5) pt.cloud = pt.cloud[keep,,drop=FALSE] #---------------------------------------------------------------------------------------# @@ -460,7 +460,7 @@ macarthur.horn <<- function( pt.cloud }else{ #----- Create a pseudo-point cloud with the MH-corrected distribution. --------------# - nzmah = ceiling(3.*Rv0/min(veg.cloud$intensity[veg.cloud$intensity %>% 0])) + nzmah = ceiling(3.*Rv0/min(veg.cloud$intensity[veg.cloud$intensity %gt% 0])) zmah = jitter(x= sample(x=zmid,size=nzmah,replace=TRUE,prob=lad),amount=0.5*deltaz) #------------------------------------------------------------------------------------# diff --git a/R-utils/monthly.template.r b/R-utils/monthly.template.r index 614067f6e..776adb2d4 100644 --- a/R-utils/monthly.template.r +++ b/R-utils/monthly.template.r @@ -46,37 +46,60 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ed$nzs = mymont$NZS ed$ndcycle = mymont$NDCYCLE ed$ntimes = ntimes + ed$nsites = mymont$PYSI.N #---------------------------------------------------------------------------------------# #----- Find which soil are we solving, and save properties into soil.prop. -------------# - ed$isoilflg = mymont$ISOILFLG ed$slz = mymont$SLZ - ed$slxsand = mymont$SLXSAND - ed$slxclay = mymont$SLXCLAY - ed$ntext = mymont$NTEXT.SOIL[ed$nzg] + ed$slhydro = mymont$SLHYDRO.REF + ed$slxsand = mymont$SLXSAND.REF + ed$slxclay = mymont$SLXCLAY.REF + ed$slxsilt = mymont$SLXSILT.REF + ed$slsoc = mymont$SLSOC.REF + ed$slph = mymont$SLPH.REF + ed$slcec = mymont$SLCEC.REF + ed$sldbd = mymont$SLDBD.REF + ed$ntext = mymont$NTEXT.SOIL[,ed$nzg] + ed$lsl = mymont$LSL #---------------------------------------------------------------------------------------# #----- Derive the soil properties. -----------------------------------------------------# - ed$soil.prop = soil.params(ed$ntext,ed$isoilflg,ed$slxsand,ed$slxclay) + ed$soil.prop = soil.params( isoilflg = 2 + , slxsand = ed$slxsand + , slxclay = ed$slxclay + , slsoc = ed$slsoc + , slph = ed$slph + , slcec = ed$slcec + , sldbd = ed$sldbd + , slhydro = ed$slhydro + , out.dfr = TRUE + )#end soil.params ed$dslz = diff(c(ed$slz,0)) ed$soil.depth = rev(cumsum(rev(ed$dslz))) - ed$soil.dry = rev(cumsum(rev(ed$soil.prop$soilcp * wdns * ed$dslz))) - ed$soil.poro = rev(cumsum(rev(ed$soil.prop$slmsts * wdns * ed$dslz))) + ed$soil.dry = apply( X = outer(wdns * ed$dslz,ed$soil.prop$soilcp) + , MARGIN = 2 + , FUN = function(x) rev(cumsum(rev(x))) + )#end apply + ed$soil.poro = apply( X = outer(wdns * ed$dslz,ed$soil.prop$soilpo) + , MARGIN = 2 + , FUN = function(x) rev(cumsum(rev(x))) + )#end apply #---------------------------------------------------------------------------------------# #----- Find the layers we care about. --------------------------------------------------# sel = ed$slz < slz.min if (any(sel)){ - ed$ka = which.max(ed$slz[sel]) + ka.min = which.max(ed$slz[sel]) + ed$ka = pmax(ka.min,ed$lsl) }else{ - ed$ka = 1 + ed$ka = ed$lsl }#end if - ed$kz = ed$nzg + ed$kz = rep(x=ed$nzg,times=length(ed$lsl)) #---------------------------------------------------------------------------------------# @@ -118,6 +141,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ndcycle = ed$ndcycle nzg = ed$nzg nzs = ed$nzs + nsites = ed$nsites #---------------------------------------------------------------------------------------# @@ -155,6 +179,17 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$crop.harvest = rep(NA_real_,times=ntimes) emean$logging.harvest = rep(NA_real_,times=ntimes) emean$combusted.fuel = rep(NA_real_,times=ntimes) + emean$fire.density = rep(NA_real_,times=ntimes) + emean$fire.intensity = rep(NA_real_,times=ntimes) + emean$fire.ignition = rep(NA_real_,times=ntimes) + emean$fire.extinction = rep(NA_real_,times=ntimes) + emean$fire.spread = rep(NA_real_,times=ntimes) + emean$fire.tlethal = rep(NA_real_,times=ntimes) + emean$fire.f.bherb = rep(NA_real_,times=ntimes) + emean$fire.f.bwoody = rep(NA_real_,times=ntimes) + emean$fire.f.fgc = rep(NA_real_,times=ntimes) + emean$fire.f.stgc = rep(NA_real_,times=ntimes) + emean$burnt.area = rep(NA_real_,times=ntimes) emean$het.resp = rep(NA_real_,times=ntimes) emean$fgc.resp = rep(NA_real_,times=ntimes) emean$fsc.resp = rep(NA_real_,times=ntimes) @@ -221,6 +256,11 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$can.vpd = rep(NA_real_,times=ntimes) emean$can.depth = rep(NA_real_,times=ntimes) emean$can.area = rep(NA_real_,times=ntimes) + emean$sfcw.temp = rep(NA_real_,times=ntimes) + emean$sfcw.fliq = rep(NA_real_,times=ntimes) + emean$sfcw.mass = rep(NA_real_,times=ntimes) + emean$sfcw.depth = rep(NA_real_,times=ntimes) + emean$sfcw.cover = rep(NA_real_,times=ntimes) emean$soil.temp.top = rep(NA_real_,times=ntimes) emean$soil.water.top = rep(NA_real_,times=ntimes) emean$soil.water.bot = rep(NA_real_,times=ntimes) @@ -243,6 +283,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$last.2yr.lvpd = rep(NA_real_,times=ntimes) emean$last.3yr.lvpd = rep(NA_real_,times=ntimes) emean$leaf.water = rep(NA_real_,times=ntimes) + emean$leaf.water.im2 = rep(NA_real_,times=ntimes) emean$phap.lwater = rep(NA_real_,times=ntimes) emean$last.1yr.lwater = rep(NA_real_,times=ntimes) emean$last.2yr.lwater = rep(NA_real_,times=ntimes) @@ -390,6 +431,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$leaf.par.beam = rep(NA_real_,times=ntimes) emean$leaf.par.diff = rep(NA_real_,times=ntimes) emean$leaf.gpp = rep(NA_real_,times=ntimes) + emean$dmin.leaf.psi = rep(NA_real_,times=ntimes) + emean$dmax.leaf.psi = rep(NA_real_,times=ntimes) emean$phap.lpar = rep(NA_real_,times=ntimes) emean$last.1yr.lpar = rep(NA_real_,times=ntimes) emean$last.2yr.lpar = rep(NA_real_,times=ntimes) @@ -422,6 +465,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ emean$acc.hydmort = rep(NA_real_,times=ntimes) emean$acc.dimort = rep(NA_real_,times=ntimes) emean$acc.recr = rep(NA_real_,times=ntimes) + emean$fire.lethal = rep(NA_real_,times=ntimes) emean$last.1yr.change = rep(NA_real_,times=ntimes) emean$last.2yr.change = rep(NA_real_,times=ntimes) emean$last.3yr.change = rep(NA_real_,times=ntimes) @@ -558,6 +602,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$leaf.temp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.ltemp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.water = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$leaf.water.im2 = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.lwater = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$wood.temp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.vpd = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -568,6 +613,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$dimort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$ncbmort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$hydmort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$fire.lethal = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$growth = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$recr = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$change = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -621,6 +667,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ szpft$leaf.par.beam = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.par.diff = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.gpp = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$dmin.leaf.psi = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) + szpft$dmax.leaf.psi = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$phap.lpar = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.rshort = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) szpft$leaf.rlong = array(data=NA_real_,dim=c(ntimes,ndbh+1,npft+1)) @@ -724,6 +772,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ qmean$can.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$leaf.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$leaf.water = matrix(data=NA,nrow=ntimes,ncol=ndcycle) + qmean$leaf.water.im2 = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$wood.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$gnd.temp = matrix(data=NA,nrow=ntimes,ncol=ndcycle) qmean$atm.shv = matrix(data=NA,nrow=ntimes,ncol=ndcycle) @@ -827,10 +876,104 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ + #---------------------------------------------------------------------------------------# + # SITE -- site level variables, we save as arrays because the number of sites is # + # constant throughout the simulations. # + #---------------------------------------------------------------------------------------# + site = list() + site$isi = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$lsl = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$ntext = matrix(data=NA_integer_,nrow=ntimes,ncol=nsites) + site$area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.density = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.extinction = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.intensity = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.tlethal = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.spread = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$burnt.area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ignition.rate = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.bherb = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.bwoody = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.fgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fire.f.stgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$lai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$tai = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$agb = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ba = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nplant = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fast.grnd.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$fast.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$struct.grnd.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$struct.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$microbe.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$slow.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$passive.soil.c = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nep = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$het.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cflxst = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$nee = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$qwflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxca = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxgc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$ustar = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rshortup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rlongup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$parup = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rshort.gnd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$par.gnd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$rnet = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wood.dens = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$vm0 = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$llspan = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$sla = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$can.depth = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$can.area = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$veg.height = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$sm.stress = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.temp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.water = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.water.im2 = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.vpd = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.gpp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$dmin.leaf.psi = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$dmax.leaf.psi = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.gsw = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par.beam = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$leaf.par.diff = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gpp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$npp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$plant.resp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$cba = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$reco = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxlc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$hflxwc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxlc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$wflxwc = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$transp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gnd.temp = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$gnd.shv = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.temp.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.water.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.water.bot = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.wetness.top = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + site$soil.wetness.bot = matrix(data=NA_real_ ,nrow=ntimes,ncol=nsites) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # PATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# patch = list() + patch$isi = list() + patch$lsl = list() + patch$ntext = list() patch$ipa = list() patch$age = list() patch$area = list() @@ -882,12 +1025,18 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$agb = list() patch$ba = list() patch$nplant = list() + patch$bleaf = list() patch$wood.dens = list() patch$vm0 = list() patch$llspan = list() patch$sla = list() patch$can.depth = list() patch$can.area = list() + patch$sfcw.temp = list() + patch$sfcw.fliq = list() + patch$sfcw.mass = list() + patch$sfcw.depth = list() + patch$sfcw.cover = list() patch$veg.height = list() patch$veg.displace = list() patch$veg.rough = list() @@ -902,8 +1051,11 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$sm.stress = list() patch$leaf.temp = list() patch$leaf.water = list() + patch$leaf.water.im2 = list() patch$leaf.vpd = list() patch$leaf.gpp = list() + patch$dmin.leaf.psi = list() + patch$dmax.leaf.psi = list() patch$leaf.gsw = list() patch$leaf.par = list() patch$leaf.par.beam = list() @@ -937,6 +1089,31 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ patch$soil.water = list() patch$soil.mstpot = list() patch$rk4step = list() + patch$growth = list() + patch$agb.growth = list() + patch$acc.growth = list() + patch$bsa.growth = list() + patch$mort = list() + patch$ncbmort = list() + patch$hydmort = list() + patch$dimort = list() + patch$fire.lethal = list() + patch$agb.mort = list() + patch$agb.ncbmort = list() + patch$agb.hydmort = list() + patch$agb.dimort = list() + patch$acc.mort = list() + patch$acc.ncbmort = list() + patch$acc.hydmort = list() + patch$acc.dimort = list() + patch$bsa.mort = list() + patch$bsa.ncbmort = list() + patch$bsa.hydmort = list() + patch$bsa.dimort = list() + patch$recr = list() + patch$agb.recr = list() + patch$acc.recr = list() + patch$bsa.recr = list() #---------------------------------------------------------------------------------------# @@ -945,66 +1122,67 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ #---------------------------------------------------------------------------------------# # QPATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# - qpatch = list() - qpatch$nep = list() - qpatch$het.resp = list() - qpatch$fgc.resp = list() - qpatch$fsc.resp = list() - qpatch$stgc.resp = list() - qpatch$stsc.resp = list() - qpatch$msc.resp = list() - qpatch$ssc.resp = list() - qpatch$psc.resp = list() - qpatch$can.temp = list() - qpatch$gnd.temp = list() - qpatch$can.shv = list() - qpatch$gnd.shv = list() - qpatch$can.vpd = list() - qpatch$can.co2 = list() - qpatch$can.prss = list() - qpatch$cflxca = list() - qpatch$cflxst = list() - qpatch$nee = list() - qpatch$hflxca = list() - qpatch$hflxgc = list() - qpatch$qwflxca = list() - qpatch$wflxca = list() - qpatch$wflxgc = list() - qpatch$ustar = list() - qpatch$albedo = list() - qpatch$rshortup = list() - qpatch$rlongup = list() - qpatch$parup = list() - qpatch$rshort.gnd = list() - qpatch$par.gnd = list() - qpatch$rnet = list() - qpatch$sm.stress = list() - qpatch$leaf.temp = list() - qpatch$leaf.water = list() - qpatch$leaf.vpd = list() - qpatch$wood.temp = list() - qpatch$par.leaf = list() - qpatch$par.leaf.beam = list() - qpatch$par.leaf.diff = list() - qpatch$leaf.gpp = list() - qpatch$leaf.gsw = list() - qpatch$leaf.par = list() - qpatch$leaf.par.beam = list() - qpatch$leaf.par.diff = list() - qpatch$assim.light = list() - qpatch$assim.rubp = list() - qpatch$assim.co2 = list() - qpatch$gpp = list() - qpatch$npp = list() - qpatch$plant.resp = list() - qpatch$reco = list() - qpatch$hflxlc = list() - qpatch$hflxwc = list() - qpatch$wflxlc = list() - qpatch$wflxwc = list() - qpatch$transp = list() - qpatch$soil.resp = list() - qpatch$rk4step = list() + qpatch = list() + qpatch$nep = list() + qpatch$het.resp = list() + qpatch$fgc.resp = list() + qpatch$fsc.resp = list() + qpatch$stgc.resp = list() + qpatch$stsc.resp = list() + qpatch$msc.resp = list() + qpatch$ssc.resp = list() + qpatch$psc.resp = list() + qpatch$can.temp = list() + qpatch$gnd.temp = list() + qpatch$can.shv = list() + qpatch$gnd.shv = list() + qpatch$can.vpd = list() + qpatch$can.co2 = list() + qpatch$can.prss = list() + qpatch$cflxca = list() + qpatch$cflxst = list() + qpatch$nee = list() + qpatch$hflxca = list() + qpatch$hflxgc = list() + qpatch$qwflxca = list() + qpatch$wflxca = list() + qpatch$wflxgc = list() + qpatch$ustar = list() + qpatch$albedo = list() + qpatch$rshortup = list() + qpatch$rlongup = list() + qpatch$parup = list() + qpatch$rshort.gnd = list() + qpatch$par.gnd = list() + qpatch$rnet = list() + qpatch$sm.stress = list() + qpatch$leaf.temp = list() + qpatch$leaf.water = list() + qpatch$leaf.water.im2 = list() + qpatch$leaf.vpd = list() + qpatch$wood.temp = list() + qpatch$par.leaf = list() + qpatch$par.leaf.beam = list() + qpatch$par.leaf.diff = list() + qpatch$leaf.gpp = list() + qpatch$leaf.gsw = list() + qpatch$leaf.par = list() + qpatch$leaf.par.beam = list() + qpatch$leaf.par.diff = list() + qpatch$assim.light = list() + qpatch$assim.rubp = list() + qpatch$assim.co2 = list() + qpatch$gpp = list() + qpatch$npp = list() + qpatch$plant.resp = list() + qpatch$reco = list() + qpatch$hflxlc = list() + qpatch$hflxwc = list() + qpatch$wflxlc = list() + qpatch$wflxwc = list() + qpatch$transp = list() + qpatch$soil.resp = list() + qpatch$rk4step = list() #---------------------------------------------------------------------------------------# @@ -1012,6 +1190,9 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ #----- Cohort level, we save as lists because the dimensions vary. ---------------------# cohort = list() + cohort$isi = list() + cohort$lsl = list() + cohort$ntext = list() cohort$ipa = list() cohort$ico = list() cohort$area = list() @@ -1086,6 +1267,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ cohort$dimort = list() cohort$ncbmort = list() cohort$hydmort = list() + cohort$fire.lethal = list() cohort$recruit = list() cohort$growth = list() cohort$agb.growth = list() @@ -1106,6 +1288,8 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ cohort$leaf.par.beam = list() cohort$leaf.par.diff = list() cohort$leaf.gpp = list() + cohort$dmin.leaf.psi = list() + cohort$dmax.leaf.psi = list() cohort$phap.lpar = list() cohort$leaf.rshort = list() cohort$leaf.rlong = list() @@ -1126,6 +1310,7 @@ create.monthly <<- function(ntimes,montha,yeara,inpref,slz.min){ ed$qmsqu = qmsqu ed$lu = lu ed$szpft = szpft + ed$site = site ed$patch = patch ed$cohort = cohort #---------------------------------------------------------------------------------------# @@ -1187,6 +1372,17 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$crop.harvest [idx ] = old.datum$emean$crop.harvest [sel ] new.datum$emean$logging.harvest [idx ] = old.datum$emean$logging.harvest [sel ] new.datum$emean$combusted.fuel [idx ] = old.datum$emean$combusted.fuel [sel ] + new.datum$emean$fire.density [idx ] = old.datum$emean$fire.density [sel ] + new.datum$emean$fire.intensity [idx ] = old.datum$emean$fire.intensity [sel ] + new.datum$emean$fire.ignition [idx ] = old.datum$emean$fire.ignition [sel ] + new.datum$emean$fire.extinction [idx ] = old.datum$emean$fire.extinction [sel ] + new.datum$emean$fire.spread [idx ] = old.datum$emean$fire.spread [sel ] + new.datum$emean$fire.tlethal [idx ] = old.datum$emean$fire.tlethal [sel ] + new.datum$emean$fire.f.bherb [idx ] = old.datum$emean$fire.f.bherb [sel ] + new.datum$emean$fire.f.bwoody [idx ] = old.datum$emean$fire.f.bwoody [sel ] + new.datum$emean$fire.f.fgc [idx ] = old.datum$emean$fire.f.fgc [sel ] + new.datum$emean$fire.f.stgc [idx ] = old.datum$emean$fire.f.stgc [sel ] + new.datum$emean$burnt.area [idx ] = old.datum$emean$burnt.area [sel ] new.datum$emean$het.resp [idx ] = old.datum$emean$het.resp [sel ] new.datum$emean$fgc.resp [idx ] = old.datum$emean$fgc.resp [sel ] new.datum$emean$fsc.resp [idx ] = old.datum$emean$fsc.resp [sel ] @@ -1264,6 +1460,11 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$can.co2 [idx ] = old.datum$emean$can.co2 [sel ] new.datum$emean$can.depth [idx ] = old.datum$emean$can.depth [sel ] new.datum$emean$can.area [idx ] = old.datum$emean$can.area [sel ] + new.datum$emean$sfcw.temp [idx ] = old.datum$emean$sfcw.temp [sel ] + new.datum$emean$sfcw.fliq [idx ] = old.datum$emean$sfcw.fliq [sel ] + new.datum$emean$sfcw.mass [idx ] = old.datum$emean$sfcw.mass [sel ] + new.datum$emean$sfcw.depth [idx ] = old.datum$emean$sfcw.depth [sel ] + new.datum$emean$sfcw.cover [idx ] = old.datum$emean$sfcw.cover [sel ] new.datum$emean$soil.temp.top [idx ] = old.datum$emean$soil.temp.top [sel ] new.datum$emean$soil.water.top [idx ] = old.datum$emean$soil.water.top [sel ] new.datum$emean$soil.water.bot [idx ] = old.datum$emean$soil.water.bot [sel ] @@ -1279,6 +1480,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$last.2yr.ltemp [idx ] = old.datum$emean$last.2yr.ltemp [sel ] new.datum$emean$last.3yr.ltemp [idx ] = old.datum$emean$last.3yr.ltemp [sel ] new.datum$emean$leaf.water [idx ] = old.datum$emean$leaf.water [sel ] + new.datum$emean$leaf.water.im2 [idx ] = old.datum$emean$leaf.water.im2 [sel ] new.datum$emean$phap.lwater [idx ] = old.datum$emean$phap.lwater [sel ] new.datum$emean$last.1yr.lwater [idx ] = old.datum$emean$last.1yr.lwater [sel ] new.datum$emean$last.2yr.lwater [idx ] = old.datum$emean$last.2yr.lwater [sel ] @@ -1423,6 +1625,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$leaf.par.beam [idx ] = old.datum$emean$leaf.par.beam [sel ] new.datum$emean$leaf.par.diff [idx ] = old.datum$emean$leaf.par.diff [sel ] new.datum$emean$leaf.gpp [idx ] = old.datum$emean$leaf.gpp [sel ] + new.datum$emean$dmin.leaf.psi [idx ] = old.datum$emean$dmin.leaf.psi [sel ] + new.datum$emean$dmax.leaf.psi [idx ] = old.datum$emean$dmax.leaf.psi [sel ] new.datum$emean$phap.lpar [idx ] = old.datum$emean$phap.lpar [sel ] new.datum$emean$last.1yr.lpar [idx ] = old.datum$emean$last.1yr.lpar [sel ] new.datum$emean$last.2yr.lpar [idx ] = old.datum$emean$last.2yr.lpar [sel ] @@ -1448,6 +1652,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$emean$last.1yr.hydmort [idx ] = old.datum$emean$last.1yr.hydmort [sel ] new.datum$emean$last.2yr.hydmort [idx ] = old.datum$emean$last.2yr.hydmort [sel ] new.datum$emean$last.3yr.hydmort [idx ] = old.datum$emean$last.3yr.hydmort [sel ] + new.datum$emean$fire.lethal [idx ] = old.datum$emean$fire.lethal [sel ] new.datum$emean$agb.change [idx ] = old.datum$emean$agb.change [sel ] new.datum$emean$acc.change [idx ] = old.datum$emean$acc.change [sel ] new.datum$emean$acc.growth [idx ] = old.datum$emean$acc.growth [sel ] @@ -1547,6 +1752,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$leaf.temp [idx,,] = old.datum$szpft$leaf.temp [sel,,] new.datum$szpft$phap.ltemp [idx,,] = old.datum$szpft$phap.ltemp [sel,,] new.datum$szpft$leaf.water [idx,,] = old.datum$szpft$leaf.water [sel,,] + new.datum$szpft$leaf.water.im2 [idx,,] = old.datum$szpft$leaf.water.im2 [sel,,] new.datum$szpft$phap.lwater [idx,,] = old.datum$szpft$phap.lwater [sel,,] new.datum$szpft$wood.temp [idx,,] = old.datum$szpft$wood.temp [sel,,] new.datum$szpft$leaf.vpd [idx,,] = old.datum$szpft$leaf.vpd [sel,,] @@ -1558,6 +1764,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$dimort [idx,,] = old.datum$szpft$dimort [sel,,] new.datum$szpft$ncbmort [idx,,] = old.datum$szpft$ncbmort [sel,,] new.datum$szpft$hydmort [idx,,] = old.datum$szpft$hydmort [sel,,] + new.datum$szpft$fire.lethal [idx,,] = old.datum$szpft$fire.lethal [sel,,] new.datum$szpft$growth [idx,,] = old.datum$szpft$growth [sel,,] new.datum$szpft$recr [idx,,] = old.datum$szpft$recr [sel,,] new.datum$szpft$change [idx,,] = old.datum$szpft$change [sel,,] @@ -1634,6 +1841,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$szpft$leaf.par.beam [idx,,] = old.datum$szpft$leaf.par.beam [sel,,] new.datum$szpft$leaf.par.diff [idx,,] = old.datum$szpft$leaf.par.diff [sel,,] new.datum$szpft$leaf.gpp [idx,,] = old.datum$szpft$leaf.gpp [sel,,] + new.datum$szpft$dmin.leaf.psi [idx,,] = old.datum$szpft$dmin.leaf.psi [sel,,] + new.datum$szpft$dmax.leaf.psi [idx,,] = old.datum$szpft$dmax.leaf.psi [sel,,] new.datum$szpft$phap.lpar [idx,,] = old.datum$szpft$phap.lpar [sel,,] new.datum$szpft$leaf.rshort [idx,,] = old.datum$szpft$leaf.rshort [sel,,] new.datum$szpft$leaf.rlong [idx,,] = old.datum$szpft$leaf.rlong [sel,,] @@ -1725,6 +1934,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$qmean$can.temp [idx,] = old.datum$qmean$can.temp [sel,] new.datum$qmean$leaf.temp [idx,] = old.datum$qmean$leaf.temp [sel,] new.datum$qmean$leaf.water [idx,] = old.datum$qmean$leaf.water [sel,] + new.datum$qmean$leaf.water.im2 [idx,] = old.datum$qmean$leaf.water.im2 [sel,] new.datum$qmean$wood.temp [idx,] = old.datum$qmean$wood.temp [sel,] new.datum$qmean$gnd.temp [idx,] = old.datum$qmean$gnd.temp [sel,] new.datum$qmean$atm.shv [idx,] = old.datum$qmean$atm.shv [sel,] @@ -1826,10 +2036,103 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ + #---------------------------------------------------------------------------------------# + # SITE -- Site-level variables. # + #---------------------------------------------------------------------------------------# + new.datum$site$isi [idx,] = old.datum$site$isi [sel,] + new.datum$site$lsl [idx,] = old.datum$site$lsl [sel,] + new.datum$site$ntext [idx,] = old.datum$site$ntext [sel,] + new.datum$site$area [idx,] = old.datum$site$area [sel,] + new.datum$site$fire.wmass.threshold[idx,] = old.datum$site$fire.wmass.threshold[sel,] + new.datum$site$fire.density [idx,] = old.datum$site$fire.density [sel,] + new.datum$site$fire.extinction [idx,] = old.datum$site$fire.extinction [sel,] + new.datum$site$fire.intensity [idx,] = old.datum$site$fire.intensity [sel,] + new.datum$site$fire.tlethal [idx,] = old.datum$site$fire.tlethal [sel,] + new.datum$site$fire.spread [idx,] = old.datum$site$fire.spread [sel,] + new.datum$site$burnt.area [idx,] = old.datum$site$burnt.area [sel,] + new.datum$site$ignition.rate [idx,] = old.datum$site$ignition.rate [sel,] + new.datum$site$fire.f.bherb [idx,] = old.datum$site$fire.f.bherb [sel,] + new.datum$site$fire.f.bwoody [idx,] = old.datum$site$fire.f.bwoody [sel,] + new.datum$site$fire.f.fgc [idx,] = old.datum$site$fire.f.fgc [sel,] + new.datum$site$fire.f.stgc [idx,] = old.datum$site$fire.f.stgc [sel,] + new.datum$site$lai [idx,] = old.datum$site$lai [sel,] + new.datum$site$wai [idx,] = old.datum$site$wai [sel,] + new.datum$site$tai [idx,] = old.datum$site$tai [sel,] + new.datum$site$agb [idx,] = old.datum$site$agb [sel,] + new.datum$site$ba [idx,] = old.datum$site$ba [sel,] + new.datum$site$nplant [idx,] = old.datum$site$nplant [sel,] + new.datum$site$fast.grnd.c [idx,] = old.datum$site$fast.grnd.c [sel,] + new.datum$site$fast.soil.c [idx,] = old.datum$site$fast.soil.c [sel,] + new.datum$site$struct.grnd.c [idx,] = old.datum$site$struct.grnd.c [sel,] + new.datum$site$struct.soil.c [idx,] = old.datum$site$struct.soil.c [sel,] + new.datum$site$microbe.soil.c [idx,] = old.datum$site$microbe.soil.c [sel,] + new.datum$site$slow.soil.c [idx,] = old.datum$site$slow.soil.c [sel,] + new.datum$site$passive.soil.c [idx,] = old.datum$site$passive.soil.c [sel,] + new.datum$site$nep [idx,] = old.datum$site$nep [sel,] + new.datum$site$het.resp [idx,] = old.datum$site$het.resp [sel,] + new.datum$site$soil.resp [idx,] = old.datum$site$soil.resp [sel,] + new.datum$site$cflxca [idx,] = old.datum$site$cflxca [sel,] + new.datum$site$cflxst [idx,] = old.datum$site$cflxst [sel,] + new.datum$site$nee [idx,] = old.datum$site$nee [sel,] + new.datum$site$hflxca [idx,] = old.datum$site$hflxca [sel,] + new.datum$site$hflxgc [idx,] = old.datum$site$hflxgc [sel,] + new.datum$site$qwflxca [idx,] = old.datum$site$qwflxca [sel,] + new.datum$site$wflxca [idx,] = old.datum$site$wflxca [sel,] + new.datum$site$wflxgc [idx,] = old.datum$site$wflxgc [sel,] + new.datum$site$ustar [idx,] = old.datum$site$ustar [sel,] + new.datum$site$rshortup [idx,] = old.datum$site$rshortup [sel,] + new.datum$site$rlongup [idx,] = old.datum$site$rlongup [sel,] + new.datum$site$parup [idx,] = old.datum$site$parup [sel,] + new.datum$site$rshort.gnd [idx,] = old.datum$site$rshort.gnd [sel,] + new.datum$site$par.gnd [idx,] = old.datum$site$par.gnd [sel,] + new.datum$site$rnet [idx,] = old.datum$site$rnet [sel,] + new.datum$site$wood.dens [idx,] = old.datum$site$wood.dens [sel,] + new.datum$site$vm0 [idx,] = old.datum$site$vm0 [sel,] + new.datum$site$llspan [idx,] = old.datum$site$llspan [sel,] + new.datum$site$sla [idx,] = old.datum$site$sla [sel,] + new.datum$site$can.depth [idx,] = old.datum$site$can.depth [sel,] + new.datum$site$can.area [idx,] = old.datum$site$can.area [sel,] + new.datum$site$veg.height [idx,] = old.datum$site$veg.height [sel,] + new.datum$site$sm.stress [idx,] = old.datum$site$sm.stress [sel,] + new.datum$site$leaf.temp [idx,] = old.datum$site$leaf.temp [sel,] + new.datum$site$leaf.water [idx,] = old.datum$site$leaf.water [sel,] + new.datum$site$leaf.water.im2 [idx,] = old.datum$site$leaf.water.im2 [sel,] + new.datum$site$leaf.vpd [idx,] = old.datum$site$leaf.vpd [sel,] + new.datum$site$leaf.gpp [idx,] = old.datum$site$leaf.gpp [sel,] + new.datum$site$dmin.leaf.psi [idx,] = old.datum$site$dmin.leaf.psi [sel,] + new.datum$site$dmax.leaf.psi [idx,] = old.datum$site$dmax.leaf.psi [sel,] + new.datum$site$leaf.gsw [idx,] = old.datum$site$leaf.gsw [sel,] + new.datum$site$leaf.par [idx,] = old.datum$site$leaf.par [sel,] + new.datum$site$leaf.par.beam [idx,] = old.datum$site$leaf.par.beam [sel,] + new.datum$site$leaf.par.diff [idx,] = old.datum$site$leaf.par.diff [sel,] + new.datum$site$gpp [idx,] = old.datum$site$gpp [sel,] + new.datum$site$npp [idx,] = old.datum$site$npp [sel,] + new.datum$site$plant.resp [idx,] = old.datum$site$plant.resp [sel,] + new.datum$site$cba [idx,] = old.datum$site$cba [sel,] + new.datum$site$reco [idx,] = old.datum$site$reco [sel,] + new.datum$site$hflxlc [idx,] = old.datum$site$hflxlc [sel,] + new.datum$site$hflxwc [idx,] = old.datum$site$hflxwc [sel,] + new.datum$site$wflxlc [idx,] = old.datum$site$wflxlc [sel,] + new.datum$site$wflxwc [idx,] = old.datum$site$wflxwc [sel,] + new.datum$site$transp [idx,] = old.datum$site$transp [sel,] + new.datum$site$gnd.temp [idx,] = old.datum$site$gnd.temp [sel,] + new.datum$site$gnd.shv [idx,] = old.datum$site$gnd.shv [sel,] + new.datum$site$soil.temp.top [idx,] = old.datum$site$soil.temp.top [sel,] + new.datum$site$soil.water.top [idx,] = old.datum$site$soil.water.top [sel,] + new.datum$site$soil.water.bot [idx,] = old.datum$site$soil.water.bot [sel,] + new.datum$site$soil.wetness.top [idx,] = old.datum$site$soil.wetness.top [sel,] + new.datum$site$soil.wetness.bot [idx,] = old.datum$site$soil.wetness.bot [sel,] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # PATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# + new.datum$patch$isi = old.datum$patch$isi + new.datum$patch$lsl = old.datum$patch$lsl + new.datum$patch$ntext = old.datum$patch$ntext new.datum$patch$ipa = old.datum$patch$ipa new.datum$patch$age = old.datum$patch$age new.datum$patch$area = old.datum$patch$area @@ -1881,12 +2184,18 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$agb = old.datum$patch$agb new.datum$patch$ba = old.datum$patch$ba new.datum$patch$nplant = old.datum$patch$nplant + new.datum$patch$bleaf = old.datum$patch$bleaf new.datum$patch$wood.dens = old.datum$patch$wood.dens new.datum$patch$vm0 = old.datum$patch$vm0 new.datum$patch$llspan = old.datum$patch$llspan new.datum$patch$sla = old.datum$patch$sla new.datum$patch$can.depth = old.datum$patch$can.depth new.datum$patch$can.area = old.datum$patch$can.area + new.datum$patch$sfcw.temp = old.datum$patch$sfcw.temp + new.datum$patch$sfcw.fliq = old.datum$patch$sfcw.fliq + new.datum$patch$sfcw.mass = old.datum$patch$sfcw.mass + new.datum$patch$sfcw.depth = old.datum$patch$sfcw.depth + new.datum$patch$sfcw.cover = old.datum$patch$sfcw.cover new.datum$patch$veg.height = old.datum$patch$veg.height new.datum$patch$veg.displace = old.datum$patch$veg.displace new.datum$patch$veg.rough = old.datum$patch$veg.rough @@ -1901,8 +2210,11 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$sm.stress = old.datum$patch$sm.stress new.datum$patch$leaf.temp = old.datum$patch$leaf.temp new.datum$patch$leaf.water = old.datum$patch$leaf.water + new.datum$patch$leaf.water.im2 = old.datum$patch$leaf.water.im2 new.datum$patch$leaf.vpd = old.datum$patch$leaf.vpd new.datum$patch$leaf.gpp = old.datum$patch$leaf.gpp + new.datum$patch$dmin.leaf.psi = old.datum$patch$dmin.leaf.psi + new.datum$patch$dmax.leaf.psi = old.datum$patch$dmax.leaf.psi new.datum$patch$leaf.gsw = old.datum$patch$leaf.gsw new.datum$patch$leaf.par = old.datum$patch$leaf.par new.datum$patch$leaf.par.beam = old.datum$patch$leaf.par.beam @@ -1936,6 +2248,31 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$patch$soil.water = old.datum$patch$soil.water new.datum$patch$soil.mstpot = old.datum$patch$soil.mstpot new.datum$patch$rk4step = old.datum$patch$rk4step + new.datum$patch$growth = old.datum$patch$growth + new.datum$patch$agb.growth = old.datum$patch$agb.growth + new.datum$patch$acc.growth = old.datum$patch$acc.growth + new.datum$patch$bsa.growth = old.datum$patch$bsa.growth + new.datum$patch$mort = old.datum$patch$mort + new.datum$patch$ncbmort = old.datum$patch$ncbmort + new.datum$patch$hydmort = old.datum$patch$hydmort + new.datum$patch$dimort = old.datum$patch$dimort + new.datum$patch$fire.lethal = old.datum$patch$fire.lethal + new.datum$patch$agb.mort = old.datum$patch$agb.mort + new.datum$patch$agb.ncbmort = old.datum$patch$agb.ncbmort + new.datum$patch$agb.hydmort = old.datum$patch$agb.hydmort + new.datum$patch$agb.dimort = old.datum$patch$agb.dimort + new.datum$patch$acc.mort = old.datum$patch$acc.mort + new.datum$patch$acc.ncbmort = old.datum$patch$acc.ncbmort + new.datum$patch$acc.hydmort = old.datum$patch$acc.hydmort + new.datum$patch$acc.dimort = old.datum$patch$acc.dimort + new.datum$patch$bsa.mort = old.datum$patch$bsa.mort + new.datum$patch$bsa.ncbmort = old.datum$patch$bsa.ncbmort + new.datum$patch$bsa.hydmort = old.datum$patch$bsa.hydmort + new.datum$patch$bsa.dimort = old.datum$patch$bsa.dimort + new.datum$patch$recr = old.datum$patch$recr + new.datum$patch$agb.recr = old.datum$patch$agb.recr + new.datum$patch$acc.recr = old.datum$patch$acc.recr + new.datum$patch$bsa.recr = old.datum$patch$bsa.recr #---------------------------------------------------------------------------------------# @@ -1944,71 +2281,75 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ #---------------------------------------------------------------------------------------# # QPATCH -- patch level variables, we save as lists because the dimensions vary. # #---------------------------------------------------------------------------------------# - new.datum$qpatch$nep = old.datum$qpatch$nep - new.datum$qpatch$het.resp = old.datum$qpatch$het.resp - new.datum$qpatch$fgc.resp = new.datum$qpatch$fgc.resp - new.datum$qpatch$fsc.resp = new.datum$qpatch$fsc.resp - new.datum$qpatch$stgc.resp = new.datum$qpatch$stgc.resp - new.datum$qpatch$stsc.resp = new.datum$qpatch$stsc.resp - new.datum$qpatch$msc.resp = new.datum$qpatch$msc.resp - new.datum$qpatch$ssc.resp = new.datum$qpatch$ssc.resp - new.datum$qpatch$psc.resp = new.datum$qpatch$psc.resp - new.datum$qpatch$can.temp = old.datum$qpatch$can.temp - new.datum$qpatch$gnd.temp = old.datum$qpatch$gnd.temp - new.datum$qpatch$can.shv = old.datum$qpatch$can.shv - new.datum$qpatch$gnd.shv = old.datum$qpatch$gnd.shv - new.datum$qpatch$can.vpd = old.datum$qpatch$can.vpd - new.datum$qpatch$can.co2 = old.datum$qpatch$can.co2 - new.datum$qpatch$can.prss = old.datum$qpatch$can.prss - new.datum$qpatch$cflxca = old.datum$qpatch$cflxca - new.datum$qpatch$cflxst = old.datum$qpatch$cflxst - new.datum$qpatch$nee = old.datum$qpatch$nee - new.datum$qpatch$hflxca = old.datum$qpatch$hflxca - new.datum$qpatch$hflxgc = old.datum$qpatch$hflxgc - new.datum$qpatch$qwflxca = old.datum$qpatch$qwflxca - new.datum$qpatch$wflxca = old.datum$qpatch$wflxca - new.datum$qpatch$wflxgc = old.datum$qpatch$wflxgc - new.datum$qpatch$ustar = old.datum$qpatch$ustar - new.datum$qpatch$albedo = old.datum$qpatch$albedo - new.datum$qpatch$rshortup = old.datum$qpatch$rshortup - new.datum$qpatch$rlongup = old.datum$qpatch$rlongup - new.datum$qpatch$parup = old.datum$qpatch$parup - new.datum$qpatch$rshort.gnd = old.datum$qpatch$rshort.gnd - new.datum$qpatch$par.gnd = old.datum$qpatch$par.gnd - new.datum$qpatch$rnet = old.datum$qpatch$rnet - new.datum$qpatch$sm.stress = old.datum$qpatch$sm.stress - new.datum$qpatch$leaf.temp = old.datum$qpatch$leaf.temp - new.datum$qpatch$leaf.water = old.datum$qpatch$leaf.water - new.datum$qpatch$leaf.vpd = old.datum$qpatch$leaf.vpd - new.datum$qpatch$wood.temp = old.datum$qpatch$wood.temp - new.datum$qpatch$par.leaf = old.datum$qpatch$par.leaf - new.datum$qpatch$par.leaf.beam = old.datum$qpatch$par.leaf.beam - new.datum$qpatch$par.leaf.diff = old.datum$qpatch$par.leaf.diff - new.datum$qpatch$leaf.gpp = old.datum$qpatch$leaf.gpp - new.datum$qpatch$leaf.gsw = old.datum$qpatch$leaf.gsw - new.datum$qpatch$leaf.par = old.datum$qpatch$leaf.par - new.datum$qpatch$leaf.par.beam = old.datum$qpatch$leaf.par.beam - new.datum$qpatch$leaf.par.diff = old.datum$qpatch$leaf.par.diff - new.datum$qpatch$assim.light = old.datum$qpatch$assim.light - new.datum$qpatch$assim.rubp = old.datum$qpatch$assim.rubp - new.datum$qpatch$assim.co2 = old.datum$qpatch$assim.co2 - new.datum$qpatch$gpp = old.datum$qpatch$gpp - new.datum$qpatch$npp = old.datum$qpatch$npp - new.datum$qpatch$plant.resp = old.datum$qpatch$plant.resp - new.datum$qpatch$reco = old.datum$qpatch$reco - new.datum$qpatch$hflxlc = old.datum$qpatch$hflxlc - new.datum$qpatch$hflxwc = old.datum$qpatch$hflxwc - new.datum$qpatch$wflxlc = old.datum$qpatch$wflxlc - new.datum$qpatch$wflxwc = old.datum$qpatch$wflxwc - new.datum$qpatch$transp = old.datum$qpatch$transp - new.datum$qpatch$soil.resp = old.datum$qpatch$soil.resp - new.datum$qpatch$rk4step = old.datum$qpatch$rk4step + new.datum$qpatch$nep = old.datum$qpatch$nep + new.datum$qpatch$het.resp = old.datum$qpatch$het.resp + new.datum$qpatch$fgc.resp = new.datum$qpatch$fgc.resp + new.datum$qpatch$fsc.resp = new.datum$qpatch$fsc.resp + new.datum$qpatch$stgc.resp = new.datum$qpatch$stgc.resp + new.datum$qpatch$stsc.resp = new.datum$qpatch$stsc.resp + new.datum$qpatch$msc.resp = new.datum$qpatch$msc.resp + new.datum$qpatch$ssc.resp = new.datum$qpatch$ssc.resp + new.datum$qpatch$psc.resp = new.datum$qpatch$psc.resp + new.datum$qpatch$can.temp = old.datum$qpatch$can.temp + new.datum$qpatch$gnd.temp = old.datum$qpatch$gnd.temp + new.datum$qpatch$can.shv = old.datum$qpatch$can.shv + new.datum$qpatch$gnd.shv = old.datum$qpatch$gnd.shv + new.datum$qpatch$can.vpd = old.datum$qpatch$can.vpd + new.datum$qpatch$can.co2 = old.datum$qpatch$can.co2 + new.datum$qpatch$can.prss = old.datum$qpatch$can.prss + new.datum$qpatch$cflxca = old.datum$qpatch$cflxca + new.datum$qpatch$cflxst = old.datum$qpatch$cflxst + new.datum$qpatch$nee = old.datum$qpatch$nee + new.datum$qpatch$hflxca = old.datum$qpatch$hflxca + new.datum$qpatch$hflxgc = old.datum$qpatch$hflxgc + new.datum$qpatch$qwflxca = old.datum$qpatch$qwflxca + new.datum$qpatch$wflxca = old.datum$qpatch$wflxca + new.datum$qpatch$wflxgc = old.datum$qpatch$wflxgc + new.datum$qpatch$ustar = old.datum$qpatch$ustar + new.datum$qpatch$albedo = old.datum$qpatch$albedo + new.datum$qpatch$rshortup = old.datum$qpatch$rshortup + new.datum$qpatch$rlongup = old.datum$qpatch$rlongup + new.datum$qpatch$parup = old.datum$qpatch$parup + new.datum$qpatch$rshort.gnd = old.datum$qpatch$rshort.gnd + new.datum$qpatch$par.gnd = old.datum$qpatch$par.gnd + new.datum$qpatch$rnet = old.datum$qpatch$rnet + new.datum$qpatch$sm.stress = old.datum$qpatch$sm.stress + new.datum$qpatch$leaf.temp = old.datum$qpatch$leaf.temp + new.datum$qpatch$leaf.water = old.datum$qpatch$leaf.water + new.datum$qpatch$leaf.water.im2 = old.datum$qpatch$leaf.water.im2 + new.datum$qpatch$leaf.vpd = old.datum$qpatch$leaf.vpd + new.datum$qpatch$wood.temp = old.datum$qpatch$wood.temp + new.datum$qpatch$par.leaf = old.datum$qpatch$par.leaf + new.datum$qpatch$par.leaf.beam = old.datum$qpatch$par.leaf.beam + new.datum$qpatch$par.leaf.diff = old.datum$qpatch$par.leaf.diff + new.datum$qpatch$leaf.gpp = old.datum$qpatch$leaf.gpp + new.datum$qpatch$leaf.gsw = old.datum$qpatch$leaf.gsw + new.datum$qpatch$leaf.par = old.datum$qpatch$leaf.par + new.datum$qpatch$leaf.par.beam = old.datum$qpatch$leaf.par.beam + new.datum$qpatch$leaf.par.diff = old.datum$qpatch$leaf.par.diff + new.datum$qpatch$assim.light = old.datum$qpatch$assim.light + new.datum$qpatch$assim.rubp = old.datum$qpatch$assim.rubp + new.datum$qpatch$assim.co2 = old.datum$qpatch$assim.co2 + new.datum$qpatch$gpp = old.datum$qpatch$gpp + new.datum$qpatch$npp = old.datum$qpatch$npp + new.datum$qpatch$plant.resp = old.datum$qpatch$plant.resp + new.datum$qpatch$reco = old.datum$qpatch$reco + new.datum$qpatch$hflxlc = old.datum$qpatch$hflxlc + new.datum$qpatch$hflxwc = old.datum$qpatch$hflxwc + new.datum$qpatch$wflxlc = old.datum$qpatch$wflxlc + new.datum$qpatch$wflxwc = old.datum$qpatch$wflxwc + new.datum$qpatch$transp = old.datum$qpatch$transp + new.datum$qpatch$soil.resp = old.datum$qpatch$soil.resp + new.datum$qpatch$rk4step = old.datum$qpatch$rk4step #---------------------------------------------------------------------------------------# #----- Cohort level, we save as lists because the dimensions vary. ---------------------# + new.datum$cohort$isi = old.datum$cohort$isi + new.datum$cohort$lsl = old.datum$cohort$lsl + new.datum$cohort$ntext = old.datum$cohort$ntext new.datum$cohort$ipa = old.datum$cohort$ipa new.datum$cohort$ico = old.datum$cohort$ico new.datum$cohort$area = old.datum$cohort$area @@ -2081,6 +2422,7 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$cohort$dimort = old.datum$cohort$dimort new.datum$cohort$ncbmort = old.datum$cohort$ncbmort new.datum$cohort$hydmort = old.datum$cohort$hydmort + new.datum$cohort$fire.lethal = old.datum$cohort$fire.lethal new.datum$cohort$recruit = old.datum$cohort$recruit new.datum$cohort$growth = old.datum$cohort$growth new.datum$cohort$agb.growth = old.datum$cohort$agb.growth @@ -2101,6 +2443,8 @@ update.monthly <<- function(new.ntimes,old.datum,montha,yeara,inpref,slz.min){ new.datum$cohort$leaf.par.beam = old.datum$cohort$leaf.par.beam new.datum$cohort$leaf.par.diff = old.datum$cohort$leaf.par.diff new.datum$cohort$leaf.gpp = old.datum$cohort$leaf.gpp + new.datum$cohort$dmin.leaf.psi = old.datum$cohort$dmin.leaf.psi + new.datum$cohort$dmax.leaf.psi = old.datum$cohort$dmax.leaf.psi new.datum$cohort$phap.lpar = old.datum$cohort$phap.lpar new.datum$cohort$leaf.rshort = old.datum$cohort$leaf.rshort new.datum$cohort$leaf.rlong = old.datum$cohort$leaf.rlong diff --git a/R-utils/neon_utils.r b/R-utils/neon_utils.r new file mode 100644 index 000000000..3a6dd1a45 --- /dev/null +++ b/R-utils/neon_utils.r @@ -0,0 +1,1630 @@ +#----- List of flags for undetermined species. --------------------------------------------# +unknown_wildcard <<- c("aff","cf","deleteme","ind","indet","na","ni","sp","spp" + ,"spnov","unknown","unidentified" + ,paste0("sp" ,sequence(99)) + ,paste0("spb" ,sequence(99)) + ,paste0("spp" ,sequence(99)) + ,paste0("sp" ,sequence(99),"cay-atdn") + ,paste0("sp" ,sequence(99),"-cay" ) + ,paste0("sp" ,sequence(99),"guyafor" ) + ,paste0("spfg",sequence(99),"-holst" ) + )#end c +unknown_common <<- "unknown" +unk_liana_common <<- "liana" +unknown_phylum <<- "Ignotophyta" +unknown_class <<- "Ignotopsida" +unknown_order <<- "Ignotales" +unknown_family <<- "Ignotaceae" +unknown_genus <<- "Ignotum" +unknown_epithet <<- "indet" +unk_liana_phylum <<- "Lianophyta" +unk_liana_class <<- "Lianopsida" +unk_liana_order <<- "Lianales" +unk_liana_family <<- "Lianaceae" +unk_liana_genus <<- "Liana" +unknown_scientific <<- paste(unknown_genus,unknown_epithet) +unk_liana_scientific <<- paste(unk_liana_genus,unknown_epithet) +#------------------------------------------------------------------------------------------# + + + +#========================================================================================== +#========================================================================================== +# This function standardises the spelling of common names of trees. +#------------------------------------------------------------------------------------------ +standard_common_name_NEON <<- function(x){ + #---~--- + # Make sure common names are lower case. + #---~--- + x = tolower(x) + #---~--- + + + #---~--- + # Remove underscore marks. + #---~--- + x = gsub(pattern="_",replacement=" ",x=x) + #---~--- + + + + #---~--- + # General substitutions. These are very aggressive, so don't use it too much. + # Good things to put here are names that are often misspelt in a way that cannot occur + # in other words. For example, abiuarana instead of abiurana is a good case; replacing + # abiu with abiurana is a bad idea because abiurana would become abiuranarana. It's + # wise to use regexpr rules such as ^ and $ to make sure gsub won't substitute more + # than it is supposed to. + #---~--- + # x = gsub(pattern="^abiuarana" ,replacement="abiurana" ,x=x) + #---~--- + + + + #---~--- + # Specific substitutions. Most cases should come here. + #---~--- + sel = (x %in% "dense sedge" ); x[sel] = NA_character_ + #---~--- + + return(x) +}#end function standard.common.name +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# This function corrects scientific names and families that are not correctly typed, +# are synonyms or have become obsolete. +#------------------------------------------------------------------------------------------# + + + + + + +#========================================================================================== +#========================================================================================== +# This attributes scientific names based on common names for NEON surveys. +# It is NOT a good idea to use this anywhere else because common names may mean completely +# diferent things... +#------------------------------------------------------------------------------------------ +scientific_lookup_NEON <<- function(datum,lookup_path,site){ + + #---~--- + # Read in the look-up table. + #---~--- + lookup_file = file.path(lookup_path,"NEON_taxon_lookup.csv") + look_up = as.data.table(read.csv(file=lookup_file,stringsAsFactors=FALSE)) + look_up$common = tolower(trim(look_up$common )) + look_up$scientific = trim(look_up$scientific) + look_up$family = trim(look_up$family ) + #---~--- + + + #---~--- + # Keep only entries for this NEON site. + #---~--- + if (site %in% names(look_up)){ + look_up = look_up[look_up[[site]],,drop=FALSE] + }else{ + cat0("-------------------------------------------------------------------") + cat0(" ERROR! Site is not available at the look-up data base." ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" Site: ",site ) + cat0(" Data base file: ",lookup_file ) + cat0(" " ) + cat0(" Edit data base file, adding all the common names occurring at" ) + cat0(" your site, and add a column named site with the entries that" ) + cat0(" should be applicable to your site. Look for existing nearby" ) + cat0(" sites, it is fine to have the same common name valid for multiple" ) + cat0(" locations. If the common name already exists in the data base" ) + cat0(" but refers to a different species in your site, duplicate the" ) + cat0(" common name, make sure to set the new entry to TRUE for the new" ) + cat0(" site, and FALSE to all the other sites. Also set the new site to" ) + cat0(" FALSE in the existing entry." ) + cat0(" " ) + cat0("-------------------------------------------------------------------") + stop("Invalid site.") + }#end if (site %in% look_up) + #---~--- + + + + #---~--- + # Break into genus and epithet. + #---~--- + ge_list = sapply(X = tolower(look_up$scientific),FUN=strsplit,split=" ") + ge_length = sapply(X = ge_list, FUN = length) + ge_mat = cbind( mapply(FUN="[",ge_list,MoreArgs=list(1)) + , mapply(FUN="[",ge_list,MoreArgs=list(2)) + )#end cbind + g = capwords(ge_mat[,1],strict=TRUE) + e = tolower(ge_mat[,2]) + g_e = paste(g,e,sep=" ") + g_e[is.na(g) & is.na(e)] = NA_character_ + look_up$scientific = g_e + look_up$genus = g + #---~--- + + + + #---~--- + # Trim the common names, and simplify/replace some names. + #---~--- + datum$common = tolower(trim(datum$common)) + datum$common[is.na(datum$common)] = unknown_common + #---~--- + + + #---~--- + # Initialise column gf.scientific in case it is not available. + #---~--- + if (! "gf.scientific" %in% names(datum)){ + datum$gf.scientific = rep(NA_integer_,times=nrow(datum)) + }#end (! "gf.scientific" %in% names(datum)) + #---~--- + + + #---~--- + # Find all unique common names. + #---~--- + unique_common = unique(datum$common) + n_common = length(unique_common) + not_found = character(0L) + for (n in sequence(n_common)){ + #---~--- + # Find the trees that have the same common name as this one. + #---~--- + cat0(" - ",n,"/",n_common," -- ",unique_common[n],".") + w_dat = which(datum$common %in% unique_common[n]) + n_dat = length(w_dat) + #---~--- + + + #---~--- + # Find the trees in the look-up table with the same common name. + #---~--- + w_look = which(look_up$common %in% unique_common[n]) + n_look = length(w_look) + #---~--- + + + + #---~--- + # Check how many trees have the same common name in the look-up table. + #---~--- + if (n_look == 1){ + #---~--- + # Only one. Use it. + #---~--- + datum$scientific [w_dat] = look_up$scientific[w_look] + datum$genus [w_dat] = look_up$genus [w_look] + datum$gf.scientific[w_dat] = 1L + }else if (n_look > 1){ + datum$scientific [w_dat] = sample( x = look_up$scientific[w_look] + , size = n_dat + , replace = TRUE + )#end sample + datum$genus [w_dat] = look_up$genus [w_look] + datum$gf.scientific[w_dat] = 1 + }else{ + not_found = c(not_found,unique_common[n]) + datum$scientific [w_dat] = unknown_scientific + datum$genus [w_dat] = unknown_genus + datum$gf.scientific[w_dat] = 0 + }#end if + #---~--- + }#end for (n in sequence(n_common)) + #---~--- + + + #---~--- + # In case species were not found, list them so the user is aware. + #---~--- + not_found = not_found[! not_found %in% unknown_common] + if (length(not_found) %gt% 0L){ + #---~--- + # Report the unmatched names. + #---~--- + cat0(" " ) + cat0(" " ) + cat0("-------------------------------------------------------------------") + cat0(" WARNING! Some names were not found in the common name data base." ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" Site: ",site ) + cat0(" Data base file: ",lookup_file ) + cat0(" " ) + cat0(" Species not found:" ) + #---~--- + + #---~--- + # Loop through unmatched names. + #---~--- + for (n in seq_along(not_found)){ + cat0(" - ",not_found[n],"." ) + }#end for (n in seq_along(not_found)) + #---~--- + + #---~--- + # End report + #---~--- + cat0(" " ) + cat0("-------------------------------------------------------------------") + cat0(" " ) + cat0(" " ) + #---~--- + }#end if (length(not_found) %gt% 0L) + #---~--- + + #---~--- + # Return standardised data. + #---~--- + return(datum) + #---~--- +}#end function scientific_lookup_NEON +#==========================================================================================# +#==========================================================================================# + + + + + + +#========================================================================================== +#========================================================================================== +# Fill in the traits for all individuals. We do this in three stages, and save how +# the trait was determined. The numbers represent the flag given for each trait. +# 0 -- Individuals have full identification and the species is listed in the +# database; we used the reported density for that species. +# 1 -- The species/genus is identified but it isn't listed in the database, we use an +# average of all other species of that genus that exist in database. +# 2 -- We could not identify the individual to the genus level, but we know the +# family. We use the average wood density of all individuals of this census that +# belong to that family. +# 3 -- No taxonomic information could be retrieved for this individual, so we filled +# with random sampling. +# +# We also add 10 when the scientific name was gap filled. +# +# INPUT variables: +# +# - datum -- data frame with data. This is going to be the output as well +# - trait -- trait to fill +# - tdb.csv -- csv file containing the trait data base +# - country -- restrict attribution to these countries (NULL uses all countries) +# - continents -- restrict attribution to these continents (NULL uses all continents) +# - fsample -- use random sampling to fill unidentified individuals, or individuals +# with genus that is not available at the trait data base? +# If FALSE then it uses averages +# - weight -- A weighting factor to give either probability or to weight +# the average. This could be a vector with weights, or a character with +# the name of the variable in datum to use as the weight, or an integer +# with the column to be used as the weighting factor +# - verbose -- Flag to control the amount of information +#------------------------------------------------------------------------------------------ +find_trait_NEON <<- function( datum + , trait = c( "wood.dens", "SLA", "leaf.phen" + , "growth.form", "woodland") + , tdb.csv = file.path(srcdir,"NEON_trait_table.csv") + , country = NULL + , continent = NULL + , fsample = TRUE + , weight = NULL + , verbose = FALSE + ){ + + #---~--- + # Check that trait is valid. + #---~--- + trait = match.arg(trait) + n.trait = paste0("n." ,trait) + gf.trait = paste0("gf.",trait) + #---~--- + + + #---~--- + # Initialise gap filling flag and region in case they are not there. + #---~--- + if (! trait %in% names(datum)){ + if ( trait %in% c("leaf.phen","growth.form") ){ + datum[[trait]] = rep(NA_character_,times=nrow(datum)) + }else if ( trait %in% "woodland" ){ + datum[[trait]] = rep(NA_logical_ ,times=nrow(datum)) + }else{ + datum[[trait]] = rep(NA_real_ ,times=nrow(datum)) + }#end if ( trait %in% c("leaf.phen","growth.form") ) + }#end (! trait %in% names(datum)) + if (! gf.trait %in% names(datum)){ + datum[[gf.trait]] = rep(NA_integer_,times=nrow(datum)) + }#end (! gf.trait %in% names(datum)) + if (! "country" %in% names(datum)){ + datum$country = rep(NA_character_,times=nrow(datum)) + }#end (! "country" %in% names(datum)) + if (! "continent" %in% names(datum)){ + datum$continent = rep(NA_character_,times=nrow(datum)) + }#end (! "continent" %in% names(datum)) + #---~--- + + + #---~--- + # Check whether weight is a vector, or a character. Make them a vector here. + #---~--- + if (is.null(weight)){ + #---~--- + # No weight provided, use equal weights. + #---~--- + wgtfac = rep(x=1/nrow(datum),times=nrow(datum)) + #---~--- + }else if (is.character(weight) && (length(weight) == 1)){ + #---~--- + # Character with column name was provided. + #---~--- + if (weight %in% names(datum)){ + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) + }else{ + stop(paste0(" Weight Variable name (",weight,") not found in datum!")) + }#end if + #---~--- + }else if (is.numeric(weight) && (length(weight) == 1)){ + #---~--- + # Column index provided. + #---~--- + if (! (weight %wr% c(1,ncol(datum)))){ + stop(paste0(" Weight column index (",weight,") doesn't make sense")) + }else if (is.numeric(datum[,weight])){ + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) + }else{ + stop(paste0(" Column ",weight," of data frame is not numeric!")) + }#end if + #---~--- + }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ + wgtfac = ifelse(weight %gt% 0, weight, 0) + }else{ + stop("Variable weight is not properly set!") + }#end if (is.null(weight)) + #---~--- + + + + #---~--- + # Check that the weighting factor makes sense. + #---~--- + if (sum(wgtfac) > 0){ + wgtfac = wgtfac / sum(wgtfac) + }else{ + stop(" Invalid weighting variable. Most numbers should be positive...") + }#end if + #---~--- + + + + #---~--- + # Read data base to fill traits. + #---~--- + tdb = read.csv(file=tdb.csv,header=TRUE,stringsAsFactors=FALSE) + keep = ! is.na(tdb[[trait]]) + tdb = tdb[keep,,drop=FALSE] + #---~--- + + + + #---~--- + # Restrict data base to valid traits in selected regions, and make sure the data base + # can be used. + #---~--- + if (! (trait %in% names(tdb))){ + stop(paste0(" Trait ",trait," is not available in trait file \"" + ,basename(tdb.csv),"\".")) + }else if (! all(c("country","continent") %in% names(tdb))){ + stop(paste0(" \"country\" and/or \"continent\" missing in trait file \"" + ,basename(tdb.csv),"\".")) + }else{ + #---~--- + # Restrict species to regions of interest. + #---~--- + if (is.null(country)){ + sel.country = rep(x=TRUE,times=nrow(tdb)) + }else{ + sel.country = tdb$country %in% country + }#end if (is.null(country)) + if (is.null(continent)){ + sel.continent = rep(x=TRUE,times=nrow(tdb)) + }else{ + sel.continent = tdb$continent %in% continent + }#end if (is.null(continent)) + keep = (! is.na(tdb[[trait]]) ) & sel.country & sel.continent + ntdb = sum(keep) + if (ntdb == 0){ + cat0(" - Selected trait: ",trait) + if (! is.null(country)){ + cat0(" - Selected countries: " ,paste(country ,collapse="; ")) + }#end if (! is.null(country)) + if (! is.null(continent)){ + cat0(" - Selected continents: ",paste(continent,collapse="; ")) + }#end if (! is.null(continent)) + stop(paste0("No data available for trait ",trait," in file \"" + ,basename(tdb.csv),"\".")) + }else{ + tdb = tdb[keep,,drop=FALSE] + }#end if (ntdb == 0) + #---~--- + }#end if (! (trait %in% names(tdb))) + #---~--- + + + #======================================================================================= + #======================================================================================= + # First loop, fill in information to all individuals for which the genus is + # known. + #--------------------------------------------------------------------------------------- + #---~--- + # Separate all species. + #---~--- + species = unique(datum$scientific) + nspecies = length(species) + sci.genus.mean = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","genus","family"))) + sci.loose.mean = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","genus","family"))) + #---~--- + + + #---~--- + # Loop through species + #---~--- + for (s in sequence(nspecies)){ + if ((! is.na(species[s])) && length(grep(unknown_genus,species[s])) == 0){ + if (verbose) cat0(" - ",s,"/",nspecies," - ",species[s],".") + + #---~--- + # Get the genus and family of this species, in case we need it. + #---~--- + igen = which (datum$scientific %in% species[s]) + this.genus = unique(datum$genus[igen]) + this.family = unique(capwords(datum$family[igen],strict=TRUE)) + if (length(this.genus) != 1 || length(this.family) != 1){ + cat0(" - Perhaps a bastard genus?") + browser() + }#end if + #---~--- + + + + #---~--- + # Check whether we have biomass for this species. + #---~--- + if (species[s] %in% tdb$scientific){ + #---~--- + # Find the index of this species in the database, and assign the trait + # from there. + #---~--- + itrait = intersect( which(tdb$scientific %in% species[s] ) + , intersect( which(tdb$genus %in% this.genus ) + , which(tdb$family %in% this.family) ) ) + + if (length(itrait) != 1){ + #---~--- + # Intersection was zero! Misidentification, maybe? + #---~--- + loose = TRUE + cat0("Weird, length(itrait)=",length(itrait),"!") + browser() + #---~--- + }else{ + if (any(c(FALSE,! is.na(tdb[[trait]][itrait])),na.rm=TRUE)){ + sel = datum$scientific %in% species[s] + datum[[trait]] [sel] = tdb[[trait]][itrait] + datum[[gf.trait]][sel] = 0L + datum$country [sel] = tdb$country [itrait] + datum$continent [sel] = tdb$continent[itrait] + fill.genus = FALSE + loose = FALSE + }else{ + loose = TRUE + fill.genus = this.genus %in% tdb$genus + }#end if + #---~--- + }#end if + #---~--- + }else{ + loose = TRUE + fill.genus = this.genus %in% tdb$genus + }#end if + #---~--- + + + + #---~--- + # If this species is to be filled with genus average. + #---~--- + if (fill.genus){ + #---~--- + # Find all the plants from this genus, take the average, and attribute + # to this species. In this case, warn the user about the species, it may + # be a typo in the scientific name that is easy to fix. + #---~--- + itrait = intersect( which( tdb$genus %in% this.genus ) + , which( tdb$family %in% this.family) + )#end intersect + + #---~--- + # Find individuals that belong to this species. + #---~--- + sel = datum$scientific %in% species[s] + nsel = sum(sel) + #---~--- + + if (length(itrait) == 0){ + #---~--- + # Intersection was zero! Misidentification, maybe? + #---~--- + loose = TRUE + #---~--- + }else if (nsel > 0){ + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = tdb[[trait ]][itrait] + t.weight = tdb[[n.trait]][itrait] / sum(tdb[[n.trait]][itrait]) + t.continent = tdb$continent [itrait] + t.country = tdb$country [itrait] + t.idx = seq_along(t.value) + if (any(is.na(t.weight))) browser() + #---~--- + + + #---~--- + # Decide whether to use sample (non-numeric) or average (numeric). + #---~--- + if (fsample || ( trait %in% c("leaf.phen","growth.form","woodland") )){ + smp.idx = lit.sample(x=t.idx,size=nsel,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + #---~--- + # Fill in missing entries. + #---~--- + datum[[trait]] [sel] = smp.trait + datum[[gf.trait]][sel] = 1L + datum$country [sel] = smp.country + datum$continent [sel] = smp.continent + sci.genus.mean = rbind(sci.genus.mean + ,c(species[s],this.genus,this.family)) + if (verbose){ + cat0(" * Species ",species[s]," not found." + ," Use genus average instead.") + }#end if + loose = FALSE + #---~--- + }#end if + #---~--- + }#end if + #---~--- + + + #---~--- + # Append plants that have no family together. + #---~--- + if (loose){ + #---~--- + # The plant probably doesn't have any family. + #---~--- + sci.loose.mean = rbind(sci.loose.mean + ,c(species[s],this.genus,this.family)) + #---~--- + }#end if + #---~--- + }#end if + #---~--- + }#end for + #---~--- + + + + #---~--- + # List all genera that were not filled with species information. + #---~--- + sci.genus.mean = sci.genus.mean[order(sci.genus.mean[,"scientific"]),,drop=FALSE] + genus.only = grepl( pattern = " NA$" + , x = sci.genus.mean[,"scientific",drop=FALSE] + , ignore.case = TRUE + )#end grepl + if (verbose && (nrow(sci.genus.mean[!genus.only,,drop=FALSE]) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0(" Found species that were not in trait data base (check for synonyms)!") + print(sci.genus.mean[! genus.only,,drop=FALSE],quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if (verbose && nrow(sci.genus.mean[!genus.only,,drop=FALSE]) > 0) + if (verbose && (nrow(sci.genus.mean[genus.only,,drop=FALSE]) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0("Only genus was provided: filled with average genus value:") + print (sci.genus.mean[genus.only,,drop=FALSE],quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if (verbose && nrow(sci.genus.mean[genus.only,,drop=FALSE]) > 0) + #---~--- + + + #---~--- + # List all genera that didn't belong to any known family. + #---~--- + if (verbose && (nrow(sci.loose.mean) > 0)){ + cat0("") + cat0("-----------------------------------------------------------------------") + cat0(" Found genera from families with no valid data in the trait data base!") + print(sci.loose.mean,quote=FALSE) + cat0("-----------------------------------------------------------------------") + cat0("") + }#end if + #---~--- + #======================================================================================= + #======================================================================================= + + + + + + #======================================================================================= + #======================================================================================= + # Second loop: we list all families, and look for individuals that have no genus + # associated. We compute the mean trait of the known individuals for that family and + # use that as an estimate of the trait. + #--------------------------------------------------------------------------------------- + #---~--- + families = unique(datum$family) + nfamilies = length(families) + sci.family.sample = matrix(nrow=0,ncol=3 + ,dimnames=list(NULL,c("scientific","family",trait))) + #---~--- + + + #---~--- + # Loop over all families + #---~--- + for (f in sequence(nfamilies)){ + if (! (families[f] %in% unknown_family)){ + if (verbose) cat0(" - ",f,"/",nfamilies," - ",families[f],".") + + #---~--- + # Get the individuals that belong to this family. + #---~--- + ifam = which (datum$family %in% families[f] & (! is.na(datum[[trait]])) ) + imiss = which (datum$family %in% families[f] & is.na(datum[[trait]]) ) + nmiss = length(imiss) + #---~--- + + if (length(imiss) > 0 && length(ifam) > 0){ + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = datum[[trait]] [ifam] + t.weight = wgtfac [ifam] + t.continent = datum$continent[ifam] + t.country = datum$country [ifam] + t.idx = seq_along(t.value) + #---~--- + + + + #---~--- + # Decide whether to use sample or average. + #---~--- + if (fsample || ( trait %in% c("leaf.phen","growth.form","woodland") )){ + smp.idx = lit.sample(x=t.idx,size=nmiss,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + + #---~--- + # Fill in with the sample/mean. + #---~--- + datum[[trait]] [imiss] = smp.trait + datum[[gf.trait]][imiss] = 2L + datum$country [imiss] = smp.country + datum$continent [imiss] = smp.continent + gf2 = cbind(datum$scientific[imiss] + ,datum$family [imiss] + ,sprintf("%6.3f",smp.trait) + )#end cbind + sci.family.sample = rbind(sci.family.sample,gf2) + #---~--- + }#end if + #---~--- + }#end if + #---~--- + }#end for + #---~--- + + + #---~--- + # Stop if there was any genus that didn't belong to any known family. + #---~--- + if (nrow(sci.family.sample) > 0){ + if (verbose){ + cat0(" Found families with unidentified genera!") + print(sci.family.sample,quote=FALSE) + }#end if + }#end if + #---~--- + + + #---~--- + # Final block. We fill in the trait for unknown individuals, by randomly sampling + # from the individuals we know the density. + #---~--- + imiss = which(is.na(datum[[trait]])) + nmiss = length(imiss) + nvalid = nrow(datum) - nmiss + + if (nmiss > 0){ + if (verbose){ + cat0(" The following families are filled with global sampling: ") + fam.global.sampling = t(t(sort(unique(datum$family[imiss])))) + print(fam.global.sampling,quote=FALSE) + }#end if + #---~--- + + + #---~--- + # Check whether this is going to be a complete guess or something slightly more + # elegant. + #---~--- + if (nvalid == 0){ + #---~--- + # Use any data from the trait data base. + #---~--- + warning(" None of the trees are known! Trait-filling is going to be very crude!") + itrait = which(tdb$life.type %in% "T") + t.value = tdb[[trait ]][itrait] + t.weight = tdb[[n.trait]][itrait] / sum(tdb[[n.trait]][itrait]) + t.continent = tdb$continent [itrait] + t.country = tdb$country [itrait] + t.idx = seq_along(t.value) + #---~--- + }else{ + + #---~--- + # Select data that can be used for weighting. + #---~--- + t.value = datum[[trait]] [-imiss] + t.weight = wgtfac [-imiss] + t.continent = datum$continent[-imiss] + t.country = datum$country [-imiss] + t.idx = seq_along(t.value) + #---~--- + }#end if (nvalid == 0) + #---~--- + + + #---~--- + # Decide whether to use sample or averaged values. + #---~--- + if (fsample || ( trait %in% c("leaf.phen") )){ + smp.idx = lit.sample(x=t.idx,size=nmiss,replace=TRUE,prob=t.weight) + smp.trait = t.value [smp.idx] + smp.country = t.country [smp.idx] + smp.continent = t.continent[smp.idx] + }else{ + smp.trait = weighted.mean (x=t.value ,w=t.weight,na.rm=TRUE) + smp.country = weighted.commonest(x=t.country ,w=t.weight,na.rm=TRUE) + smp.continent = weighted.commonest(x=t.continent,w=t.weight,na.rm=TRUE) + }#end if (fsample || ( trait %in% c("leaf.phen") )) + #---~--- + + + #---~--- + # Fill the remaining gaps. + #---~--- + datum[[trait]] [imiss] = smp.trait + datum$country [imiss] = smp.country + datum$continent [imiss] = smp.continent + datum[[gf.trait]][imiss] = 3L + #---~--- + }#end if + #---~--- + + + #---~--- + # Adjust the gap-filling flag for trait by adding whether the scientific name + # itself was gap-filled. + #---~--- + if ("gf.scientific" %in% names(datum)){ + datum[[gf.trait]] = datum[[gf.trait]] + as.integer(10 * datum$gf.scientific) + }#end if ("gf.scientific" %in% names(datum)) + #---~--- + + + #---~--- + # Assign a plant functional type based on the wood density. + #---~--- + if (trait %in% "wood.dens"){ + pft.cut = cut(datum[[trait]],breaks=pft.breaks) + pft.levels = levels(pft.cut) + pft.idx = match(pft.cut,pft.levels) + datum$pft = mypfts[pft.idx] + }#end if (trait %in% "wood.dens") + #---~--- + return(datum) +}#end function find_trait_NEON +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# This function assigns a PFT given the genus and the full data set. This will +# use imputed data for those genera that do not have all traits. +#------------------------------------------------------------------------------------------ +assign_pft_NEON <<- function(datum,path=srcdir,refsites,verbose=FALSE,...){ + #---~--- + # Load the cluster analysis with the medoid matrix. + #---~--- + neon_lut = read.csv( file = file.path(srcdir,"NEON_taxon_lookup.csv") + , header = TRUE + , stringsAsFactors = FALSE + )#end read.csv + #---~--- + + + #---~--- + # Select species from the sites of interest (it is fine to use more than one + # reference site, just mind that they should be somewhat similar. + #---~--- + sel = rep(FALSE,times=nrow(neon_lut)) + for (r in seq_along(refsites)){ + site = refsites[r] + sel = sel | neon_lut[[site]] + }#end for (r in seq_along(refsites)) + neon_lut = neon_lut[sel,,drop=FALSE] + #---~--- + + + + #---~--- + # Initialise genus with the actual one, but replace those not find in the + # look-up table. + #---~--- + if ("scientific.name" %in% names(datum)) datum$scientific = datum$scientific.name + if ("genus.name" %in% names(datum)) datum$genus = datum$genus.name + if ("family.name" %in% names(datum)) datum$family = datum$family.name + #---~--- + + + + #---~--- + # Initialise use.scientific with the actual scientific name. We will replace + # those that are not found in the look-up table for traits. + #---~--- + ans = rep(NA_integer_,times=nrow(datum)) + #---~--- + + + #---~--- + # First attempt, fill in the species that have an exact match. + #---~--- + idx = match(datum$scientific,neon_lut$scientific) + sel = ! is.na(idx) + ans[sel] = neon_lut$pft[idx[sel]] + #---~--- + + + #---~--- + # Second attempt, find genera that can be filled with existing data. + #---~--- + un_genus = sort(unique(datum$genus[is.na(ans)])) + un_genus = un_genus[un_genus %in% neon_lut$genus] + for (u in seq_along(un_genus)){ + #---~--- + # Handy alias. + #---~--- + genus_now = un_genus[u] + #---~--- + + + #---~--- + # Retrieve PFTs associated with this genus. + #---~--- + pft_pool = neon_lut$pft[neon_lut$genus %in% genus_now] + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$genus %in% genus_now ) & is.na(ans) + ans[sel] = lit.sample(x=pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_genus)) + #---~--- + + + #---~--- + # Third attempt, find families that can be filled with existing data. + #---~--- + un_family = sort(unique(datum$family[is.na(ans)])) + un_family = un_genus[un_family %in% neon_lut$family] + for (u in seq_along(un_family)){ + #---~--- + # Handy alias. + #---~--- + family_now = un_family[u] + #---~--- + + #---~--- + # Retrieve PFTs associated with this family. We include any existing data from + # this family that has been already filled, as families can be broad and it may + # be better to assume unidentified species are close to the identified species. + #---~--- + pft_pool = c( neon_lut$pft[neon_lut$family %in% family_now] + , ans[ ( datum$family %in% family_now ) & (! is.na(ans))] + )#end c + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$family %in% family_now ) & is.na(ans) + ans[sel] = lit.sample(x=pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_family)) + #---~--- + + + #---~--- + # Last attempt, sample from within the entries that have been identified. + #---~--- + sel = is.na(ans) + ans[sel] = lit.sample(x=ans[! sel],size=sum(sel),replace=TRUE) + + un_family = sort(unique(datum$family[is.na(ans)])) + un_family = un_genus[un_family %in% neon_lut$family] + for (u in seq_along(un_family)){ + #---~--- + # Handy alias. + #---~--- + family_now = un_family[u] + #---~--- + + #---~--- + # Retrieve PFTs associated with this genus. + #---~--- + pft_pool = neon_lut$pft[neon_lut$family %in% family_now] + #---~--- + + + #---~--- + # Fill in missing data with random sampling. + #---~--- + sel = ( datum$family %in% family_now ) & is.na(ans) + ans[sel] = lit.sample(pft_pool,size=sum(sel),replace=TRUE) + #---~--- + }#end for (u in seq_along(un_family)) + #---~--- + + + + + #---~--- + # Assign PFT + #---~--- + return(ans) + #---~--- +}#end function assign_pft_NEON +#========================================================================================== +#========================================================================================== + + + + + + +#========================================================================================== +#========================================================================================== +# Biomass allometry that is used for the NEON plots. Results are always in kgC/plant. +# +# References: +# +# Chojnacky DC, Heath LS , Jenkins JC. 2014. Updated generalized biomass equations for +# North American tree species. Forestry (Lond), 87: 129-151. +# doi:10.1093/forestry/cpt053. +# +# Lutz JA, Furniss TJ, Germain SJ, Becker KML, Blomdahl EM, Jeronimo SMA, Cansler CA, +# Freund JA, Swanson ME , Larson AJ. 2017. Shrub communities, spatial patterns, and +# shrub- mediated tree mortality following reintroduced fire in Yosemite National Park, +# California, USA. Fire Ecol., 13: 104-126. doi:10.4996/fireecology.1301104. +# +# Input: +# ---------------------------------------------------------------------------------------- +# dxh --- Diameter of reference (either DBH or basal diameter) [cm] +# wdens --- Wood density [g/cm3] +# scientific --- Species +# genus --- Genus +# family --- Family +# type --- Plant type: +# B - broadleaf tree +# N - needleleaf tree +# S - shrubs +# dead --- Life status: +# TRUE - plant is dead +# FALSE - plant is alive +# In case dead = NULL, all plants are assumed to be alive. +# eps.dbh --- Relative uncertainty for DBH [1 means 100%] +# eps.height --- Relative uncertainty for height [1 means 100%] +# eps.wdens --- Relative uncertainty for wood density [1 means 100%] +# out.err --- Output error in addition to the estimates of biomass/necromass? +# ---------------------------------------------------------------------------------------- +# +# +# +# ---------------------------------------------------------------------------------------- +# Output: +# ---------------------------------------------------------------------------------------- +# - In case out.err is FALSE, the function returns a vector with biomass for each entry. +# - In case out.err is TRUE, the output is a data frame with the following vectors +# with the same length as the entries: +# * agb -- biomass (necromass) [kgC] +# * ae.agb -- uncertainty in biomass due to allometry [kgC, not relative] +# * me.agb -- uncertainty in biomass due to measurement [kgC, not relative] +# * lnagb -- log(biomass), used for error propagation. +# * sd.lnagb -- standard error of log-biomass +#------------------------------------------------------------------------------------------ +agb_NEON <<- function( dbh + , ddh + , wdens + , scientific + , genus + , family + , type + , phenology + , woodland + , dead = NULL + , eps.dxh = 0.02 + , eps.height = 0.167 + , eps.wdens = 0.10 + , out.err = FALSE + ){ + #---~--- + # If variable "dead" is missing, assume all individuals are alive + #---~--- + if (is.null(dead)) dead = rep(FALSE,times=length(dbh)) + #---~--- + + + + #---~--- + # Make sure all terms have the same length and correct type. + #---~--- + lens = unique( c( length(dbh) , length(ddh) , length(wdens), length(scientific) + , length(genus) , length(family), length(type) , length(phenology) + , length(woodland), length(dead) ) ) + if ( length(lens) != 1 ){ + #---~--- + # Stop if any variable has a different length. + #---~--- + cat0("-----------------------------------------------------------") + cat0(" Variables don't have the same length." ) + cat0(" DBH = ",length(dbh) ) + cat0(" DDH = ",length(ddh) ) + cat0(" WDENS = ",length(wdens) ) + cat0(" SCIENTIFIC = ",length(scientific) ) + cat0(" GENUS = ",length(genus) ) + cat0(" FAMILY = ",length(family) ) + cat0(" TYPE = ",length(type) ) + cat0(" PHENOLOGY = ",length(phenology) ) + cat0(" WOODLAND = ",length(woodland) ) + cat0(" DEAD = ",length(dead) ) + cat0("-----------------------------------------------------------") + stop(" Incorrect input data.") + #---~--- + }else{ + fine.dbh = is.numeric (dbh) || all(is.na(dbh )) + fine.ddh = is.numeric (ddh) || all(is.na(ddh )) + fine.wdens = is.numeric (wdens) || all(is.na(wdens )) + fine.scientific = is.character(scientific) || all(is.na(scientific)) + fine.genus = is.character(genus) || all(is.na(genus )) + fine.family = is.character(family) || all(is.na(family )) + fine.type = is.character(type) || all(is.na(type )) + fine.phenology = is.character(phenology) || all(is.na(phenology )) + fine.woodland = is.logical (woodland) || all(is.na(woodland )) + fine.dead = is.logical (dead) || all(is.na(dead )) + all.fine = ( fine.dbh && fine.ddh && fine.wdens && fine.scientific + && fine.genus && fine.family && fine.type && fine.phenology + && fine.woodland && fine.dead + )#end all.fine + #---~--- + # Stop if anything is unexpected. + #---~--- + if (! all.fine){ + cat0("-----------------------------------------------------------") + cat0(" Not all variables have the correct type." ) + cat0(" DBH (numeric) = ",fine.dbh ) + cat0(" DDH (numeric) = ",fine.ddh ) + cat0(" WDENS (numeric) = ",fine.wdens ) + cat0(" SCIENTIFIC (character) = ",fine.scientific ) + cat0(" GENUS (character) = ",fine.genus ) + cat0(" FAMILY (character) = ",fine.family ) + cat0(" TYPE (character) = ",fine.type ) + cat0(" PHENOLOGY (character) = ",fine.phenology ) + cat0(" WOODLAND (logical) = ",fine.woodland ) + cat0(" DEAD (logical) = ",fine.dead ) + cat0("-----------------------------------------------------------") + stop(" Incorrect data types.") + }#end if (! all.fine) + #---~--- + }#end if ( length(lens) != 1) + #---~--- + + + + #---~--- + # Initialise the output. + #---~--- + a0.agb = NA_real_ * dbh + a1.agb = NA_real_ * dbh + #---~--- + + + + #---~--- + # Simplify phenology labels. + #---~--- + phenology = toupper(substr(phenology,1,1)) + #---~--- + + + #---~--- + # Link names to the equation sets. + #---~--- + bleaf = ( type %in% "B" ) & (! dead) + nleaf = ( type %in% "N" ) & (! dead) + shrub = ( type %in% "S" ) & (! dead) + tree = ( bleaf | nleaf ) & (! shrub) + wlnd = tree & woodland + multigroup.01 = family %in% c( "Cornaceae" , "Ericaceae", "Lauraceae" + , "Platanaceae", "Rosaceae" , "Ulmaceae" ) + multigroup.02 = family %in% c("Fabaceae","Juglandaceae") + multigroup.03 = family %in% c("Hippocastanaceae","Tiliaceae") + multigroup.04 = family %in% c("Fabaceae","Rosaceae") + #---~--- + + + + #---~--- + # Define generic diameter (useful for shrubs). + #---~--- + dxh = ifelse( test = shrub | wlnd + , yes = ifelse( test = is.finite(ddh), yes = ddh, no = dbh ) + , no = ifelse( test = is.finite(dbh), yes = dbh, no = ddh ) + )#end ifelse + #---~--- + + + #---~--- + # Handles for the tree equations + #---~--- + t.abies.lwr = (genus %in% "Abies" ) & (wdens %lt% 0.35 ) & tree + t.abies.upr = (genus %in% "Abies" ) & (wdens %ge% 0.35 ) & tree + t.cupressaceae.lwr = (family %in% "Cupressaceae" ) & (wdens %lt% 0.30 ) & tree + t.cupressaceae.mid = (family %in% "Cupressaceae" ) & (wdens %wl% c(0.30,0.40)) & tree + t.cupressaceae.upr = (family %in% "Cupressaceae" ) & (wdens %ge% 0.40 ) & tree + t.larix = (genus %in% "Larix" ) & tree + t.picea.lwr = (genus %in% "Picea" ) & (wdens %lt% 0.35 ) & tree + t.picea.upr = (genus %in% "Picea" ) & (wdens %ge% 0.35 ) & tree + t.pinus.lwr = (genus %in% "Pinus" ) & (wdens %lt% 0.45 ) & tree + t.pinus.upr = (genus %in% "Pinus" ) & (wdens %ge% 0.45 ) & tree + t.pseudotsuga = (genus %in% "Pseudotsuga" ) & tree + t.tsuga.lwr = (genus %in% "Tsuga" ) & (wdens %lt% 0.40 ) & tree + t.tsuga.upr = (genus %in% "Tsuga" ) & (wdens %ge% 0.40 ) & tree + t.aceraceae.lwr = (family %in% "Aceraceae" ) & (wdens %lt% 0.50 ) & tree + t.aceraceae.upr = (family %in% "Aceraceae" ) & (wdens %ge% 0.50 ) & tree + t.betulaceae.lwr = (family %in% "Betulaceae" ) & (wdens %lt% 0.40 ) & tree + t.betulaceae.lmd = (family %in% "Betulaceae" ) & (wdens %wl% c(0.40,0.50)) & tree + t.betulaceae.umd = (family %in% "Betulaceae" ) & (wdens %wl% c(0.50,0.60)) & tree + t.betulaceae.upr = (family %in% "Betulaceae" ) & (wdens %ge% 0.60 ) & tree + t.multigroup.01 = (family %in% multigroup.01 ) & tree + t.carya = (genus %in% "Carya" ) & tree + t.multigroup.02 = (family %in% multigroup.02 ) & ( ! genus %in% "Carya" ) & tree + t.fagaceae.dcd = (family %in% "Fagaceae" ) & (phenology %in% "D" ) & tree + t.fagaceae.evg = (family %in% "Fagaceae" ) & (phenology %in% "E" ) & tree + t.hamamelidaceae = (family %in% "Hamamelidaceae") & tree + t.multigroup.03 = (family %in% multigroup.03 ) & tree + t.magnoliaceae = (family %in% "Magnoliaceae" ) & tree + t.oleaceae.lwr = (family %in% "Oleaceae" ) & (wdens %lt% 0.55 ) & tree + t.oleaceae.upr = (family %in% "Oleaceae" ) & (wdens %ge% 0.55 ) & tree + t.salicaceae.lwr = (family %in% "Salicaceae" ) & (wdens %lt% 0.35 ) & tree + t.salicaceae.upr = (family %in% "Salicaceae" ) & (wdens %ge% 0.35 ) & tree + w.cupressaceae = (family %in% "Cupressaceae" ) & wlnd + w.multigroup.04 = (family %in% multigroup.04 ) & wlnd + w.fagaceae = (family %in% "Fagaceae" ) & wlnd + w.pinaceae = (family %in% "Pinaceae" ) & wlnd + #---~--- + + + #---~--- + # Handles for the shrub equations. + #---~--- + s.arctostaphylos = (genus %in% "Arctostaphylos") & shrub + s.ceanothus = (genus %in% "Ceanothus" ) & shrub + s.chrysolepis = (genus %in% "Chrysolepis" ) & shrub + s.corylus = (genus %in% "Corylus" ) & shrub + s.cornus = (genus %in% "Cornus" ) & shrub + s.leucothoe = (genus %in% "Leucothoe" ) & shrub + s.rhododendron = (genus %in% "Rhododendron" ) & shrub + s.ribes = (genus %in% "Ribes" ) & shrub + s.rosa = (genus %in% "Rosa" ) & shrub + s.rubus = (genus %in% "Rubus" ) & shrub + s.sambucus = (genus %in% "Sambucus" ) & shrub + s.symphoricarpos = (genus %in% "Symphoricarpos") & shrub + s.vaccinium = (genus %in% "Vaccinium" ) & shrub + #---~--- + + + + #---~--- + # Set coefficients. We initialise them with a generic equation that only + # distinguishes whether they are shrubs, broadleaf trees, or needleleaf trees. For + # trees, we currently used some common families, but this can be refined later. + # After the initial assignment, we update the coefficients if we find a better match + # for the tree/shrub. + #---~--- + #--- General coefficients + a0.agb[bleaf ] = -2.2118 ; a1.agb[bleaf ] = 2.4133 + a0.agb[nleaf ] = -2.6177 ; a1.agb[nleaf ] = 2.4638 + a0.agb[shrub ] = -3.1478 ; a1.agb[shrub ] = 2.3750 + #--- Specific coefficients + a0.agb[t.abies.lwr ] = -2.3123 ; a1.agb[t.abies.lwr ] = 2.3482 + a0.agb[t.abies.upr ] = -3.1774 ; a1.agb[t.abies.upr ] = 2.6426 + a0.agb[t.cupressaceae.lwr] = -1.9615 ; a1.agb[t.cupressaceae.lwr] = 2.1063 + a0.agb[t.cupressaceae.mid] = -2.7765 ; a1.agb[t.cupressaceae.mid] = 2.4195 + a0.agb[t.cupressaceae.upr] = -2.6327 ; a1.agb[t.cupressaceae.upr] = 2.4757 + a0.agb[t.larix ] = -2.3012 ; a1.agb[t.larix ] = 2.3853 + a0.agb[t.picea.lwr ] = -3.0300 ; a1.agb[t.picea.lwr ] = 2.5567 + a0.agb[t.picea.upr ] = -2.1364 ; a1.agb[t.picea.upr ] = 2.3233 + a0.agb[t.pinus.lwr ] = -2.6177 ; a1.agb[t.pinus.lwr ] = 2.4638 + a0.agb[t.pinus.upr ] = -3.0506 ; a1.agb[t.pinus.upr ] = 2.6465 + a0.agb[t.pseudotsuga ] = -2.4623 ; a1.agb[t.pseudotsuga ] = 2.4852 + a0.agb[t.tsuga.lwr ] = -2.3480 ; a1.agb[t.tsuga.lwr ] = 2.3876 + a0.agb[t.tsuga.upr ] = -2.9208 ; a1.agb[t.tsuga.upr ] = 2.5697 + a0.agb[t.aceraceae.lwr ] = -2.0470 ; a1.agb[t.aceraceae.lwr ] = 2.3852 + a0.agb[t.aceraceae.upr ] = -1.8011 ; a1.agb[t.aceraceae.upr ] = 2.3852 + a0.agb[t.betulaceae.lwr ] = -2.5932 ; a1.agb[t.betulaceae.lwr ] = 2.5349 + a0.agb[t.betulaceae.lmd ] = -2.2271 ; a1.agb[t.betulaceae.lmd ] = 2.4513 + a0.agb[t.betulaceae.umd ] = -1.8096 ; a1.agb[t.betulaceae.umd ] = 2.3480 + a0.agb[t.betulaceae.upr ] = -2.2652 ; a1.agb[t.betulaceae.upr ] = 2.5349 + a0.agb[t.multigroup.01 ] = -2.2118 ; a1.agb[t.multigroup.01 ] = 2.4133 + a0.agb[t.carya ] = -2.5095 ; a1.agb[t.carya ] = 2.6175 + a0.agb[t.multigroup.02 ] = -2.5095 ; a1.agb[t.multigroup.02 ] = 2.5437 + a0.agb[t.fagaceae.dcd ] = -2.0705 ; a1.agb[t.fagaceae.dcd ] = 2.4410 + a0.agb[t.fagaceae.evg ] = -2.2198 ; a1.agb[t.fagaceae.evg ] = 2.4410 + a0.agb[t.hamamelidaceae ] = -2.6390 ; a1.agb[t.hamamelidaceae ] = 2.5466 + a0.agb[t.multigroup.03 ] = -2.4108 ; a1.agb[t.multigroup.03 ] = 2.4177 + a0.agb[t.magnoliaceae ] = -2.5497 ; a1.agb[t.magnoliaceae ] = 2.5011 + a0.agb[t.oleaceae.lwr ] = -2.0314 ; a1.agb[t.oleaceae.lwr ] = 2.3524 + a0.agb[t.oleaceae.upr ] = -1.8384 ; a1.agb[t.oleaceae.upr ] = 2.3524 + a0.agb[t.salicaceae.lwr ] = -2.6863 ; a1.agb[t.salicaceae.lwr ] = 2.4561 + a0.agb[t.salicaceae.upr ] = -2.4441 ; a1.agb[t.salicaceae.upr ] = 2.4561 + a0.agb[w.cupressaceae ] = -2.7096 ; a1.agb[w.cupressaceae ] = 2.1942 + a0.agb[w.multigroup.04 ] = -2.9255 ; a1.agb[w.multigroup.04 ] = 2.4109 + a0.agb[w.fagaceae ] = -3.0304 ; a1.agb[w.fagaceae ] = 2.4982 + a0.agb[w.pinaceae ] = -3.2007 ; a1.agb[w.pinaceae ] = 2.5339 + a0.agb[s.arctostaphylos ] = -3.5892 ; a1.agb[s.arctostaphylos ] = 2.6846 + a0.agb[s.ceanothus ] = -3.2406 ; a1.agb[s.ceanothus ] = 2.6502 + a0.agb[s.chrysolepis ] = -3.0198 ; a1.agb[s.chrysolepis ] = 2.3110 + a0.agb[s.corylus ] = -3.3776 ; a1.agb[s.corylus ] = 2.3720 + a0.agb[s.cornus ] = -3.5928 ; a1.agb[s.cornus ] = 2.6470 + a0.agb[s.leucothoe ] = -4.1588 ; a1.agb[s.leucothoe ] = 2.3060 + a0.agb[s.rhododendron ] = -3.1478 ; a1.agb[s.rhododendron ] = 2.3750 + a0.agb[s.ribes ] = -3.1478 ; a1.agb[s.ribes ] = 2.3750 + a0.agb[s.rosa ] = -3.1478 ; a1.agb[s.rosa ] = 2.3750 + a0.agb[s.rubus ] = -3.1478 ; a1.agb[s.rubus ] = 2.3750 + a0.agb[s.sambucus ] = -3.3378 ; a1.agb[s.sambucus ] = 2.3720 + a0.agb[s.symphoricarpos ] = -3.1478 ; a1.agb[s.symphoricarpos ] = 2.3750 + a0.agb[s.vaccinium ] = -3.1478 ; a1.agb[s.vaccinium ] = 2.3750 + #---~--- + + + #---~--- + # Find biomass. + #---~--- + agb = exp(a0.agb + a1.agb * log(dxh)) / C2B + #---~--- + + + #---~--- + # Check whether to estimate associated errors (measurement and allometry), + # following: + # + # Chave, J., and co-authors, 2004: Error propagation and scaling for tropical forest + # biomass estimates. Phil. Trans. R. Soc. Lond. B., 359, 409-420. + # doi:10.1098/rstb.2003.1425 + #---~--- + if (out.err){ + #---~--- + # Find error associated with allometry. The papers do not present the actual error + # of each equation. For the time being, we use the same error as reported by + # Chave et al. (2014) as a zero-order guess. + # + # Chave, J., and co-authors, 2014: Improved allometric models to estimate the + # aboveground biomass of tropical trees. Glob. Change Biol., 20, 3177-3190 + # doi:10.1111/gcb.12629 + #---~--- + ae.agb = sqrt(exp(0.357^2)-1)*agb + #---~--- + + + + #---~--- + # Find error associated with measurements. + #---~--- + me.agb = agb * a1.agb * eps.dxh + #---~--- + + + #---~--- + # Save the standard error of the log scale: it will be useful for error analysis. + # The 0*agb term will ensure that sd.lnagb will be NA when agb is NA. + #---~--- + sd.lnagb = 0.357 + 0. * agb + #---~--- + + #---~--- + # Combine estimates and errors in a data frame. + #---~--- + ans = data.frame( agb = agb + , a0 = a0.agb + , a1 = a1.agb + , ae.agb = ae.agb + , me.agb = me.agb + , lnagb = log(agb) - 0.5 * sd.lnagb^2 + , sd.lnagb = sd.lnagb + )#end data.frame + #---~--- + + }else{ + #---~--- + # No error needed. Return estimate only. + #---~--- + ans = agb + #---~--- + }#end if + #---~--- + + return(ans) +}#end function agb_NEON +#========================================================================================== +#========================================================================================== + + + + + +#========================================================================================== +#========================================================================================== +# This function determines the plot aggregated error due to measurement and +# allometry for NEON. +# +# Input: +# ---------------------------------------------------------------------------------------- +# datum - a data frame with all trees in this plot (note, you can't run this for all +# plots at once, either use a for loop or mapply). The data frame must +# contain the following variables: +# * nplant - 1/area sampled if tree is alive, zero if tree is dead [1/m2] +# * ntotal - 1/area sampled [1/m2] +# For nplant/ntotal, if the sampled area was 2500 m2, the number should be +# 0.0004. In case a differential sampling effort was used, then nplant +# varies. For example, if trees with 10 <= DBH < 35 cm were measured in a +# 50x5 subplot and trees with DBH >= 35 cm were measured in the entire +# 2500m2 plots, then nplant should be 0.004 for the trees with DBH < 35cm +# and 0.0004 for trees with DBH >= 35cm. +# * AGC - above-ground carbon [ kgC] +# * ME.AGC - measurement uncertainty of above-ground carbon [ kgC] +# * LNAGC - log of above-ground carbon +# * SD.LNAGC - allometry uncertainty, using the log-scale +# * X - x position in the plot (used only if epsilon.smp is NULL) +# * Y - y position in the plot (used only if epsilon.smp is NULL) +# xmax - maximum size along the x axis (used only if epsilon.smp is NULL) +# ymax - maximum size along the y axis (used only if epsilon.smp is NULL) +# subalong - which axis has the subplot +# epsilon.smp - in case epsilon.smp is null, the function will try to estimate within-plot +# sampling uncertainty. This is unlikely to work unless you have large +# plots or at the very least have plots without sub-sampling. +# Alternatively, you may provide the number from previous studies. +# n.sub - number of subplot samples +# n.real - number of replicates for estimating uncertainty. Large numbers +# (10000 or more) are needed for stable results. +# ---------------------------------------------------------------------------------------- +# +# +# +# ---------------------------------------------------------------------------------------- +# Output: +# ---------------------------------------------------------------------------------------- +# A vector with 8 numbers: +# se.agb.xxxxx - uncertainties for plot estimate of biomass (no standing dead) [kgC/m2] +# se.acd.xxxxx - uncertainties for plot estimate of biomass+necromass [kgC/m2] +# se.xxx.measurement - contribution of measurement uncertainty to plot uncertainty +# se.xxx.allometry - contribution of allometry uncertainty to plot uncertainty +# se.xxx.sampling - contribution of sampling uncertainty to plot uncertainty +# se.xxx.census - total uncertainty (combining the three terms above). +#------------------------------------------------------------------------------------------ +find_agb_error_NEON <<- function(datum,xmax,ymax,subalong=c("x","y"),epsilon.smp=NULL + ,n.sub=25,n.real=10000){ + + #---~--- + # Standardise subalong. + #---~--- + subalong = match.arg(subalong) + #---~--- + + + #---~--- + # Number of data points. + #---~--- + ndatum = nrow(datum) + #---~--- + + + #---~--- + # First, find the combined error. + #---~--- + se.use = data.frame( measurement = sqrt(log(1+(datum$ME.AGC / datum$AGC)^2)) + , allometry = datum$SD.LNAGC + )#end datum + #---~--- + + + #---~--- + # Initialise answer. + #---~--- + se.agb = rep(x=NA_real_,length(se.use)+2) + names(se.agb) = c(names(se.use),"sampling","census") + #---~--- + + + + #---~--- + # Create a population matrix. + #---~--- + NPLANT = matrix( data = rep(datum$nplant,times=n.real), nrow=ndatum,ncol=n.real) + #---~--- + + + #---~--- + # Initialise answer. We will create the vector before and loop through the errors. + #---~--- + for (e in seq_along(se.use)){ + AGC = matrix( data = rlnorm( n = n.real*ndatum + , meanlog = rep(datum$LNAGC,times=n.real) + , sdlog = rep(se.use[[e]],times=n.real) + )#end rlnorm + , nrow = ndatum + , ncol = n.real + )#end matrix + AGB = colSums(NPLANT * AGC) + se.agb[e] = sd(AGB) + }#end for (e in seq_along(se.use)) + #---~--- + + + #---~--- + # Find total biomass, to be used by the within plot sampling error. + #---~--- + agb.bar = sum(datum$nplant * datum$AGC) + #---~--- + + + #---~--- + # Unless epsilon.smp is provided, we estimate the within-plot sampling error. + #---~--- + if (is.null(epsilon.smp)){ + #---~--- + # Split domain into smaller subsplots. + #---~--- + if (subalong %in% "x"){ + xbreaks = seq(from=0,to=xmax,length.out=n.sub+1) + xlwr = sqrt(.Machine$double.eps) * xmax + xupr = (1. - sqrt(.Machine$double.eps)) * xmax + xnow = pmax(xlwr,pmin(xupr,datum$X)) + isub = as.integer(cut(xnow,breaks=xbreaks)) + }else{ + ybreaks = seq(from=0,to=ymax,length.out=n.sub+1) + ylwr = sqrt(.Machine$double.eps) * ymax + yupr = (1. - sqrt(.Machine$double.eps)) * ymax + ynow = pmax(ylwr,pmin(yupr,datum$Y)) + isub = as.integer(cut(ynow,breaks=ybreaks)) + }#end if + #---~--- + + + #---~--- + # Find the AGB/ACD for each subplot. + #---~--- + agb.sub = rep(0.,times=n.sub) + acd.sub = rep(0.,times=n.sub) + agb.tmp = tapply(X=n.sub*datum$nplant*datum$AGC,INDEX=isub,FUN=sum) + acd.tmp = tapply(X=n.sub*datum$ntotal*datum$AGC,INDEX=isub,FUN=sum) + agb.idx = as.integer(names(agb.tmp)) + acd.idx = as.integer(names(acd.tmp)) + agb.sub[agb.idx] = agb.tmp + acd.sub[acd.idx] = acd.tmp + #---~--- + + + + + #---~--- + # Create replicates using bootstrap with replacement. + #---~--- + AGB = colMeans( matrix( data = sample(agb.sub,size=n.real*n.sub,replace=TRUE) + , nrow = n.sub + , ncol = n.real + )#end matrix + )#end colMeans + se.agb["sampling"] = sd(AGB) + #---~--- + }else{ + #---~--- + # Use pre-defined sampling error. + #---~--- + se.agb["sampling"] = epsilon.smp * agb.bar + #---~--- + }#end if (is.null(epsilon.smp)) + #---~--- + + + + #---~--- + # Find combined source of errors. + #---~--- + se.agb["census"] = sqrt(sum(se.agb[c("measurement","allometry","sampling")]^2)) + #---~--- + + + #---~--- + # Error is the standard deviation of all realisations. + #---~--- + ans = se.agb + names(ans) = paste0("se.agb.",names(se.agb)) + #---~--- + + + #---~--- + # Return answer. + #---~--- + return(ans) + #---~--- +}#end find_agb_error_NEON +#========================================================================================== +#========================================================================================== diff --git a/R-utils/nls.wgtfct.r b/R-utils/nls.wgtfct.r index 1236456ca..fbdbf21c7 100644 --- a/R-utils/nls.wgtfct.r +++ b/R-utils/nls.wgtfct.r @@ -126,7 +126,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. --------------------------------# - xysigma = ifelse(xysigma %>% 0 ,xysigma,NA) + xysigma = ifelse(xysigma %gt% 0 ,xysigma,NA) assign(x="xysigma",value=xysigma,envir=newEnv) #------------------------------------------------------------------------------------# }#end if (length(grep("xysigma", expr)) > 0) @@ -148,7 +148,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. --------------------------------# - yysigma = ifelse(yysigma %>% 0 ,yysigma,NA) + yysigma = ifelse(yysigma %gt% 0 ,yysigma,NA) assign(x="yysigma",value=yysigma,envir=newEnv) #------------------------------------------------------------------------------------# }#end if (length(grep("yysigma", expr)) > 0) @@ -207,7 +207,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. -----------------------------# - xrsigma = ifelse(xrsigma %>% 0 ,xrsigma,NA) + xrsigma = ifelse(xrsigma %gt% 0 ,xrsigma,NA) assign(x="xrsigma",value=xrsigma,envir=newEnv) #---------------------------------------------------------------------------------# }#end if (length(grep("xrsigma", expr)) > 0) @@ -229,7 +229,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ #----- Append variable to the temporary environment. -----------------------------# - yrsigma = ifelse(yrsigma %>% 0 ,yrsigma,NA) + yrsigma = ifelse(yrsigma %gt% 0 ,yrsigma,NA) assign(x="yrsigma",value=yrsigma,envir=newEnv) #---------------------------------------------------------------------------------# }#end if (length(grep("yrsigma", expr)) > 0) @@ -243,7 +243,7 @@ nls.wgtfct <<- function(expr,nbrks=10){ # values or negative numbers, if they somehow exist, replace them by zero. # #---------------------------------------------------------------------------------------# ans = eval(expr=parse(text = expr), envir = newEnv) - ans = ifelse(ans %>% 0, ans, 0) + ans = ifelse(ans %gt% 0, ans, 0) ans = c(ans) names(ans) = NULL #---------------------------------------------------------------------------------------# diff --git a/R-utils/normalise.r b/R-utils/normalise.r index 6845f4cb3..3ae20ad41 100644 --- a/R-utils/normalise.r +++ b/R-utils/normalise.r @@ -19,7 +19,7 @@ normalise <<- function(x,mu,sigma,distr=c("best","normal","lognormal","skewnorma #----- Exclude missing points. ---------------------------------------------------------# xfit = x[is.finite(x)] nxfit = length(xfit) - lntry = all(xfit %>% 0) + lntry = all(xfit %gt% 0) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# diff --git a/R-utils/numutils.r b/R-utils/numutils.r index 8444e5dc1..3cd30589b 100644 --- a/R-utils/numutils.r +++ b/R-utils/numutils.r @@ -15,6 +15,41 @@ cbrt <<- function(x){ +#==========================================================================================# +#==========================================================================================# +# Function that finds the integer divisors of an integer and positive number. # +#------------------------------------------------------------------------------------------# +divisors <<- function(x){ + #---- Do not attempt to find divisors for non-integer quantities. ----------------------# + xint = as.integer(x) + #---------------------------------------------------------------------------------------# + + #---- Find the results for each value. -------------------------------------------------# + if (length(x) > 1L){ + ans = mapply( FUN = divisors, x = as.list(x)) + }else if( xint %eq% x){ + #--- Vector of potential divisors. We stop at half to speed up the code. ------------# + ans = seq_len(ceiling(abs(x)/2)) + ans = c(ans[ (x %% ans) %eq% 0L],x) + #------------------------------------------------------------------------------------# + }else{ + #---- Number is not integer, return nothing. ----------------------------------------# + ans = integer(length=0L) + #------------------------------------------------------------------------------------# + }#end if(length(x) > 1L) + #---------------------------------------------------------------------------------------# + + #---- Return results. ------------------------------------------------------------------# + return(ans) + #---------------------------------------------------------------------------------------# +}#end function divisors +#==========================================================================================# +#==========================================================================================# + + + + + #==========================================================================================# #==========================================================================================# # Functions that finds round of the log of the number. # @@ -34,7 +69,21 @@ round.log2 <<- function(x,...) 2^(round(log2(x),...)) # Base 10 exponential. # #------------------------------------------------------------------------------------------# exp10 <<- function(x,...) 10^x +#==========================================================================================# +#==========================================================================================# + + + + +#==========================================================================================# +#==========================================================================================# +# Negative log of negative numbers. # +#------------------------------------------------------------------------------------------# +neglog <<- function(x,...) -log(-x) +negexp <<- function(x,...) -exp(-x) +neglog10 <<- function(x,...) -log10(-x) +negexp10 <<- function(x,...) -10^(-x) #==========================================================================================# #==========================================================================================# @@ -54,11 +103,11 @@ bound <<- function(x,lwr=min(x,na.rm=TRUE),upr=max(x,na.rm=TRUE),buff=2^-23){ #---------------------------------------------------------------------------------------# # Don't let the bounds to be insane. # #---------------------------------------------------------------------------------------# - if (lwr %>% upr){ + if (lwr %gt% upr){ cat0(" - Lower limit: ",lwr) cat0(" - Upper limit: ",upr) stop(" Lower and upper limit must be finite and lower cannot be greater than upper.") - }#end if (lwr %>% upr) + }#end if (lwr %gt% upr) #---------------------------------------------------------------------------------------# @@ -68,7 +117,7 @@ bound <<- function(x,lwr=min(x,na.rm=TRUE),upr=max(x,na.rm=TRUE),buff=2^-23){ if (! (buff %wr% c(0,1-2^-23))){ cat0(" - buff: ",buff) stop(" Buffer must be between 0 (including) and 1 (excluding).") - }#end if (lwr %>% upr) + }#end if (! (buff %wr% c(0,1-2^-23))) #---------------------------------------------------------------------------------------# @@ -271,7 +320,7 @@ weighted.frac <<- function(x,w,na.rm=TRUE){ names(ans) = names(x) return(ans) #------------------------------------------------------------------------------------# - }else if (all(w %==% 0.)){ + }else if (all(w %eq% 0.)){ #----- Give equal chances in case all weights were zero. ----------------------------# w = rep(x=1.,times=nrow(x)) #------------------------------------------------------------------------------------# @@ -305,9 +354,9 @@ weighted.frac <<- function(x,w,na.rm=TRUE){ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FALSE){ #----- Delete the missing values if the user asked to do it. ---------------------------# - if (any(w <= 0, na.rm = TRUE) || any(is.infinite(w)) || any(is.na(w))){ + if (any(w %le% 0, na.rm = TRUE) || any(is.infinite(w)) || any(is.na(w))){ stop(" Weights (w) must be positive and finite, and entirely defined!") - }else if(qu < 0. || qu > 1.){ + }else if(qu %or% c(0,1.)){ stop(" Quantile (qu) must be between 0 and 1. ") }else if(na.rm){ keep = ! is.na(x) @@ -318,6 +367,14 @@ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FAL + #---------------------------------------------------------------------------------------# + # If nothing remains, return NA. # + #---------------------------------------------------------------------------------------# + if (length(x) == 0) return(NA_real_) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Define the probabilities by normalising the weights. # #---------------------------------------------------------------------------------------# @@ -341,18 +398,18 @@ weighted.quantile <<- function(x,w,qu=0.50,size.minp=10,na.rm=FALSE,out.case=FAL #---------------------------------------------------------------------------------------# # Sort the values by the probability. # #---------------------------------------------------------------------------------------# - if (qu <= cum[1]){ + if (qu %le% cum[1]){ qout = x[1] case = "minimum" - }else if (qu >= cum[length(cum)]){ + }else if (qu %ge% cum[length(cum)]){ qout = x[length(cum)] case = "maximum" - }else if (any(cum == qu)){ - qout = x[which(cum == qu)] + }else if (any(cum %eq% qu)){ + qout = x[which(cum %eq% qu)] case = "exact" }else{ - below = qu - cum ; below[below < 0] = Inf - above = cum - qu ; above[above < 0] = Inf + below = qu - cum ; below[below %lt% 0] = Inf + above = cum - qu ; above[above %lt% 0] = Inf i.below = which.min(below) i.above = which.min(above) w.below = 1. / (below[i.below]^2) @@ -404,7 +461,7 @@ weighted.sd <<- function(x,w,M=NULL,na.rm=FALSE){ #---------------------------------------------------------------------------------------# # Check whether at least one weight is non-zero. # #---------------------------------------------------------------------------------------# - if (all(w %==% 0)){ + if (all(w %eq% 0)){ ans = NA }else{ xwm = weighted.mean(x=x,w=w) @@ -735,7 +792,7 @@ meansdcv <<- function (x, na.rm = FALSE){ nx = length(xx) mu = mean(xx) sigma = sd(xx) - cvar = ifelse(sigma %>% 0,mu/sigma,NA) + cvar = ifelse(sigma %gt% 0,mu/sigma,NA) ans = c( mean = mu , sd = sigma @@ -1086,7 +1143,7 @@ mean.se <<- function(x,...) sqrt(x = mean(x=x^2,...) / length(x[is.fini #==========================================================================================# # Mean of elements that are finite and above minimum. # #------------------------------------------------------------------------------------------# -mean.above <<- function(x,xlwr,xnot=xlwr) if(any(x%>=%xlwr)){mean(x[x%>=%xlwr])}else{xnot} +mean.above <<- function(x,xlwr,xnot=xlwr) if(any(x%ge%xlwr)){mean(x[x%ge%xlwr])}else{xnot} #==========================================================================================# #==========================================================================================# @@ -1646,6 +1703,32 @@ left.cumprod <<- function(x) c(0,cumprod(x)[-length(x)]) +#==========================================================================================# +#==========================================================================================# +# These functions are similar to cumsum, except that they ignore values above or below # +# a certain threshold (source: (https://stackoverflow.com/questions/63636052/ # +# calculate-cumulative-sum-cumsum-floored-at-zero). # +#------------------------------------------------------------------------------------------# +#----- cumulative sum floored at thresh. --------------------------------------------------# +floor.cumsum <<- function(x,thresh=0){ + cs = cumsum(x) + cn = cummin(cs) + ans = cs - pmin(cn,thresh) + return(ans) +}#end floor.cumsum +#----- cumulative sum capped at thresh. ---------------------------------------------------# +ceiling.cumsum <<- function(x,thresh=0){ + cs = cumsum(x) + cx = cummax(cs) + ans = cs - pmax(cx,thresh) + return(ans) +}#end ceiling.cumsum +#==========================================================================================# +#==========================================================================================# + + + + #==========================================================================================# #==========================================================================================# # This function calculates cumulative sum for data with gaps. It will treat NA as # @@ -1742,7 +1825,7 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #---------------------------------------------------------------------------------------# if (all(! (is.na(x) | is.nan(x)))){ #------------------------------------------------------------------------------------# - # Decide what to do based on whether to limit maximum (thmax=TRUE) or maximum # + # Decide what to do based on whether to limit maximum (thmax=TRUE) or minimum # # (thmax=FALSE) values. I couldn't think of a vector way to solve this, so for now # # I am using for loops. # #------------------------------------------------------------------------------------# @@ -1755,9 +1838,9 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #---------------------------------------------------------------------------------# }else{ #----- Threshold is the maximum allowed value. -----------------------------------# - ans[1] = max(c(thresh,x[1])) + ans[1] = max(c(xthresh,x[1])) for (i in sequence(nx)[-1]){ - ans[i] = max(thresh,ans[i-1]+x[i]) + ans[i] = max(xthresh,ans[i-1]+x[i]) }#end for (i in sequence(nx)[-1]) #---------------------------------------------------------------------------------# }#end if (thmax) @@ -1792,7 +1875,7 @@ thresh.cumsum <<- function(x,xthresh,thmax=TRUE,na.rm=FALSE){ #------------------------------------------------------------------------------------------# aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #----- Check that fmin makes sense. ----------------------------------------------------# - if (! (fmin %>=% 0.0 & fmin %<=% 1.0)){ + if (! (fmin %ge% 0.0 & fmin %le% 1.0)){ stop (paste0("fmin must be between 0 and 1! Yours is set to ",fmin,"...")) }#end if #---------------------------------------------------------------------------------------# @@ -1815,8 +1898,8 @@ aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #----- Use only valid points. -------------------------------------------------------# xuse = x[is.finite(x)] ans = fun(xuse,...) - discard = ! is.finite(ans) - ans[discard] = NA + is.bad = ! is.finite(ans) + ans[is.bad] = NA #------------------------------------------------------------------------------------# }else if (nkeep >= 1){ #----- Use only valid points. -------------------------------------------------------# @@ -1860,7 +1943,7 @@ aggr.fmin <<- function(x,fun=mean,fmin=0.5,...){ #------------------------------------------------------------------------------------------# aggr.se <<- function(x,fmin=0.5,...){ #----- Check that fmin makes sense. ----------------------------------------------------# - if (! (fmin %>=% 0.0 & fmin %<=% 1.0)){ + if (! (fmin %ge% 0.0 & fmin %le% 1.0)){ stop (paste0("fmin must be between 0 and 1! Yours is set to ",fmin,"...")) }#end if #---------------------------------------------------------------------------------------# @@ -1879,8 +1962,8 @@ aggr.se <<- function(x,fmin=0.5,...){ xuse = x[is.finite(x)] nuse = length(xuse) ans = sqrt(mean(xuse^2)/nuse) - discard = ! is.finite(ans) - ans[discard] = NA + is.bad = ! is.finite(ans) + ans[is.bad] = NA #------------------------------------------------------------------------------------# }else{ #----- Return NA. -------------------------------------------------------------------# @@ -1912,18 +1995,44 @@ max.abs.diff <<- function(x,y,na.rm=TRUE) max(abs(x-y),na.rm=na.rm) #==========================================================================================# #==========================================================================================# -# This function counts the number of valid entries. # +# This function checks whether or not the values are valid. # #------------------------------------------------------------------------------------------# -count.valid <<- function(x,qq.rm=FALSE){ +is.valid <<- function(x,qq.rm=FALSE){ type.x = typeof(x) if (type.x %in% "logical"){ - ans = sum(! is.na(x)) + ans = ! is.na(x) }else if (type.x %in% "character"){ - ans = sum(! ( is.na(x) | ((x %in% "") & qq.rm))) + ans = ! ( is.na(x) | ((x %in% "") & qq.rm)) }else{ - ans = sum(is.finite(x)) + ans = ! is.finite(x) }#end if (type.x %in% c("logical","character")) return(ans) -}#end count.finite +}#end is.finite +#==========================================================================================# +#==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# This function counts the number of valid entries. # +#------------------------------------------------------------------------------------------# +count.valid <<- function(x,qq.rm=FALSE) sum(is.valid(x,qq.rm=qq.rm)) +#==========================================================================================# +#==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Error function and complementary error function. These are borrowed from package # +# pracma, use locally defined to avoid conflicts with many other functions. # +#------------------------------------------------------------------------------------------# +errfun <<- function(x){ pchisq(2 * x^2,1) * sign(x)} +errfunc <<- function(x){ 2. * pnorm(-sqrt(2.)*x)} #==========================================================================================# #==========================================================================================# diff --git a/R-utils/operators.r b/R-utils/operators.r index ea5278d88..cc92a5aa0 100644 --- a/R-utils/operators.r +++ b/R-utils/operators.r @@ -5,7 +5,7 @@ #----- Safe logical operators. These will always return FALSE if x or y are not finite. --# -'%==%' <<- function(x,y){ +'%eq%' <<- function(x,y){ if (any(c(FALSE,is.numeric(x) & is.numeric(y)),na.rm=TRUE)){ ans = is.finite(unlist(x)) & is.finite(unlist(y)) & x == y }else{ @@ -13,7 +13,7 @@ }#end if return(ans) }#end function -'%!=%' <<- function(x,y){ +'%ne%' <<- function(x,y){ if (any(c(FALSE,is.numeric(x) & is.numeric(y)),na.rm=TRUE)){ ans = is.finite(unlist(x)) & is.finite(unlist(y)) & x != y }else{ @@ -21,10 +21,10 @@ }#end if return(ans) }#end function -'%>%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x > y -'%<%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x < y -'%>=%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x >= y -'%<=%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x <= y +'%gt%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x > y +'%lt%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x < y +'%ge%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x >= y +'%le%' <<- function(x,y) is.finite(unlist(x)) & is.finite(unlist(y)) & x <= y #------------------------------------------------------------------------------------------# diff --git a/R-utils/optim.gbm.r b/R-utils/optim.gbm.r index f60dd04ae..c1b89d481 100644 --- a/R-utils/optim.gbm.r +++ b/R-utils/optim.gbm.r @@ -137,6 +137,9 @@ optim.gbm <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) diff --git a/R-utils/optim.lsq.htscd.r b/R-utils/optim.lsq.htscd.r index 3f3eccdb3..e15b51aaf 100644 --- a/R-utils/optim.lsq.htscd.r +++ b/R-utils/optim.lsq.htscd.r @@ -619,7 +619,7 @@ optim.lsq.htscd <<- function( lsq.formula #---------------------------------------------------------------------------------# # Accept step only if it converged. # #---------------------------------------------------------------------------------# - success = opt.1st$convergence %==% 0 + success = opt.1st$convergence %eq% 0 #---------------------------------------------------------------------------------# }#end if ("try-error" %in% is(opt.1st)) #------------------------------------------------------------------------------------# @@ -734,7 +734,7 @@ optim.lsq.htscd <<- function( lsq.formula # solution, as the likelihood is a product of probabilities, which should be less # # than 1, hence the negative requirement. # #---------------------------------------------------------------------------------# - success = opt.hess$convergence %==% 0 + success = opt.hess$convergence %eq% 0 #---------------------------------------------------------------------------------# }#end if ("try-error" %in% is(opt.hess)) #------------------------------------------------------------------------------------# @@ -949,7 +949,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.boot$convergence %==% 0 + success = opt.boot$convergence %eq% 0 nsteps.now = opt.boot$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -1092,7 +1092,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.sxobs$convergence %==% 0 + success = opt.sxobs$convergence %eq% 0 nsteps.now = opt.sxobs$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -1232,7 +1232,7 @@ optim.lsq.htscd <<- function( lsq.formula # bogus solution, as the likelihood is a product of probabilities, which # # should be less than 1, hence the negative requirement. # #------------------------------------------------------------------------------# - success = opt.syobs$convergence %==% 0 + success = opt.syobs$convergence %eq% 0 nsteps.now = opt.syobs$counts["function"] #------------------------------------------------------------------------------# }#end if @@ -2389,7 +2389,7 @@ print.lsq.htscd <<- function(object){ coeff.table[,1] = sprintf("%g",signif(coeff.table[,1],5)) coeff.table[,2] = sprintf("%g",signif(coeff.table[,2],5)) coeff.table[,3] = sprintf("%g",signif(coeff.table[,3],4)) - coeff.table[,4] = ifelse( p.value %<% 1.e-16,"< 1e-16",sprintf("%g",signif(p.value,3))) + coeff.table[,4] = ifelse( p.value %lt% 1.e-16,"< 1e-16",sprintf("%g",signif(p.value,3))) #----- Append the significance test. ---------------------------------------------------# sig.brks = c(-Inf,0.001,0.01,0.05,0.1,Inf) diff --git a/R-utils/optim.pls.r b/R-utils/optim.pls.r index f8634bf5c..b11798a1d 100644 --- a/R-utils/optim.pls.r +++ b/R-utils/optim.pls.r @@ -67,7 +67,11 @@ optim.pls <<- function( formula #----- Run PLS. ------------------------------------------------------------------------# if (verbose) cat0( " > PLS (full model)") - ans = plsr(formula=form.now,data=data,verbose=verbose,...) + ans = plsr( formula = form.now + , data = data + , verbose = verbose + , ... + )#end plsr ans$orig.formula = formula ans$formula = form.now ans$yname = yname @@ -79,16 +83,18 @@ optim.pls <<- function( formula #----- Retrieve MSE in case back-transformation is sought. -----------------------------# - resnow = ans$residuals[,1,] - rsumsq = apply(X=resnow,MARGIN=2,FUN=sum2,na.rm=TRUE) - nnow = apply(X=resnow,MARGIN=2,FUN=function(x) sum(is.finite(x))) - msenow = MSEP(object=ans,"adjCV") - ans$mse = c(msenow$val[1,1,-1]) - ans$vary = if(ylog){var(log(data[yname]),na.rm=TRUE)}else{var(data[yname],na.rm=TRUE)} - ans$fve = 1 - ans$mse / ans$vary - max.fve = max(ans$fve,na.rm=TRUE) - rel.fve = ans$fve / max.fve - ans$ncomp = min(which(rel.fve >= fve.tolerance)) + msenow.t = MSEP(object=ans,"train")$val[,,] + msenow.a = MSEP(object=ans,"adjCV")$val[,,] + if (ylog){ + yvar = var(log(data[[yname]]),na.rm=TRUE) + }else{ + yvar = var(data[[yname]],na.rm=TRUE) + }#end if (ylog) + fve = 1. - msenow.a / yvar + max.fve = max(fve,na.rm=TRUE) + rel.fve = fve / max.fve + ans$ncomp = min(which(rel.fve %ge% fve.tolerance)) - 1L + ans$mse = apply(ans$residuals[,1,],MARGIN=2L,FUN=mean2) #---------------------------------------------------------------------------------------# @@ -106,7 +112,7 @@ optim.pls <<- function( formula ans$ln.pred = ypred ans$ln.sigma = sqrt(ans$mse[ans$ncomp]) ans$predicted = exp(ypred + 0.5 * ans$mse[ans$ncomp]) - ans$sigma = with(ans,sqrt(exp(mse[ncomp])-1)*exp(2.*ans$ln.pred + mse[ncomp])) + ans$sigma = with(ans,sqrt(exp(mse[ncomp])-1)*exp(2.*ln.pred + mse[ncomp])) plwr = 0.5 * (1.0 - ci.level) pupr = 0.5 * (1.0 + ci.level) ans$qlow = qlnorm(p=plwr,meanlog=ans$ln.pred,sdlog=ans$ln.sigma) @@ -139,7 +145,6 @@ optim.pls <<- function( formula dotdotdot = modifyList( x = dotdotdot , val = list( verbose = FALSE , model = FALSE - , ncomp = ans$ncomp )#end list )#end modifyList #---------------------------------------------------------------------------------------# @@ -228,6 +233,9 @@ optim.pls <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) @@ -248,8 +256,12 @@ optim.pls <<- function( formula #----- Call PLS. --------------------------------------------------------------------# - dotnow = modifyList(x=dotdotdot,val=list(data=boot.data)) - pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + dotnow = modifyList(x=dotdotdot,val=list(data=boot.data)) + pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + boot.fine = ! ("try-error" %in% is(pls.now)) + if (boot.fine){ + boot.fine = any(is.finite(pls.now$fitted.values)) + }#end if (boot.fine) #------------------------------------------------------------------------------------# @@ -257,12 +269,11 @@ optim.pls <<- function( formula #------------------------------------------------------------------------------------# # Check whether to append to the data set. # #------------------------------------------------------------------------------------# - if (! ("try-error" %in% is(pls.now))){ + if (boot.fine){ ib = ib + 1 #----- Retrieve MSE in case back-transformation is sought. -----------------------# - mse.now = MSEP(object=pls.now,"adjCV") - mse.now = c(mse.now$val[1,1,ans$ncomp+1]) + mse.now = mean2(pls.now$residuals[,1,ans$ncomp],na.rm=TRUE) #---------------------------------------------------------------------------------# @@ -288,7 +299,7 @@ optim.pls <<- function( formula #---------------------------------------------------------------------------------# }else if (verbose){ cat0(" > Bootstrap realisation failed, skip it.") - }#end if (! ("try-error" %in% is(pls.now))) + }#end if (boot.fine) #------------------------------------------------------------------------------------# }#end while (ib < n.boot) #---------------------------------------------------------------------------------------# @@ -363,17 +374,20 @@ optim.pls <<- function( formula #----- Call PLS. -----------------------------------------------------------------# dotnow = modifyList(x=dotdotdot,val=list(data=sim.data)) pls.now = try(do.call(what="plsr",args=dotnow),silent=TRUE) + syobs.fine = ! ("try-error" %in% is(pls.now)) + if (syobs.fine){ + syobs.fine = any(is.finite(pls.now$fitted.values)) + }#end if (boot.fine) #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# # Check whether to append to the data set. # #---------------------------------------------------------------------------------# - if (! ("try-error" %in% is(pls.now))){ + if (syobs.fine){ #----- Retrieve MSE in case back-transformation is sought. --------------------# - mse.now = MSEP(object=pls.now,"adjCV") - mse.now = c(mse.now$val[1,1,ans$ncomp+1]) + mse.now = mean2(pls.now$residuals[,1,ans$ncomp]) #------------------------------------------------------------------------------# @@ -405,7 +419,7 @@ optim.pls <<- function( formula #----- Show banner to entertain the bored user. -------------------------------# if (verbose) cat0(" > Sigma-y realisation failed, skip it.") #------------------------------------------------------------------------------# - }#end if (! ("try-error" %in% is(pls.now))) + }#end if (syobs.fine) #---------------------------------------------------------------------------------# diff --git a/R-utils/optim.randomforest.r b/R-utils/optim.randomforest.r index d73f55381..ba774f152 100644 --- a/R-utils/optim.randomforest.r +++ b/R-utils/optim.randomforest.r @@ -136,6 +136,9 @@ optim.randomForest <<- function( formula if (is.null (boot.class)){ idx = sample.int(n=n.data,replace=TRUE) ixval = which(! (sequence(n.data) %in% idx)) + }else if (n.uniq.class == 1L){ + idx = sample.int(n=n.data,replace=TRUE) + ixval = which(! (sequence(n.data) %in% idx)) }else{ use.class = lit.sample(x=uniq.class,size=n.uniq.class,replace=TRUE) use.sample = mapply( FUN = function(x,y) which(y %in% x) diff --git a/R-utils/optim.size.pft.bio.r b/R-utils/optim.size.pft.bio.r index 5c1865bb9..4a2d4b889 100644 --- a/R-utils/optim.size.pft.bio.r +++ b/R-utils/optim.size.pft.bio.r @@ -3,70 +3,209 @@ # This function finds the relative error of both the size structure and the basal # # area by species. # #------------------------------------------------------------------------------------------# -optim.size.pft.bio <<- function( logdbh.minus.min # Log of DBH above minimum - , obs.dbh.cnt # Frequency of each DBH class (dbh.bks) - , dbh.bks # DBH breaks for size evaluation - , dbh.table # DBH table by species - , census # Table with the full census - , datum # Table with the sought properties - , pft.var = "pft" # Variable to determine the PFT - , dbh.min = 10. # Minimum DBH - , tiny.off = 1.e-20 # Tiny offset +optim.size.pft.bio <<- function( logdbh.minus.min # Log of DBH above minimum + , obs.dbh.cnt # Frequency of each DBH class + # (dbh.cnt.bks) + , dbh.cnt.bks # DBH breaks for size + # evaluation + , dbh.table.obs # DBH table by species + , dbh.table.bks = dbh.cnt.bks # DBH breaks by species + , dbh.max = NULL # Maximum DBH by species + , bsa.summ = NULL # Basal area summary + , dbh.bsa.bks = dbh.cnt.bks # DBH breaks for basal area + , cnt.log = TRUE # Use log for count? + , bsa.log = FALSE # Use log for basal area? + , survey.area # Total surveyed area (m2) + , census # Table with the full census + , datum # Table with the sought + # properties + , pft.var = "pft" # Variable to determine the PFT + , dbh.min = 10. # Minimum DBH + , tiny.off = 1.e-7 # Tiny offset ){ #----- Revert back to DBH. -------------------------------------------------------------# dbh.now = dbh.min + exp(logdbh.minus.min) - pft.now = rownames(dbh.table) + pft.now = rownames(dbh.table.obs) #---------------------------------------------------------------------------------------# #----- Find the error due to size distribution. ----------------------------------------# - dbh.cut = cut(dbh.now,dbh.bks) - dbh.cnt = tiny.off + table(dbh.cut) - if (tiny.off == 0){ - rmse.size = ( sum((dbh.cnt/sum(dbh.cnt)-obs.dbh.cnt/sum(obs.dbh.cnt))^2) - / length(obs.dbh.cnt) ) + mod.dbh.cut = cut(dbh.now,dbh.cnt.bks) + mod.dbh.cnt = table(mod.dbh.cut) + obs.dbh.tot = sum(obs.dbh.cnt) + mod.dbh.cnt = mod.dbh.cnt / obs.dbh.tot + obs.dbh.cnt = obs.dbh.cnt / obs.dbh.tot + if (cnt.log){ + ln.obs.dbh.cnt = log(tiny.off + obs.dbh.cnt) + ln.mod.dbh.cnt = log(tiny.off + mod.dbh.cnt) + mse.size = ( sum( ( ln.obs.dbh.cnt - ln.mod.dbh.cnt )^2 ) + / length(ln.obs.dbh.cnt) ) }else{ - rmse.size = sum((log(dbh.cnt)-log(obs.dbh.cnt))^2) / length(obs.dbh.cnt) + mse.size = sum( ( mod.dbh.cnt - obs.dbh.cnt)^2 ) / length(obs.dbh.cnt) }#end if + wgt.size = length(mse.size) #---------------------------------------------------------------------------------------# + #----- Find the error due to size distribution. ----------------------------------------# - dbh.cut = cut(dbh.now,dbh.bks) - dbh.mod = tiny.off + table(census[[pft.var]],dbh.cut) - dbh.cnt = array(0,dim=dim(dbh.table),dimnames=dimnames(dbh.table)) - maponto = match(rownames(dbh.mod),rownames(dbh.cnt)) - dbh.cnt[maponto,] = dbh.mod - - use = ! is.na(dbh.table) - dbh.cnt = tiny.off + c(dbh.cnt [use]) - dbh.obs = tiny.off + c(dbh.table[use]) - - if (tiny.off == 0){ - rmse.class = ( sum((dbh.cnt/sum(dbh.cnt)-dbh.obs/sum(dbh.obs))^2) - / length(dbh.obs) ) + if (is.list(dbh.table.bks)){ + #----- Get dbh thresholds for each species. -----------------------------------------# + o = order(names(dbh.table.bks)) + dbh.table.cut = dbh.table.bks[o] + #------------------------------------------------------------------------------------# + + + #----- Get size count using species-specific thresholds. ----------------------------# + dbh.list = split(x=dbh.now,f=census[[pft.var]]) + dbh.table.tmp = t( mapply( FUN = function(dbh,dcut){ + dbh.cut = cut(dbh,dcut) + dbh.tbl = table(dbh.cut) + idx = match(names(dbh.tbl),levels(dbh.cut)) + ans = rep(0L,times=nlevels(dbh.cut)) + ans[idx] = dbh.tbl + return(ans) + }#end function + , dbh = dbh.list + , dcut = dbh.table.cut + )#end mapply + )#end t + #------------------------------------------------------------------------------------# + }else{ + #---- Get size count using global thresholds. ---------------------------------------# + dbh.table.cut = cut(dbh.now,dbh.table.bks) + dbh.table.tmp = table(census[[pft.var]],dbh.table.cut) + #------------------------------------------------------------------------------------# + }#end if (is.null(dbh.table.bks)) + #---------------------------------------------------------------------------------------# + + + + #----- Align results so it matches the reference table. --------------------------------# + dbh.table.mod = array( data = 0 + , dim = dim(dbh.table.obs) + , dimnames = dimnames(dbh.table.obs) + )#end array + idx = match(rownames(dbh.table.tmp),rownames(dbh.table.mod)) + dbh.table.mod[idx,] = dbh.table.tmp + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check for valid data, as sometimes PFT-specific distribution exists for a few # + # species only. Then normalise data for both observations and estimates # + #---------------------------------------------------------------------------------------# + dbh.table.use = ! is.na(dbh.table.obs) + dbh.table.tot = sum(dbh.table.obs[dbh.table.use]) + dbh.table.obs = dbh.table.obs[dbh.table.use] / dbh.table.tot + dbh.table.mod = dbh.table.mod[dbh.table.use] / dbh.table.tot + #---------------------------------------------------------------------------------------# + + if (cnt.log){ + ln.dbh.table.mod = log(tiny.off + dbh.table.mod) + ln.dbh.table.obs = log(tiny.off + dbh.table.obs) + mse.class = ( sum( ( ln.dbh.table.mod - ln.dbh.table.obs)^2 ) + / length(dbh.table.obs) ) }else{ - rmse.class = sum((log(dbh.cnt)-log(dbh.obs))^2) / length(dbh.obs) + mse.class = sum( (dbh.table.mod - dbh.table.obs)^2 ) / length(dbh.table.obs) }#end if + wgt.class = length(mse.class) #---------------------------------------------------------------------------------------# - #----- Find the error due to basal area by PFT. ----------------------------------------# - bsa.now = 0.25 * pi * dbh.now^2 - bsa.pft = tapply(X=bsa.now,INDEX=census[[pft.var]],FUN=sum,na.rm=TRUE) - idx = match(datum[[pft.var]],names(bsa.pft)) - rmse.bsa = sum((log(datum$bsa) - log(bsa.pft[idx]))^2) / length(datum$bsa) #---------------------------------------------------------------------------------------# + # Not every survey provides the basal area by species. In case it is missing, make a # + # dummy error and dummy length. # + #---------------------------------------------------------------------------------------# + if ("bsa" %in% names(datum)){ + + + #----- Find modelled basal area by PFT. ---------------------------------------------# + bsa.now = pio4 * dbh.now^2 / survey.area + bsa.pft.obs = datum$bsa + names(bsa.pft.obs) = datum[[pft.var]] + bsa.pft.mod = tapply(X=bsa.now,INDEX=census[[pft.var]],FUN=sum,na.rm=TRUE) + idx = match(names(bsa.pft.obs),names(bsa.pft.mod)) + bsa.pft.mod = bsa.pft.mod[idx] + #------------------------------------------------------------------------------------# + - rmse = sqrt( ( length(rmse.size ) * rmse.size^2 - + length(rmse.bsa ) * rmse.bsa^2 - + length(rmse.class) * rmse.class^2 ) - / ( length(rmse.size) + length(rmse.bsa) + length(rmse.class) ) ) + #----- Normalise basal area, taking observed total as the reference. ----------------# + bsa.pft.tot = sum(bsa.pft.obs) + bsa.pft.obs = bsa.pft.obs / bsa.pft.tot + bsa.pft.mod = bsa.pft.mod / bsa.pft.mod + #------------------------------------------------------------------------------------# + + + #----- Calculate error. -------------------------------------------------------------# + if (bsa.log){ + ln.bsa.pft.obs = log(tiny.off + bsa.pft.obs) + ln.bsa.pft.mod = log(tiny.off + bsa.pft.mod) + mse.bsa = sum( ( ln.bsa.pft.mod - ln.bsa.pft.obs )^2 ) / length(ln.bsa.pft.obs) + }else{ + mse.bsa = sum( ( bsa.pft.mod - bsa.pft.obs)^2 ) / length(bsa.pft.obs) + }#end if (bsa.log) + wgt.bsa = length(mse.bsa) + #------------------------------------------------------------------------------------# + }else{ + #----- Make dummy error. ------------------------------------------------------------# + mse.bsa = 0. + wgt.bsa = 0. + #------------------------------------------------------------------------------------# + }#end if + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # In case a general basal area by size class. # + #---------------------------------------------------------------------------------------# + if (is.null(bsa.summ)){ + #----- Make dummy error. ------------------------------------------------------------# + mse.bss = 0. + wgt.bss = 0. + #------------------------------------------------------------------------------------# + }else{ + #----- Find the total basal area by DBH class. --------------------------------------# + dbh.bsa.cut = cut(dbh.now,dbh.bsa.bks) + bsa.now = pio4 * dbh.now^2 / survey.area + dbh.bsa.mod = tapply(X=bsa.now,INDEX=dbh.bsa.cut,FUN=sum,na.rm=TRUE) + #------------------------------------------------------------------------------------# + + + #----- Normalise basal area distribution, using observations as reference. ----------# + dbh.bsa.tot = sum(bsa.summ) + dbh.bsa.obs = bsa.summ / dbh.bsa.tot + dbh.bsa.mod = dbh.bsa.mod / dbh.bsa.tot + #------------------------------------------------------------------------------------# + + + + #----- Find error associated with basal area size distribution. ---------------------# + if (bsa.log){ + ln.dbh.bsa.obs = log(tiny.off + dbh.bsa.obs) + ln.dbh.bsa.mod = log(tiny.off + dbh.bsa.mod) + mse.bss = ( sum( ( ln.dbh.bsa.mod - ln.dbh.bsa.obs )^2 ) + / length(ln.dbh.bsa.obs) ) + }else{ + mse.bss = sum( ( dbh.bsa.mod - dbh.bsa.obs )^2 ) / length(dbh.bsa.obs) + }#end if (bsa.log) + wgt.bss = length(mse.bss) + #------------------------------------------------------------------------------------# + }#end if (is.null(bsa.summ)) + #---------------------------------------------------------------------------------------# + + #----- Find total error. ---------------------------------------------------------------# + rmse = sqrt( ( wgt.size * mse.size + wgt.class * mse.class + + wgt.bsa * mse.bsa + wgt.bss * mse.bss ) + / ( wgt.size + wgt.class + wgt.bsa + wgt.bss ) ) + #---------------------------------------------------------------------------------------# return(rmse) }#end function diff --git a/R-utils/pcomp_varlist.r b/R-utils/pcomp_varlist.r index bbbae70fe..77c569c46 100644 --- a/R-utils/pcomp_varlist.r +++ b/R-utils/pcomp_varlist.r @@ -3443,7 +3443,7 @@ , plog = FALSE , plog.dbh = FALSE , plt = TRUE - , qf.miss = "ifelse(lai$ts %>% 0, gpp$ts/lai$ts, 0.)" + , qf.miss = "ifelse(lai$ts %gt% 0, gpp$ts/lai$ts, 0.)" , pslwr = NA_real_ , psupr = NA_real_ )#end list @@ -4171,35 +4171,35 @@ )#end list scen.xyz$yvar = scen.xyz$xvar scen.xyz$zvar = list( list( vname = "agb" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "wood.dens" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.ecue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list )#end list @@ -4578,67 +4578,67 @@ )#end list panel.xyz$yvar = panel.xyz$xvar panel.xyz$zvar = list( list( vname = "agb" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "f.bstorage" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.dcbadt" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.ecue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.etue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.gpp" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = TRUE )#end list , list( vname = "last.1yr.npp" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.plresp" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.rue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.transp" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.xyz = FALSE )#end list , list( vname = "wood.dens" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.xyz = FALSE )#end list )#end list @@ -4738,23 +4738,23 @@ )#end list panel.map$yvar = panel.map$xvar panel.map$zvar = list( list( vname = "last.1yr.ncbmort" - , col.scheme = "iclife" + , col.scheme = "iprgn" , plog.map = TRUE )#end list , list( vname = "last.1yr.growth" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = TRUE )#end list , list( vname = "last.1yr.change" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = FALSE )#end list , list( vname = "last.1yr.cue" - , col.scheme = "clife" + , col.scheme = "prgn" , plog.map = FALSE )#end list , list( vname = "last.1yr.wue" - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , plog.map = FALSE )#end list )#end list diff --git a/R-utils/petutils.r b/R-utils/petutils.r index 9a61ca0c3..73d553363 100644 --- a/R-utils/petutils.r +++ b/R-utils/petutils.r @@ -157,7 +157,7 @@ pet.penmon <<- function( rnet #----- Find the potential ET (kgW/m2/s). -----------------------------------------------# anom = ( eslope * (rnet - fgnd) + rhos * cpdry * vpdef / ra ) aden = splat * (eslope + psycho * (1. + rc / ra)) - ans = ifelse( test = aden %!=% 0., yes = anom / aden, no = NA_real_) + ans = ifelse( test = aden %ne% 0., yes = anom / aden, no = NA_real_) #---------------------------------------------------------------------------------------# return(ans) }#end function pet.penmon @@ -233,7 +233,7 @@ pet.prtay <<- function( rnet #----- Find the potential ET (kgW/m2/s). -----------------------------------------------# anom = alpha * eslope * ( rnet - fgnd ) aden = splat * (eslope + psycho) - ans = ifelse( test = aden %!=% 0., yes = anom / aden, no = NA_real_) + ans = ifelse( test = aden %ne% 0., yes = anom / aden, no = NA_real_) #---------------------------------------------------------------------------------------# return(ans) }#end function pet.prtay diff --git a/R-utils/pft.coms.r b/R-utils/pft.coms.r index ac246f4fd..4a3a5f152 100644 --- a/R-utils/pft.coms.r +++ b/R-utils/pft.coms.r @@ -102,7 +102,7 @@ par.twilight.min <<- 0.5 * Watts.2.Ein # Minimum non-nocturnal PAR. #----- This is a flag for the maximum representable number in R. --------------------------# -discard <<- 2^1023 +huge.num <<- 2^1023 #------------------------------------------------------------------------------------------# @@ -333,9 +333,9 @@ wdr.fs <<- 0.30 #------------------------------------------------------------------------------------------# # Define reference heights for tropical allometry. # #------------------------------------------------------------------------------------------# -# IALLOM ........ 0, 1, 2, 3, 4..............................# -hgt.ref.trop = c(NA_real_,NA_real_, 61.7,NA_real_,NA_real_)[iallom+1] -hgt.max.trop = c( 35., 35., 35., 46., 46.)[iallom+1] +# IALLOM ........ 0, 1, 2, 3, 4, 5.....................# +hgt.ref.trop = c(NA_real_,NA_real_, 61.7,NA_real_,NA_real_,NA_real_)[iallom+1] +hgt.max.trop = c( 35., 35., 35., 46., 46., 46.)[iallom+1] #------------------------------------------------------------------------------------------# @@ -366,7 +366,7 @@ hgt.max.trop = c( 35., 35., 35., 46., 46.)[iallom+1] # Glob. Change Biol., 23(1):177-190. doi:10.1111/gcb.13388 (J17). # # # #------------------------------------------------------------------------------------------# -c14f15.bl.xx = c(0.46769540,0.6410495) # c(0.09747026,0.7587000) +c14f15.bl.xx = c(0.23384770,0.6410495) # c(0.09747026,0.7587000) c14f15.bs.tf = c(0.06080334,1.0044785) # c(0.08204475,0.9814422) c14f15.bs.sv = c(0.05602791,1.0093501) # c(0.08013971,0.9818603) c14f15.bs.gr = c(1.e-5,1.0) * c14f15.bl.xx @@ -1093,6 +1093,12 @@ pft = as.data.frame(pft,stringsAsFactors=FALSE) +#----- Create flag to identify PFTs that should use the D^2*H allometry. ------------------# +pft$ddh.allom = (iallom %in% c(3,4,5)) & pft$tropical & (! pft$liana) +#------------------------------------------------------------------------------------------# + + + #----- Adjust Vm0 based on settings and to make units consistent. -------------------------# pft$vm0 = ifelse( test = pft$pathway == 4 , yes = pft$vm0 * vmfact.c4 @@ -1521,7 +1527,7 @@ if (iallom %in% c(0,1)){ pft$b1Ht[tropical] = 0.0352 pft$b2Ht[tropical] = 0.694 #---------------------------------------------------------------------------------------# -}else if (iallom %in% c(3)){ +}else if (iallom %in% c(3,5)){ #---------------------------------------------------------------------------------------# # Allometric equation based on the fitted curve using the Sustainable Landscapes # # data set (L16) and the size- and site-dependent stratified sampling and aggregation # @@ -1595,15 +1601,15 @@ pft$hgt.show = pft$hgt.min + 0.015 * (pft$hgt.max - pft$hgt.min) pft$qsw = pft$SLA / sapwood.ratio.orig for (ipft in sequence(npft+1)){ #---- Check PFT and allometry. ---------------------------------------------------------# - if (pft$tropical[ipft] && pft$conifer[ipft] && iallom %in% c(3)){ + if (pft$tropical[ipft] && pft$conifer[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = pft$SLA[ipft] * pft$rho[ipft] / sapwood.factor["aa"] - }else if (pft$tropical[ipft] && pft$grass[ipft] && iallom %in% c(3)){ + }else if (pft$tropical[ipft] && pft$grass[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = 1.0e-5 - }else if (pft$tropical[ipft] && iallom %in% c(3)){ + }else if (pft$tropical[ipft] && iallom %in% c(3,5)){ pft$qsw[ipft] = pft$SLA[ipft] * pft$rho[ipft] / sapwood.factor["bl"] }else{ pft$qsw[ipft] = pft$SLA[ipft] / sapwood.ratio.orig - }#end if (pft$tropical[ipft] && is.finite(pft$rho[ipft]) && iallom %in% c(3,4)) + }#end if (pft$tropical[ipft] && is.finite(pft$rho[ipft]) && iallom %in% c(3,5)) #---------------------------------------------------------------------------------------# }#end for (ipft in sequence(npft)) #------------------------------------------------------------------------------------------# @@ -1717,7 +1723,9 @@ pft$b1Xs = 0.315769481 pft$b1Xb = 0. pft$qbark = 0. for (ipft in sequence(npft+1)){ - skip = pft$grass[ipft] || pft$liana[ipft] || (! pft$tropical[ipft]) || ( iallom != 3 ) + skip = ( pft$grass[ipft] || pft$liana[ipft] || (! pft$tropical[ipft]) + || ( ! (iallom %in% c(3,5) ) ) + )#end skip if (! skip){ #------------------------------------------------------------------------------------# # Variable b1Xs is the ratio between sapwood thickness and DBH. It is currently # @@ -1763,7 +1771,7 @@ pft$dbh.min = rep(NA,times=npft+1) pft$dbh.crit = rep(NA,times=npft+1) for (ipft in sequence(npft+1)){ if (pft$tropical[ipft]){ - if (iallom %in% c(0,1,3,4)){ + if (iallom %in% c(0,1,3,4,5)){ pft$dbh.min [ipft] = exp((log(pft$hgt.min[ipft])-pft$b1Ht[ipft])/pft$b2Ht[ipft]) pft$dbh.crit [ipft] = exp((log(pft$hgt.max[ipft])-pft$b1Ht[ipft])/pft$b2Ht[ipft]) }else if (iallom %in% c(2)){ @@ -1842,7 +1850,7 @@ for (ipft in sequence(npft+1)){ pft$b2Bs.small[ipft] = ndead.small[2] pft$b1Bs.large[ipft] = C2B * exp(ndead.large[1]) * pft$rho[ipft] / ndead.large[3] pft$b2Bs.large[ipft] = ndead.large[2] - }else if (iallom %in% c(3,4)){ + }else if (iallom %in% c(3,4,5)){ if (pft$grass[ipft]){ c14f15.bs.xx = c14f15.bs.gr }else if (pft$savannah[ipft]){ @@ -1871,7 +1879,7 @@ for (ipft in sequence(npft+1)){ }else if (iallom %in% c(2)){ pft$b1Ca[ipft] = exp(ncrown.area[1]) pft$b2Ca[ipft] = ncrown.area[2] - }else if (iallom %in% c(3,4)){ + }else if (iallom %in% c(3,4,5)){ #---------------------------------------------------------------------------------# # Allometry using the Sustainable Landscapes data. # #---------------------------------------------------------------------------------# @@ -1918,7 +1926,7 @@ for (ipft in sequence(npft+1)){ # R2 = 0.673 # # RMSE = 2.29 # #------------------------------------------------------------------------------------# - if (iallom %in% c(3,4) && (! pft$grass[ipft])){ + if (iallom %in% c(3,4,5) && (! pft$grass[ipft])){ pft$b1Cl[ipft] = 0.29754 pft$b2Cl[ipft] = 1.0324 }#end if @@ -1943,10 +1951,10 @@ for (ipft in sequence(npft+1)){ }else if(iallom %in% c(2)){ pft$b1Bl[ipft] = C2B * exp(nleaf[1]) * pft$rho[ipft] / nleaf[3] pft$b2Bl[ipft] = nleaf[2] - }else if(iallom %in% c(3)){ + }else if(iallom %in% c(3,5)){ #---------------------------------------------------------------------------------# # Leaf allometry, use the individual leaf area allometry derived from the BAAD # - # data base (F15), scaled by the specific leaf area. # + # data base (F15), scaled by the specific leaf area, and described in L20. # # # # Reference: # # # @@ -1955,8 +1963,15 @@ for (ipft in sequence(npft+1)){ # database for woody plants. Ecology, 96 (5):1445-1445. # # doi:10.1890/14-1889.1 (F15). # # # + # Longo M, Saatchi SS, Keller M, Bowman KW, Ferraz A, Moorcroft PR, Morton D, # + # Bonal D, Brando P, Burban B et al. 2020. Impacts of degradation on water, # + # energy, and carbon cycling of the Amazon tropical forests. # + # J. Geophys. Res.-Biogeosci., 125: e2020JG005677. # + # doi:10.1029/2020JG005677 (L20). # + # # #---------------------------------------------------------------------------------# - pft$b1Bl[ipft] = c14f15.bl.xx[1] / pft$SLA[ipft] + # pft$b1Bl[ipft] = C2B * c14f15.bl.xx[1] / pft$SLA[ipft] + pft$b1Bl[ipft] = c14f15.bl.xx[1] pft$b2Bl[ipft] = c14f15.bl.xx[2] #---------------------------------------------------------------------------------# }else{ @@ -2108,9 +2123,9 @@ if (iallom %in% c(0)){ , no = 0.4223014 )#end ifelse #---------------------------------------------------------------------------------------# -}else if (iallom %in% c(3)){ +}else if (iallom %in% c(4,5)){ #----- Test allometry based on excavation data in Panama, using height as predictor. ---# - pft$b1Rd [sequence(npft+1)] = -0.609 + pft$b1Rd [sequence(npft+1)] = -0.609 * 2 pft$b2Rd [sequence(npft+1)] = 0.580 #---------------------------------------------------------------------------------------# }#end if @@ -2125,34 +2140,34 @@ if (iallom %in% c(0)){ # BDead -> DBH parameters. These are calculated a posteriori because they are just # # the inverse of size->BDead allometry. # #------------------------------------------------------------------------------------------# -pft$d2DBH.small = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d2DBH.small = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bs.small ) , no = 1. / pft$b2Bs.small )#end ifelse -pft$d1DBH.small = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d1DBH.small = ifelse( test = pft$ddh.allom , yes = ( C2B / ( pft$b1Bs.small * exp(pft$b1Ht*pft$b2Bs.small) ) ) ^ pft$d2DBH.small , no = ( C2B / pft$b1Bs.small ) ^ pft$d2DBH.small )#end ifelse -pft$d2DBH.large = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d2DBH.large = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bs.large ) , no = 1. / pft$b2Bs.large )#end ifelse -pft$d1DBH.large = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$d1DBH.large = ifelse( test = pft$ddh.allom , yes = ( C2B / ( pft$b1Bs.large * exp(pft$b1Ht*pft$b2Bs.large) ) ) ^ pft$d2DBH.large , no = ( C2B / pft$b1Bs.large ) ^ pft$d2DBH.large )#end ifelse -pft$l2DBH = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$l2DBH = ifelse( test = pft$ddh.allom , yes = 1. / ( ( 2. + pft$b2Ht ) * pft$b2Bl ) , no = 1. / pft$b2Bl )#end ifelse -pft$l1DBH = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) - , yes = ( C2B / ( pft$b1Bl * exp(pft$b1Ht*pft$b2Bl) ) ) +pft$l1DBH = ifelse( test = pft$ddh.allom + , yes = ( 1. / ( pft$b1Bl * exp(pft$b1Ht*pft$b2Bl) ) ) ^ pft$l2DBH , no = ( C2B / pft$b1Bl ) ^ pft$l2DBH )#end ifelse -pft$bdead.crit = ifelse( test = pft$tropical & (! pft$liana) & (iallom %in% c(3,4)) +pft$bdead.crit = ifelse( test = pft$ddh.allom , yes = pft$b1Bs.small / C2B * ( pft$dbh.crit * pft$dbh.crit * pft$hgt.max) ^ pft$b2Bs.small @@ -2214,8 +2229,7 @@ pft$b2Efrd = rep(x=0.1822,times=npft+1) #------------------------------------------------------------------------------------------# pft$b1WAI = ifelse( test = pft$grass , yes = 0.0 - , no = ifelse( test = pft$tropical & (! pft$liana) - & (iallom %in% c(3,4)) + , no = ifelse( test = pft$ddh.allom , yes = ifelse( test = pft$conifer , yes = 0.01148449 , no = 0.00378399 @@ -2228,8 +2242,7 @@ pft$b1WAI = ifelse( test = pft$grass )#end ifelse pft$b2WAI = ifelse( test = pft$grass , yes = 0.0 - , no = ifelse( test = pft$tropical & (! pft$liana) - & (iallom %in% c(3,4)) + , no = ifelse( test = pft$ddh.allom , yes = ifelse( test = pft$conifer , yes = 0.77075160 , no = 0.81667933 @@ -2352,6 +2365,12 @@ pft$kplastic.ltor = -1 * with(pft,kplastic.vm0*eplastic.vm0+kplastic.sla*eplasti +#------ Fire survivorship parameters for when using the old models. -----------------------# +pft$fire.s.efac = -0.12 +pft$fire.s.max = ifelse(test = pft$grass,yes = 0.1, no = 0.9) +#------------------------------------------------------------------------------------------# + + #----- Make it global. --------------------------------------------------------------------# pft <<- pft #------------------------------------------------------------------------------------------# diff --git a/R-utils/plot.rgb.r b/R-utils/plot.rgb.r index 52bdf3804..51e184f80 100644 --- a/R-utils/plot.rgb.r +++ b/R-utils/plot.rgb.r @@ -271,8 +271,8 @@ plot.rgb <<- function( x green.l = seq(from=0,to=1-red.span[n],by=0.5*delta) blue.l = seq(from=0,to=1-red.span[n],by=0.5*delta) rgb.l = expand.grid(red=red.span[n],green=green.l,blue=blue.l) - keep = ( rowSums(rgb.l) %>=% (1-sqrt(.Machine$double.eps)) - & rowSums(rgb.l) %<=% (1+sqrt(.Machine$double.eps)) ) + keep = ( rowSums(rgb.l) %ge% (1-sqrt(.Machine$double.eps)) + & rowSums(rgb.l) %le% (1+sqrt(.Machine$double.eps)) ) rgb.l = rgb.l[keep,] / rowSums(rgb.l[keep,]) #---------------------------------------------------------------------------------# diff --git a/R-utils/plotutils.r b/R-utils/plotutils.r index 9144630d9..5fd56c5d3 100644 --- a/R-utils/plotutils.r +++ b/R-utils/plotutils.r @@ -24,7 +24,7 @@ open.plot <<- function( fichier #----- Fichier must be provided unless we are plotting on screen. ----------------------# - if (missing(fichier) && (! outform %in% c("x11","quartz","windows"))){ + if (missing(fichier) && (! outform %in% c("x11","quartz","windows","default"))){ stop("Output file (\"fichier\") must be provided when plotting on file!") }#end if (missing(fichier) && (! outform %in% c("x11","quartz","windows"))) #---------------------------------------------------------------------------------------# @@ -77,7 +77,7 @@ open.plot <<- function( fichier , paper = size$paper , ... )#end postscript - }else if (outform[o] %in% "pdf"){ + }else if (outform %in% "pdf"){ pdf ( file = fichier , onefile = FALSE , width = size$width @@ -85,6 +85,9 @@ open.plot <<- function( fichier , pointsize = ptsz , paper = size$paper )#end pdf + }else if (outform %in% "default"){ + # Don't open any device, let the script open at the default location. + dev.new() }#end if #---------------------------------------------------------------------------------------# @@ -111,12 +114,11 @@ close.plot <<- function( outform = switch( EXPR = get.os() if (outform %in% c("x11","quartz","windows")){ locator(n=n) dev.off() + }else if (outform %in% "default"){ }else{ dev.off() }#end if dummy = clean.tmp() - - invisible() }#end close.plot #==========================================================================================# diff --git a/R-utils/pmonthly_varlist.r b/R-utils/pmonthly_varlist.r index 746b3275f..2f42736b5 100644 --- a/R-utils/pmonthly_varlist.r +++ b/R-utils/pmonthly_varlist.r @@ -422,6 +422,32 @@ tspftdbh[[n]] = list( vnam = "leaf.gsw" , scsout = TRUE )#end list n = n + 1 +tspftdbh[[n]] = list( vnam = "dmin.leaf.psi" + , desc = "Midday leaf water potential" + , e.unit = untab$mpa + , i.unit = untab$mpa + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 +tspftdbh[[n]] = list( vnam = "dmax.leaf.psi" + , desc = "Pre-dawn leaf water potential" + , e.unit = untab$mpa + , i.unit = untab$mpa + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 tspftdbh[[n]] = list( vnam = "leaf.gbw" , desc = "Leaf boundary layer conductance" , e.unit = untab$kgwom2loday @@ -542,6 +568,19 @@ tspftdbh[[n]] = list( vnam = "dimort" , scsout = TRUE )#end list n = n + 1 +tspftdbh[[n]] = list( vnam = "fire.lethal" + , desc = "Fire lethality rate" + , e.unit = untab$pcpopoyr + , i.unit = untab$pcpopoyr + , plog = FALSE + , pft = TRUE + , pftdbh = TRUE + , sas = FALSE + , bar.plot = FALSE + , stack = FALSE + , scsout = TRUE + )#end list +n = n + 1 tspftdbh[[n]] = list( vnam = "recr" , desc = "Recruitment rate" , e.unit = untab$pcpopoyr @@ -1447,7 +1486,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gpp" , desc = "Gross Primary productivity" , unit = untab$kgcom2oyr - , col.scheme = "atlas" + , col.scheme = "brbg" , fco.mmean = TRUE , fco.qmean = FALSE , box.plot = FALSE @@ -1456,7 +1495,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "npp" , desc = "Net Primary productivity" , unit = untab$kgcom2oyr - , col.scheme = "atlas" + , col.scheme = "brbg" , fco.mmean = TRUE , fco.qmean = FALSE , box.plot = FALSE @@ -1465,7 +1504,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "plant.resp" , desc = "Plant respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1474,7 +1513,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "het.resp" , desc = "Heterotrophic respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1483,7 +1522,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "fgc.resp" , desc = "Surface litter respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1492,7 +1531,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "fsc.resp" , desc = "Sub-surface litter respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1501,7 +1540,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "stgc.resp" , desc = "Surface woody debris respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1510,7 +1549,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "stsc.resp" , desc = "Sub-surface woody debris respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1519,7 +1558,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "msc.resp" , desc = "Microbial soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1528,7 +1567,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "ssc.resp" , desc = "Humified soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1537,7 +1576,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "psc.resp" , desc = "Passive soil respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1582,7 +1621,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "nep" , desc = "Net ecosystem production" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1591,7 +1630,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "reco" , desc = "Ecosystem respiration" , unit = untab$kgcom2oyr - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1600,7 +1639,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "hflxca" , desc = "Sensible heat flux" , unit = untab$wom2 - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1609,7 +1648,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxca" , desc = "Water flux" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1618,7 +1657,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxgc" , desc = "Ground evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1627,7 +1666,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxlc" , desc = "Leaf evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1636,7 +1675,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wflxwc" , desc = "Wood evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1645,7 +1684,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "evap" , desc = "Evaporation" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1654,7 +1693,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "transp" , desc = "Transpiration" , unit = untab$kgwom2oday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1663,7 +1702,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "nee" , desc = "Net ecosystem exchange" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1672,7 +1711,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "cflxca" , desc = "CO2 flux" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1681,7 +1720,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "cflxst" , desc = "CO2 flux" , unit = untab$umolcom2os - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1690,7 +1729,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.temp" , desc = "Canopy air temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1699,7 +1738,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.temp" , desc = "Atmospheric temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1708,7 +1747,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.temp" , desc = "Leaf temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1717,7 +1756,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wood.temp" , desc = "Wood temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1726,7 +1765,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gnd.temp" , desc = "Ground temperature" , unit = untab$degC - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1735,7 +1774,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.shv" , desc = "Atmospheric specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1744,7 +1783,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.shv" , desc = "Canopy air specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1753,7 +1792,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "gnd.shv" , desc = "Ground specific humidity" , unit = untab$gwokg - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1762,7 +1801,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "atm.co2" , desc = "Atmospheric CO2 mixing ratio" , unit = untab$molcomol - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1771,7 +1810,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "can.co2" , desc = "Canopy air CO2 mixing ratio" , unit = untab$molcomol - , col.scheme = "panoply" + , col.scheme = "puor" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1780,7 +1819,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rain" , desc = "Total monthly precipitation" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1789,7 +1828,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "runoff" , desc = "Total monthly runoff" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1798,7 +1837,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "intercepted" , desc = "Total monthly interception" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1807,7 +1846,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "wshed" , desc = "Total monthly dripping" , unit = untab$mm - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1816,7 +1855,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "sm.stress" , desc = "Fraction of open stomata" , unit = untab$empty - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1825,7 +1864,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.gbw" , desc = "Leaf boundary layer conductance" , unit = untab$kgwom2loday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1834,7 +1873,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "leaf.gsw" , desc = "Stomatal conductance" , unit = untab$kgwom2loday - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1843,7 +1882,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshort" , desc = "Downward shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1852,7 +1891,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshort.gnd" , desc = "Abs. gnd. shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1861,7 +1900,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rshortup" , desc = "Outgoing shortwave radiation" , unit = untab$wom2 - , col.scheme = "icloudy" + , col.scheme = "ibugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1870,7 +1909,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlong" , desc = "Downward longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1879,7 +1918,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlong.gnd" , desc = "Abs. gnd. longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1888,7 +1927,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "rlongup" , desc = "Outgoing longwave radiation" , unit = untab$wom2 - , col.scheme = "cloudy" + , col.scheme = "bugy" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1897,7 +1936,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "albedo" , desc = "Shortwave albedo" , unit = untab$empty - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1906,7 +1945,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "ustar" , desc = "Friction velocity" , unit = untab$mos - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1915,7 +1954,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "paw" , desc = "Potential available water" , unit = untab$pcsat - , col.scheme = "ipanoply" + , col.scheme = "rdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1924,7 +1963,7 @@ n = n + 1 squeeze[[n]] = list( vnam = "smpot" , desc = "Integrated matric potential" , unit = untab$mpa - , col.scheme = "panoply" + , col.scheme = "irdbu" , fco.mmean = FALSE , fco.qmean = FALSE , box.plot = FALSE @@ -1944,8 +1983,8 @@ theme[[n]] = list( vnam = c( "gpp", "plant.resp", "het.resp", , "npp", "nep") , desc = c( "GPP","Plant resp.","Het. resp.","Ecos. Resp." , "NPP", "NEP") - , colour = c( "darkgreen", "gold", "purple3", "orangered" - ,"chartreuse3","dodgerblue3") + , colour = c( "#009E73", "#F0E442", "#332288", "#882255" + , "#56B4E9", "#0072B2") , lwd = c( 2.5, 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -1958,6 +1997,7 @@ theme[[n]] = list( vnam = c( "gpp", "plant.resp", "het.resp", , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -1968,8 +2008,8 @@ theme[[n]] = list( vnam = c( "rshort", "rlong","rshort.gnd", "qwf , "hflxca") , desc = c( "Down SW", "Down LW", "Abs. Grnd", "'Latent'" , "Sensible") - , colour = c("goldenrod","chartreuse4", "purple4","dodgerblue3" - ,"firebrick") + , colour = c( "#E69F00", "#56B4E9", "#332288", "#0072B2" + , "#882255") , lwd = c( 2.5, 2.5, 2.5, 2.5 ,2.5) , type = "o" @@ -1982,6 +2022,7 @@ theme[[n]] = list( vnam = c( "rshort", "rlong","rshort.gnd", "qwf , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -1992,8 +2033,8 @@ theme[[n]] = list( vnam = c( "wflxgc", "wflxca", "wfl , "wflxwc", "transp") , desc = c("Ground->Canopy", "Canopy->Atm", "Leaf->Canopy" , "Wood->Canopy", "Transpiration") - , colour = c( "#3B24B3", "#2996CC", "#A3CC52" - , "#990F0F", "#306614") + , colour = c( "#332288", "#0072B2", "#56B4E9" + , "#882255", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2006,8 +2047,9 @@ theme[[n]] = list( vnam = c( "wflxgc", "wflxca", "wfl , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) - , mmean.lim = c(0,5.0) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list @@ -2016,8 +2058,8 @@ theme[[n]] = list( vnam = c( "hflxgc", "hflxca", "hfl , "hflxwc") , desc = c("Ground->Canopy", "Canopy->Atm", "Leaf->Canopy" , "Wood->Canopy") - , colour = c( "#3B24B3", "#2996CC", "#A3CC52" - , "#990F0F") + , colour = c( "#332288", "#0072B2", "#56B4E9" + , "#882255", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5) , type = "o" @@ -2030,6 +2072,7 @@ theme[[n]] = list( vnam = c( "hflxgc", "hflxca", "hfl , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2040,8 +2083,8 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" , "wood.temp", "gnd.temp") , desc = c( "Atmosphere","Canopy air", "Leaf" , "Wood", "Ground") - , colour = c( "deepskyblue", "grey45","chartreuse4" - ,"darkgoldenrod", "orangered") + , colour = c( "#56B4E9", "grey45", "#009E73" + , "#882255", "#332288") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2054,6 +2097,7 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2062,7 +2106,7 @@ theme[[n]] = list( vnam = c( "atm.temp", "can.temp", "leaf.temp" n = n + 1 theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") , desc = c( "Atmosphere","Canopy air", "Ground") - , colour = c("deepskyblue", "slateblue","darkgoldenrod") + , colour = c( "#56B4E9", "#0072B2", "#332288") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2074,6 +2118,7 @@ theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2082,7 +2127,7 @@ theme[[n]] = list( vnam = c( "atm.shv", "can.shv", "gnd.shv") n = n + 1 theme[[n]] = list( vnam = c( "atm.co2", "can.co2") , desc = c( "Atmosphere", "Canopy air") - , colour = c("deepskyblue", "slateblue") + , colour = c( "#56B4E9", "#0072B2") , lwd = c(2.5,2.5) , type = "o" , plog = FALSE @@ -2094,6 +2139,7 @@ theme[[n]] = list( vnam = c( "atm.co2", "can.co2") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2102,7 +2148,7 @@ theme[[n]] = list( vnam = c( "atm.co2", "can.co2") n = n + 1 theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", "wshed") , desc = c("Precipitation","Total runoff","Interception","Dripping") - , colour = c( "royalblue4", "orangered", "chartreuse4", "purple2") + , colour = c( "#0072B2", "#E69F00", "#009E73", "#332288") , lwd = c( 2.5, 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2114,6 +2160,7 @@ theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2122,7 +2169,7 @@ theme[[n]] = list( vnam = c( "rain", "runoff", "intercepted", n = n + 1 theme[[n]] = list( vnam = c("npat.global") , desc = c("Patch count") - , colour = c( "orangered") + , colour = c( "#D55E00") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2134,6 +2181,7 @@ theme[[n]] = list( vnam = c("npat.global") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2142,7 +2190,7 @@ theme[[n]] = list( vnam = c("npat.global") n = n + 1 theme[[n]] = list( vnam = c( "ncoh.global") , desc = c("Cohort count") - , colour = c( "chartreuse4") + , colour = c( "#009E73") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2154,6 +2202,7 @@ theme[[n]] = list( vnam = c( "ncoh.global") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2162,7 +2211,7 @@ theme[[n]] = list( vnam = c( "ncoh.global") n = n + 1 theme[[n]] = list( vnam = c( "workload", "specwork") , desc = c("RK4 steps (Total)","Avg. RK4 steps per patch") - , colour = c( "purple3", "chartreuse2") + , colour = c( "#56B4E9", "#009E73") , lwd = c( 2.5, 2.5) , type = "o" , plog = TRUE @@ -2174,6 +2223,7 @@ theme[[n]] = list( vnam = c( "workload", "specwork") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2182,7 +2232,7 @@ theme[[n]] = list( vnam = c( "workload", "specwork") n = n + 1 theme[[n]] = list( vnam = c( "rk4step") , desc = c("Thermodynamic time step") - , colour = c( "deepskyblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = TRUE @@ -2194,20 +2244,17 @@ theme[[n]] = list( vnam = c( "rk4step") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "plant.resp", "leaf.resp", "stem.resp" - , "root.resp") - , desc = c( "Autotrophic", "Leaf", "Stem" - , "Root") - , colour = c( "#143305", "#A3CC52", "#E65C17" - , "#990F0F") - , lwd = c( 2.5, 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "root.resp", "stem.resp", "leaf.resp") + , desc = c( "Root", "Stem", "Leaf") + , colour = c( "#332288", "#E69F00", "#009E73") + , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE , prefix = "pltissueresp" @@ -2218,20 +2265,17 @@ theme[[n]] = list( vnam = c( "plant.resp", "leaf.resp", "stem.re , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) - , mmean.lim = c(0.,4.5) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) - , ymean.lim = c(0.,4.5) + , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "plant.resp", "aerobic.resp", "growth.resp" - , "storage.resp") - , desc = c( "Autotrophic", "Aerobic", "Growth" - , "Storage") - , colour = c( "#143305", "#2996CC", "#3B24B3" - , "#B49ED2") - , lwd = c( 2.5, 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "aerobic.resp", "growth.resp", "storage.resp") + , desc = c( "Aerobic", "Growth", "Storage") + , colour = c( "#0072B2", "#E69F00", "#785EF0") + , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE , prefix = "plprocresp" @@ -2242,24 +2286,25 @@ theme[[n]] = list( vnam = c( "plant.resp", "aerobic.resp", "growth.re , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(0.,4.5) , qmean.lim = c(NA,NA) , ymean.lim = c(0.,4.5) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "het.resp", "fgc.resp", "fsc.resp" - , "stgc.resp", "stsc.resp", "msc.resp" - , "ssc.resp", "psc.resp") - , desc = c( "Heterotrophic", "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris", "Microbial" - , "Humified soil", "Passive soil") - , colour = c( "#143305", "#A3CC52", "#E65C17" - , "#990F0F", "#3B24B3", "#2996CC" - , "#B49ED2", "#F1BD3B") +theme[[n]] = list( vnam = c( "psc.resp", "ssc.resp", "stsc.resp" + , "msc.resp", "fsc.resp", "stgc.resp" + , "fgc.resp") + , desc = c( "Passive soil", "Humified soil","BG Woody Debris" + , "Microbial", "BG Litter","AG Woody Debris" + , "AG Litter") + , colour = c( "#811F9E", "#1BA2F7", "#880D32" + , "#CCCA3D", "#107C92", "#F87856" + , "#2BD2DB") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5, 2.5 - , 2.5, 2.5) + , 2.5) , type = "o" , plog = FALSE , prefix = "hetresp" @@ -2270,18 +2315,19 @@ theme[[n]] = list( vnam = c( "het.resp", "fgc.resp", "fsc , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) - , mmean.lim = c(0.,4.5) + , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) - , ymean.lim = c(0.,4.5) + , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" - , "stgc.in", "stsc.in") - , desc = c( "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris") - , colour = c( "#A3CC52", "#E65C17" - , "#990F0F", "#3B24B3") +theme[[n]] = list( vnam = c( "stsc.in", "fsc.in" + , "stgc.in", "fgc.in") + , desc = c("BG Woody Debris", "BG Litter" + ,"AG Woody Debris", "AG Litter") + , colour = c( "#880D32", "#107C92" + , "#F87856", "#2BD2DB") , lwd = c( 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2294,6 +2340,7 @@ theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2302,7 +2349,7 @@ theme[[n]] = list( vnam = c( "fgc.in", "fsc.in" n = n + 1 theme[[n]] = list( vnam = c( "atm.vels", "ustar") , desc = c("Wind speed","Friction velocity") - , colour = c("deepskyblue", "slateblue") + , colour = c( "#56B4E9", "#332288") , lwd = c( 2.5, 2.5) , type = "o" , plog = FALSE @@ -2314,28 +2361,25 @@ theme[[n]] = list( vnam = c( "atm.vels", "ustar") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) , ymean.lim = c(NA,NA) )#end list n = n + 1 -theme[[n]] = list( vnam = c( "fast.grnd.c", "fast.soil.c" - , "struct.grnd.c", "struct.soil.c" - , "microbe.soil.c", "slow.soil.c" - , "passive.soil.c") - , desc = c( "AG Litter", "BG Litter" - ,"AG Woody Debris","BG Woody Debris" - , "Microbial", "Humified" - , "Passive") - , colour = c( "#A3CC52", "#1E4C08" - , "#E65C17", "#990F0F" - , "#2996CC", "#3B24B3" - , "#F1BD3B") - , lwd = c( 2.5, 2.5 - , 2.5, 2.5 - , 2.5, 2.5 - , 2.5) +theme[[n]] = list( vnam = c( "passive.soil.c", "slow.soil.c", "microbe.soil.c" + , "struct.soil.c", "fast.soil.c", "struct.grnd.c" + , "fast.grnd.c") + , desc = c( "Passive", "Humified", "Microbial" + ,"BG Woody Debris", "BG Litter","AG Woody Debris" + , "AG Litter") + , colour = c( "#811F9E", "#1BA2F7", "#880D32" + , "#CCCA3D", "#107C92", "#F87856" + , "#2BD2DB") + , lwd = c( 2.5, 2.5, 2.5 + , 2.5, 2.5, 2.5 + , 2.5) , type = "o" , plog = FALSE , prefix = "soil_carbon" @@ -2346,6 +2390,7 @@ theme[[n]] = list( vnam = c( "fast.grnd.c", "fast.soil.c" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2356,8 +2401,8 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" , "logging.harvest", "combusted.fuel") , desc = c( "Crop (Seeds)", "Crop (Other)" , "Logging Harvest","Combusted Biomass") - , colour = c( "chartreuse3", "dodgerblue3" - , "orangered", "firebrick") + , colour = c( "#009E73", "#0072B2" + , "#E69F00", "#882255") , lwd = c( 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2370,6 +2415,7 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2378,7 +2424,7 @@ theme[[n]] = list( vnam = c( "crop.yield", "crop.harvest" n = n + 1 theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") , desc = c( "Atmosphere", "Canopy air", "Leaf") - , colour = c("deepskyblue","dodgerblue4","chartreuse3") + , colour = c( "#56B4E9", "#0072B2", "#009E73") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2390,6 +2436,7 @@ theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2398,7 +2445,7 @@ theme[[n]] = list( vnam = c( "atm.vpd", "can.vpd", "leaf.vpd") n = n + 1 theme[[n]] = list( vnam = c( "paw") , desc = c("Pot.Av.Water") - , colour = c( "steelblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2410,6 +2457,7 @@ theme[[n]] = list( vnam = c( "paw") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = TRUE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2418,7 +2466,7 @@ theme[[n]] = list( vnam = c( "paw") n = n + 1 theme[[n]] = list( vnam = c( "smpot") , desc = c("Neg. Potential") - , colour = c( "royalblue4") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2430,6 +2478,7 @@ theme[[n]] = list( vnam = c( "smpot") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2438,7 +2487,7 @@ theme[[n]] = list( vnam = c( "smpot") n = n + 1 theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") , desc = c( "ED-2.2","Malhi et al. (2009)") - , colour = c( "orangered", "gold") + , colour = c( "#882255", "#E69F00") , lwd = c( 2.5, 2.5) , type = "o" , plog = FALSE @@ -2450,6 +2499,7 @@ theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2458,7 +2508,7 @@ theme[[n]] = list( vnam = c("water.deficit", "malhi.deficit") n = n + 1 theme[[n]] = list( vnam = c( "nee", "cflxca", "cflxst") , desc = c( "NEE", "CO2 Flux","CO2 Storage") - , colour = c("chartreuse4","steelblue", "orangered") + , colour = c( "#009E73", "#56B4E9", "#E69F00") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2470,6 +2520,7 @@ theme[[n]] = list( vnam = c( "nee", "cflxca", "cflxst") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2480,8 +2531,8 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" , "rshort.gnd", "rshortup") , desc = c("Down Top canopy", "Beam", "Diffuse" , "Abs. Ground","Up Top canopy") - , colour = c( "deepskyblue","darkgoldenrod", "grey45" - , "firebrick", "royalblue3") + , colour = c( "#56B4E9", "#E69F00", "grey45" + , "#882255", "#0072B2") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2494,6 +2545,7 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2502,7 +2554,7 @@ theme[[n]] = list( vnam = c( "rshort", "rshort.beam","rshort.diff" n = n + 1 theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") , desc = c("Down Top canopy","Upward LW", "Abs. Ground") - , colour = c( "deepskyblue","orangered","darkgoldenrod") + , colour = c( "#56B4E9", "#E69F00", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2514,6 +2566,7 @@ theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2522,7 +2575,7 @@ theme[[n]] = list( vnam = c( "rlong", "rlongup", "rlong.gnd") n = n + 1 theme[[n]] = list( vnam = c( "albedo", "albedo.par","albedo.nir") , desc = c("SW Albedo (Net)", "PAR Albedo","NIR Albedo") - , colour = c( "deepskyblue","chartreuse3", "orangered") + , colour = c( "#56B4E9", "#009E73", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2534,6 +2587,7 @@ theme[[n]] = list( vnam = c( "albedo", "albedo.par","albedo.nir") , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2544,8 +2598,8 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" , "par.gnd", "parup") , desc = c("Down Top canopy", "Beam", "Diffuse" , "Abs. Ground","Up Top canopy") - , colour = c( "deepskyblue", "firebrick","slateblue" - , "darkgoldenrod", "chartreuse3") + , colour = c( "#56B4E9", "#882255", "#332288" + , "#E69F00", "#009E73") , lwd = c( 2.5, 2.5, 2.5 , 2.5, 2.5) , type = "o" @@ -2558,6 +2612,7 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2566,7 +2621,7 @@ theme[[n]] = list( vnam = c( "par.tot", "par.beam", "par.diff" n = n + 1 theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "wood.gbw") , desc = c( "Leaf (Stomata)","Leaf (Bnd. Lyr.)","Wood (Bnd. Lyr.)") - , colour = c( "chartreuse4", "steelblue", "sienna") + , colour = c( "#009E73", "#56B4E9", "#882255") , lwd = c( 2.5, 2.5, 2.5) , type = "o" , plog = FALSE @@ -2578,6 +2633,7 @@ theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "w , mmean = TRUE , qmean = TRUE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2586,7 +2642,7 @@ theme[[n]] = list( vnam = c( "leaf.gsw", "leaf.gbw", "w n = n + 1 theme[[n]] = list( vnam = c( "vm0") , desc = c( "Max. Carboxylation") - , colour = c( "dodgerblue") + , colour = c( "#0072B2") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2596,8 +2652,9 @@ theme[[n]] = list( vnam = c( "vm0") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2606,7 +2663,7 @@ theme[[n]] = list( vnam = c( "vm0") n = n + 1 theme[[n]] = list( vnam = c( "sla") , desc = c( "Specific leaf area") - , colour = c( "forestgreen") + , colour = c( "#009E73") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2616,8 +2673,9 @@ theme[[n]] = list( vnam = c( "sla") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2626,7 +2684,7 @@ theme[[n]] = list( vnam = c( "sla") n = n + 1 theme[[n]] = list( vnam = c( "llspan") , desc = c( "Leaf longevity") - , colour = c( "purple2") + , colour = c( "#332288") , lwd = c( 2.5) , type = "o" , plog = FALSE @@ -2636,8 +2694,9 @@ theme[[n]] = list( vnam = c( "llspan") , legpos = "topleft" , emean = TRUE , mmean = TRUE - , qmean = TRUE + , qmean = FALSE , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -2650,9 +2709,9 @@ theme[[n]] = list( vnam = c( "veg.height", "can.depth" , desc = c( "Vegetation height", "Canopy depth" , "Displacement height","Vegetation Roughness" , "Net roughness") - , colour = c( "deepskyblue", "firebrick" - , "slateblue", "darkgoldenrod" - , "chartreuse3") + , colour = c( "#56B4E9", "#882255" + , "#332288", "#E69F00" + , "#009E73") , lwd = c(2.5,2.5,2.5,2.5,2.5) , type = "o" , plog = FALSE @@ -2664,6 +2723,157 @@ theme[[n]] = list( vnam = c( "veg.height", "can.depth" , mmean = TRUE , qmean = FALSE , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.intensity") + , desc = c( "Fire intensity") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.intensity" + , title = "Fire intensity" + , unit = untab$kwom + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.density") + , desc = c("Fire count density") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.density" + , title = "Fire count density" + , unit = untab$oneokm2 + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.ignition") + , desc = c( "Fire ignition") + , colour = c( "#882255") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.ignition" + , title = "Fire ignition rate" + , unit = untab$oneokm2omo + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c("fire.extinction") + , desc = c("Fire extinction") + , colour = c( "#0072B2") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.extinction" + , title = "Fire extinction rate" + , unit = untab$pcoday + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.spread") + , desc = c( "Fire spread") + , colour = c( "#332288") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.spread" + , title = "Fire spread rate" + , unit = untab$momin + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "fire.f.bherb", "fire.f.bwoody" + , "fire.f.fgc", "fire.f.stgc") + , desc = c( "Herbaceous", "Woody (live)" + , "Fine litter","Structural litter") + , colour = c( "#009E73", "#E69F00" + , "#56B4E9", "#332288") + , lwd = c(2.5,2.5,2.5,2.5) + , type = "o" + , plog = FALSE + , prefix = "fire.consumption" + , title = "Relative fuel consumption" + , unit = untab$pc + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE + , emean.lim = c(NA,NA) + , mmean.lim = c(NA,NA) + , qmean.lim = c(NA,NA) + , ymean.lim = c(NA,NA) + )#end list +n = n + 1 +theme[[n]] = list( vnam = c( "burnt.area") + , desc = c( "Burnt area") + , colour = c( "#D55E00") + , lwd = c(2.5) + , type = "o" + , plog = FALSE + , prefix = "burnt.area" + , title = "Burnt area" + , unit = untab$pc + , legpos = "topleft" + , emean = TRUE + , mmean = TRUE + , qmean = FALSE + , ymean = TRUE + , stack = FALSE , emean.lim = c(NA,NA) , mmean.lim = c(NA,NA) , qmean.lim = c(NA,NA) @@ -3220,7 +3430,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.water" , desc = "Soil moisture" , unit = untab$m3wom3 - , csch = "ipanoply" + , csch = "rdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE @@ -3231,7 +3441,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.temp" , desc = "Soil temperature" , unit = untab$degC - , csch = "panoply" + , csch = "irdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE @@ -3242,7 +3452,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.mstpot" , desc = "(Negative) Soil moisture potential" , unit = untab$mpa - , csch = "panoply" + , csch = "irdbu" , pnlog = TRUE , mmean = TRUE , emean = TRUE @@ -3253,7 +3463,7 @@ n = n + 1 soilplot[[n]] = list( vnam = "soil.extracted" , desc = "Water extraction by plants" , unit = untab$kgwom3oday - , csch = "ipanoply" + , csch = "rdbu" , pnlog = FALSE , mmean = TRUE , emean = TRUE diff --git a/R-utils/polar.periodogram.r b/R-utils/polar.periodogram.r index 5e9494d6b..69f8efae3 100644 --- a/R-utils/polar.periodogram.r +++ b/R-utils/polar.periodogram.r @@ -55,7 +55,7 @@ polar.periodogram <<- function( X nn = ncol (X) FF = fft(Xp) / mm / nn II = abs(FF) * abs(FF) * mm * nn - sig2 = var(c(X)) + sig2 = var(c(Xp),na.rm=TRUE) #---------------------------------------------------------------------------------------# @@ -113,25 +113,28 @@ polar.periodogram <<- function( X #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # Find the variance of the retained spectrum. # + #---------------------------------------------------------------------------------------# + sig2p = sum(II.keep) + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Decide how to aggregate data. # #---------------------------------------------------------------------------------------# if (which.bin %in% "radius"){ m.II = tapply(X=II.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=R.cut,FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% c("theta","angle")){ m.II = tapply(X=II.keep,INDEX=TH.cut,FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=TH.cut,FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% "both"){ m.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + ans = m.II / sig2p }else if (which.bin %in% "length"){ - m.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=mean,na.rm=TRUE) - s.II = tapply(X=II.keep,INDEX=list(R.cut,TH.cut),FUN=sd ,na.rm=TRUE) - ans = m.II / s.II + m.II = tapply(X=II.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) + ans = m.II / sig2p len = tapply(X=LL.keep,INDEX=R.cut,FUN=mean,na.rm=TRUE) names(ans) = len }else if (which.bin %in% "none"){ @@ -148,3 +151,58 @@ polar.periodogram <<- function( X }#end polar.periodogram #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# This function is a wrapper for the FOTO package, when using matrices as opposed to # +# rasters. It internally creates a raster that is then sent to the package function. This # +# copies part of the steps in the function "foto" because the package by default applies # +# the principal component analysis and this is done separately. # +#------------------------------------------------------------------------------------------# +foto.periodogram <<- function(X){ + #------ Create a temporary raster to send to the FOTO function. ------------------------# + myenv = environment() + nx = nrow(X) + ny = ncol(X) + yswap = rev(sequence(ny)) + Xt = t(X[,yswap]) + img = raster(Xt) + wsize = min(nx,ny)/1 + N = ceiling(img@nrows/wsize) + M = ceiling(img@ncols/wsize) + cells = N * M + #---------------------------------------------------------------------------------------# + + + + #------ Run the FOTO function for this raster. Single window using the entire image. ---# + Imat = matrix(img,wsize,wsize) + fftim = Mod(stats::fft(Imat))^2 + offfft = ceiling(dim(Imat)[1]/2) + r = sqrt((col(Imat) - offfft)^2 + (row(Imat) - offfft)^2) + rzonal = raster::zonal( x = raster::raster(fftim) + , z = raster::raster(r) + , fun = "mean" + , na.rm = TRUE + )#end raster::zonal + rspec = rev(rzonal[, 2]) + names(rspec) = rev(rzonal[, 1]) + sigma = sd(Imat,na.rm=TRUE) + rscal = rspec / sigma + + iuse = rev(sequence(wsize/2)[-c(1,2)]) + ans = rscal[iuse] + #---------------------------------------------------------------------------------------# + + + #----- Return answer. ------------------------------------------------------------------# + return(ans) + #---------------------------------------------------------------------------------------# +}#end foto.periodogram +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/poly.clockwise.r b/R-utils/poly.clockwise.r index 7a44bb09f..159008649 100644 --- a/R-utils/poly.clockwise.r +++ b/R-utils/poly.clockwise.r @@ -19,11 +19,11 @@ poly.clockwise <<- function(x,y=NULL){ #------ Make sure this is a closed path. -----------------------------------------------# nxy = length(x) - if (! ( x[1] %==% x[nxy] && y[1] %==% y[nxy] ) ){ + if (! ( x[1] %eq% x[nxy] && y[1] %eq% y[nxy] ) ){ x = c(x,x[1]) y = c(y,y[1]) nxy = nxy + 1 - }#end if (! ( x[1] %==% x[nxy] && y[1] %==% y[nxy] ) ) + }#end if (! ( x[1] %eq% x[nxy] && y[1] %eq% y[nxy] ) ) #---------------------------------------------------------------------------------------# diff --git a/R-utils/pop.interp.r b/R-utils/pop.interp.r index dd2f6d38d..4ffbb49a1 100644 --- a/R-utils/pop.interp.r +++ b/R-utils/pop.interp.r @@ -33,7 +33,7 @@ pop.interp <<- function( p #---------------------------------------------------------------------------------------# #----- For the prediction step, we only keep entries with actual population. -----------# - keep = p %>% 0 + keep = p %gt% 0 #---------------------------------------------------------------------------------------# diff --git a/R-utils/pop.loess.r b/R-utils/pop.loess.r index e19259ae4..baeec7333 100644 --- a/R-utils/pop.loess.r +++ b/R-utils/pop.loess.r @@ -16,7 +16,7 @@ pop.loess <<- function(p,z=seq_along(p),pfill=1e-6,zinf=1.25*max(z),...){ #---------------------------------------------------------------------------------------# #----- For the prediction step, we only keep entries with actual population. -----------# - keep = p %>% 0 + keep = p %gt% 0 #---------------------------------------------------------------------------------------# diff --git a/R-utils/pretty.log.r b/R-utils/pretty.log.r index 7c8e0770d..aa8f91997 100644 --- a/R-utils/pretty.log.r +++ b/R-utils/pretty.log.r @@ -14,15 +14,15 @@ pretty.log = function(x,base=10,n=5,forcelog=FALSE){ # gives a more legible scale. # #---------------------------------------------------------------------------------------# if (base == 10 && dlog.neat %wr% c(0.1,0.5) && (! forcelog)){ - sel = abs(log.neat - as.integer(log.neat)) %<% (0.5 * dlog.neat) + sel = abs(log.neat - as.integer(log.neat)) %lt% (0.5 * dlog.neat) tens = sort(c(neat[sel],base^(c(floor(min(log.neat)),ceiling(max(log.neat)))))) #------------------------------------------------------------------------------------# # Fix scale so it looks nicer if dtens is 2 or 3. # #------------------------------------------------------------------------------------# - if (dlog.neat %<% 0.15){ + if (dlog.neat %lt% 0.15){ mult = c(1,2,3,5,7) - }else if (dlog.neat %<% 0.35){ + }else if (dlog.neat %lt% 0.35){ mult = c(1,2,5) }else{ mult = c(1,3) @@ -33,7 +33,7 @@ pretty.log = function(x,base=10,n=5,forcelog=FALSE){ vlevels = vlevels[aa:zz] still.log = TRUE #------------------------------------------------------------------------------------# - }else if(dlog.neat %<% 0.1 && (! forcelog)){ + }else if(dlog.neat %lt% 0.1 && (! forcelog)){ #----- The plot is hardly log, use normal units instead. ---------------------------# vlevels = pretty(x=x,n=n) still.log = FALSE diff --git a/R-utils/pretty.time.r b/R-utils/pretty.time.r index 05e1aab3e..56dec6c3b 100644 --- a/R-utils/pretty.time.r +++ b/R-utils/pretty.time.r @@ -327,21 +327,21 @@ pretty.elapsed <<- function(x,base,n=5,...){ #---------------------------------------------------------------------------------------# # Re-scale data based on the pretty limits. # #---------------------------------------------------------------------------------------# - if (diff.base %<=% 0.075 || diff.base %>=% 0.75){ + if (diff.base %le% 0.075 || diff.base %ge% 0.75){ dbase = diff.base * base - }else if (diff.base %<% 0.15){ + }else if (diff.base %lt% 0.15){ if (base == 30){ dbase = base / 15 }else{ dbase = base / 12 }#end if (base == 30) - }else if (diff.base %<% 0.35){ + }else if (diff.base %lt% 0.35){ if (base == 30){ dbase = base / 6 }else{ dbase = base / 4 }#end if (base == 30) - }else if (diff.base %<% 0.50){ + }else if (diff.base %lt% 0.50){ dbase = base / 3 }else{ dbase = base / 2 diff --git a/R-utils/pretty.xylim.r b/R-utils/pretty.xylim.r index 3140e148f..e6f942136 100644 --- a/R-utils/pretty.xylim.r +++ b/R-utils/pretty.xylim.r @@ -36,7 +36,7 @@ pretty.xylim <<- function(u,fracexp=0.00,is.log=FALSE){ #----- Select the data that we consider for the range. ---------------------------------# vec.u = c(u) - if (is.log) vec.u[! (vec.u %>% 0)] = NA + if (is.log) vec.u[! (vec.u %gt% 0)] = NA ulimit = range(vec.u,finite=TRUE) #---------------------------------------------------------------------------------------# diff --git a/R-utils/ptcloud.2.patch.r b/R-utils/ptcloud.2.patch.r index b9610a17f..1e135a436 100644 --- a/R-utils/ptcloud.2.patch.r +++ b/R-utils/ptcloud.2.patch.r @@ -284,8 +284,8 @@ ptcloud.2.patch <<- function( pt.cloud hgt.cutoff = dbh2h(dbh=dbh0.min ,ipft=pft.def) hgt.bottom = hgt.cutoff }#end if (cstep %in% "calibration") - k.sel = which(hgtprof[ipk] %>=% hgt.cutoff) - k.bot = which(hgtprof[ipk] %>=% hgt.bottom) + k.sel = which(hgtprof[ipk] %ge% hgt.cutoff) + k.bot = which(hgtprof[ipk] %ge% hgt.bottom) #---------------------------------------------------------------------------------# @@ -305,15 +305,15 @@ ptcloud.2.patch <<- function( pt.cloud }else if (length(k.sel) == 0){ #----- Tallest cohort is outside range of DBH. Don't constrain. --------------# k.idx = ibnd[max(k.bot) + 1] - sel = hgtprof %>=% hgtprof[k.idx] + sel = hgtprof %ge% hgtprof[k.idx] bel = sel #------------------------------------------------------------------------------# }else{ #----- Keep only cohorts whose peak is above minimum DBH. ---------------------# k.idx = ibnd[max(k.sel) + 1] b.idx = ibnd[max(k.bot) + 1] - sel = hgtprof %>=% hgtprof[k.idx] - bel = hgtprof %>=% hgtprof[b.idx] + sel = hgtprof %ge% hgtprof[k.idx] + bel = hgtprof %ge% hgtprof[b.idx] #------------------------------------------------------------------------------# }#end if ((length(k.sel) == 0) && (length(k.bot) == 0)) #---------------------------------------------------------------------------------# @@ -341,7 +341,7 @@ ptcloud.2.patch <<- function( pt.cloud #------ Selected data. --------------------------------------------------------# ulai = sapply(X=c.ulai,FUN=sum ) uipk = sapply(X=c.uipk,FUN=commonest) - keep = ulai %>% 0. + keep = ulai %gt% 0. if (any(keep)){ ulai = c(ulai [keep],0) uipk = uipk [keep] @@ -360,7 +360,7 @@ ptcloud.2.patch <<- function( pt.cloud #------ Total data. -----------------------------------------------------------# blai = sapply(X=b.ulai,FUN=sum ) bipk = sapply(X=b.uipk,FUN=commonest) - beep = blai %>% 0. + beep = blai %gt% 0. if (any(beep)){ blai = c(blai [beep],0) bipk = bipk [beep] @@ -472,7 +472,7 @@ ptcloud.2.patch <<- function( pt.cloud ipft.bft = rep(mypfts , each = bcoh ) + 0L * bpft wdns.bft = rep(pft$rho[mypfts], each = bcoh ) + 0. * bpft sla.bft = rep(pft$SLA[mypfts], each = bcoh ) + 0. * bpft - bleaf.bft = ( size2bl(dbh=dbh.bft,hgt=hgt.bft,sla=sla.pft,ipft=ipft.bft) + bleaf.bft = ( size2bl(dbh=dbh.bft,hgt=hgt.bft,sla=sla.bft,ipft=ipft.bft) + 0. * bpft )#end bleaf.bft bdead.bft = size2bd(dbh=dbh.bft,hgt=hgt.bft,ipft=ipft.bft) + 0. * bpft @@ -603,7 +603,7 @@ ptcloud.2.patch <<- function( pt.cloud #----- Check for degenerate solution. -----------------------------------------# - suspicious = (sum(lai.pft*f.net) %>% 12) + suspicious = (sum(lai.pft*f.net) %gt% 12) #------------------------------------------------------------------------------# @@ -613,11 +613,11 @@ ptcloud.2.patch <<- function( pt.cloud # This indicates that most of the returns are coming from below the # # calibration layer (DBH > 10cm) so it is really unconstrained. # #------------------------------------------------------------------------------# - x.bsa = (f.bsa %>=% f.max.oth) && (b.bsa %<=% b.min.oth) - x.lai = (f.lai %>=% f.max.oth) && (b.lai %<=% b.min.oth) - x.agb = (f.agb %>=% f.max.oth) && (b.agb %<=% b.min.oth) - x.npl = (f.npl %>=% f.max.npl) && (b.npl %<=% b.min.npl) - x.net = (f.net %>=% f.max.oth) && (b.net %<=% b.min.oth) + x.bsa = (f.bsa %ge% f.max.oth) && (b.bsa %le% b.min.oth) + x.lai = (f.lai %ge% f.max.oth) && (b.lai %le% b.min.oth) + x.agb = (f.agb %ge% f.max.oth) && (b.agb %le% b.min.oth) + x.npl = (f.npl %ge% f.max.npl) && (b.npl %le% b.min.npl) + x.net = (f.net %ge% f.max.oth) && (b.net %le% b.min.oth) x.any = x.npl || x.bsa || x.lai || x.agb || x.net f.bsa = ifelse(test=x.any,yes=f.net.def,no=f.bsa) f.lai = ifelse(test=x.any,yes=f.net.def,no=f.lai) @@ -724,7 +724,7 @@ ptcloud.2.patch <<- function( pt.cloud #----- Check for degenerate solution. -----------------------------------------# - suspicious = suspicious || (pssnow$lai %>% 12) + suspicious = suspicious || (pssnow$lai %gt% 12) if (suspicious){ if (nidx > 0){ #----- Aggregate information of the suspicious patch. -------------------# @@ -737,7 +737,7 @@ ptcloud.2.patch <<- function( pt.cloud + css.agf * ( css.bsap + css.bbark + cssnow$bdead ) )#end css.agb css.bsa = 0.25 * pi * cssnow$dbh * cssnow$dbh - css.use = cssnow$dbh %>=% 10.0 + css.use = cssnow$dbh %ge% 10.0 npl.show = 10000. * sum(cssnow$n[css.use]) lai.show = sum(cssnow$lai) agb.show = sum(cssnow$n[css.use]*css.agb[css.use]) diff --git a/R-utils/qapply.r b/R-utils/qapply.r index b05ceca20..b9606058a 100644 --- a/R-utils/qapply.r +++ b/R-utils/qapply.r @@ -8,6 +8,15 @@ #------------------------------------------------------------------------------------------# qapply <<- function(X,INDEX,DIM,FUN,...){ + #---------------------------------------------------------------------------------------# + # Find out whether X is a data frame. If so, we return the same variable types and # + # names. # + #---------------------------------------------------------------------------------------# + X.df = is.data.frame(X) + if (missing(DIM) && X.df) DIM = 1 + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Find the number of dimensions. # #---------------------------------------------------------------------------------------# @@ -86,6 +95,18 @@ qapply <<- function(X,INDEX,DIM,FUN,...){ }#end if #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # If the original data was a data frame and DIM was 1 (or missing), make sure the # + # output is also a data frame. # + #---------------------------------------------------------------------------------------# + if (X.df && (DIM == 1)){ + eout = as.data.frame(eout) + names(eout) = names(X) + }#end if (X.df && (DIM == 1)) + #---------------------------------------------------------------------------------------# + + return(eout) }#end function qapply #==========================================================================================# diff --git a/R-utils/radiation_profile_utils.r b/R-utils/radiation_profile_utils.r index 28322c49d..d908a12c9 100644 --- a/R-utils/radiation_profile_utils.r +++ b/R-utils/radiation_profile_utils.r @@ -74,7 +74,7 @@ layer.absorption <<- function(ipaco,down,up){ rel.last <<- function(x){ if (length(x) == 0){ ans = NA - }else if (x[1] %==% 0){ + }else if (x[1] %eq% 0){ ans = NA }else{ ans = x[length(x)] /x[1] diff --git a/R-utils/rain.downscale.r b/R-utils/rain.downscale.r index 3b538417c..47092c4cc 100644 --- a/R-utils/rain.downscale.r +++ b/R-utils/rain.downscale.r @@ -63,7 +63,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 #----- Find the ratio following Ryan's thesis. -----------------------------------------# - g.mu.lut = ifelse(test=g.rho.lut %>% 0,yes=g.rbar.lut/g.rho.lut,no=0.) + g.mu.lut = ifelse(test=g.rho.lut %gt% 0,yes=g.rbar.lut/g.rho.lut,no=0.) #---------------------------------------------------------------------------------------# @@ -72,7 +72,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 mu.in = mu.in.lut [idx] g.rbar = g.rbar.lut[idx] g.mu = g.mu.lut [idx] - sg.mu = ifelse(test = g.mu %>% 0., yes = mu.in / g.mu, no = 0.) + sg.mu = ifelse(test = g.mu %gt% 0., yes = mu.in / g.mu, no = 0.) #---------------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 SG.MU = matrix( data = sg.mu , nrow = ndat.in, ncol = nsub) G.RBAR = matrix( data = g.rbar , nrow = ndat.in, ncol = nsub) PRATE.IN = matrix( data = prate.in, nrow = ndat.in, ncol = nsub) - WGT.OUT = ifelse( test = SG.MU %>% 0. & PRATE.IN %>% 0. + WGT.OUT = ifelse( test = SG.MU %gt% 0. & PRATE.IN %gt% 0. , yes = PRATE.IN / SG.MU * log(1.0/(1.0 - CDF.MAT)) , no = 1 / nsub )#end ifelse @@ -126,21 +126,21 @@ rain.downscale <<- function(lon,when.in,prate.in,mu.in.lut,nsub,rain.min=0.2/360 #---------------------------------------------------------------------------------------# if (mask.low){ ptotal.out = sum(prate.out) - prate.mask = ifelse(prate.out %>=% rain.min, prate.out, 0.) + prate.mask = ifelse(prate.out %ge% rain.min, prate.out, 0.) ptotal.mask = sum(prate.mask) - if (ptotal.mask %>=% rain.min){ + if (ptotal.mask %ge% rain.min){ prate.out = prate.mask * ptotal.out / ptotal.mask - }#end if (ptotal.mask %>=% rain.min) + }#end if (ptotal.mask %ge% rain.min) }#end if (mask.low) #---------------------------------------------------------------------------------------# #------ Make sure the average output rainfall matches the average input rainfall. ------# prate.out.bar = mean(prate.out,na.rm=TRUE) - if (prate.out.bar %>=% rain.min){ + if (prate.out.bar %ge% rain.min){ prate.in.bar = mean(prate.in,na.rm=TRUE) prate.out = prate.out * prate.in.bar / prate.out.bar - }#end if (prate.out.bar %>=% rain.min) + }#end if (prate.out.bar %ge% rain.min) #---------------------------------------------------------------------------------------# return(prate.out) diff --git a/R-utils/rconstants.r b/R-utils/rconstants.r index b1f65e8a0..478f76792 100644 --- a/R-utils/rconstants.r +++ b/R-utils/rconstants.r @@ -38,6 +38,7 @@ golden <<- 0.5*(1+sqrt(5.)) # Golden ratio [ #------------------------------------------------------------------------------------------# stefan <<- 5.6696e-8 # Stefan-Boltzmann constant [ W/m2/K4] boltzmann <<- 1.3806503e-23 # Boltzmann constant [m2 kg/s2/K] +astro <<- 149597870700 # One astronomical unit (as of 2012) [ m] t00 <<- 273.15 # 0 degC [ degC] rmol <<- 8.314510 # Molar gas constant [ J/mol/K] volmol <<- 0.022710980 # Molar volume at STP [ m3] @@ -46,6 +47,38 @@ clight <<- 299792458 # Speed of light [ #------------------------------------------------------------------------------------------# + +#------------------------------------------------------------------------------------------# +# General Earth properties # +#------------------------------------------------------------------------------------------# +vonk <<- 0.40 # Von Karman constant [ ---] +grav <<- 9.80665 # Gravity acceleration [ m/s2] +gg <<- .5 * grav # Half of grav [ m/s2] +erad <<- 6370997. # Earth radius [ m] +sunrad <<- 695508000. # Sun radius [ m] +spcon <<- pio180*erad # One degree of latitude [ m] +spconkm <<- spcon*0.001 # One degree of latitude [ km] +eradi <<- 1./erad # Inverse of Earth radius [ 1/m] +erad2 <<- erad*2 # Earth diameter [ m] +eprjarea <<- pi*erad^2 # Earth's projected area [ m2] +ausphere <<- 4*pi*astro^2 # Sphere area for one astronomical unit [ m2] +ehgt <<- 8500. # Earth's scale height (~ RT/g) [ m] +esolid <<- pi*sunrad^2/astro^2 # Solar angle of Earth's interception [ sr] +ss60 <<- 1.8663 # Polar stereo conversion to 60 deg [ ] +omega <<- 7.292e-5 # Earth's rotation speed [ rad/s] +viscos <<- .15e-4 # Viscosity coefficient [ ] +tsun <<- 5778 # Sun temperature [ K] +radsol <<- stefan*tsun^4/pi # Extraterrestrial solar irradiance [ W/m2] +solar <<- radsol*esolid # Solar constant [ W/m2] +p00 <<- 1.e5 # Reference pressure [ Pa] +prefsea <<- 101325. # Reference sea level pressure [ Pa] +p00i <<- 1. / p00 # 1/p00 [ 1/Pa] +o2.ref <<- 0.209 # Nominal O2 concentration [ mol/mol] +capri <<- -23.44 * pio180 # Tropic of Capricornium latitude [ rad] +shsummer <<- -10 # Day of year of S.Hemisphere summer solstice [ day] +#------------------------------------------------------------------------------------------# + + #------------------------------------------------------------------------------------------# # Molar masses and derived variables # #------------------------------------------------------------------------------------------# @@ -64,46 +97,112 @@ mmh2oi <<- 1./mmh2o # 1./mmh2o [ #------------------------------------------------------------------------------------------# -# Time conversion units # +# Conversion factors for time units. # #------------------------------------------------------------------------------------------# -yr.day <<- 365.2425 # # of days in a year [ day/yr] -yr.ftnight <<- 26 # # of fornights in a year [ftnight/yr] -yr.mon <<- 12 # # of months in a year [ mon/yr] -day.sec <<- 86400. # # of seconds in a day [ s/day] -day.sec2 <<- day.sec^2 # # Square of day.sec [ s2/day2] -day.mon <<- yr.day/yr.mon # # of days in a month [ day/mon] -day.min <<- 1440. # # of minutes in a day [ min/day] -day.hr <<- 24. # # of hours in a day [ hr/day] -hr.sec <<- 3600. # # of seconds in an hour [ s/hr] -hr.min <<- 60. # # of minutes in an hour [ min/hr] -min.sec <<- 60. # # of seconds in a minute [ s/min] -yr.sec <<- yr.day * day.sec # # of seconds in a year [ s/yr] -kg2g <<- 1000. # # of grams in a kilogram [ g/kg] +min.sec <<- 60. # # of seconds in a minute [ s/min] +hr.min <<- 60. # # of minutes in an hour [ min/hr] +day.hr <<- 24. # # of hours in a day [ hr/day] +day.week <<- 7. # # of days in a week [ day/wk] +yr.day <<- 365.2425 # # of days in a year [ day/yr] +yr.ftnight <<- 26 # # of fortnights in a year [ftnight/yr] +yr.mon <<- 12 # # of months in a year [ mon/yr] +#----- Derived quantities. ----------------------------------------------------------------# +hr.sec <<- hr.min * min.sec # # of seconds in an hour [ s/hr] +day.min <<- day.hr * hr.min # # of minutes in a day [ min/day] +day.sec <<- day.hr * hr.sec # # of seconds in a day [ s/day] +day.sec2 <<- day.sec^2 # # Square of day.sec [ s2/day2] +day.mon <<- yr.day/yr.mon # # of days in a month [ day/mon] +yr.sec <<- yr.day * day.sec # # of seconds in a year [ s/yr] +yr.week <<- yr.day / day.week # # of weeks in a year [ wk/yr] #------------------------------------------------------------------------------------------# #------------------------------------------------------------------------------------------# -# General Earth properties # +# Conversion factors for mass units. # #------------------------------------------------------------------------------------------# -vonk <<- 0.40 # Von Karman constant [ ---] -grav <<- 9.80665 # Gravity acceleration [ m/s2] -gg <<- .5 * grav # Half of grav [ m/s2] -erad <<- 6370997. # Earth radius [ m] -spcon <<- pio180*erad # One degree of latitude [ m] -spconkm <<- spcon*0.001 # One degree of latitude [ km] -eradi <<- 1./erad # Inverse of Earth radius [ 1/m] -erad2 <<- erad*2 # Earth diameter [ m] -ss60 <<- 1.8663 # Polar stereo conversion to 60 deg [ ] -omega <<- 7.292e-5 # Earth's rotation speed [ rad/s] -viscos <<- .15e-4 # Viscosity coefficient [ ] -solar <<- 1.3533e3 # Solar constant [ W/m2] -p00 <<- 1.e5 # Reference pressure [ Pa] -prefsea <<- 101325. # Reference sea level pressure [ Pa] -p00i <<- 1. / p00 # 1/p00 [ 1/Pa] -o2.ref <<- 0.209 # Nominal O2 concentration [ mol/mol] -capri <<- -23.44 * pio180 # Tropic of Capricornium latitude [ rad] -shsummer <<- -10 # Day of year of S.Hemisphere summer solstice [ day] +kg2g <<- 1000. # # of grams in a kilogram [ g/kg] +g2kg <<- 1. / kg2g # # of kilograms in a gram [ kg/g] +g2mg <<- 1000. # # of milligrams in a gram [ mg/g] +mg2g <<- 1. / g2mg # # of grams in a milligram [ g/mg] +mg2ug <<- 1000. # # of micrograms in a milligram [ ug/mg] +ug2mg <<- 1. / mg2ug # # of milligrams in a microgram [ mg/ug] +kg2mg <<- kg2g * g2mg # # of milligrams in a kilogram [ mg/kg] +mg2kg <<- 1. / kg2g # # of kilograms in a milligram [ kg/mg] +#------------------------------------------------------------------------------------------# + + + +#------------------------------------------------------------------------------------------# +# Miscellaneous convertion factors. # +#------------------------------------------------------------------------------------------# +mol.2.mmol <<- 1.e3 # mol => mmol +mmol.2.mol <<- 1. / mol.2.mmol # mmol => mol +mol.2.umol <<- 1.e6 # mol => umol +umol.2.mol <<- 1. / mol.2.umol # umol => mol +umol.2.mmol <<- umol.2.mol * mol.2.mmol # umol => mmol +mmol.2.umol <<- 1. / umol.2.mmol # umol => mmol +umol.2.kgC <<- 1.20107e-8 # umol(CO2) => kg(C) +Watts.2.Ein <<- 4.6e-6 # W/m2 => mol/m2/s +Ein.2.Watts <<- 1./Watts.2.Ein # mol/m2/s => W/m2 +kgC.2.umol <<- 1. / umol.2.kgC # kg(C) => umol(CO2) +kgom2.2.tonoha <<- 10. # kg(C)/m2 => ton(C)/ha +tonoha.2.kgom2 <<- 0.1 # ton(C)/ha => kg(C)/m2 +umols.2.kgCyr <<- umol.2.kgC * yr.sec # umol(CO2)/s => kg(C)/yr +umols.2.kgWday <<- umol.2.mol*mmh2o*day.sec # umol (H2O)/s => kg (H2O) / day +mols.2.kgCyr <<- mol.2.umol * umols.2.kgCyr # umol(CO2)/s => kg(C)/yr +mols.2.kgWday <<- mol.2.umol * umols.2.kgWday # umol (H2O)/s => kg (H2O) / day +kgCyr.2.umols <<- 1. / umols.2.kgCyr # kg(C)/yr => umol(CO2)/s +kgCday.2.umols <<- kgC.2.umol / day.sec # kg(C)/day => umol(CO2)/s +kgWday.2.umols <<- 1. / umols.2.kgWday # kg (H2O) / day => umol (H2O)/s +Torr.2.Pa <<- prefsea / 760. # Torr => Pa +Pa.2.Torr <<- 1. / Torr.2.Pa # Pa => Torr +hPa.2.Pa <<- 100. # hPa => Pa +Pa.2.hPa <<- 1. / hPa.2.Pa # Pa => hPa +kPa.2.Pa <<- 1000. # kPa => Pa +Pa.2.kPa <<- 1. / kPa.2.Pa # Pa => kPa +kPa.2.hPa <<- kPa.2.Pa * Pa.2.hPa # kPa => hPa +hPa.2.kPa <<- 1. / kPa.2.hPa # hPa => kPa +MPa.2.Pa <<- 1.e6 # MPa => Pa +Pa.2.MPa <<- 1. / MPa.2.Pa # Pa => MPa +kt.2.mos <<- 1852 / hr.sec # knots => m/s +mos.2.kt <<- 1. / kt.2.mos # m/s => knots +frac2pc <<- 100. # fraction => percent +pc2frac <<- 1. / frac2pc # percent => fraction +cm.2.m <<- 0.01 # cm => m +m.2.cm <<- 1. / cm.2.m # m => cm +mm.2.m <<- 0.001 # mm => m +m.2.mm <<- 1. / mm.2.m # m => mm +dm.2.cm <<- 10. # mm => dm +cm.2.dm <<- 1. / dm.2.cm # dm => mm +mm.2.cm <<- 0.1 # mm => cm +cm.2.mm <<- 1. / mm.2.cm # cm => mm +um.2.mm <<- 0.001 # um => mm +mm.2.um <<- 1. / um.2.mm # mm => um +um.2.cm <<- um.2.mm * mm.2.cm # um => cm +cm.2.um <<- 1. / um.2.mm # cm => um +in.2.cm <<- 2.54 # in => cm +cm.2.in <<- 1. / in.2.cm # cm => in +in.2.m <<- in.2.cm * cm.2.m # in => m +m.2.in <<- 1. / in.2.m # m => in +ft.2.cm <<- 30.48 # ft => cm +cm.2.ft <<- 1. / ft.2.cm # cm => ft +ft.2.m <<- ft.2.cm * cm.2.m # ft => m +m.2.ft <<- 1. / ft.2.m # m => ft +ha.2.m2 <<- 10000. # hectare => m2 +m2.2.ha <<- 1./ha.2.m2 # m2 => hectare +m2.2.cm2 <<- m.2.cm^2 # cm2 => m2 +cm2.2.m2 <<- 1./m2.2.cm2 # m2 => cm2 +cm2.2.mm2 <<- cm.2.mm^2 # cm2 => mm2 +mm2.2.cm2 <<- 1./cm2.2.mm2 # mm2 => cm2 +m2.2.mm2 <<- m2.2.cm2 * cm2.2.mm2 # m2 => mm2 +mm2.2.m2 <<- 1. / m2.2.mm2 # mm2 => m2 +MJ.2.J <<- 1.e6 # MJ => J +J.2.MJ <<- 1./MJ.2.J # J => MJ +kJ.2.J <<- 1000. # kJ => J +J.2.kJ <<- 1./kJ.2.J # J => kJ +W.2.MJoday <<- J.2.MJ * day.sec # W (J/s) => MJ/day +MJoday.2.W <<- 1. / W.2.MJoday # MJ/day => W (J/s) #------------------------------------------------------------------------------------------# @@ -192,6 +291,20 @@ cliqi <<- 1./cliq # Inverse of water heat capacity +#------------------------------------------------------------------------------------------# +# Soil matric potential unit conversion. # +#------------------------------------------------------------------------------------------# +m.2.mpa <<- grav * wdns * 1.e-6 # Matric potential convesion [ mPa/m] +mpa.2.m <<- 1. / m.2.mpa # Matric potential convesion [ m/mPa] +mm.2.mpa <<- grav * wdns * 1.e-9 # Matric potential convesion [ mPa/mm] +mpa.2.mm <<- 1. / mm.2.mpa # Matric potential convesion [ mm/mPa] +um.2.mpa <<- grav * wdns * 1.e-12 # Matric potential convesion [ mPa/um] +mpa.2.um <<- 1. / um.2.mpa # Matric potential convesion [ um/mPa] +#------------------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------------------# # Ice properties # #------------------------------------------------------------------------------------------# @@ -278,26 +391,6 @@ htripoli <<- cpdry*ttripoli # Sensible enthalpy at T=Ttr htripolii <<- 1./htripoli # 1./htripoli [ kg/J] #------------------------------------------------------------------------------------------# -#------------------------------------------------------------------------------------------# -# Unit conversion, it must be defined locally even for coupled runs. # -#------------------------------------------------------------------------------------------# -mol.2.umol <<- 1.e6 # mol => umol -umol.2.mol <<- 1.e-6 # umol => mol -umol.2.kgC <<- 1.20107e-8 # umol(CO2) => kg(C) -Watts.2.Ein <<- 4.6e-6 # W/m2 => mol/m2/s -Ein.2.Watts <<- 1./Watts.2.Ein # mol/m2/s => W/m2 -kgC.2.umol <<- 1. / umol.2.kgC # kg(C) => umol(CO2) -kgom2.2.tonoha <<- 10. # kg(C)/m2 => ton(C)/ha -tonoha.2.kgom2 <<- 0.1 # ton(C)/ha => kg(C)/m2 -umols.2.kgCyr <<- umol.2.kgC * yr.sec # umol(CO2)/s => kg(C)/yr -kgCyr.2.umols <<- 1. / umols.2.kgCyr # kg(C)/yr => umol(CO2)/s -kgCday.2.umols <<- kgC.2.umol / day.sec # kg(C)/day => umol(CO2)/s -Torr.2.Pa <<- prefsea / 760. # Torr => Pa -Pa.2.Torr <<- 1. / Torr.2.Pa # Pa => Torr -kt.2.mos <<- 1852 / hr.sec # knots => m/s -mos.2.kt <<- 1. / kt.2.mos # m/s => knots -#------------------------------------------------------------------------------------------# - #------------------------------------------------------------------------------------------# @@ -354,8 +447,14 @@ almost.one <<- 1.-almost.zero #------------------------------------------------------------------------------------------# # Default NA for chron objects. # #------------------------------------------------------------------------------------------# -NA_dates_ <<- chron(dates=NA) -NA_times_ <<- chron(times=NA) -NA_chron_ <<- chron(dates=NA,times=NA) +if ("chron" %in% rownames(installed.packages())){ + NA_dates_ <<- chron::chron(dates=NA) + NA_times_ <<- chron::chron(times=NA) + NA_chron_ <<- chron::chron(dates=NA,times=NA) +}#end if ("chron" %in% rownames(installed.packages())) +#------------------------------------------------------------------------------------------# + + +#---- Default NA for logical objects. -----------------------------------------------------# NA_logical_ <<- as.logical(NA) #------------------------------------------------------------------------------------------# diff --git a/R-utils/read.q.files.r b/R-utils/read.q.files.r index dfc756644..d586142ca 100644 --- a/R-utils/read.q.files.r +++ b/R-utils/read.q.files.r @@ -24,21 +24,17 @@ read.q.files <<- function( datum nzg = datum$nzg nzs = datum$nzs ndcycle = datum$ndcycle - isoilflg = datum$isoilflg slz = datum$slz slt = c(datum$slz[-1],0) - slxsand = datum$slxsand - slxclay = datum$slxclay - ntext = datum$ntext soil.prop = datum$soil.prop dslz = datum$dslz soil.depth = datum$soil.depth soil.dry = datum$soil.dry soil.poro = datum$soil.poro soilcp = datum$soil.prop$soilcp - slmsts = datum$soil.prop$slmsts - ka = datum$ka - kz = datum$kz + soilpo = datum$soil.prop$soilpo + kasi = datum$ka + kzsi = datum$kz #---------------------------------------------------------------------------------------# @@ -72,6 +68,7 @@ read.q.files <<- function( datum lu = datum$lu qmean = datum$qmean qmsqu = datum$qmsqu + site = datum$site patch = datum$patch qpatch = datum$qpatch cohort = datum$cohort @@ -110,15 +107,18 @@ read.q.files <<- function( datum h5file.bz2 = paste(datum$input[m],"bz2",sep=".") h5file.gz = paste(datum$input[m],"gz" ,sep=".") if (file.exists(h5file)){ + dummy = touch(h5file) mymont = hdf5load(file=h5file,load=FALSE,verbosity=0,tidy=TRUE) }else if(file.exists(h5file.bz2)){ + dummy = touch(h5file.bz2) temp.file = file.path(tempdir(),basename(h5file)) dummy = bunzip2(filename=h5file.bz2,destname=temp.file,remove=FALSE) mymont = hdf5load(file=temp.file,load=FALSE,verbosity=0,tidy=TRUE) dummy = file.remove(temp.file) }else if(file.exists(h5file.gz)){ + dummy = touch(h5file.gz) temp.file = file.path(tempdir(),basename(h5file)) dummy = gunzip(filename=h5file.gz,destname=temp.file,remove=FALSE) mymont = hdf5load(file=temp.file,load=FALSE,verbosity=0,tidy=TRUE) @@ -354,6 +354,21 @@ read.q.files <<- function( datum mymont$MMEAN.LLSPAN.CO = 12. / pft$leaf.turnover.rate[mymont$PFT] mymont$MMEAN.VM.BAR.CO = pft$vm0[mymont$PFT] }#end if (! "SLA" %in% names(mymont)) + #----- Patch-level mean diel for canopy temperature and density may be missing. -----# + if (mean(c(mymont$QMEAN.CAN.TEMP.PA)) %eq% 0.){ + mymont$QMEAN.CAN.EXNER.PA = press2exner ( pres = mymont$QMEAN.CAN.PRSS.PA ) + mymont$QMEAN.CAN.TEMP.PA = extheta2temp( exner = mymont$QMEAN.CAN.EXNER.PA + , theta = mymont$QMEAN.CAN.THETA.PA + )#end extheta2temp + mymont$QMEAN.CAN.RHOS.PA = idealdenssh ( pres = mymont$QMEAN.CAN.PRSS.PA + , temp = mymont$QMEAN.CAN.TEMP.PA + , qvpr = mymont$QMEAN.CAN.SHV.PA + )#end idealdenssh + mymont$QMEAN.CAN.DMOL.PA = idealdmolsh ( pres = mymont$QMEAN.CAN.PRSS.PA + , temp = mymont$QMEAN.CAN.TEMP.PA + , qvpr = mymont$QMEAN.CAN.SHV.PA + )#end idealdenssh + }#end if (mean(c(mymont$QMEAN.CAN.TEMP.PA)) %eq% 0.) #------------------------------------------------------------------------------------# @@ -365,6 +380,56 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# + #---- Read in the site-level area. --------------------------------------------------# + isi = sequence(mymont$NSITES.GLOBAL) + areasi = mymont$AREA.SI + nsites = mymont$PYSI.N + npatches = mymont$SIPA.N + nsites.tot = sum(nsites) + npatches.tot = sum(npatches) + #------------------------------------------------------------------------------------# + + + #----- Read a few patch-level variables. --------------------------------------------# + ntextsi = mymont$NTEXT.SOIL[,nzg] + ntextpa = rep(x=ntextsi,times=npatches) + areapa = mymont$AREA * rep(areasi,times=npatches) + areapa = areapa / sum(areapa) + isipa = rep(isi,times=npatches) + ipa = sequence(mymont$NPATCHES.GLOBAL) + lupa = mymont$DIST.TYPE + agepa = mymont$AGE + lslsi = mymont$LSL + lslpa = rep(x=lslsi,times=npatches) + kapa = rep(x=kasi ,times=npatches) + #------------------------------------------------------------------------------------# + + + #----- Create table for a few soil profile properties at patch level. ---------------# + dslz.pa = matrix(data=dslz ,nrow=npatches.tot,ncol=nzg,byrow=TRUE ) + soilcp.pa = matrix(data=soilcp[ntextpa],nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soilpo.pa = matrix(data=soilpo[ntextpa],nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.area = matrix(data=areapa ,nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.lsl = matrix(data=lslpa ,nrow=npatches.tot,ncol=nzg,byrow=FALSE) + soil.valid = as.numeric(col(soil.lsl) >= soil.lsl) + 0 * soil.lsl + soil.mask = ifelse(test=col(soil.lsl) >= soil.lsl,yes=1.,no=NA_real_) + 0 * soil.lsl + soil.area = apply(X=soil.area*soil.valid, MARGIN=2,FUN=reweight.valid) + #------------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------------# + # Weighting factors for top/bottom soil averages, which accounts for maximum # + # soil depth by site. # + #------------------------------------------------------------------------------------# + p.tt.wgtz = matrix(tt.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.tm.wgtz = matrix(tm.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.bm.wgtz = matrix(bm.wgtz,nrow=npatches.tot,ncol=nzg,byrow=TRUE) + p.tt.wgtz = t(apply(X=p.tt.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + p.tm.wgtz = t(apply(X=p.tm.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + p.bm.wgtz = t(apply(X=p.bm.wgtz*soil.valid,MARGIN=1,FUN=reweight.valid)) + #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# # Find the mean latent heat of vaporisation. Because we assume it to be a # @@ -448,6 +513,7 @@ read.q.files <<- function( datum emean$gnd.shv [m] = mymont$MMEAN.GND.SHV.PY * kg2g emean$leaf.temp [m] = mymont$MMEAN.LEAF.TEMP.PY - t00 emean$leaf.water [m] = mymont$MMEAN.LEAF.WATER.PY + emean$leaf.water.im2 [m] = mymont$MMEAN.LEAF.WATER.IM2.PY emean$leaf.vpd [m] = mymont$MMEAN.LEAF.VPDEF.PY * 0.01 emean$wood.temp [m] = mymont$MMEAN.WOOD.TEMP.PY - t00 emean$hflxca [m] = - mymont$MMEAN.SENSIBLE.AC.PY @@ -510,6 +576,26 @@ read.q.files <<- function( datum emean$leaf.gbw [m] = mymont$MMEAN.LEAF.GBW.PY * day.sec emean$leaf.gsw [m] = mymont$MMEAN.LEAF.GSW.PY * day.sec emean$wood.gbw [m] = mymont$MMEAN.WOOD.GBW.PY * day.sec + #----- Snowpack/flooding variables. -------------------------------------------------# + emean$sfcw.mass [m] = mymont$MMEAN.SFCW.MASS.PY + emean$sfcw.temp [m] = mymont$MMEAN.SFCW.TEMP.PY - t00 + emean$sfcw.fliq [m] = mymont$MMEAN.SFCW.FLIQ.PY + emean$sfcw.depth [m] = mymont$MMEAN.SFCW.DEPTH.PY + emean$sfcw.cover [m] = mymont$MMEAN.SNOWFAC.PY + #----- Fire variables. --------------------------------------------------------------# + emean$fire.density [m] = mymont$MMEAN.FIRE.DENSITY.PY * 1.e6 + emean$fire.intensity [m] = mymont$MMEAN.FIRE.INTENSITY.PY * 1.e-3 + emean$fire.ignition [m] = mymont$MMEAN.IGNITION.RATE.PY * 1.e6 * mondays * day.sec + emean$fire.extinction [m] = 100. * (1. - exp(-mymont$MMEAN.FIRE.EXTINCTION.PY)) + emean$fire.spread [m] = mymont$MMEAN.FIRE.SPREAD.PY * min.sec + emean$fire.tlethal [m] = mymont$MMEAN.FIRE.TLETHAL.PY / min.sec + emean$fire.f.bherb [m] = mymont$MMEAN.FIRE.F.BHERB.PY * 100. + emean$fire.f.bwoody [m] = mymont$MMEAN.FIRE.F.BWOODY.PY * 100. + emean$fire.f.fgc [m] = mymont$MMEAN.FIRE.F.FGC.PY * 100. + emean$fire.f.stgc [m] = mymont$MMEAN.FIRE.F.STGC.PY * 100. + emean$burnt.area [m] = weighted.mean( x = mymont$BURNT.AREA * 100. + , w = areasi + )#end weigthed.mean #------------------------------------------------------------------------------------# @@ -532,13 +618,51 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# + #------------------------------------------------------------------------------------# + # For soil properties, we must integrate across all patches, skipping layers # + # that were not solved by the model. This implies different weights across patches # + # for different layers (unused layers had weight set to zero). We do not set na.rm # + # to TRUE because we may have layers that were not resolved at all, and they shall # + # remain undefined. # + #------------------------------------------------------------------------------------# + soil.temp.lyr = apply( X = ( mymont$MMEAN.SOIL.TEMP.PA - t00 ) * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.water.lyr = apply( X = mymont$MMEAN.SOIL.WATER.PA * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.mstpot.lyr = apply( X = mymont$MMEAN.SOIL.MSTPOT.PA * soil.area + * (-1.) * grav * wdns * 1.e-6 + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.extracted.lyr = apply( X = mymont$MMEAN.TRANSLOSS.PA * soil.area / dslz.pa + * day.sec + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.wetness.lyr = ( ( mymont$MMEAN.SOIL.WATER.PA - soilcp.pa) + / ( soilpo.pa - soilcp.pa) ) + soil.wetness.lyr = apply( X = soil.wetness.lyr * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + #------------------------------------------------------------------------------------# + #------ Read in soil properties. ----------------------------------------------------# - emean$soil.temp [m,] = mymont$MMEAN.SOIL.TEMP.PY - t00 - emean$soil.water [m,] = mymont$MMEAN.SOIL.WATER.PY - emean$soil.mstpot [m,] = - mymont$MMEAN.SOIL.MSTPOT.PY * grav * wdns * 1.e-6 - emean$soil.extracted[m,] = - mymont$MMEAN.TRANSLOSS.PY * day.sec / dslz + emean$soil.temp [m,] = soil.temp.lyr + emean$soil.water [m,] = soil.water.lyr + emean$soil.mstpot [m,] = soil.mstpot.lyr + emean$soil.extracted[m,] = soil.extracted.lyr #------------------------------------------------------------------------------------# @@ -546,9 +670,6 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Find average near-surface soil temperature. # #------------------------------------------------------------------------------------# - soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PY - t00 - soil.water.lyr = mymont$MMEAN.SOIL.WATER.PY - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) emean$soil.temp.top [m] = sum(soil.temp.lyr * tt.wgtz) emean$soil.water.top [m] = sum(soil.water.lyr * tm.wgtz) * wdns * dz.msttop emean$soil.water.bot [m] = sum(soil.water.lyr * bm.wgtz) * wdns * dz.mstbot @@ -559,12 +680,22 @@ read.q.files <<- function( datum #----- Find averaged soil properties. -----------------------------------------------# - swater.now = rev(cumsum(rev(mymont$MMEAN.SOIL.WATER.PY * wdns * dslz))) - smoist.avg = swater.now / (wdns * soil.depth) - emean$paw [m] = 100. * ( ( swater.now[ka] - soil.dry [ka] ) - / ( soil.poro [ka] - soil.dry [ka] ) ) - emean$smpot[m] = ( - smoist2mpot(smoist=smoist.avg[ka],mysoil=soil.prop) - * 0.001 * grav ) + emean$paw [m] = 0. + emean$smpot[m] = 0. + for (p in sequence(npatches.tot)){ + ntext = ntextpa[p] + ka = kapa [p] + swater.now = rev(cumsum(rev(mymont$MMEAN.SOIL.WATER.PA[p,] * wdns * dslz))) + smoist.now = swater.now / (wdns * soil.depth) + paw.now = ( 100. * ( ( swater.now - soil.dry [,ntext] ) + / ( soil.poro [,ntext] - soil.dry [,ntext] ) ) + )#end paw.now + smpot.now = ( smoist2mpot(smoist=smoist.now,mysoil=soil.prop[ntext,]) + * (-1.) * grav * wdns * 1.e-6 + )#end smpot.now + emean$paw [m] = emean$paw [m] + paw.now [ka] * areapa[p] + emean$smpot[m] = emean$smpot[m] + smpot.now[ka] * areapa[p] + }#end for (p in sequence(nsites)) #------------------------------------------------------------------------------------# @@ -613,107 +744,156 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Read the mean diurnal cycle and the mean sum of the squares. # #------------------------------------------------------------------------------------# - qmean$gpp [m,] = mymont$QMEAN.GPP.PY - qmean$npp [m,] = mymont$QMEAN.NPP.PY - qmean$het.resp [m,] = mymont$QMEAN.RH.PY - qmean$fgc.resp [m,] = mymont$QMEAN.FGC.RH.PY - qmean$fsc.resp [m,] = mymont$QMEAN.FSC.RH.PY - qmean$stgc.resp [m,] = mymont$QMEAN.STGC.RH.PY - qmean$stsc.resp [m,] = mymont$QMEAN.STSC.RH.PY - qmean$msc.resp [m,] = mymont$QMEAN.MSC.RH.PY - qmean$ssc.resp [m,] = mymont$QMEAN.SSC.RH.PY - qmean$psc.resp [m,] = mymont$QMEAN.PSC.RH.PY - qmean$assim.light [m,] = mymont$QMEAN.A.LIGHT.PY - qmean$assim.rubp [m,] = mymont$QMEAN.A.RUBP.PY - qmean$assim.co2 [m,] = mymont$QMEAN.A.CO2.PY - qmean$assim.ratio [m,] = ( mymont$QMEAN.A.LIGHT.PY - / pmax(1e-6, pmin( mymont$QMEAN.A.RUBP.PY - , mymont$QMEAN.A.CO2.PY ))) - qmean$nee [m,] = ( mymont$QMEAN.CARBON.ST.PY - - mymont$QMEAN.CARBON.AC.PY ) - qmean$reco [m,] = mymont$QMEAN.PLRESP.PY + mymont$QMEAN.RH.PY - qmean$cflxca [m,] = - mymont$QMEAN.CARBON.AC.PY - qmean$cflxst [m,] = - mymont$QMEAN.CARBON.ST.PY - qmean$hflxca [m,] = - mymont$QMEAN.SENSIBLE.AC.PY - qmean$hflxlc [m,] = mymont$QMEAN.SENSIBLE.LC.PY - qmean$hflxwc [m,] = mymont$QMEAN.SENSIBLE.WC.PY - qmean$hflxgc [m,] = mymont$QMEAN.SENSIBLE.GC.PY - qmean$wflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * day.sec - qmean$qwflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * qmean.can.alvli.py - qmean$wflxlc [m,] = mymont$QMEAN.VAPOR.LC.PY * day.sec - qmean$wflxwc [m,] = mymont$QMEAN.VAPOR.WC.PY * day.sec - qmean$wflxgc [m,] = mymont$QMEAN.VAPOR.GC.PY * day.sec - qmean$runoff [m,] = ( mymont$QMEAN.RUNOFF.PY - + mymont$QMEAN.DRAINAGE.PY ) * day.sec - qmean$intercepted [m,] = ( mymont$QMEAN.INTERCEPTED.AL.PY - + mymont$QMEAN.INTERCEPTED.AW.PY ) * day.sec - qmean$wshed [m,] = ( mymont$QMEAN.WSHED.LG.PY - + mymont$QMEAN.WSHED.WG.PY ) * day.sec - qmean$evap [m,] = ( mymont$QMEAN.VAPOR.GC.PY - + mymont$QMEAN.VAPOR.WC.PY - + mymont$QMEAN.VAPOR.LC.PY ) * day.sec - qmean$transp [m,] = mymont$QMEAN.TRANSP.PY * day.sec - qmean$atm.temp [m,] = mymont$QMEAN.ATM.TEMP.PY - t00 - qmean$can.temp [m,] = mymont$QMEAN.CAN.TEMP.PY - t00 - qmean$leaf.temp [m,] = mymont$QMEAN.LEAF.TEMP.PY - t00 - qmean$leaf.water [m,] = mymont$QMEAN.LEAF.WATER.PY - qmean$wood.temp [m,] = mymont$QMEAN.WOOD.TEMP.PY - t00 - qmean$gnd.temp [m,] = mymont$QMEAN.GND.TEMP.PY - t00 - qmean$atm.shv [m,] = mymont$QMEAN.ATM.SHV.PY * kg2g - qmean$can.shv [m,] = mymont$QMEAN.CAN.SHV.PY * kg2g - qmean$gnd.shv [m,] = mymont$QMEAN.GND.SHV.PY * kg2g - qmean$atm.vpd [m,] = mymont$QMEAN.ATM.VPDEF.PY * 0.01 - qmean$can.vpd [m,] = mymont$QMEAN.CAN.VPDEF.PY * 0.01 - qmean$leaf.vpd [m,] = mymont$QMEAN.LEAF.VPDEF.PY * 0.01 - qmean$atm.co2 [m,] = mymont$QMEAN.ATM.CO2.PY - qmean$can.co2 [m,] = mymont$QMEAN.CAN.CO2.PY - qmean$atm.vels [m,] = mymont$QMEAN.ATM.VELS.PY - qmean$ustar [m,] = mymont$QMEAN.USTAR.PY - qmean$atm.prss [m,] = mymont$QMEAN.ATM.PRSS.PY * 0.01 - qmean$can.prss [m,] = mymont$QMEAN.CAN.PRSS.PY * 0.01 - qmean$sm.stress [m,] = 1. - mymont$QMEAN.FS.OPEN.PY - qmean$rain [m,] = mymont$QMEAN.PCPG.PY * day.sec - qmean$rshort [m,] = mymont$QMEAN.ATM.RSHORT.PY - qmean$rshort.beam [m,] = ( mymont$QMEAN.ATM.RSHORT.PY - - mymont$QMEAN.ATM.RSHORT.DIFF.PY ) - qmean$rshort.diff [m,] = mymont$QMEAN.ATM.RSHORT.DIFF.PY - qmean$rshort.gnd [m,] = mymont$QMEAN.RSHORT.GND.PY - qmean$rshortup [m,] = mymont$QMEAN.RSHORTUP.PY - qmean$rlong [m,] = mymont$QMEAN.ATM.RLONG.PY - qmean$rlong.gnd [m,] = mymont$QMEAN.RLONG.GND.PY - qmean$rlongup [m,] = mymont$QMEAN.RLONGUP.PY - qmean$par.tot [m,] = mymont$QMEAN.ATM.PAR.PY * Watts.2.Ein * 1.e6 - qmean$par.beam [m,] = ( mymont$QMEAN.ATM.PAR.PY - - mymont$QMEAN.ATM.PAR.DIFF.PY ) * Watts.2.Ein * 1.e6 - qmean$par.diff [m,] = mymont$QMEAN.ATM.PAR.DIFF.PY * Watts.2.Ein * 1.e6 - qmean$par.gnd [m,] = mymont$QMEAN.PAR.GND.PY * Watts.2.Ein * 1.e6 - qmean$parup [m,] = mymont$QMEAN.PARUP.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf [m,] = mymont$QMEAN.PAR.L.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf.beam[m,] = mymont$QMEAN.PAR.L.BEAM.PY * Watts.2.Ein * 1.e6 - qmean$par.leaf.diff[m,] = mymont$QMEAN.PAR.L.DIFF.PY * Watts.2.Ein * 1.e6 - qmean$rnet [m,] = mymont$QMEAN.RNET.PY - qmean$albedo [m,] = mymont$QMEAN.ALBEDO.PY + qmean$gpp [m,] = mymont$QMEAN.GPP.PY + qmean$npp [m,] = mymont$QMEAN.NPP.PY + qmean$het.resp [m,] = mymont$QMEAN.RH.PY + qmean$fgc.resp [m,] = mymont$QMEAN.FGC.RH.PY + qmean$fsc.resp [m,] = mymont$QMEAN.FSC.RH.PY + qmean$stgc.resp [m,] = mymont$QMEAN.STGC.RH.PY + qmean$stsc.resp [m,] = mymont$QMEAN.STSC.RH.PY + qmean$msc.resp [m,] = mymont$QMEAN.MSC.RH.PY + qmean$ssc.resp [m,] = mymont$QMEAN.SSC.RH.PY + qmean$psc.resp [m,] = mymont$QMEAN.PSC.RH.PY + qmean$assim.light [m,] = mymont$QMEAN.A.LIGHT.PY + qmean$assim.rubp [m,] = mymont$QMEAN.A.RUBP.PY + qmean$assim.co2 [m,] = mymont$QMEAN.A.CO2.PY + qmean$assim.ratio [m,] = ( mymont$QMEAN.A.LIGHT.PY + / pmax(1e-6, pmin( mymont$QMEAN.A.RUBP.PY + , mymont$QMEAN.A.CO2.PY ))) + qmean$nee [m,] = ( mymont$QMEAN.CARBON.ST.PY + - mymont$QMEAN.CARBON.AC.PY ) + qmean$reco [m,] = mymont$QMEAN.PLRESP.PY + mymont$QMEAN.RH.PY + qmean$cflxca [m,] = - mymont$QMEAN.CARBON.AC.PY + qmean$cflxst [m,] = - mymont$QMEAN.CARBON.ST.PY + qmean$hflxca [m,] = - mymont$QMEAN.SENSIBLE.AC.PY + qmean$hflxlc [m,] = mymont$QMEAN.SENSIBLE.LC.PY + qmean$hflxwc [m,] = mymont$QMEAN.SENSIBLE.WC.PY + qmean$hflxgc [m,] = mymont$QMEAN.SENSIBLE.GC.PY + qmean$wflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * day.sec + qmean$qwflxca [m,] = - mymont$QMEAN.VAPOR.AC.PY * qmean.can.alvli.py + qmean$wflxlc [m,] = mymont$QMEAN.VAPOR.LC.PY * day.sec + qmean$wflxwc [m,] = mymont$QMEAN.VAPOR.WC.PY * day.sec + qmean$wflxgc [m,] = mymont$QMEAN.VAPOR.GC.PY * day.sec + qmean$runoff [m,] = ( mymont$QMEAN.RUNOFF.PY + + mymont$QMEAN.DRAINAGE.PY ) * day.sec + qmean$intercepted [m,] = ( mymont$QMEAN.INTERCEPTED.AL.PY + + mymont$QMEAN.INTERCEPTED.AW.PY ) * day.sec + qmean$wshed [m,] = ( mymont$QMEAN.WSHED.LG.PY + + mymont$QMEAN.WSHED.WG.PY ) * day.sec + qmean$evap [m,] = ( mymont$QMEAN.VAPOR.GC.PY + + mymont$QMEAN.VAPOR.WC.PY + + mymont$QMEAN.VAPOR.LC.PY ) * day.sec + qmean$transp [m,] = mymont$QMEAN.TRANSP.PY * day.sec + qmean$atm.temp [m,] = mymont$QMEAN.ATM.TEMP.PY - t00 + qmean$can.temp [m,] = mymont$QMEAN.CAN.TEMP.PY - t00 + qmean$leaf.temp [m,] = mymont$QMEAN.LEAF.TEMP.PY - t00 + qmean$leaf.water [m,] = mymont$QMEAN.LEAF.WATER.PY + qmean$leaf.water.im2[m,] = mymont$QMEAN.LEAF.WATER.IM2.PY + qmean$wood.temp [m,] = mymont$QMEAN.WOOD.TEMP.PY - t00 + qmean$gnd.temp [m,] = mymont$QMEAN.GND.TEMP.PY - t00 + qmean$atm.shv [m,] = mymont$QMEAN.ATM.SHV.PY * kg2g + qmean$can.shv [m,] = mymont$QMEAN.CAN.SHV.PY * kg2g + qmean$gnd.shv [m,] = mymont$QMEAN.GND.SHV.PY * kg2g + qmean$atm.vpd [m,] = mymont$QMEAN.ATM.VPDEF.PY * 0.01 + qmean$can.vpd [m,] = mymont$QMEAN.CAN.VPDEF.PY * 0.01 + qmean$leaf.vpd [m,] = mymont$QMEAN.LEAF.VPDEF.PY * 0.01 + qmean$atm.co2 [m,] = mymont$QMEAN.ATM.CO2.PY + qmean$can.co2 [m,] = mymont$QMEAN.CAN.CO2.PY + qmean$atm.vels [m,] = mymont$QMEAN.ATM.VELS.PY + qmean$ustar [m,] = mymont$QMEAN.USTAR.PY + qmean$atm.prss [m,] = mymont$QMEAN.ATM.PRSS.PY * 0.01 + qmean$can.prss [m,] = mymont$QMEAN.CAN.PRSS.PY * 0.01 + qmean$sm.stress [m,] = 1. - mymont$QMEAN.FS.OPEN.PY + qmean$rain [m,] = mymont$QMEAN.PCPG.PY * day.sec + qmean$rshort [m,] = mymont$QMEAN.ATM.RSHORT.PY + qmean$rshort.beam [m,] = ( mymont$QMEAN.ATM.RSHORT.PY + - mymont$QMEAN.ATM.RSHORT.DIFF.PY ) + qmean$rshort.diff [m,] = mymont$QMEAN.ATM.RSHORT.DIFF.PY + qmean$rshort.gnd [m,] = mymont$QMEAN.RSHORT.GND.PY + qmean$rshortup [m,] = mymont$QMEAN.RSHORTUP.PY + qmean$rlong [m,] = mymont$QMEAN.ATM.RLONG.PY + qmean$rlong.gnd [m,] = mymont$QMEAN.RLONG.GND.PY + qmean$rlongup [m,] = mymont$QMEAN.RLONGUP.PY + qmean$par.tot [m,] = mymont$QMEAN.ATM.PAR.PY * Watts.2.Ein * 1.e6 + qmean$par.beam [m,] = ( mymont$QMEAN.ATM.PAR.PY + - mymont$QMEAN.ATM.PAR.DIFF.PY ) * Watts.2.Ein * 1.e6 + qmean$par.diff [m,] = mymont$QMEAN.ATM.PAR.DIFF.PY * Watts.2.Ein * 1.e6 + qmean$par.gnd [m,] = mymont$QMEAN.PAR.GND.PY * Watts.2.Ein * 1.e6 + qmean$parup [m,] = mymont$QMEAN.PARUP.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf [m,] = mymont$QMEAN.PAR.L.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf.beam [m,] = mymont$QMEAN.PAR.L.BEAM.PY * Watts.2.Ein * 1.e6 + qmean$par.leaf.diff [m,] = mymont$QMEAN.PAR.L.DIFF.PY * Watts.2.Ein * 1.e6 + qmean$rnet [m,] = mymont$QMEAN.RNET.PY + qmean$albedo [m,] = mymont$QMEAN.ALBEDO.PY if (all(c("QMEAN.ALBEDO.PAR.PY","QMEAN.ALBEDO.NIR.PY") %in% names(mymont))){ - qmean$albedo.par[m,] = mymont$QMEAN.ALBEDO.PAR.PY - qmean$albedo.nir[m,] = mymont$QMEAN.ALBEDO.NIR.PY + qmean$albedo.par [m,] = mymont$QMEAN.ALBEDO.PAR.PY + qmean$albedo.nir [m,] = mymont$QMEAN.ALBEDO.NIR.PY }else{ - qmean$albedo.par[m,] = ifelse( mymont$QMEAN.ATM.PAR.PY > 0.5 - , mymont$QMEAN.PARUP.PY / mymont$QMEAN.ATM.PAR.PY - , mymont$QMEAN.ALBEDO.PY - )#end ifelse - qmean$albedo.nir[m,] = ifelse( mymont$QMEAN.ATM.NIR.PY > 0.5 - , mymont$QMEAN.NIRUP.PY / mymont$QMEAN.ATM.NIR.PY - , mymont$QMEAN.ALBEDO.PY - )#end ifelse + qmean$albedo.par [m,] = ifelse( mymont$QMEAN.ATM.PAR.PY > 0.5 + , mymont$QMEAN.PARUP.PY / mymont$QMEAN.ATM.PAR.PY + , mymont$QMEAN.ALBEDO.PY + )#end ifelse + qmean$albedo.nir [m,] = ifelse( mymont$QMEAN.ATM.NIR.PY > 0.5 + , mymont$QMEAN.NIRUP.PY / mymont$QMEAN.ATM.NIR.PY + , mymont$QMEAN.ALBEDO.PY + )#end ifelse }#end if - qmean$rlong.albedo [m,] = mymont$QMEAN.RLONG.ALBEDO.PY - qmean$leaf.gbw [m,] = mymont$QMEAN.LEAF.GBW.PY * day.sec - qmean$leaf.gsw [m,] = mymont$QMEAN.LEAF.GSW.PY * day.sec - qmean$wood.gbw [m,] = mymont$QMEAN.WOOD.GBW.PY * day.sec - qmean$rk4step [m,] = mymont$QMEAN.RK4STEP.PY - qmean$soil.water [m,,] = mymont$QMEAN.SOIL.WATER.PY - qmean$soil.temp [m,,] = mymont$QMEAN.SOIL.TEMP.PY - t00 - qmean$soil.mstpot [m,,] = - mymont$QMEAN.SOIL.MSTPOT.PY * grav * wdns * 1.e-6 + qmean$rlong.albedo [m,] = mymont$QMEAN.RLONG.ALBEDO.PY + qmean$leaf.gbw [m,] = mymont$QMEAN.LEAF.GBW.PY * day.sec + qmean$leaf.gsw [m,] = mymont$QMEAN.LEAF.GSW.PY * day.sec + qmean$wood.gbw [m,] = mymont$QMEAN.WOOD.GBW.PY * day.sec + qmean$rk4step [m,] = mymont$QMEAN.RK4STEP.PY + #------------------------------------------------------------------------------------# + + + + #------ For soils, we must account for different soil depths. -----------------------# + for (h in sequence(ndcycle)){ + odim = dim(mymont$QMEAN.SOIL.TEMP.PA)[-2] + soil.temp.pa = mymont$QMEAN.SOIL.TEMP.PA [,h,] - t00 + soil.water.pa = mymont$QMEAN.SOIL.WATER.PA[,h,] + soil.temp.pa = array(soil.temp.pa ,dim=odim) + soil.water.pa = array(soil.water.pa,dim=odim) + soil.mstpot.pa = soil.water.pa * (-1.) * grav * wdns * 1.e-6 + soil.wetness.pa = ( ( soil.water.pa - soilcp.pa) + / ( soilpo.pa - soilcp.pa) ) + + + #----- Populate data structure by hour of the day. -------------------------------# + soil.temp.lyr = apply( X = soil.temp.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.water.lyr = apply( X = soil.water.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.mstpot.lyr = apply( X = soil.mstpot.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + soil.wetness.lyr = apply( X = soil.wetness.pa * soil.area + , MARGIN = 2 + , FUN = sum + , na.rm = FALSE + )#end apply + #---------------------------------------------------------------------------------# + + + #----- Copy results for the hour. ------------------------------------------------# + qmean$soil.temp [m,h,] = soil.temp.lyr + qmean$soil.water [m,h,] = soil.water.lyr + qmean$soil.mstpot [m,h,] = soil.mstpot.lyr + qmean$soil.temp.top [m,h ] = sum(soil.temp.lyr * tt.wgtz) + qmean$soil.water.top [m,h ] = sum(soil.water.lyr * tm.wgtz) * wdns * dz.msttop + qmean$soil.water.bot [m,h ] = sum(soil.water.lyr * bm.wgtz) * wdns * dz.mstbot + qmean$soil.wetness.top[m,h ] = sum(soil.wetness.lyr * tm.wgtz) + qmean$soil.wetness.bot[m,h ] = sum(soil.wetness.lyr * bm.wgtz) + #---------------------------------------------------------------------------------# + }#end for (h in sequence(ndcycle)) #------------------------------------------------------------------------------------# @@ -751,36 +931,6 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# - - #------------------------------------------------------------------------------------# - # Find average soil temperature and water content at specific layers. # - #------------------------------------------------------------------------------------# - soil.temp.lyr = mymont$QMEAN.SOIL.TEMP.PY [1,,] - t00 - soil.water.lyr = mymont$QMEAN.SOIL.WATER.PY[1,,] - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) - qmean$soil.temp.top [m,] = rowSums(soil.temp.lyr * q.tt.wgtz) - qmean$soil.water.top [m,] = rowSums(soil.water.lyr * q.tm.wgtz) * wdns * dz.msttop - qmean$soil.water.bot [m,] = rowSums(soil.water.lyr * q.bm.wgtz) * wdns * dz.mstbot - qmean$soil.wetness.top[m,] = rowSums(soil.wetness.lyr * q.tm.wgtz) - qmean$soil.wetness.bot[m,] = rowSums(soil.wetness.lyr * q.bm.wgtz) - #------------------------------------------------------------------------------------# - - - #---- Read in the site-level area. --------------------------------------------------# - areasi = mymont$AREA.SI - npatches = mymont$SIPA.N - #------------------------------------------------------------------------------------# - - - #----- Read a few patch-level variables. --------------------------------------------# - areapa = mymont$AREA * rep(areasi,times=npatches) - areapa = areapa / sum(areapa) - ipa = sequence(mymont$NPATCHES.GLOBAL) - lupa = mymont$DIST.TYPE - agepa = mymont$AGE - #------------------------------------------------------------------------------------# - - #------------------------------------------------------------------------------------# # Get the water deficit, and the estimate using Malhi's ET (100mm/month). # #------------------------------------------------------------------------------------# @@ -819,7 +969,10 @@ read.q.files <<- function( datum # Get the total number of cohorts. # #------------------------------------------------------------------------------------# ncohorts = mymont$PACO.N - ipaconow = rep(sequence(mymont$NPATCHES.GLOBAL),times=mymont$PACO.N) + isiconow = rep( x = isipa , times = mymont$PACO.N) + lslconow = rep( x = lslpa , times = mymont$PACO.N) + ntextconow = rep( x = ntextpa, times = mymont$PACO.N) + ipaconow = rep( x = ipa , times = mymont$PACO.N) q.ipaconow = matrix( data = ipaconow , nrow = mymont$NCOHORTS.GLOBAL , ncol = mymont$NDCYC @@ -922,6 +1075,7 @@ read.q.files <<- function( datum )#end size2ca )#end pmin taiconow = laiconow + waiconow + agvolumeconow = agbconow / wood.densconow * 1.e-3 #------ Auxiliary variables for mean diurnal cycle. ------------------------------# q.pftconow = matrix( data = pftconow , nrow = mymont$NCOHORTS.GLOBAL @@ -1102,10 +1256,10 @@ read.q.files <<- function( datum #----- Flags to tell whether leaves and branchwood were resolvable. --------------# - leaf.okconow = mymont$MMEAN.LEAF.HCAP.CO %>=% pft$veg.hcap.min[pftconow ] - wood.okconow = mymont$MMEAN.WOOD.HCAP.CO %>=% pft$veg.hcap.min[pftconow ] - q.leaf.okconow = mymont$QMEAN.LEAF.HCAP.CO %>=% pft$veg.hcap.min[q.pftconow] - q.wood.okconow = mymont$QMEAN.WOOD.HCAP.CO %>=% pft$veg.hcap.min[q.pftconow] + leaf.okconow = mymont$MMEAN.LEAF.HCAP.CO %ge% pft$veg.hcap.min[pftconow ] + wood.okconow = mymont$MMEAN.WOOD.HCAP.CO %ge% pft$veg.hcap.min[pftconow ] + q.leaf.okconow = mymont$QMEAN.LEAF.HCAP.CO %ge% pft$veg.hcap.min[q.pftconow] + q.wood.okconow = mymont$QMEAN.WOOD.HCAP.CO %ge% pft$veg.hcap.min[q.pftconow] #---------------------------------------------------------------------------------# @@ -1300,6 +1454,13 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# + + #----- Leaf water potential. -----------------------------------------------------# + dmin.leaf.psiconow = mymont$MMEAN.DMIN.LEAF.PSI.CO * wdns * grav * 1.e-6 + dmax.leaf.psiconow = mymont$MMEAN.DMAX.LEAF.PSI.CO * wdns * grav * 1.e-6 + #---------------------------------------------------------------------------------# + + #----- Find the net radiation for leaves (in m2/leaf!). --------------------------# par.mult = Watts.2.Ein * 1.e6 leaf.parconow = ifelse( leaf.okconow & showconow @@ -1358,39 +1519,47 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# # Leaf/wood thermal properties. # #---------------------------------------------------------------------------------# - leaf.waterconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.WATER.CO / laiconow - , no = NA - )#end ifelse - leaf.tempconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.TEMP.CO - t00 - , no = NA - )#end ifelse - wood.tempconow = ifelse( test = wood.okconow & showconow - , yes = mymont$MMEAN.WOOD.TEMP.CO - t00 - , no = NA - )#end ifelse - leaf.vpdconow = ifelse( test = leaf.okconow & showconow - , yes = mymont$MMEAN.LEAF.VPDEF.CO * 0.01 - , no = NA - )#end ifelse - #----- Mean diurnal cycle. -------------------------------------------------------# - q.leaf.waterconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.WATER.CO / q.laiconow + leaf.waterconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.WATER.CO / laiconow + , no = NA + )#end ifelse + leaf.water.im2conow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.WATER.IM2.CO / laiconow , no = NA )#end ifelse - q.leaf.tempconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.TEMP.CO - t00 + leaf.tempconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.TEMP.CO - t00 , no = NA )#end ifelse - q.wood.tempconow = ifelse( test = q.wood.okconow & q.showconow - , yes = mymont$QMEAN.WOOD.TEMP.CO - t00 + wood.tempconow = ifelse( test = wood.okconow & showconow + , yes = mymont$MMEAN.WOOD.TEMP.CO - t00 , no = NA )#end ifelse - q.leaf.vpdconow = ifelse( test = q.leaf.okconow & q.showconow - , yes = mymont$QMEAN.LEAF.VPDEF.CO * 0.01 + leaf.vpdconow = ifelse( test = leaf.okconow & showconow + , yes = mymont$MMEAN.LEAF.VPDEF.CO * 0.01 , no = NA )#end ifelse + #----- Mean diurnal cycle. -------------------------------------------------------# + q.leaf.waterconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.WATER.CO / q.laiconow + , no = NA + )#end ifelse + q.leaf.water.im2conow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.WATER.IM2.CO / q.laiconow + , no = NA + )#end ifelse + q.leaf.tempconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.TEMP.CO - t00 + , no = NA + )#end ifelse + q.wood.tempconow = ifelse( test = q.wood.okconow & q.showconow + , yes = mymont$QMEAN.WOOD.TEMP.CO - t00 + , no = NA + )#end ifelse + q.leaf.vpdconow = ifelse( test = q.leaf.okconow & q.showconow + , yes = mymont$QMEAN.LEAF.VPDEF.CO * 0.01 + , no = NA + )#end ifelse #---------------------------------------------------------------------------------# @@ -1453,6 +1622,17 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------# + # Find fire lethality rate. # + #---------------------------------------------------------------------------------# + fire.lethalconow = mymont$MMEAN.FIRE.LETHAL.RATE.CO + #---------------------------------------------------------------------------------# + + + + #------ Find the AGB and basal area of the previous month. -----------------------# agbcolmon = agbconow * exp(-agb.growthconow/12.) bacolmon = baconow * exp(-bsa.growthconow/12.) @@ -1501,24 +1681,28 @@ read.q.files <<- function( datum phap.leaf.gsaconow = NA + pftconow phap.can.shv.conow = NA + pftconow }else if (one.cohort){ - phap.lparconow = mean(mymont$QMEAN.PAR.L.CO [phap]) - phap.ltempconow = mean(mymont$QMEAN.LEAF.TEMP.CO [phap]) - phap.lwaterconow = mean(mymont$QMEAN.LEAF.WATER.CO[phap]) - phap.lvpdconow = mean(mymont$QMEAN.LEAF.VPDEF.CO[phap]) - phap.fs.openconow = mean(mymont$QMEAN.FS.OPEN.CO [phap]) - phap.lpsiconow = mean(mymont$QMEAN.TRANSP.CO [phap]) - phap.leaf.gbaconow = mean(mymont$QMEAN.LEAF.GBW.CO [phap]) - phap.leaf.gsaconow = mean(mymont$QMEAN.LEAF.GSW.CO [phap]) - phap.can.shv.conow = rep(mean(mymont$QMEAN.CAN.SHV.PA[phap]),times=ncohorts) + phap.lparconow = mean(mymont$QMEAN.PAR.L.CO [phap]) + phap.ltempconow = mean(mymont$QMEAN.LEAF.TEMP.CO [phap]) + phap.lwaterconow = mean(mymont$QMEAN.LEAF.WATER.CO [phap]) + phap.lwater.im2conow = mean(mymont$QMEAN.LEAF.WATER.IM2.CO [phap]) + phap.lvpdconow = mean(mymont$QMEAN.LEAF.VPDEF.CO [phap]) + phap.fs.openconow = mean(mymont$QMEAN.FS.OPEN.CO [phap]) + phap.lpsiconow = mean(mymont$QMEAN.TRANSP.CO [phap]) + phap.leaf.gbaconow = mean(mymont$QMEAN.LEAF.GBW.CO [phap]) + phap.leaf.gsaconow = mean(mymont$QMEAN.LEAF.GSW.CO [phap]) + phap.can.shv.conow = rep( x = mean(mymont$QMEAN.CAN.SHV.PA[phap]) + , times = ncohorts + )#end rep }else{ - phap.lparconow = rowMeans(mymont$QMEAN.PAR.L.CO [,phap]) - phap.ltempconow = rowMeans(mymont$QMEAN.LEAF.TEMP.CO [,phap]) - phap.lwaterconow = rowMeans(mymont$QMEAN.LEAF.WATER.CO[,phap]) - phap.lvpdconow = rowMeans(mymont$QMEAN.LEAF.VPDEF.CO[,phap]) - phap.fs.openconow = rowMeans(mymont$QMEAN.FS.OPEN.CO [,phap]) - phap.lpsiconow = rowMeans(mymont$QMEAN.TRANSP.CO [,phap]) - phap.leaf.gbaconow = rowMeans(mymont$QMEAN.LEAF.GBW.CO [,phap]) - phap.leaf.gsaconow = rowMeans(mymont$QMEAN.LEAF.GSW.CO [,phap]) + phap.lparconow = rowMeans(mymont$QMEAN.PAR.L.CO [,phap]) + phap.ltempconow = rowMeans(mymont$QMEAN.LEAF.TEMP.CO [,phap]) + phap.lwaterconow = rowMeans(mymont$QMEAN.LEAF.WATER.CO [,phap]) + phap.lwater.im2conow = rowMeans(mymont$QMEAN.LEAF.WATER.IM2.CO[,phap]) + phap.lvpdconow = rowMeans(mymont$QMEAN.LEAF.VPDEF.CO [,phap]) + phap.fs.openconow = rowMeans(mymont$QMEAN.FS.OPEN.CO [,phap]) + phap.lpsiconow = rowMeans(mymont$QMEAN.TRANSP.CO [,phap]) + phap.leaf.gbaconow = rowMeans(mymont$QMEAN.LEAF.GBW.CO [,phap]) + phap.leaf.gsaconow = rowMeans(mymont$QMEAN.LEAF.GSW.CO [,phap]) if (one.patch){ phap.can.shv.conow = rep( x = mean(mymont$QMEAN.CAN.SHV.PA[phap]) , times = ncohorts @@ -1585,132 +1769,140 @@ read.q.files <<- function( datum }else{ #----- Make everything NA. -------------------------------------------------------# - ipaconow = NA - icoconow = NA - areaconow = NA - luconow = NA - dbhconow = NA - dbhcut = NA - dbhlevs = NA - dbhfac = NA - dbhconow.1ago = NA - dbhcut.1ago = NA - dbhlevs.1ago = NA - dbhfac.1ago = NA - dbhconow.lmon = NA - dbhcut.lmon = NA - dbhlevs.lmon = NA - dbhfac.lmon = NA - ageconow = NA - pftconow = NA - nplantconow = NA - heightconow = NA - wood.densconow = NA - vm0conow = NA - llspanconow = NA - slaconow = NA - baconow = NA - agbconow = NA - biomassconow = NA - laiconow = NA - waiconow = NA - taiconow = NA - gppconow = NA - leaf.respconow = NA - stem.respconow = NA - root.respconow = NA - froot.respconow = NA - croot.respconow = NA - aerobic.respconow = NA - growth.respconow = NA - storage.respconow = NA - plant.respconow = NA - assim.lightconow = NA - assim.rubpconow = NA - assim.co2conow = NA - assim.ratioconow = NA - nppconow = NA - cbaconow = NA - cbamaxconow = NA - cbalightconow = NA - cbamoistconow = NA - cbarelconow = NA - mcostconow = NA - ldropconow = NA - dcbadtconow = NA - sm.stressconow = NA - lightconow = NA - light.beamconow = NA - light.diffconow = NA - thbarkconow = NA - baliveconow = NA - bdeadconow = NA - btimberconow = NA - bleafconow = NA - bsapwoodconow = NA - bfrootconow = NA - bcrootconow = NA - brootconow = NA - bstemconow = NA - bbarkconow = NA - bstorageconow = NA - bseedsconow = NA - byieldconow = NA - hflxlcconow = NA - wflxlcconow = NA - transpconow = NA - i.hflxlcconow = NA - i.wflxlcconow = NA - i.transpconow = NA - wueconow = NA - cueconow = NA - ecueconow = NA - etueconow = NA - leaf.tempconow = NA - leaf.waterconow = NA - wood.tempconow = NA - leaf.vpdconow = NA - demandconow = NA - supplyconow = NA - mortconow = NA - ncbmortconow = NA - hydmortconow = NA - dimortconow = NA - recruitconow = NA - growthconow = NA - agb.growthconow = NA - bsa.growthconow = NA - leaf.gbwconow = NA - leaf.gswconow = NA - wood.gbwconow = NA - f.gppconow = NA - f.plant.respconow = NA - f.nppconow = NA - f.mcoconow = NA - f.dcbadtconow = NA - f.cbaconow = NA - f.bstorageconow = NA - f.bleafconow = NA - f.bstemconow = NA - f.brootconow = NA - f.bbarkconow = NA - f.bseedsconow = NA - leaf.parconow = NA - leaf.par.beamconow = NA - leaf.par.diffconow = NA - leaf.rshortconow = NA - leaf.rlongconow = NA - leaf.gppconow = NA - rueconow = NA - opencanconow = NA - useconow = NA - phap.lparconow = NA - phap.ltempconow = NA - phap.lwaterconow = NA - phap.lvpdconow = NA - phap.smsconow = NA - phap.lgbwconow = NA - phap.lgswconow = NA + isiconow = NA_integer_ + lslconow = NA_integer_ + ntextconow = NA_integer_ + ipaconow = NA_integer_ + icoconow = NA_integer_ + areaconow = NA_real_ + luconow = NA_integer_ + dbhconow = NA_real_ + dbhcut = NA_real_ + dbhlevs = NA_real_ + dbhfac = NA_real_ + dbhconow.1ago = NA_real_ + dbhcut.1ago = NA_real_ + dbhlevs.1ago = NA_real_ + dbhfac.1ago = NA_real_ + dbhconow.lmon = NA_real_ + dbhcut.lmon = NA_real_ + dbhlevs.lmon = NA_real_ + dbhfac.lmon = NA_real_ + ageconow = NA_real_ + pftconow = NA_integer_ + nplantconow = NA_real_ + heightconow = NA_real_ + wood.densconow = NA_real_ + vm0conow = NA_real_ + llspanconow = NA_real_ + slaconow = NA_real_ + baconow = NA_real_ + agbconow = NA_real_ + biomassconow = NA_real_ + laiconow = NA_real_ + waiconow = NA_real_ + taiconow = NA_real_ + agvolumeconow = NA_real_ + gppconow = NA_real_ + leaf.respconow = NA_real_ + stem.respconow = NA_real_ + root.respconow = NA_real_ + froot.respconow = NA_real_ + croot.respconow = NA_real_ + aerobic.respconow = NA_real_ + growth.respconow = NA_real_ + storage.respconow = NA_real_ + plant.respconow = NA_real_ + assim.lightconow = NA_real_ + assim.rubpconow = NA_real_ + assim.co2conow = NA_real_ + assim.ratioconow = NA_real_ + nppconow = NA_real_ + cbaconow = NA_real_ + cbamaxconow = NA_real_ + cbalightconow = NA_real_ + cbamoistconow = NA_real_ + cbarelconow = NA_real_ + mcostconow = NA_real_ + ldropconow = NA_real_ + dcbadtconow = NA_real_ + sm.stressconow = NA_real_ + lightconow = NA_real_ + light.beamconow = NA_real_ + light.diffconow = NA_real_ + thbarkconow = NA_real_ + baliveconow = NA_real_ + bdeadconow = NA_real_ + btimberconow = NA_real_ + bleafconow = NA_real_ + bsapwoodconow = NA_real_ + bfrootconow = NA_real_ + bcrootconow = NA_real_ + brootconow = NA_real_ + bstemconow = NA_real_ + bbarkconow = NA_real_ + bstorageconow = NA_real_ + bseedsconow = NA_real_ + byieldconow = NA_real_ + hflxlcconow = NA_real_ + wflxlcconow = NA_real_ + transpconow = NA_real_ + i.hflxlcconow = NA_real_ + i.wflxlcconow = NA_real_ + i.transpconow = NA_real_ + wueconow = NA_real_ + cueconow = NA_real_ + ecueconow = NA_real_ + etueconow = NA_real_ + leaf.tempconow = NA_real_ + leaf.waterconow = NA_real_ + leaf.water.im2conow = NA_real_ + wood.tempconow = NA_real_ + leaf.vpdconow = NA_real_ + demandconow = NA_real_ + supplyconow = NA_real_ + mortconow = NA_real_ + ncbmortconow = NA_real_ + hydmortconow = NA_real_ + dimortconow = NA_real_ + fire.lethalconow = NA_real_ + recruitconow = NA_real_ + growthconow = NA_real_ + agb.growthconow = NA_real_ + bsa.growthconow = NA_real_ + leaf.gbwconow = NA_real_ + leaf.gswconow = NA_real_ + wood.gbwconow = NA_real_ + f.gppconow = NA_real_ + f.plant.respconow = NA_real_ + f.nppconow = NA_real_ + f.mcoconow = NA_real_ + f.dcbadtconow = NA_real_ + f.cbaconow = NA_real_ + f.bstorageconow = NA_real_ + f.bleafconow = NA_real_ + f.bstemconow = NA_real_ + f.brootconow = NA_real_ + f.bbarkconow = NA_real_ + f.bseedsconow = NA_real_ + leaf.parconow = NA_real_ + leaf.par.beamconow = NA_real_ + leaf.par.diffconow = NA_real_ + leaf.rshortconow = NA_real_ + leaf.rlongconow = NA_real_ + leaf.gppconow = NA_real_ + dmin.leaf.psiconow = NA_real_ + dmax.leaf.psiconow = NA_real_ + rueconow = NA_real_ + opencanconow = NA_real_ + useconow = NA_real_ + phap.lparconow = NA_real_ + phap.ltempconow = NA_real_ + phap.lwaterconow = NA_real_ + phap.lvpdconow = NA_real_ + phap.smsconow = NA_real_ + phap.lgbwconow = NA_real_ + phap.lgswconow = NA_real_ }#end if #------------------------------------------------------------------------------------# #====================================================================================# @@ -1731,6 +1923,9 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# plab = paste0("y",sprintf("%4.4i",thisyear),"m",sprintf("%2.2i",thismonth)) #----- Bind the current patches. ----------------------------------------------------# + patch$isi [[plab]] = isipa + patch$lsl [[plab]] = lslpa + patch$ntext [[plab]] = ntextpa patch$ipa [[plab]] = ipa patch$age [[plab]] = agepa patch$area [[plab]] = areapa @@ -1769,18 +1964,25 @@ read.q.files <<- function( datum patch$rshort.gnd [[plab]] = mymont$MMEAN.RSHORT.GND.PA patch$par.gnd [[plab]] = mymont$MMEAN.PAR.GND.PA * Watts.2.Ein * 1e6 patch$rnet [[plab]] = mymont$MMEAN.RNET.PA + patch$sfcw.temp [[plab]] = mymont$MMEAN.SFCW.TEMP.PA - t00 + patch$sfcw.fliq [[plab]] = mymont$MMEAN.SFCW.FLIQ.PA + patch$sfcw.mass [[plab]] = mymont$MMEAN.SFCW.MASS.PA + patch$sfcw.depth [[plab]] = mymont$MMEAN.SFCW.DEPTH.PA + patch$sfcw.cover [[plab]] = mymont$MMEAN.SNOWFAC.PA #----- Find soil averages. ----------------------------------------------------------# - soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PA - t00 - soil.water.lyr = mymont$MMEAN.SOIL.WATER.PA - soil.wetness.lyr = (soil.water.lyr - soilcp) / (slmsts - soilcp) - p.tt.wgtz = matrix(tt.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - p.tm.wgtz = matrix(tm.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - p.bm.wgtz = matrix(bm.wgtz,nrow=npatches,ncol=nzg,byrow=TRUE) - patch$soil.temp.top [[plab]] = rowSums(soil.temp.lyr * p.tt.wgtz) - patch$soil.water.top [[plab]] = rowSums(soil.water.lyr * p.tm.wgtz) * wdns*dz.msttop - patch$soil.water.bot [[plab]] = rowSums(soil.water.lyr * p.bm.wgtz) * wdns*dz.mstbot - patch$soil.wetness.top[[plab]] = rowSums(soil.water.lyr * p.tm.wgtz) - patch$soil.wetness.bot[[plab]] = rowSums(soil.water.lyr * p.bm.wgtz) + soil.temp.lyr = mymont$MMEAN.SOIL.TEMP.PA * soil.mask - t00 + soil.water.lyr = mymont$MMEAN.SOIL.WATER.PA * soil.mask + soil.wetness.lyr = ( (soil.water.lyr - soilcp.pa) + / (soilpo.pa - soilcp.pa) ) * soil.mask + patch$soil.temp.top [[plab]] = rowSums(soil.temp.lyr * p.tt.wgtz,na.rm=TRUE) + patch$soil.water.top [[plab]] = ( rowSums(soil.water.lyr * p.tm.wgtz,na.rm=TRUE) + * wdns*dz.msttop + )#end soil.water.top + patch$soil.water.bot [[plab]] = ( rowSums(soil.water.lyr * p.bm.wgtz,na.rm=TRUE) + * wdns*dz.mstbot + )#end soil.water.bot + patch$soil.wetness.top[[plab]] = rowSums(soil.water.lyr * p.tm.wgtz,na.rm=TRUE) + patch$soil.wetness.bot[[plab]] = rowSums(soil.water.lyr * p.bm.wgtz,na.rm=TRUE) #----- Bind the current mean diurnal cycle patch. -----------------------------------# qpatch$rk4step [[plab]] = mymont$QMEAN.RK4STEP.PA qpatch$nep [[plab]] = mymont$QMEAN.NEP.PA @@ -1823,92 +2025,122 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Initialise patch-level properties that are derived from cohort-level. # #------------------------------------------------------------------------------------# - patch$lai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$agb [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$ba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$nplant [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wood.dens [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$vm0 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$llspan [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$sla [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$can.depth [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$can.area [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$sm.stress [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 - patch$leaf.water [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$leaf.vpd [[plab]] = mymont$MMEAN.CAN.VPDEF.PA * 0.01 - patch$wood.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 - patch$par.leaf [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$par.leaf.beam [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$par.leaf.diff [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$phap.lpar [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.ltemp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lwater [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lvpd [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.sms [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lgbw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$phap.lgsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.gpp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.gsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par.beam [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$leaf.par.diff [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.light [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.rubp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$assim.co2 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) - patch$gpp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$npp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$cba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$plant.resp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$hflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$hflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$wflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$transp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) - patch$soil.resp [[plab]] = mymont$MMEAN.RH.PA - patch$fast.grnd.c [[plab]] = mymont$MMEAN.FAST.GRND.C.PA - patch$fast.soil.c [[plab]] = mymont$MMEAN.FAST.SOIL.C.PA - patch$struct.grnd.c [[plab]] = mymont$MMEAN.STRUCT.GRND.C.PA - patch$struct.soil.c [[plab]] = mymont$MMEAN.STRUCT.SOIL.C.PA - patch$microbe.soil.c[[plab]] = mymont$MMEAN.MICROBE.SOIL.C.PA - patch$slow.soil.c [[plab]] = mymont$MMEAN.SLOW.SOIL.C.PA - patch$passive.soil.c[[plab]] = mymont$MMEAN.PASSIVE.SOIL.C.PA - patch$fgc.in [[plab]] = mymont$MMEAN.FGC.IN.PA - patch$fsc.in [[plab]] = mymont$MMEAN.FSC.IN.PA - patch$stgc.in [[plab]] = mymont$MMEAN.STGC.IN.PA - patch$stsc.in [[plab]] = mymont$MMEAN.STSC.IN.PA - patch$soil.temp [[plab]] = mymont$MMEAN.SOIL.TEMP.PA - t00 - patch$soil.water [[plab]] = mymont$MMEAN.SOIL.WATER.PA - patch$soil.mstpot [[plab]] = - mymont$MMEAN.SOIL.MSTPOT.PA * grav * wdns * 1.e-6 + patch$lai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wai [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$agb [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$ba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$nplant [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wood.dens [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$vm0 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$llspan [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$sla [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$can.depth [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$can.area [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$sm.stress [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 + patch$leaf.water [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$leaf.water.im2 [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$leaf.vpd [[plab]] = mymont$MMEAN.CAN.VPDEF.PA * 0.01 + patch$wood.temp [[plab]] = mymont$MMEAN.CAN.TEMP.PA - t00 + patch$par.leaf [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$par.leaf.beam [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$par.leaf.diff [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$phap.lpar [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.ltemp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lwater [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lvpd [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.sms [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lgbw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$phap.lgsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.gpp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.gsw [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dmin.leaf.psi [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dmax.leaf.psi [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par.beam [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$leaf.par.diff [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.light [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.rubp [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$assim.co2 [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$gpp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$npp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$cba [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$plant.resp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$hflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$hflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wflxlc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$wflxwc [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$transp [[plab]] = rep(0. ,times=mymont$NPATCHES.GLOBAL) + patch$soil.resp [[plab]] = mymont$MMEAN.RH.PA + patch$fast.grnd.c [[plab]] = mymont$MMEAN.FAST.GRND.C.PA + patch$fast.soil.c [[plab]] = mymont$MMEAN.FAST.SOIL.C.PA + patch$struct.grnd.c [[plab]] = mymont$MMEAN.STRUCT.GRND.C.PA + patch$struct.soil.c [[plab]] = mymont$MMEAN.STRUCT.SOIL.C.PA + patch$microbe.soil.c [[plab]] = mymont$MMEAN.MICROBE.SOIL.C.PA + patch$slow.soil.c [[plab]] = mymont$MMEAN.SLOW.SOIL.C.PA + patch$passive.soil.c [[plab]] = mymont$MMEAN.PASSIVE.SOIL.C.PA + patch$fgc.in [[plab]] = mymont$MMEAN.FGC.IN.PA + patch$fsc.in [[plab]] = mymont$MMEAN.FSC.IN.PA + patch$stgc.in [[plab]] = mymont$MMEAN.STGC.IN.PA + patch$stsc.in [[plab]] = mymont$MMEAN.STSC.IN.PA + patch$soil.temp [[plab]] = mymont$MMEAN.SOIL.TEMP.PA - t00 + patch$soil.water [[plab]] = mymont$MMEAN.SOIL.WATER.PA + patch$soil.mstpot [[plab]] = - mymont$MMEAN.SOIL.MSTPOT.PA * grav * wdns * 1.e-6 + #------ Demographic rates. ----------------------------------------------------------# + patch$growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.growth [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$fire.lethal [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.mort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.ncbmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.hydmort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.dimort [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$agb.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$acc.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) + patch$bsa.recr [[plab]] = rep(NA_real_,times=mymont$NPATCHES.GLOBAL) #------ Mean diurnal cycle. ---------------------------------------------------------# zero.qpatch = matrix(data=0., nrow=mymont$NPATCHES.GLOBAL,ncol=mymont$NDCYC) na.qpatch = matrix(data=NA, nrow=mymont$NPATCHES.GLOBAL,ncol=mymont$NDCYC) - qpatch$sm.stress [[plab]] = na.qpatch - qpatch$leaf.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 - qpatch$leaf.water [[plab]] = zero.qpatch - qpatch$leaf.vpd [[plab]] = mymont$QMEAN.CAN.VPDEF.PA * 0.01 - qpatch$wood.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 - qpatch$par.leaf [[plab]] = zero.qpatch - qpatch$par.leaf.beam[[plab]] = zero.qpatch - qpatch$par.leaf.diff[[plab]] = zero.qpatch - qpatch$leaf.gpp [[plab]] = na.qpatch - qpatch$leaf.gsw [[plab]] = na.qpatch - qpatch$leaf.par [[plab]] = na.qpatch - qpatch$leaf.par.beam[[plab]] = na.qpatch - qpatch$leaf.par.diff[[plab]] = na.qpatch - qpatch$assim.light [[plab]] = na.qpatch - qpatch$assim.rubp [[plab]] = na.qpatch - qpatch$assim.co2 [[plab]] = na.qpatch - qpatch$gpp [[plab]] = zero.qpatch - qpatch$npp [[plab]] = zero.qpatch - qpatch$plant.resp [[plab]] = zero.qpatch - qpatch$hflxlc [[plab]] = zero.qpatch - qpatch$hflxwc [[plab]] = zero.qpatch - qpatch$wflxlc [[plab]] = zero.qpatch - qpatch$wflxwc [[plab]] = zero.qpatch - qpatch$transp [[plab]] = zero.qpatch - qpatch$soil.resp [[plab]] = mymont$QMEAN.RH.PA + qpatch$sm.stress [[plab]] = na.qpatch + qpatch$leaf.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 + qpatch$leaf.water [[plab]] = zero.qpatch + qpatch$leaf.water.im2[[plab]] = zero.qpatch + qpatch$leaf.vpd [[plab]] = mymont$QMEAN.CAN.VPDEF.PA * 0.01 + qpatch$wood.temp [[plab]] = mymont$QMEAN.CAN.TEMP.PA - t00 + qpatch$par.leaf [[plab]] = zero.qpatch + qpatch$par.leaf.beam [[plab]] = zero.qpatch + qpatch$par.leaf.diff [[plab]] = zero.qpatch + qpatch$leaf.gpp [[plab]] = na.qpatch + qpatch$leaf.gsw [[plab]] = na.qpatch + qpatch$leaf.par [[plab]] = na.qpatch + qpatch$leaf.par.beam [[plab]] = na.qpatch + qpatch$leaf.par.diff [[plab]] = na.qpatch + qpatch$assim.light [[plab]] = na.qpatch + qpatch$assim.rubp [[plab]] = na.qpatch + qpatch$assim.co2 [[plab]] = na.qpatch + qpatch$gpp [[plab]] = zero.qpatch + qpatch$npp [[plab]] = zero.qpatch + qpatch$plant.resp [[plab]] = zero.qpatch + qpatch$hflxlc [[plab]] = zero.qpatch + qpatch$hflxwc [[plab]] = zero.qpatch + qpatch$wflxlc [[plab]] = zero.qpatch + qpatch$wflxwc [[plab]] = zero.qpatch + qpatch$transp [[plab]] = zero.qpatch + qpatch$soil.resp [[plab]] = mymont$QMEAN.RH.PA #------------------------------------------------------------------------------------# @@ -1918,54 +2150,63 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# #----- Find some auxiliary patch-level properties. -------------------------------# - nplant.pa = tapply( X = mymont$NPLANT * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - lai.pa = tapply( X = mymont$MMEAN.LAI.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wai.pa = tapply( X = mymont$WAI.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.energy.pa = tapply( X = mymont$MMEAN.LEAF.ENERGY.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.water.pa = tapply( X = mymont$MMEAN.LEAF.WATER.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - leaf.hcap.pa = tapply( X = mymont$MMEAN.LEAF.HCAP.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.pa = tapply( X = mymont$MMEAN.PAR.L.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.beam.pa = tapply( X = mymont$MMEAN.PAR.L.BEAM.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - par.leaf.diff.pa = tapply( X = mymont$MMEAN.PAR.L.DIFF.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.energy.pa = tapply( X = mymont$MMEAN.WOOD.ENERGY.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.water.pa = tapply( X = mymont$MMEAN.WOOD.WATER.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply - wood.hcap.pa = tapply( X = mymont$MMEAN.WOOD.HCAP.CO * showconow - , INDEX = ipaconow - , FUN = sum - )#end tapply + nplant.pa = tapply( X = mymont$NPLANT * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + lai.pa = tapply( X = mymont$MMEAN.LAI.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wai.pa = tapply( X = mymont$WAI.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + + leaf.energy.pa = tapply( X = mymont$MMEAN.LEAF.ENERGY.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.water.pa = tapply( X = mymont$MMEAN.LEAF.WATER.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.water.im2.pa = tapply( X = mymont$MMEAN.LEAF.WATER.IM2.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + leaf.hcap.pa = tapply( X = mymont$MMEAN.LEAF.HCAP.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.pa = tapply( X = mymont$MMEAN.PAR.L.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.beam.pa = tapply( X = mymont$MMEAN.PAR.L.BEAM.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + par.leaf.diff.pa = tapply( X = mymont$MMEAN.PAR.L.DIFF.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.energy.pa = tapply( X = mymont$MMEAN.WOOD.ENERGY.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.water.pa = tapply( X = mymont$MMEAN.WOOD.WATER.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.water.im2.pa = tapply( X = mymont$MMEAN.WOOD.WATER.IM2.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply + wood.hcap.pa = tapply( X = mymont$MMEAN.WOOD.HCAP.CO * showconow + , INDEX = ipaconow + , FUN = sum + )#end tapply #----- Make root respiration extensive. ------------------------------------------# root.resp.pa = tapply( X = root.respconow*nplantconow , INDEX = ipaconow @@ -2002,18 +2243,21 @@ read.q.files <<- function( datum #----- Find the temperature and liquid fraction of leaf and wood. ----------------# - leaf.empty = leaf.hcap.pa == 0 - wood.empty = wood.hcap.pa == 0 - leaf.temp.pa = uextcm2tl( uext = leaf.energy.pa - , wmass = leaf.water.pa - , dryhcap = leaf.hcap.pa )$temp - t00 - wood.temp.pa = uextcm2tl( uext = wood.energy.pa - , wmass = wood.water.pa - , dryhcap = wood.hcap.pa )$temp - t00 - leaf.water.pa = leaf.water.pa / lai.pa - leaf.temp.pa [leaf.empty] = NA - leaf.water.pa[leaf.empty] = NA - wood.temp.pa [wood.empty] = NA + leaf.empty = leaf.hcap.pa == 0 + wood.empty = wood.hcap.pa == 0 + leaf.temp.pa = uextcm2tl( uext = leaf.energy.pa + , wmass = leaf.water.pa + + leaf.water.im2.pa + , dryhcap = leaf.hcap.pa )$temp - t00 + wood.temp.pa = uextcm2tl( uext = wood.energy.pa + , wmass = wood.water.pa + + wood.water.im2.pa + , dryhcap = wood.hcap.pa )$temp - t00 + leaf.water.pa = leaf.water.pa / lai.pa + leaf.temp.pa [leaf.empty] = NA_real_ + leaf.water.pa [leaf.empty] = NA_real_ + leaf.water.im2.pa[leaf.empty] = NA_real_ + wood.temp.pa [wood.empty] = NA_real_ #---------------------------------------------------------------------------------# @@ -2021,12 +2265,42 @@ read.q.files <<- function( datum #----- Find the variables that must be rendered extensive. -----------------------# - agb.pa = tapply(X=agbconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - ba.pa = tapply(X=baconow *nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - gpp.pa = tapply(X=gppconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - npp.pa = tapply(X=nppconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - cba.pa = tapply(X=cbaconow*nplantconow,INDEX=ipaconow,FUN=sum,na.rm=TRUE) - plant.resp.pa = tapply( X = plant.respconow*nplantconow + agb.pa = tapply( X = agbconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + agvolume.pa = tapply( X = agvolumeconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + bleaf.pa = tapply( X = bleafconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + ba.pa = tapply( X = baconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + gpp.pa = tapply( X = gppconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + npp.pa = tapply( X = nppconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + cba.pa = tapply( X = cbaconow * nplantconow * showconow + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + plant.resp.pa = tapply( X = plant.respconow * nplantconow * showconow , INDEX = ipaconow , FUN = sum , na.rm = TRUE @@ -2077,6 +2351,21 @@ read.q.files <<- function( datum + #---------------------------------------------------------------------------------# + # Canopy water potential is scaled by the canopy volume (based on Xiangtao's # + # suggestion). # + #---------------------------------------------------------------------------------# + dmin.leaf.psi.pa = mapply( FUN = weighted.mean + , x = split(dmin.leaf.psiconow,ipaconow) + , w = split(agvolumeconow ,ipaconow) + , SIMPLIFY = TRUE + )#end mapply + dmax.leaf.psi.pa = mapply( FUN = weighted.mean + , x = split(dmax.leaf.psiconow,ipaconow) + , w = split(agvolumeconow ,ipaconow) + , SIMPLIFY = TRUE + )#end mapply + #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# @@ -2216,83 +2505,271 @@ read.q.files <<- function( datum , SIMPLIFY = TRUE )#end mapply #----- Discard data from empty cohorts. -----------------------------------------# - leaf.gpp.pa [leaf.empty] = NA - leaf.par.pa [leaf.empty] = NA - leaf.par.beam.pa[leaf.empty] = NA - leaf.par.diff.pa[leaf.empty] = NA - leaf.gsw.pa [leaf.empty] = NA - leaf.vpd.pa [leaf.empty] = NA - sm.stress.pa [leaf.empty] = NA - assim.light.pa [leaf.empty] = NA - assim.rubp.pa [leaf.empty] = NA - assim.co2.pa [leaf.empty] = NA - phap.lpar.pa [leaf.empty] = NA - phap.ltemp.pa [leaf.empty] = NA - phap.lwater.pa [leaf.empty] = NA - phap.lvpd.pa [leaf.empty] = NA - phap.sms.pa [leaf.empty] = NA - phap.lgbw.pa [leaf.empty] = NA - phap.lgsw.pa [leaf.empty] = NA + leaf.gpp.pa [leaf.empty] = NA_real_ + leaf.par.pa [leaf.empty] = NA_real_ + leaf.par.beam.pa[leaf.empty] = NA_real_ + leaf.par.diff.pa[leaf.empty] = NA_real_ + leaf.gsw.pa [leaf.empty] = NA_real_ + leaf.vpd.pa [leaf.empty] = NA_real_ + sm.stress.pa [leaf.empty] = NA_real_ + assim.light.pa [leaf.empty] = NA_real_ + assim.rubp.pa [leaf.empty] = NA_real_ + assim.co2.pa [leaf.empty] = NA_real_ + phap.lpar.pa [leaf.empty] = NA_real_ + phap.ltemp.pa [leaf.empty] = NA_real_ + phap.lwater.pa [leaf.empty] = NA_real_ + phap.lvpd.pa [leaf.empty] = NA_real_ + phap.sms.pa [leaf.empty] = NA_real_ + phap.lgbw.pa [leaf.empty] = NA_real_ + phap.lgsw.pa [leaf.empty] = NA_real_ #---------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------# # Copy the data back to the patch. # #---------------------------------------------------------------------------------# - idx.leaf = idx[! leaf.empty] - idx.wood = idx[! wood.empty] - patch$lai [[plab]][idx ] = lai.pa - patch$wai [[plab]][idx ] = wai.pa - patch$agb [[plab]][idx ] = agb.pa - patch$ba [[plab]][idx ] = ba.pa - patch$nplant [[plab]][idx ] = nplant.pa - patch$can.depth [[plab]][idx ] = can.depth.pa - patch$can.area [[plab]][idx ] = can.area.pa - patch$veg.height [[plab]][idx ] = veg.height.pa - patch$veg.displace [[plab]][idx ] = veg.displace.pa - patch$veg.rough [[plab]][idx ] = veg.rough.pa - patch$can.rough [[plab]][idx ] = can.rough.pa - patch$wood.dens [[plab]][idx ] = wood.dens.pa - patch$vm0 [[plab]][idx ] = vm0.pa - patch$llspan [[plab]][idx ] = llspan.pa - patch$sla [[plab]][idx ] = sla.pa - patch$par.leaf [[plab]][idx ] = par.leaf.pa - patch$par.leaf.beam[[plab]][idx ] = par.leaf.beam.pa - patch$par.leaf.diff[[plab]][idx ] = par.leaf.diff.pa - patch$phap.lpar [[plab]][idx.leaf] = phap.lpar.pa [! leaf.empty] - patch$phap.ltemp [[plab]][idx.leaf] = phap.ltemp.pa [! leaf.empty] - patch$phap.lwater [[plab]][idx.leaf] = phap.lwater.pa [! leaf.empty] - patch$phap.lvpd [[plab]][idx.leaf] = phap.lvpd.pa [! leaf.empty] - patch$phap.sms [[plab]][idx.leaf] = phap.sms.pa [! leaf.empty] - patch$phap.lgbw [[plab]][idx.leaf] = phap.lgbw.pa [! leaf.empty] - patch$phap.lgsw [[plab]][idx.leaf] = phap.lgsw.pa [! leaf.empty] - patch$sm.stress [[plab]][idx.leaf] = sm.stress.pa [! leaf.empty] - patch$leaf.temp [[plab]][idx.leaf] = leaf.temp.pa [! leaf.empty] - patch$leaf.water [[plab]][idx.leaf] = leaf.water.pa [! leaf.empty] - patch$leaf.vpd [[plab]][idx.leaf] = leaf.vpd.pa [! leaf.empty] - patch$leaf.gpp [[plab]][idx.leaf] = leaf.gpp.pa [! leaf.empty] - patch$leaf.gsw [[plab]][idx.leaf] = leaf.gsw.pa [! leaf.empty] - patch$leaf.par [[plab]][idx.leaf] = leaf.par.pa [! leaf.empty] - patch$leaf.par.beam[[plab]][idx.leaf] = leaf.par.beam.pa[! leaf.empty] - patch$leaf.par.diff[[plab]][idx.leaf] = leaf.par.diff.pa[! leaf.empty] - patch$assim.light [[plab]][idx.leaf] = assim.light.pa [! leaf.empty] - patch$assim.rubp [[plab]][idx.leaf] = assim.rubp.pa [! leaf.empty] - patch$assim.co2 [[plab]][idx.leaf] = assim.co2.pa [! leaf.empty] - patch$wood.temp [[plab]][idx.wood] = wood.temp.pa [! wood.empty] - patch$gpp [[plab]][idx ] = gpp.pa - patch$npp [[plab]][idx ] = npp.pa - patch$cba [[plab]][idx ] = cba.pa - patch$plant.resp [[plab]][idx ] = plant.resp.pa - patch$hflxlc [[plab]][idx ] = hflxlc.pa - patch$hflxwc [[plab]][idx ] = hflxwc.pa - patch$wflxlc [[plab]][idx ] = wflxlc.pa - patch$wflxwc [[plab]][idx ] = wflxwc.pa - patch$transp [[plab]][idx ] = transp.pa + idx.leaf = idx[! leaf.empty] + idx.wood = idx[! wood.empty] + patch$lai [[plab]][idx ] = lai.pa + patch$wai [[plab]][idx ] = wai.pa + patch$agb [[plab]][idx ] = agb.pa + patch$ba [[plab]][idx ] = ba.pa + patch$nplant [[plab]][idx ] = nplant.pa + patch$bleaf [[plab]][idx ] = bleaf.pa + patch$can.depth [[plab]][idx ] = can.depth.pa + patch$can.area [[plab]][idx ] = can.area.pa + patch$veg.height [[plab]][idx ] = veg.height.pa + patch$veg.displace [[plab]][idx ] = veg.displace.pa + patch$veg.rough [[plab]][idx ] = veg.rough.pa + patch$can.rough [[plab]][idx ] = can.rough.pa + patch$wood.dens [[plab]][idx ] = wood.dens.pa + patch$vm0 [[plab]][idx ] = vm0.pa + patch$llspan [[plab]][idx ] = llspan.pa + patch$sla [[plab]][idx ] = sla.pa + patch$par.leaf [[plab]][idx ] = par.leaf.pa + patch$par.leaf.beam [[plab]][idx ] = par.leaf.beam.pa + patch$par.leaf.diff [[plab]][idx ] = par.leaf.diff.pa + patch$phap.lpar [[plab]][idx.leaf] = phap.lpar.pa [! leaf.empty] + patch$phap.ltemp [[plab]][idx.leaf] = phap.ltemp.pa [! leaf.empty] + patch$phap.lwater [[plab]][idx.leaf] = phap.lwater.pa [! leaf.empty] + patch$phap.lvpd [[plab]][idx.leaf] = phap.lvpd.pa [! leaf.empty] + patch$phap.sms [[plab]][idx.leaf] = phap.sms.pa [! leaf.empty] + patch$phap.lgbw [[plab]][idx.leaf] = phap.lgbw.pa [! leaf.empty] + patch$phap.lgsw [[plab]][idx.leaf] = phap.lgsw.pa [! leaf.empty] + patch$sm.stress [[plab]][idx.leaf] = sm.stress.pa [! leaf.empty] + patch$leaf.temp [[plab]][idx.leaf] = leaf.temp.pa [! leaf.empty] + patch$leaf.water [[plab]][idx.leaf] = leaf.water.pa [! leaf.empty] + patch$leaf.water.im2[[plab]][idx.leaf] = leaf.water.im2.pa[! leaf.empty] + patch$leaf.vpd [[plab]][idx.leaf] = leaf.vpd.pa [! leaf.empty] + patch$leaf.gpp [[plab]][idx.leaf] = leaf.gpp.pa [! leaf.empty] + patch$leaf.gsw [[plab]][idx.leaf] = leaf.gsw.pa [! leaf.empty] + patch$leaf.par [[plab]][idx.leaf] = leaf.par.pa [! leaf.empty] + patch$leaf.par.beam [[plab]][idx.leaf] = leaf.par.beam.pa [! leaf.empty] + patch$leaf.par.diff [[plab]][idx.leaf] = leaf.par.diff.pa [! leaf.empty] + patch$assim.light [[plab]][idx.leaf] = assim.light.pa [! leaf.empty] + patch$assim.rubp [[plab]][idx.leaf] = assim.rubp.pa [! leaf.empty] + patch$assim.co2 [[plab]][idx.leaf] = assim.co2.pa [! leaf.empty] + patch$wood.temp [[plab]][idx.wood] = wood.temp.pa [! wood.empty] + patch$dmin.leaf.psi [[plab]][idx ] = dmin.leaf.psi.pa + patch$dmax.leaf.psi [[plab]][idx ] = dmax.leaf.psi.pa + patch$gpp [[plab]][idx ] = gpp.pa + patch$npp [[plab]][idx ] = npp.pa + patch$cba [[plab]][idx ] = cba.pa + patch$plant.resp [[plab]][idx ] = plant.resp.pa + patch$hflxlc [[plab]][idx ] = hflxlc.pa + patch$hflxwc [[plab]][idx ] = hflxwc.pa + patch$wflxlc [[plab]][idx ] = wflxlc.pa + patch$wflxwc [[plab]][idx ] = wflxwc.pa + patch$transp [[plab]][idx ] = transp.pa #------ Soil respiration mixes cohort (root) and patch (hetetrophic). ------------# - patch$soil.resp [[plab]][idx] = patch$soil.resp [[plab]][idx] + root.resp.pa + patch$soil.resp [[plab]][idx] = patch$soil.resp [[plab]][idx] + root.resp.pa + #---------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + # Demographic rates. # + #---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + for (jpa in sequence(mymont$NPATCHES.GLOBAL)){ + + #------------------------------------------------------------------------------# + # For mortality and growth, we keep deleting the tiny cohorts because they # + # skew the rates quite significantly and they are rarely included in forest # + # inventory surveys. # + #------------------------------------------------------------------------------# + psel = (ipaconow == jpa) & (dbhconow >= census.dbh.min) + if (any(psel)){ + #----- Growth rates are weighted by population. ----------------------------# + dbh.growth = - 100. * log( weighted.mean( x = exp(-growthconow [psel]) + , w = nplantconow [psel] + * dbhconow [psel] + )#end weighted.mean + )#end log + agb.growth = - 100. * log( weighted.mean( x = exp(-agb.growthconow[psel]) + , w = nplantconow [psel] + * agbconow [psel] + )#end weighted.mean + )#end log + bsa.growth = - 100. * log( weighted.mean( x = exp(-bsa.growthconow[psel]) + , w = nplantconow [psel] + * baconow [psel] + )#end weighted.mean + )#end log + acc.growth = sum( nplantconow[psel] + * agbconow[psel] * (1.-exp(-agb.growthconow[psel])) + )#end sum + patch$growth [[plab]][jpa] = dbh.growth + patch$agb.growth [[plab]][jpa] = agb.growth + patch$acc.growth [[plab]][jpa] = acc.growth + patch$bsa.growth [[plab]][jpa] = bsa.growth + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total number of plants and previous population if the only # + # mortality was the mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] ) + previous = sum( nplantconow[psel] * exp(mortconow [psel])) + ncb.previous = sum( nplantconow[psel] * exp(ncbmortconow [psel])) + hyd.previous = sum( nplantconow[psel] * exp(hydmortconow [psel])) + di.previous = sum( nplantconow[psel] * exp(dimortconow [psel])) + fl.previous = sum( nplantconow[psel] * exp(fire.lethalconow[psel])) + patch$mort [[plab]][jpa] = log(previous / survivor) + patch$ncbmort [[plab]][jpa] = log(ncb.previous / survivor) + patch$hydmort [[plab]][jpa] = log(hyd.previous / survivor) + patch$dimort [[plab]][jpa] = log(di.previous / survivor) + patch$fire.lethal[[plab]][jpa] = log(fl.previous / survivor) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total AGB and previous AGB if the only mortality was the # + # mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * agbcolmon[psel]) + previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(mortconow [psel]) + )#end sum + ncb.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(ncbmortconow [psel]) + )#end sum + hyd.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(hydmortconow [psel]) + )#end sum + di.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp(dimortconow [psel]) + )#end sum + patch$agb.mort [[plab]][jpa] = log( previous / survivor ) + patch$agb.ncbmort[[plab]][jpa] = log( ncb.previous / survivor ) + patch$agb.hydmort[[plab]][jpa] = log( hyd.previous / survivor ) + patch$agb.dimort [[plab]][jpa] = log( di.previous / survivor ) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total AGB and previous AGB if the only mortality was the # + # mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * agbcolmon[psel]) + previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( mortconow [psel] / 12.) + )#end sum + ncb.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( ncbmortconow[psel] / 12.) + )#end sum + hyd.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( hydmortconow[psel] / 12.) + )#end sum + di.previous = sum( nplantconow[psel] * agbcolmon[psel] + * exp( dimortconow [psel] / 12.) + )#end sum + patch$acc.mort [[plab]][jpa] = 12. * (previous - survivor) + patch$acc.ncbmort[[plab]][jpa] = 12. * (ncb.previous - survivor) + patch$acc.hydmort[[plab]][jpa] = 12. * (hyd.previous - survivor) + patch$acc.dimort [[plab]][jpa] = 12. * (di.previous - survivor) + #---------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------# + # Find the total basal area and previous basal area if the only # + # mortality was the mortality we test. # + #---------------------------------------------------------------------------# + survivor = sum( nplantconow[psel] * bacolmon[psel]) + previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(mortconow [psel]) + )#end sum + ncb.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(ncbmortconow [psel]) + )#end sum + hyd.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(hydmortconow [psel]) + )#end sum + di.previous = sum( nplantconow[psel] * bacolmon[psel] + * exp(dimortconow [psel]) + )#end sum + patch$bsa.mort [[plab]][jpa] = log( previous / survivor ) + patch$bsa.ncbmort[[plab]][jpa] = log( ncb.previous / survivor ) + patch$bsa.hydmort[[plab]][jpa] = log( hyd.previous / survivor ) + patch$bsa.dimort [[plab]][jpa] = log( di.previous / survivor ) + #---------------------------------------------------------------------------# + }#end if + #------------------------------------------------------------------------------# + + + + #------------------------------------------------------------------------------# + # Recruitment: we must determine whether the plant grew into the new # + # category or not. # + #------------------------------------------------------------------------------# + psel.pop = (ipaconow == jpa) & (dbhconow >= census.dbh.min) + psel.est = psel.pop & (dbhconow.1ago >= census.dbh.min) + psel.elm = psel.pop & (dbhconow.lmon >= census.dbh.min) + if (any(psel.pop) & any(psel.est)){ + + #----- Recruitment rate in terms of individuals. ---------------------------# + population = sum(nplantconow[psel.pop]) + established = sum(nplantconow[psel.est]) + patch$recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of above-ground biomass. ------------------# + population = sum(nplantconow[psel.pop]*agbconow[psel.pop]) + established = sum(nplantconow[psel.est]*agbconow[psel.est]) + patch$agb.recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of above-ground biomass. ------------------# + population = sum(nplantconow[psel.pop]*agbconow[psel.pop]) + established = sum(nplantconow[psel.elm]*agbconow[psel.elm]) + patch$acc.recr[[plab]][jpa] = 12. * (population - established) + #---------------------------------------------------------------------------# + + + #----- Recruitment rate in terms of basal area. ----------------------------# + population = sum(nplantconow[psel.pop]*baconow [psel.pop]) + established = sum(nplantconow[psel.est]*baconow [psel.est]) + patch$bsa.recr[[plab]][jpa] = log(population / established) + #---------------------------------------------------------------------------# + }#end if + #------------------------------------------------------------------------------# + }#end for (jpa in sequence(mymont$NPATCHES.GLOBAL)) + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------# + + @@ -2308,78 +2785,90 @@ read.q.files <<- function( datum #----- Find some auxiliary patch-level properties. -------------------------------# - q.nplant.pa = qapply( X = q.nplantconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.lai.pa = qapply( X = q.laiconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wai.pa = qapply( X = q.waiconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.energy.pa = qapply( X = mymont$QMEAN.LEAF.ENERGY.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.water.pa = qapply( X = mymont$QMEAN.LEAF.WATER.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.leaf.hcap.pa = qapply( X = mymont$QMEAN.LEAF.HCAP.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.pa = qapply( X = mymont$QMEAN.PAR.L.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.beam.pa = qapply( X = mymont$QMEAN.PAR.L.BEAM.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.par.leaf.diff.pa = qapply( X = mymont$QMEAN.PAR.L.DIFF.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.energy.pa = qapply( X = mymont$QMEAN.WOOD.ENERGY.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.water.pa = qapply( X = mymont$QMEAN.WOOD.WATER.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply - q.wood.hcap.pa = qapply( X = mymont$QMEAN.WOOD.HCAP.CO * q.showconow - , DIM = 1 - , INDEX = ipaconow - , FUN = sum - , na.rm = TRUE - )#end tapply + q.nplant.pa = qapply( X = q.nplantconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.lai.pa = qapply( X = q.laiconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wai.pa = qapply( X = q.waiconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.energy.pa = qapply( X = mymont$QMEAN.LEAF.ENERGY.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.water.pa = qapply( X = mymont$QMEAN.LEAF.WATER.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.water.im2.pa = qapply( X = mymont$QMEAN.LEAF.WATER.IM2.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.leaf.hcap.pa = qapply( X = mymont$QMEAN.LEAF.HCAP.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.pa = qapply( X = mymont$QMEAN.PAR.L.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.beam.pa = qapply( X = mymont$QMEAN.PAR.L.BEAM.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.par.leaf.diff.pa = qapply( X = mymont$QMEAN.PAR.L.DIFF.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.energy.pa = qapply( X = mymont$QMEAN.WOOD.ENERGY.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.water.pa = qapply( X = mymont$QMEAN.WOOD.WATER.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.water.im2.pa = qapply( X = mymont$QMEAN.WOOD.WATER.IM2.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply + q.wood.hcap.pa = qapply( X = mymont$QMEAN.WOOD.HCAP.CO * q.showconow + , DIM = 1 + , INDEX = ipaconow + , FUN = sum + , na.rm = TRUE + )#end tapply #----- Make root respiration extensive. ------------------------------------------# q.root.resp.pa = qapply( X = q.root.respconow * q.nplantconow , DIM = 1 @@ -2392,27 +2881,33 @@ read.q.files <<- function( datum #----- Find the temperature and liquid fraction of leaf and wood. ----------------# - q.leaf.empty = q.leaf.hcap.pa == 0 - q.wood.empty = q.wood.hcap.pa == 0 - q.leaf.temp.pa = uextcm2tl( uext = q.leaf.energy.pa - , wmass = q.leaf.water.pa - , dryhcap = q.leaf.hcap.pa )$temp - t00 - q.wood.temp.pa = uextcm2tl( uext = q.wood.energy.pa - , wmass = q.wood.water.pa - , dryhcap = q.wood.hcap.pa )$temp - t00 - q.leaf.water.pa = q.leaf.water.pa / q.lai.pa - q.leaf.temp.pa = ifelse( test = q.leaf.hcap.pa == 0 - , yes = NA - , no = q.leaf.temp.pa - )#end ifelse - q.leaf.water.pa = ifelse( test = q.leaf.hcap.pa == 0 - , yes = NA - , no = q.leaf.water.pa - )#end ifelse - q.wood.temp.pa = ifelse( test = q.wood.hcap.pa == 0 - , yes = NA - , no = q.wood.temp.pa - )#end ifelse + q.leaf.empty = q.leaf.hcap.pa == 0 + q.wood.empty = q.wood.hcap.pa == 0 + q.leaf.temp.pa = uextcm2tl( uext = q.leaf.energy.pa + , wmass = q.leaf.water.pa + + q.leaf.water.im2.pa + , dryhcap = q.leaf.hcap.pa )$temp - t00 + q.wood.temp.pa = uextcm2tl( uext = q.wood.energy.pa + , wmass = q.wood.water.pa + + q.wood.water.im2.pa + , dryhcap = q.wood.hcap.pa )$temp - t00 + q.leaf.water.pa = q.leaf.water.pa / q.lai.pa + q.leaf.temp.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.temp.pa + )#end ifelse + q.leaf.water.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.water.pa + )#end ifelse + q.leaf.water.im2.pa = ifelse( test = q.leaf.hcap.pa == 0. + , yes = NA_real_ + , no = q.leaf.water.im2.pa + )#end ifelse + q.wood.temp.pa = ifelse( test = q.wood.hcap.pa == 0. + , yes = NA_real_ + , no = q.wood.temp.pa + )#end ifelse #---------------------------------------------------------------------------------# @@ -2546,16 +3041,16 @@ read.q.files <<- function( datum )#end mapply )#end t #----- Discard data from empty cohorts. -----------------------------------------# - q.leaf.gpp.pa [q.leaf.empty] = NA - q.leaf.par.pa [q.leaf.empty] = NA - q.leaf.par.beam.pa[q.leaf.empty] = NA - q.leaf.par.diff.pa[q.leaf.empty] = NA - q.leaf.gsw.pa [q.leaf.empty] = NA - q.leaf.vpd.pa [q.leaf.empty] = NA - q.sm.stress.pa [q.leaf.empty] = NA - q.assim.light.pa [q.leaf.empty] = NA - q.assim.rubp.pa [q.leaf.empty] = NA - q.assim.co2.pa [q.leaf.empty] = NA + q.leaf.gpp.pa [q.leaf.empty] = NA_real_ + q.leaf.par.pa [q.leaf.empty] = NA_real_ + q.leaf.par.beam.pa[q.leaf.empty] = NA_real_ + q.leaf.par.diff.pa[q.leaf.empty] = NA_real_ + q.leaf.gsw.pa [q.leaf.empty] = NA_real_ + q.leaf.vpd.pa [q.leaf.empty] = NA_real_ + q.sm.stress.pa [q.leaf.empty] = NA_real_ + q.assim.light.pa [q.leaf.empty] = NA_real_ + q.assim.rubp.pa [q.leaf.empty] = NA_real_ + q.assim.co2.pa [q.leaf.empty] = NA_real_ #---------------------------------------------------------------------------------# @@ -2564,30 +3059,31 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------------# # Copy the data back to the patch. # #---------------------------------------------------------------------------------# - qpatch$par.leaf [[plab]][idx ,] = q.par.leaf.pa - qpatch$par.leaf.beam[[plab]][idx ,] = q.par.leaf.beam.pa - qpatch$par.leaf.diff[[plab]][idx ,] = q.par.leaf.diff.pa - qpatch$sm.stress [[plab]][idx.leaf,] = q.sm.stress.pa [! q.leaf.empty] - qpatch$leaf.temp [[plab]][idx.leaf,] = q.leaf.temp.pa [! q.leaf.empty] - qpatch$leaf.water [[plab]][idx.leaf,] = q.leaf.water.pa [! q.leaf.empty] - qpatch$leaf.vpd [[plab]][idx.leaf,] = q.leaf.vpd.pa [! q.leaf.empty] - qpatch$leaf.gpp [[plab]][idx.leaf,] = q.leaf.gpp.pa [! q.leaf.empty] - qpatch$leaf.gsw [[plab]][idx.leaf,] = q.leaf.gsw.pa [! q.leaf.empty] - qpatch$leaf.par [[plab]][idx.leaf,] = q.leaf.par.pa [! q.leaf.empty] - qpatch$leaf.par.beam[[plab]][idx.leaf,] = q.leaf.par.beam.pa[! q.leaf.empty] - qpatch$leaf.par.diff[[plab]][idx.leaf,] = q.leaf.par.diff.pa[! q.leaf.empty] - qpatch$assim.light [[plab]][idx.leaf,] = q.assim.light.pa [! q.leaf.empty] - qpatch$assim.rubp [[plab]][idx.leaf,] = q.assim.rubp.pa [! q.leaf.empty] - qpatch$assim.co2 [[plab]][idx.leaf,] = q.assim.co2.pa [! q.leaf.empty] - qpatch$wood.temp [[plab]][idx.wood,] = q.wood.temp.pa [! q.wood.empty] - qpatch$gpp [[plab]][idx ,] = q.gpp.pa - qpatch$npp [[plab]][idx ,] = q.npp.pa - qpatch$plant.resp [[plab]][idx ,] = q.plant.resp.pa - qpatch$hflxlc [[plab]][idx ,] = q.hflxlc.pa - qpatch$hflxwc [[plab]][idx ,] = q.hflxwc.pa - qpatch$wflxlc [[plab]][idx ,] = q.wflxlc.pa - qpatch$wflxwc [[plab]][idx ,] = q.wflxwc.pa - qpatch$transp [[plab]][idx ,] = q.transp.pa + qpatch$par.leaf [[plab]][idx ,] = q.par.leaf.pa + qpatch$par.leaf.beam [[plab]][idx ,] = q.par.leaf.beam.pa + qpatch$par.leaf.diff [[plab]][idx ,] = q.par.leaf.diff.pa + qpatch$sm.stress [[plab]][idx.leaf,] = q.sm.stress.pa [! q.leaf.empty] + qpatch$leaf.temp [[plab]][idx.leaf,] = q.leaf.temp.pa [! q.leaf.empty] + qpatch$leaf.water [[plab]][idx.leaf,] = q.leaf.water.pa [! q.leaf.empty] + qpatch$leaf.water.im2[[plab]][idx.leaf,] = q.leaf.water.im2.pa[! q.leaf.empty] + qpatch$leaf.vpd [[plab]][idx.leaf,] = q.leaf.vpd.pa [! q.leaf.empty] + qpatch$leaf.gpp [[plab]][idx.leaf,] = q.leaf.gpp.pa [! q.leaf.empty] + qpatch$leaf.gsw [[plab]][idx.leaf,] = q.leaf.gsw.pa [! q.leaf.empty] + qpatch$leaf.par [[plab]][idx.leaf,] = q.leaf.par.pa [! q.leaf.empty] + qpatch$leaf.par.beam [[plab]][idx.leaf,] = q.leaf.par.beam.pa [! q.leaf.empty] + qpatch$leaf.par.diff [[plab]][idx.leaf,] = q.leaf.par.diff.pa [! q.leaf.empty] + qpatch$assim.light [[plab]][idx.leaf,] = q.assim.light.pa [! q.leaf.empty] + qpatch$assim.rubp [[plab]][idx.leaf,] = q.assim.rubp.pa [! q.leaf.empty] + qpatch$assim.co2 [[plab]][idx.leaf,] = q.assim.co2.pa [! q.leaf.empty] + qpatch$wood.temp [[plab]][idx.wood,] = q.wood.temp.pa [! q.wood.empty] + qpatch$gpp [[plab]][idx ,] = q.gpp.pa + qpatch$npp [[plab]][idx ,] = q.npp.pa + qpatch$plant.resp [[plab]][idx ,] = q.plant.resp.pa + qpatch$hflxlc [[plab]][idx ,] = q.hflxlc.pa + qpatch$hflxwc [[plab]][idx ,] = q.hflxwc.pa + qpatch$wflxlc [[plab]][idx ,] = q.wflxlc.pa + qpatch$wflxwc [[plab]][idx ,] = q.wflxwc.pa + qpatch$transp [[plab]][idx ,] = q.transp.pa #------ Soil respiration mixes cohort (root) and patch (hetetrophic). ------------# qpatch$soil.resp[[plab]][idx,] = qpatch$soil.resp[[plab]][idx,] + q.root.resp.pa #---------------------------------------------------------------------------------# @@ -2615,6 +3111,340 @@ read.q.files <<- function( datum + #====================================================================================# + #====================================================================================# + #====================================================================================# + #====================================================================================# + # Find the site-level variables. # + #------------------------------------------------------------------------------------# + #---- Time-invariant variables (we keep time to make post-post-processing easier). --# + site$isi [m,] = isi + site$lsl [m,] = lslsi + site$ntext[m,] = ntextsi + site$area [m,] = areasi + #---- Variables that can be copied directly from the output. ------------------------# + site$fire.density [m,] = mymont$MMEAN.FIRE.DENSITY.SI * 1.e6 + site$fire.extinction[m,] = 100. * (1. - exp(-mymont$MMEAN.FIRE.EXTINCTION.SI)) + site$fire.intensity [m,] = mymont$MMEAN.FIRE.INTENSITY.SI * 1.e3 + site$fire.tlethal [m,] = mymont$MMEAN.FIRE.TLETHAL.SI / min.sec + site$fire.spread [m,] = mymont$MMEAN.FIRE.SPREAD.SI * min.sec + site$burnt.area [m,] = mymont$BURNT.AREA * 100. + site$ignition.rate [m,] = mymont$MMEAN.IGNITION.RATE.SI * 1.e6*mondays*day.sec + site$fire.f.bherb [m,] = mymont$MMEAN.FIRE.F.BHERB.SI * 100. + site$fire.f.bwoody [m,] = mymont$MMEAN.FIRE.F.BWOODY.SI * 100. + site$fire.f.fgc [m,] = mymont$MMEAN.FIRE.F.FGC.SI * 100. + site$fire.f.stgc [m,] = mymont$MMEAN.FIRE.F.STGC.SI * 100. + #----- Variables that should be scaled by area (most of them). ----------------------# + site$lai [m,] = weighted.mean( x = patch$lai [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wai [m,] = weighted.mean( x = patch$wai [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$agb [m,] = weighted.mean( x = patch$agb [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$ba [m,] = weighted.mean( x = patch$ba [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nplant [m,] = weighted.mean( x = patch$nplant [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$fast.grnd.c [m,] = weighted.mean( x = patch$fast.grnd.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$fast.soil.c [m,] = weighted.mean( x = patch$fast.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$struct.grnd.c [m,] = weighted.mean( x = patch$struct.grnd.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$struct.soil.c [m,] = weighted.mean( x = patch$struct.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$microbe.soil.c [m,] = weighted.mean( x = patch$microbe.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$slow.soil.c [m,] = weighted.mean( x = patch$slow.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$passive.soil.c [m,] = weighted.mean( x = patch$passive.soil.c [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nep [m,] = weighted.mean( x = patch$nep [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$het.resp [m,] = weighted.mean( x = patch$het.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.resp [m,] = weighted.mean( x = patch$soil.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cflxca [m,] = weighted.mean( x = patch$cflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cflxst [m,] = weighted.mean( x = patch$cflxst [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$nee [m,] = weighted.mean( x = patch$nee [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxca [m,] = weighted.mean( x = patch$hflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxgc [m,] = weighted.mean( x = patch$hflxgc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$qwflxca [m,] = weighted.mean( x = patch$qwflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxca [m,] = weighted.mean( x = patch$wflxca [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxgc [m,] = weighted.mean( x = patch$wflxgc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$ustar [m,] = weighted.mean( x = patch$ustar [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rshortup [m,] = weighted.mean( x = patch$rshortup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rlongup [m,] = weighted.mean( x = patch$rlongup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$parup [m,] = weighted.mean( x = patch$parup [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rshort.gnd [m,] = weighted.mean( x = patch$rshort.gnd [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$par.gnd [m,] = weighted.mean( x = patch$par.gnd [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$rnet [m,] = weighted.mean( x = patch$rnet [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$can.depth [m,] = weighted.mean( x = patch$can.depth [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$can.area [m,] = weighted.mean( x = patch$can.area [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$veg.height [m,] = weighted.mean( x = patch$veg.height [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$sm.stress [m,] = weighted.mean( x = patch$sm.stress [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gpp [m,] = weighted.mean( x = patch$gpp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$npp [m,] = weighted.mean( x = patch$npp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$plant.resp [m,] = weighted.mean( x = patch$plant.resp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$cba [m,] = weighted.mean( x = patch$cba [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$reco [m,] = weighted.mean( x = patch$reco [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxlc [m,] = weighted.mean( x = patch$hflxlc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$hflxwc [m,] = weighted.mean( x = patch$hflxwc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxlc [m,] = weighted.mean( x = patch$wflxlc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$wflxwc [m,] = weighted.mean( x = patch$wflxwc [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$transp [m,] = weighted.mean( x = patch$transp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gnd.temp [m,] = weighted.mean( x = patch$gnd.temp [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$gnd.shv [m,] = weighted.mean( x = patch$gnd.shv [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.temp.top [m,] = weighted.mean( x = patch$soil.temp.top [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.water.top [m,] = weighted.mean( x = patch$soil.water.top [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.water.bot [m,] = weighted.mean( x = patch$soil.water.bot [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.wetness.top[m,] = weighted.mean( x = patch$soil.wetness.top[[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$soil.wetness.bot[m,] = weighted.mean( x = patch$soil.wetness.bot[[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.water [m,] = weighted.mean( x = patch$leaf.water [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.water.im2 [m,] = weighted.mean( x = patch$leaf.water.im2 [[plab]] + , w = areapa + , na.rm = TRUE + )#end weighted.mean + #----- Quantities that should be weighted by leaf area. -----------------------------# + laiareapa = patch$lai[[plab]] * areapa + if ( sum(laiareapa) > tiny.num ){ + site$vm0 [m,] = weighted.mean( x = patch$vm0 [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.temp [m,] = weighted.mean( x = patch$leaf.temp [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.vpd [m,] = weighted.mean( x = patch$leaf.vpd [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.gpp [m,] = weighted.mean( x = patch$leaf.gpp [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.gsw [m,] = weighted.mean( x = patch$leaf.gsw [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par [m,] = weighted.mean( x = patch$leaf.par [[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par.beam[m,] = weighted.mean( x = patch$leaf.par.beam[[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + site$leaf.par.diff[m,] = weighted.mean( x = patch$leaf.par.diff[[plab]] + , w = laiareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$vm0 [m,] = NA_real_ + site$leaf.temp [m,] = NA_real_ + site$leaf.vpd [m,] = NA_real_ + site$leaf.gpp [m,] = NA_real_ + site$leaf.gsw [m,] = NA_real_ + site$leaf.par [m,] = NA_real_ + site$leaf.par.beam[m,] = NA_real_ + site$leaf.par.diff[m,] = NA_real_ + }#end if ( sum(laiareapa) > tiny.num) + #---- Wood density is scaled by basal area. -----------------------------------------# + basareapa = patch$ba[[plab]] * areapa + if ( sum(basareapa) > tiny.num ){ + site$wood.dens [m,] = weighted.mean( x = patch$wood.dens [[plab]] + , w = basareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$wood.dens [m,] = NA_real_ + }#end if (sum(basareapa) > tiny.num) + #---- SLA and leaf life span use leaf biomass as weighting factor. ------------------# + bleafareapa = patch$bleaf[[plab]] * areapa + if ( sum(bleafareapa) > tiny.num ){ + + ltor.si = weighted.mean( x = ltor.pa + , w = bleafareapa + , na.rm = TRUE + )#end weighted.mean + site$sla [m,] = weighted.mean( x = patch$sla[[plab]] + , w = bleafareapa + , na.rm = TRUE + )#end weighted.mean + site$llspan [m,] = ifelse( test = ltor.si %gt% 0. + , yes = 1. / ltor.si + , no = NA_real_ + )#end ifelse + }else{ + site$llspan [m,] = NA_real_ + site$sla [m,] = NA_real_ + }#end if ( sum(bleafareapa) > tiny.num ) + #---- Leaf water potential. Use aboveground volume as weighting factor. ------------# + agvolumeareapa = agvolume.pa * areapa + if ( sum(agvolumeareapa) > tiny.num ){ + site$dmin.leaf.psi[m,] = weighted.mean( x = patch$dmin.leaf.psi[[plab]] + , w = agvolumeareapa + , na.rm = TRUE + )#end weighted.mean + site$dmax.leaf.psi[m,] = weighted.mean( x = patch$dmax.leaf.psi[[plab]] + , w = agvolumeareapa + , na.rm = TRUE + )#end weighted.mean + }else{ + site$dmin.leaf.psi[m,] = NA_real_ + site$dmax.leaf.psi[m,] = NA_real_ + }#end if ( sum(agvolumeareapa) > tiny.num ) + #------------------------------------------------------------------------------------# + + + #====================================================================================# + #====================================================================================# + #====================================================================================# + #====================================================================================# + @@ -2623,14 +3453,15 @@ read.q.files <<- function( datum # (whatever/plant) to "extensive" (whatever/m2). Sometimes they may be used to # # build weighted averages. # #------------------------------------------------------------------------------------# - w.nplant = nplantconow * areaconow - w.lai = laiconow * areaconow - w.wai = waiconow * areaconow - w.tai = taiconow * areaconow - w.biomass = biomassconow * w.nplant - w.bleaf = bleafconow * w.nplant - w.balive = baliveconow * w.nplant - w.basarea = baconow * w.nplant + w.nplant = nplantconow * areaconow + w.lai = laiconow * areaconow + w.wai = waiconow * areaconow + w.tai = taiconow * areaconow + w.biomass = biomassconow * w.nplant + w.bleaf = bleafconow * w.nplant + w.balive = baliveconow * w.nplant + w.basarea = baconow * w.nplant + w.agvolume = agvolumeconow * w.nplant #------------------------------------------------------------------------------------# @@ -2897,118 +3728,122 @@ read.q.files <<- function( datum #----- Leaf/wood intensive properties , weighted means using LAI/WAI. ------# - szpft$sm.stress [m,d,p] = weighted.mean( x = sm.stressconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.sms [m,d,p] = weighted.mean( x = phap.smsconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par [m,d,p] = weighted.mean( x = leaf.parconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par.beam[m,d,p] = weighted.mean( x = leaf.par.beamconow[sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.par.diff[m,d,p] = weighted.mean( x = leaf.par.diffconow[sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lpar [m,d,p] = weighted.mean( x = phap.lparconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.rshort [m,d,p] = weighted.mean( x = leaf.rshortconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.rlong [m,d,p] = weighted.mean( x = leaf.rlongconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gpp [m,d,p] = weighted.mean( x = leaf.gppconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.temp [m,d,p] = weighted.mean( x = leaf.tempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.ltemp [m,d,p] = weighted.mean( x = phap.ltempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.water [m,d,p] = weighted.mean( x = leaf.waterconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lwater [m,d,p] = weighted.mean( x = phap.lwaterconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$wood.temp [m,d,p] = weighted.mean( x = wood.tempconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.vpd [m,d,p] = weighted.mean( x = leaf.vpdconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lvpd [m,d,p] = weighted.mean( x = phap.lvpdconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.transp [m,d,p] = weighted.mean( x = i.transpconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.wflxlc [m,d,p] = weighted.mean( x = i.wflxlcconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$i.hflxlc [m,d,p] = weighted.mean( x = i.hflxlcconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gbw [m,d,p] = weighted.mean( x = leaf.gbwconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lgbw [m,d,p] = weighted.mean( x = phap.lgbwconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$leaf.gsw [m,d,p] = weighted.mean( x = leaf.gswconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$phap.lgsw [m,d,p] = weighted.mean( x = phap.lgswconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.light [m,d,p] = weighted.mean( x = assim.lightconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.rubp [m,d,p] = weighted.mean( x = assim.rubpconow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$assim.co2 [m,d,p] = weighted.mean( x = assim.co2conow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$vm0 [m,d,p] = weighted.mean( x = vm0conow [sel] - , w = w.lai [sel] - , na.rm = TRUE - )#end weighted.mean - szpft$wood.gbw [m,d,p] = weighted.mean( x = wood.gbwconow [sel] - , w = w.wai [sel] - , na.rm = TRUE - )#end weighted.mean + szpft$sm.stress [m,d,p] = weighted.mean( x = sm.stressconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.sms [m,d,p] = weighted.mean( x = phap.smsconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par [m,d,p] = weighted.mean( x = leaf.parconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par.beam [m,d,p] = weighted.mean( x = leaf.par.beamconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.par.diff [m,d,p] = weighted.mean( x = leaf.par.diffconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lpar [m,d,p] = weighted.mean( x = phap.lparconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.rshort [m,d,p] = weighted.mean( x = leaf.rshortconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.rlong [m,d,p] = weighted.mean( x = leaf.rlongconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gpp [m,d,p] = weighted.mean( x = leaf.gppconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.temp [m,d,p] = weighted.mean( x = leaf.tempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.ltemp [m,d,p] = weighted.mean( x = phap.ltempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.water [m,d,p] = weighted.mean( x = leaf.waterconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.water.im2[m,d,p] = weighted.mean( x = leaf.water.im2conow[sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lwater [m,d,p] = weighted.mean( x = phap.lwaterconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$wood.temp [m,d,p] = weighted.mean( x = wood.tempconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.vpd [m,d,p] = weighted.mean( x = leaf.vpdconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lvpd [m,d,p] = weighted.mean( x = phap.lvpdconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.transp [m,d,p] = weighted.mean( x = i.transpconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.wflxlc [m,d,p] = weighted.mean( x = i.wflxlcconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$i.hflxlc [m,d,p] = weighted.mean( x = i.hflxlcconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gbw [m,d,p] = weighted.mean( x = leaf.gbwconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lgbw [m,d,p] = weighted.mean( x = phap.lgbwconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$leaf.gsw [m,d,p] = weighted.mean( x = leaf.gswconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$phap.lgsw [m,d,p] = weighted.mean( x = phap.lgswconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.light [m,d,p] = weighted.mean( x = assim.lightconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.rubp [m,d,p] = weighted.mean( x = assim.rubpconow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$assim.co2 [m,d,p] = weighted.mean( x = assim.co2conow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$vm0 [m,d,p] = weighted.mean( x = vm0conow [sel] + , w = w.lai [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$wood.gbw [m,d,p] = weighted.mean( x = wood.gbwconow [sel] + , w = w.wai [sel] + , na.rm = TRUE + )#end weighted.mean #---------------------------------------------------------------------------# @@ -3060,6 +3895,19 @@ read.q.files <<- function( datum #---------------------------------------------------------------------------# + #----- Leaf water potential: averaged by volume. ---------------------------# + szpft$dmin.leaf.psi[m,d,p] = weighted.mean( x = dmin.leaf.psiconow[sel] + , w = w.agvolume [sel] + , na.rm = TRUE + )#end weighted.mean + szpft$dmax.leaf.psi[m,d,p] = weighted.mean( x = dmax.leaf.psiconow[sel] + , w = w.agvolume [sel] + , na.rm = TRUE + )#end weighted.mean + #---------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------# # SLA: use leaf biomass as weight so bleaf, SLA, and LAI are consistent. # #---------------------------------------------------------------------------# @@ -3077,7 +3925,7 @@ read.q.files <<- function( datum , w = w.bleaf [sel] , na.rm = TRUE )#end weighted.mean - szpft$llspan [m,d,p] = ifelse( test = szpft$llspan[m,d,p] %>% 0 + szpft$llspan [m,d,p] = ifelse( test = szpft$llspan[m,d,p] %gt% 0 , yes = 1./szpft$llspan[m,d,p] , no = NA_real_ )#end ifelse @@ -3166,8 +4014,9 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------# - # For mortality and growth, we keep deleting the tiny guys because they # - # skew the rates quite significantly. # + # For mortality and growth, we keep deleting the tiny cohorts because they # + # skew the rates quite significantly and they are rarely included in forest # + # inventory surveys. # #------------------------------------------------------------------------------# sel = sel.pft & sel.dbh & dbhconow >= dbhminconow if (any(sel)){ @@ -3202,15 +4051,17 @@ read.q.files <<- function( datum # Find the total number of plants and previous population if the only # # mortality was the mortality we test. # #---------------------------------------------------------------------------# - survivor = sum( w.nplant[sel] ) - previous = sum( w.nplant[sel] * exp(mortconow [sel]) ) - ncb.previous = sum( w.nplant[sel] * exp(ncbmortconow[sel]) ) - hyd.previous = sum( w.nplant[sel] * exp(hydmortconow[sel]) ) - di.previous = sum( w.nplant[sel] * exp(dimortconow [sel]) ) - szpft$mort [m,d,p] = log( previous / survivor ) - szpft$ncbmort[m,d,p] = log( ncb.previous / survivor ) - szpft$hydmort[m,d,p] = log( hyd.previous / survivor ) - szpft$dimort [m,d,p] = log( di.previous / survivor ) + survivor = sum( w.nplant[sel] ) + previous = sum( w.nplant[sel] * exp(mortconow [sel]) ) + ncb.previous = sum( w.nplant[sel] * exp(ncbmortconow [sel]) ) + hyd.previous = sum( w.nplant[sel] * exp(hydmortconow [sel]) ) + di.previous = sum( w.nplant[sel] * exp(dimortconow [sel]) ) + fl.previous = sum( w.nplant[sel] * exp(fire.lethalconow[sel]) ) + szpft$mort [m,d,p] = log( previous / survivor ) + szpft$ncbmort [m,d,p] = log( ncb.previous / survivor ) + szpft$hydmort [m,d,p] = log( hyd.previous / survivor ) + szpft$dimort [m,d,p] = log( di.previous / survivor ) + szpft$fire.lethal[m,d,p] = log( fl.previous / survivor ) #---------------------------------------------------------------------------# @@ -3445,6 +4296,8 @@ read.q.files <<- function( datum emean$leaf.rshort [m] = szpft$leaf.rshort [m,ndbh+1,npft+1] emean$leaf.rlong [m] = szpft$leaf.rlong [m,ndbh+1,npft+1] emean$leaf.gpp [m] = szpft$leaf.gpp [m,ndbh+1,npft+1] + emean$dmin.leaf.psi [m] = szpft$dmin.leaf.psi [m,ndbh+1,npft+1] + emean$dmax.leaf.psi [m] = szpft$dmax.leaf.psi [m,ndbh+1,npft+1] emean$transp [m] = szpft$transp [m,ndbh+1,npft+1] emean$wue [m] = szpft$wue [m,ndbh+1,npft+1] emean$npp [m] = szpft$npp [m,ndbh+1,npft+1] @@ -3453,6 +4306,7 @@ read.q.files <<- function( datum emean$etue [m] = szpft$etue [m,ndbh+1,npft+1] emean$cue [m] = szpft$cue [m,ndbh+1,npft+1] emean$ecue [m] = szpft$ecue [m,ndbh+1,npft+1] + emean$fire.lethal [m] = szpft$fire.lethal [m,ndbh+1,npft+1] emean$agb.growth [m] = szpft$agb.growth [m,ndbh+1,npft+1] emean$agb.mort [m] = szpft$agb.mort [m,ndbh+1,npft+1] emean$agb.dimort [m] = szpft$agb.dimort [m,ndbh+1,npft+1] @@ -3483,8 +4337,10 @@ read.q.files <<- function( datum #------------------------------------------------------------------------------------# # Convert leaf water to kg/m2leaf. # #------------------------------------------------------------------------------------# - emean$leaf.water [m ] = emean$leaf.water[m ] / pmax(emean$lai[m],0.01) - qmean$leaf.water [m,] = qmean$leaf.water[m,] / pmax(emean$lai[m],0.01) + emean$leaf.water [m ] = emean$leaf.water [m ] / pmax(emean$lai[m],0.01) + emean$leaf.water.im2[m ] = emean$leaf.water.im2[m ] / pmax(emean$lai[m],0.01) + qmean$leaf.water [m,] = qmean$leaf.water [m,] / pmax(emean$lai[m],0.01) + qmean$leaf.water.im2[m,] = qmean$leaf.water.im2[m,] / pmax(emean$lai[m],0.01) #------------------------------------------------------------------------------------# @@ -3757,6 +4613,9 @@ read.q.files <<- function( datum clab = paste( "y",sprintf("%4.4i",thisyear ) , "m",sprintf("%2.2i",thismonth),sep="") #----- Binding the current cohorts. ----------------------------------------------# + cohort$isi [[clab]] = isiconow + cohort$lsl [[clab]] = lslconow + cohort$ntext [[clab]] = ntextconow cohort$ipa [[clab]] = ipaconow cohort$ico [[clab]] = icoconow cohort$area [[clab]] = areaconow @@ -3823,10 +4682,11 @@ read.q.files <<- function( datum cohort$etue [[clab]] = etueconow cohort$demand [[clab]] = demandconow cohort$supply [[clab]] = supplyconow - cohort$mort [[clab]] = 100. * (1.0 - exp(-mortconow )) - cohort$ncbmort [[clab]] = 100. * (1.0 - exp(-ncbmortconow )) - cohort$hydmort [[clab]] = 100. * (1.0 - exp(-hydmortconow )) - cohort$dimort [[clab]] = 100. * (1.0 - exp(-dimortconow )) + cohort$mort [[clab]] = 100. * (1.0 - exp(-mortconow )) + cohort$ncbmort [[clab]] = 100. * (1.0 - exp(-ncbmortconow )) + cohort$hydmort [[clab]] = 100. * (1.0 - exp(-hydmortconow )) + cohort$dimort [[clab]] = 100. * (1.0 - exp(-dimortconow )) + cohort$fire.lethal [[clab]] = 100. * (1.0 - exp(-fire.lethalconow)) cohort$recruit [[clab]] = recruitconow cohort$growth [[clab]] = 100. * growthconow cohort$agb.growth [[clab]] = 100. * agb.growthconow @@ -3853,6 +4713,8 @@ read.q.files <<- function( datum cohort$leaf.temp [[clab]] = leaf.tempconow cohort$leaf.vpd [[clab]] = leaf.vpdconow cohort$leaf.gsw [[clab]] = leaf.gswconow + cohort$dmin.leaf.psi[[clab]] = dmin.leaf.psiconow + cohort$dmax.leaf.psi[[clab]] = dmax.leaf.psiconow } #end if month=sasmonth #------------------------------------------------------------------------------------# }# end for (m in tresume,ntimes) @@ -3873,6 +4735,7 @@ read.q.files <<- function( datum datum$lu = lu datum$qmean = qmean datum$qmsqu = qmsqu + datum$site = site datum$patch = patch datum$qpatch = qpatch datum$cohort = cohort @@ -3883,3 +4746,24 @@ read.q.files <<- function( datum }#end function read.q.files #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Function that updates weighting factors, and checks that there are valid factors. # +# Useful for when the simulation has heterogeneous soil depths. # +#------------------------------------------------------------------------------------------# +reweight.valid <<- function(x){ + xsum = sum(x,na.rm=TRUE) + if (xsum %eq% 0){ + ans = rep(NA_real_,times=length(x)) + }else{ + ans = x / xsum + }#end if + return(ans) +}#end reweight.valid +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/rshort.bdown.r b/R-utils/rshort.bdown.r index d8d4ddc35..0ffc2b9b5 100644 --- a/R-utils/rshort.bdown.r +++ b/R-utils/rshort.bdown.r @@ -1,4 +1,4 @@ -#==========================================================================================# + #==========================================================================================# #==========================================================================================# # This subroutine computes the split between direct and diffuse radiation, and # # between visible and near-infrared radiation. Three methods are provided: # @@ -47,17 +47,18 @@ rshort.bdown <<- function(rad.in,atm.prss,cosz,rad.type=c("rshort","par","nir") if (length(atm.prss) == 1) atm.prss = rep(atm.prss,times=length(rad.in)) #----- Prevent clearness index method to be used when rad.type is not rshort. ----------# - if ( (! rad.method %in% "wn85") && (! (rad.type %in% "rshort")) ){ + if ( (rad.method %in% "sib") && (! (rad.type %in% "rshort")) ){ cat0(" - Radiation method: ",rad.method,".") cat0(" - Input radiation type: ",rad.type,".") - stop(" Radiation input type must be \"rshort\" unless using method \"wn85\".)") + stop(" Radiation input type must be \"rshort\" if using method \"sib\".)") }#end if #---------------------------------------------------------------------------------------# ans = switch( EXPR = rad.method , wn85 = rshort.bdown.weissnorman(rad.in,atm.prss,cosz,rad.type) - , clearidx = rshort.bdown.clearidx (rad.in,atm.prss,cosz,apply.bx10.corr) + , clearidx = rshort.bdown.clearidx (rad.in,atm.prss,cosz,apply.bx10.corr + ,rad.type) , sib = rshort.bdown.sib (rad.in,atm.prss,cosz) )#end switch return(ans) @@ -98,65 +99,38 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz #------ Initialise the radiation with NAs. ---------------------------------------------# - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - rshort.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + rshort.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in + #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %gt% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# - - #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # - #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - if (rad.type %in% "par"){ - par.diff [night] = rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] / fvis.diff.def - }else if(rad.type %in% "nir"){ - par.diff [night] = fvis.diff.def * rad.in[night] / fnir.diff.def - nir.diff [night] = rad.in[night] - }else{ - par.diff [night] = fvis.diff.def * rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] - }#end if - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - rshort.full [night] = rshort.beam[night] + rshort.diff[night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 - #---------------------------------------------------------------------------------------# - - - - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0) - log10secz = log10(secz) + #----- Save the Chapman function to account for the earth's curvature. -----------------# + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = fvis.beam.def * rshort.beam.toa nir.beam.toa = fnir.beam.def * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -167,7 +141,7 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -178,7 +152,7 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -189,19 +163,30 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot #---------------------------------------------------------------------------------------# @@ -210,11 +195,11 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # Find the actual total for PAR and NIR, using equations 7 and 8. # #---------------------------------------------------------------------------------------# if (rad.type %in% "par"){ - ratio = ifelse(day, rad.in / par.full.pot, 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / par.full.pot) }else if (rad.type %in% "nir"){ - ratio = ifelse(day, rad.in / nir.full.pot, 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / nir.full.pot) }else{ - ratio = ifelse(day, rad.in / (par.full.pot + nir.full.pot), 0.) + ratio = ifelse(test = night, yes = 0., no = rad.in / (par.full.pot + nir.full.pot)) }#end if par.full = ratio * par.full.pot nir.full = ratio * nir.full.pot @@ -249,15 +234,46 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz #---------------------------------------------------------------------------------------# # Find the radiation components. # #---------------------------------------------------------------------------------------# - par.beam [day] = fvis.beam.act[day] * par.full[day] - par.diff [day] = fvis.diff.act[day] * par.full[day] - nir.beam [day] = fnir.beam.act[day] * nir.full[day] - nir.diff [day] = fnir.diff.act[day] * nir.full[day] - rshort.beam [day] = par.beam [day] + nir.beam [day] - rshort.diff [day] = par.diff [day] + nir.diff [day] - rshort.full [day] = rshort.beam[day] + rshort.diff[day] + par.beam = fvis.beam.act * par.full + par.diff = fvis.diff.act * par.full + nir.beam = fnir.beam.act * nir.full + nir.diff = fnir.diff.act * nir.full + rshort.beam = par.beam + nir.beam + rshort.diff = par.diff + nir.diff + rshort.full = rshort.beam + rshort.diff #---------------------------------------------------------------------------------------# - rshort.bdown = data.frame( par.beam = par.beam + + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Save output data frame. # + #---------------------------------------------------------------------------------------# + rshort.bdown = data.frame( chapman = chapman + , eff.cosz = eff.cosz + , par.beam = par.beam , par.diff = par.diff , par.full = par.full , nir.beam = nir.beam @@ -286,7 +302,8 @@ rshort.bdown.weissnorman <<- function(rad.in,atm.prss,cosz # between visible and near-infrared radiation, using the clearness index method (BD08, # # TW05, BX10). # #------------------------------------------------------------------------------------------# -rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ +rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr + ,rad.type=c("rshort","par","nir")){ #---------------------------------------------------------------------------------------# # Local constants. # #---------------------------------------------------------------------------------------# @@ -307,57 +324,42 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #------ Initialise the radiation with NAs (except for rshort.full). --------------------# - rshort.full = rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + rshort.full = NA_real_ * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %ge% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # - #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - par.diff [night] = tw05.eqn02[1] * rshort.full[night] - nir.diff [night] = (1. - tw05.eqn02[1]) * rshort.full[night] - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 + # Save the Chapman function to account for the earth's curvature and find the # + # effective cosine of the zenith angle. # #---------------------------------------------------------------------------------------# - - - - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0.) - log10secz = log10(secz) + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = tw05.eqn02[1] * rshort.beam.toa nir.beam.toa = (1. - tw05.eqn02[1]) * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -369,7 +371,7 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -380,7 +382,7 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -391,24 +393,62 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Find the clearness index based on total shortwave radiation, then find the # # fraction of PAR radiation as a function of total radiation and clearness index, # # following TW05, eqn. 2. # #---------------------------------------------------------------------------------------# - fkt = ifelse(day,pmax(0.,pmin(1.,rshort.full / rshort.beam.toa)),0.) - fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) - par.full[day] = fpar[day] * rshort.full[day] - nir.full[day] = rshort.full[day] - par.full[day] + if (rad.type %in% "par"){ + par.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., par.full / par.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + rshort.full = par.full / fpar + nir.full = rshort.full - par.full + }else if (rad.type %in% "nir"){ + nir.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., nir.full / nir.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + rshort.full = nir.full / (1.-fpar) + par.full = rshort.full - nir.full + + }else{ + rshort.full = rad.in + fkt = ifelse( test = night + , yes = 0. + , no = pmax(0.,pmin(1., rshort.full / rshort.beam.toa)) + )#end ifelse + fpar = tw05.eqn02[1] + fkt * ( tw05.eqn02[2] + fkt * tw05.eqn02[3] ) + par.full = fpar * rshort.full + nir.full = rshort.full - par.full + }#end if #---------------------------------------------------------------------------------------# - + + #---------------------------------------------------------------------------------------# # Find the uncorrected diffuse fraction based on BD08. We use this equation # @@ -442,12 +482,12 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Find the radiation components. # #---------------------------------------------------------------------------------------# - par.diff [day] = fdiff [day] * par.full[day] - par.beam [day] = par.full[day] - par.diff[day] - nir.diff [day] = fdiff [day] * nir.full[day] - nir.beam [day] = nir.full[day] - nir.diff[day] - rshort.diff[day] = par.diff[day] + nir.diff[day] - rshort.beam[day] = par.beam[day] + nir.beam[day] + par.diff = fdiff * par.full + par.beam = par.full - par.diff + nir.diff = fdiff * nir.full + nir.beam = nir.full - nir.diff + rshort.diff = par.diff + nir.diff + rshort.beam = par.beam + nir.beam #---------------------------------------------------------------------------------------# @@ -455,16 +495,40 @@ rshort.bdown.clearidx <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - rshort.bdown = data.frame( par.beam = par.beam + rshort.bdown = data.frame( chapman = chapman + , eff.cosz = eff.cosz + , par.beam = par.beam , par.diff = par.diff , par.full = par.full , nir.beam = nir.beam @@ -512,56 +576,42 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #------ Initialise the radiation with NAs (except for rshort.full). --------------------# rshort.full = rad.in - rshort.beam = NA * rad.in - rshort.diff = NA * rad.in - par.beam = NA * rad.in - nir.beam = NA * rad.in - par.diff = NA * rad.in - nir.diff = NA * rad.in - par.full = NA * rad.in - nir.full = NA * rad.in - par.max = NA * rad.in - nir.max = NA * rad.in - rshort.max = NA * rad.in + rshort.beam = NA_real_ * rad.in + rshort.diff = NA_real_ * rad.in + par.beam = NA_real_ * rad.in + nir.beam = NA_real_ * rad.in + par.diff = NA_real_ * rad.in + nir.diff = NA_real_ * rad.in + par.full = NA_real_ * rad.in + nir.full = NA_real_ * rad.in + par.max = NA_real_ * rad.in + nir.max = NA_real_ * rad.in + rshort.max = NA_real_ * rad.in #---------------------------------------------------------------------------------------# #------ Make day and night flags. ------------------------------------------------------# - ntimes = length(cosz) - day = cosz %>% cosz.min - night = ! day + ntimes = length(cosz) + day = cosz %gt% cosz.min + night = cosz %lt% cosz.twilight + twilight = (! day) & (! night) #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# - # First thing to check is whether this is daytime or "night-time". If the zenith # - # angle is too close to horizon, we assume it's dawn/dusk and all radiation goes to # - # diffuse. # + # Save the Chapman function to account for the earth's curvature and find the # + # effective cosine of the zenith angle. # #---------------------------------------------------------------------------------------# - par.beam [night] = 0.0 - nir.beam [night] = 0.0 - par.diff [night] = fvis.diff.def * rad.in[night] - nir.diff [night] = fnir.diff.def * rad.in[night] - par.full [night] = par.beam [night] + par.diff [night] - nir.full [night] = nir.beam [night] + nir.diff [night] - rshort.beam [night] = par.beam [night] + nir.beam [night] - rshort.diff [night] = par.diff [night] + nir.diff [night] - par.max [night] = 0.0 - nir.max [night] = 0.0 - rshort.max [night] = 0.0 + chapman = pmin(lnexp.max,huestis.fun(cosz=cosz)) + eff.cosz = ifelse( test = night, yes = 0., no = 1./chapman) + log10chapman = log10(chapman) #---------------------------------------------------------------------------------------# - #----- Save 1/cos(zen), which is the secant. We will use this several times. ----------# - secz = ifelse(day, 1. / cosz, 0.) - log10secz = log10(secz) - #---------------------------------------------------------------------------------------# - - #----- Total radiation at the top of the atmosphere [ W/m2], using ED defaults. -------# - rshort.beam.toa = solar * ifelse(day,cosz,0.) + rshort.beam.toa = solar * eff.cosz par.beam.toa = fvis.beam.def * rshort.beam.toa nir.beam.toa = fnir.beam.def * rshort.beam.toa #---------------------------------------------------------------------------------------# @@ -573,7 +623,7 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # and 9 of WN85. # #---------------------------------------------------------------------------------------# par.beam.pot = ( par.beam.toa - * exp ( par.beam.expext * (atm.prss / prefsea) * secz) ) + * exp ( par.beam.expext * (atm.prss / prefsea) * chapman) ) par.diff.pot = par2diff.sun * (par.beam.toa - par.beam.pot) par.full.pot = par.beam.pot + par.diff.pot #---------------------------------------------------------------------------------------# @@ -584,7 +634,7 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # Find the NIR absorption of 10 mm of precipitable water, using WN85 equation 6. # #---------------------------------------------------------------------------------------# w10 = ( rshort.beam.toa - * 10 ** ((wn85.06[1]) + log10secz * (wn85.06[2] + wn85.06[3] * log10secz)) + * 10 ** ((wn85.06[1]) + log10chapman * (wn85.06[2] + wn85.06[3] * log10chapman)) )#end w10 #---------------------------------------------------------------------------------------# @@ -595,34 +645,43 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ # 4, 5, and 10 of WN85. # #---------------------------------------------------------------------------------------# nir.beam.pot = ( ( nir.beam.toa - * exp ( nir.beam.expext * (atm.prss / prefsea) * secz) - w10 ) ) + * exp ( nir.beam.expext * (atm.prss / prefsea) * chapman) - w10 ) ) nir.diff.pot = nir2diff.sun * ( nir.beam.toa - nir.beam.pot - w10 ) nir.full.pot = nir.beam.pot + nir.diff.pot #---------------------------------------------------------------------------------------# + #---------------------------------------------------------------------------------------# + # In case of twilight, set beam radiation to zero and diffuse radiation to # + # potential. # + #---------------------------------------------------------------------------------------# + par.beam.pot[twilight] = 0.0 + par.diff.pot[twilight] = par.full.pot[twilight] + nir.beam.pot[twilight] = 0.0 + nir.diff.pot[twilight] = nir.full.pot[twilight] + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# # Find the cloud cover estimate and the fraction of diffuse radiation. # #---------------------------------------------------------------------------------------# - cloud = ifelse( day - , pmin(1.,pmax(0.,(csib[5] * cosz - rshort.full) / (csib[4] * cosz))) - , 0.5 - )#end ifelse - difrat = ifelse(day,pmin(1.,pmax(0.,0.0604 / ( cosz -0.0223 ) + 0.0683)),1.0) + cloud = pmin(1.,pmax(0.,(csib[5] * eff.cosz - rshort.full) / (csib[4] * eff.cosz))) + difrat = pmin(1.,pmax(0.,0.0604 / ( eff.cosz -0.0223 ) + 0.0683)) difrat = difrat + ( 1. - difrat ) * cloud vnrat = ( ( csib[1] - cloud*csib[2] ) / ( ( csib[1] - cloud*csib[3] ) + ( csib[1] - cloud*csib[2] )) )#end vnrat - rshort.diff[day] = difrat[day] * vnrat[day] * rshort.full[day] - rshort.beam[day] = rshort.full[day] - rshort.diff[day] - par.diff [day] = fvis.diff.def * rshort.diff[day] - nir.diff [day] = fnir.diff.def * rshort.diff[day] - par.beam [day] = fvis.beam.def * rshort.beam[day] - nir.beam [day] = fnir.beam.def * rshort.beam[day] - par.full [day] = par.diff[day] + par.beam[day] - nir.full [day] = nir.diff[day] + nir.beam[day] + rshort.diff = ifelse(test=day,yes=difrat * vnrat * rshort.full,no=rshort.full) + rshort.beam = rshort.full - rshort.diff + par.diff = fvis.diff.def * rshort.diff + nir.diff = fnir.diff.def * rshort.diff + par.beam = fvis.beam.def * rshort.beam + nir.beam = fnir.beam.def * rshort.beam + par.full = par.diff + par.beam + nir.full = nir.diff + nir.beam #---------------------------------------------------------------------------------------# @@ -630,11 +689,36 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# - par.max [day] = par.full.pot[day] - nir.max [day] = nir.full.pot[day] - rshort.max[day] = par.full.pot[day] + nir.full.pot[day] + par.max = par.full.pot + nir.max = nir.full.pot + rshort.max = par.full.pot + nir.full.pot + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Last thing to check is whether this is night time. If the zenith angle is more # + # than the typical angle for civil twilight, assume nighttime and set radiation to zero # + # (true radiation will still be slightly more than zero, but this avoids numerical # + # errors. # + #---------------------------------------------------------------------------------------# + par.beam [night] = 0.0 + nir.beam [night] = 0.0 + par.diff [night] = 0.0 + nir.diff [night] = 0.0 + par.full [night] = 0.0 + nir.full [night] = 0.0 + rshort.beam[night] = 0.0 + rshort.diff[night] = 0.0 + rshort.full[night] = 0.0 + par.max [night] = 0.0 + nir.max [night] = 0.0 + rshort.max [night] = 0.0 #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Total maximum radiation. # #---------------------------------------------------------------------------------------# @@ -657,3 +741,65 @@ rshort.bdown.sib <<- function(rad.in,atm.prss,cosz,apply.bx10.corr){ }#end function rshort.bdown.sib #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# This function calculates the effect of sun angle increasing the optical depth in a # +# sphere. This allows accounting for the diffuse radiation at twilight, using the # +# modified Chapman function following: # +# # +# Reference: # +# # +# Huestis DL. 2001. Accurate evaluation of the chapman function for atmospheric # +# attenuation. J. Quant. Spectrosc. Radiat. Transf., 69: 709-721. # +# doi:10.1016/S0022-4073(00)00107-2 # +# # +# # +# Input variables: # +# - tvir. Virtual temperature, in Kelvin. # +# - cosz. Cosine of the sun's zenith angle. # +# - dzen. Bin width of the zenith angle for the numerical integration # +#------------------------------------------------------------------------------------------# +huestis.fun <<- function(cosz,alt=0.,dzen=0.05){ + #----- Dimensionless curvature ratio. --------------------------------------------------# + xx = ( erad + alt ) / ehgt + #---------------------------------------------------------------------------------------# + + + #---- Create the look-up table. --------------------------------------------------------# + zend.ref = seq(from=0,to=180-dzen,by=dzen) + lambda.ref = mid.points(zend.ref) + nzen = length(zend.ref) + ZEND.REF = matrix(data=zend.ref,nrow=nzen,ncol=nzen,byrow=FALSE) + LAMBDA.REF = matrix(data=zend.ref,nrow=nzen,ncol=nzen,byrow=TRUE ) + LAMBDA.REF = pmin(ZEND.REF,LAMBDA.REF) + DLAMBDA.REF = t(apply(X=LAMBDA.REF,MARGIN=1,FUN=diff)) + LAMBDA.REF = t(apply(X=LAMBDA.REF,MARGIN=1,FUN=mid.points)) + ZEND.REF = ZEND.REF[,-nzen] + SINZ.REF = sin(ZEND.REF*pio180) + SINL.REF = sin(LAMBDA.REF*pio180) + COSL.REF = cos(LAMBDA.REF*pio180) + KERNEL = ifelse( test = SINL.REF %eq% 0. + , yes = 0. + , no = exp(xx*(1.-SINZ.REF/SINL.REF))/(1.+COSL.REF) + )#end ifelse + huestis.ref = 1+xx*sin(zend.ref*pio180) * rowSums(KERNEL*DLAMBDA.REF*pio180) + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Create matrices with the reference. # + #---------------------------------------------------------------------------------------# + zend = dzen * round(acos(cosz)/pio180/dzen) + idx = match(zend,zend.ref) + ans = 0.*cosz + c(huestis.ref[idx]) + return(ans) + #---------------------------------------------------------------------------------------# +}#end function huestis.fun +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/sample.by.quant.r b/R-utils/sample.by.quant.r index 6a5e1cb62..05ea05f12 100644 --- a/R-utils/sample.by.quant.r +++ b/R-utils/sample.by.quant.r @@ -37,18 +37,17 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ #----- First we check whether a is valid. ----------------------------------------------# - if (length(a) != 1){ - stop (paste(" Factor a must be a scalar, and you entered one with length " - ,length(a),"...",sep="")) - }#end if + if (! (length(a) %eq% 1L)){ + stop(paste0(" Factor \"a\" must be scalar. The input one has length ",length(a),".")) + }#end if (! (length(a) %eq% 1L)) #---------------------------------------------------------------------------------------# #----- First we check whether x or v are valid. ----------------------------------------# if (missing(x) || missing(v)){ - cat (" - x is missing: ",missing(x),"\n") - cat (" - v is missing: ",missing(v),"\n") - stop(" Either x or v (or both) is missing...") + cat (" - \"x\" is missing: ",missing(x),"\n") + cat (" - \"v\" is missing: ",missing(v),"\n") + stop(" Either \"x\" or \"v\" (or both) is missing.") }else if (length(x) < length(v)){ v.names = as.numeric(names(v)) ix = match(x,v.names) @@ -74,7 +73,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ v = v[as.numeric(names(v)) %in% keep] }else{ ix = sequence(length(x)) - }#end if + }#end if (missing(x) || missing(v)) #---------------------------------------------------------------------------------------# @@ -86,7 +85,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ stop(" Variable method must be scalar!") }else{ use = substring(tolower(method),1,1) - }#end if + }#end if (length(method) != 1) #---------------------------------------------------------------------------------------# @@ -124,7 +123,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = rep(1/nx,times=nx) )#end list - }else if (a == 0){ + }else if (a %in% 0L){ s = sample(x=x,size=nx,replace=TRUE) cnt = table(s) prob = rep(0,times=nx) @@ -137,7 +136,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "p"){ + }else if (use %in% "p"){ prob = abs(a) ^ (sign(a)*(1-2*quant)) @@ -149,7 +148,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "l"){ + }else if (use %in% "l"){ prob = inv.logit((a-sign(a))*(quant-0.5-0.01*a)) s = sample(x=x,size=nx,replace=TRUE,prob=prob) ans = list( orig = x @@ -159,7 +158,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "b"){ + }else if (use %in% "b"){ s = rep(NA,times=nx) prob = abs(a) ^ (sign(a)*quant > sign(a)*0.5) s[1] = sample(x=x,size=1,replace=TRUE,prob=prob) @@ -179,7 +178,7 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ , quant = quant , prob = prob )#end list - }else if (use == "s"){ + }else if (use %in% "s"){ #----- Find the skew normal statistics. ---------------------------------------------# v.loc = sn.location(x=v,na.rm=TRUE) v.scl = sn.scale (x=v,na.rm=TRUE) @@ -193,8 +192,8 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ s.scl = v.scl s.shp = v.shp d.shp = round.log(abs(s.shp)) - q.100 = qsn(p=0.10,location=s.loc,scale=s.scl,shape=s.shp) - q.900 = qsn(p=0.90,location=s.loc,scale=s.scl,shape=s.shp) + q.100 = qsn(p=0.10,xi=s.loc,omega=s.scl,alpha=s.shp) + q.900 = qsn(p=0.90,xi=s.loc,omega=s.scl,alpha=s.shp) v.min = min(v) v.max = max(v) #it = 0 @@ -207,14 +206,14 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ # if (q.900 > v.max){ # s.shp = s.shp - 0.1 * d.shp # }#end if - # q.100 = qsn(p=0.10,location=s.loc,scale=s.scl,shape=s.shp) - # q.900 = qsn(p=0.90,location=s.loc,scale=s.scl,shape=s.shp) + # q.100 = qsn(p=0.10,xi=s.loc,omega=s.scl,alpha=s.shp) + # q.900 = qsn(p=0.90,xi=s.loc,omega=s.scl,alpha=s.shp) #}#end while #------------------------------------------------------------------------------------# #----- Use the new statistics to find the new distribution. -------------------------# - v.goal = rsn(n=nx,location=s.loc,scale=s.scl,shape=s.shp) + v.goal = rsn(n=nx,xi=s.loc,omega=s.scl,alpha=s.shp) s.idx = mapply(FUN=which.closest,x=v.goal,MoreArgs=list(A=v)) s = x[s.idx] cnt = table(s) @@ -231,10 +230,10 @@ sample.by.quant <<- function(x,v,method="skew",a=1){ #------------------------------------------------------------------------------------# }else{ - stop (paste(" Method ",method," is not recognised...",sep="")) + stop (paste0(" Method ",method," is not recognised.")) }#end if #---------------------------------------------------------------------------------------# return(ans) -}#end function +}#end function sample.by.quant #------------------------------------------------------------------------------------------# diff --git a/R-utils/showutils.r b/R-utils/showutils.r index 304a9a4c7..3194b288d 100644 --- a/R-utils/showutils.r +++ b/R-utils/showutils.r @@ -67,7 +67,7 @@ fill.bg <<- function(pch,col,bg="white",dial=0.0){ #----- Discard colours for those points without background support. --------------------# - rgb.bg = ifelse(test=pch %>% 20,yes=rgb.bg,no="transparent") + rgb.bg = ifelse(test=pch %gt% 20,yes=rgb.bg,no="transparent") #---------------------------------------------------------------------------------------# return(rgb.bg) diff --git a/R-utils/soilutils.r b/R-utils/soilutils.r index 7563cf0a6..b941f11f0 100644 --- a/R-utils/soilutils.r +++ b/R-utils/soilutils.r @@ -122,8 +122,85 @@ nstext.polygon <<- nstext.polygon #==========================================================================================# # This function finds the soil parameters. # #------------------------------------------------------------------------------------------# -soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd - ,out.dfr=FALSE){ +soil.params <<- function( ntext = NA_integer_ + , isoilflg = 1 + , slxsand = NA_real_ + , slxclay = NA_real_ + , slsoc = NA_real_ + , slph = NA_real_ + , slcec = NA_real_ + , sldbd = NA_real_ + , slhydro = ifelse( test = ntext %in% c(12,13) + , yes = ntext + , no = isoil.hydro + )#end ifelse + , out.dfr = FALSE + ){ + + #----- Decide whether to call function recursively. ------------------------------------# + ulen = unique( c(length(ntext),length(isoilflg),length(slxsand),length(slsoc) + ,length(slph),length(slcec),length(sldbd),length(slhydro) + )#end c + )#end unique + if (any(ulen > 1)){ + #----- There are vectors. Ensure all data are either scalar or same-sized vector. ---# + if (any(! ulen %in% c(1,max(ulen)))){ + #----- Stop the execution, the data are inconsistent. ----------------------------# + cat0("---------------------------------------------------------------------") + cat0(" Input data must be either scalars or vectors with the same size.") + cat0("---------------------------------------------------------------------") + cat0(" Length(ntext) = ",length(ntext) ,".") + cat0(" Length(isoilflg) = ",length(isoilflg),".") + cat0(" Length(slxsand) = ",length(slxsand) ,".") + cat0(" Length(slxclay) = ",length(slxclay) ,".") + cat0(" Length(slsoc) = ",length(slsoc) ,".") + cat0(" Length(slph) = ",length(slph) ,".") + cat0(" Length(slcec) = ",length(slcec) ,".") + cat0(" Length(sldbd) = ",length(sldbd) ,".") + cat0(" Length(slhydro) = ",length(slhydro) ,".") + cat0("---------------------------------------------------------------------") + stop(" Dimension mismatch of input variables.") + #---------------------------------------------------------------------------------# + }#end if (any(! ulen %in% c(1,max(ulen)))) + #------------------------------------------------------------------------------------# + + + #----- At this point we are clear. Turn data into vectors. -------------------------# + mxlen = max(ulen) + if (length(ntext ) %in% c(1)) ntext = rep(x=ntext ,times=mxlen) + if (length(isoilflg) %in% c(1)) isoilflg = rep(x=isoilflg,times=mxlen) + if (length(slxsand ) %in% c(1)) slxsand = rep(x=slxsand ,times=mxlen) + if (length(slxclay ) %in% c(1)) slxclay = rep(x=slxclay ,times=mxlen) + if (length(slsoc ) %in% c(1)) slsoc = rep(x=slsoc ,times=mxlen) + if (length(slph ) %in% c(1)) slph = rep(x=slph ,times=mxlen) + if (length(slcec ) %in% c(1)) slcec = rep(x=slcec ,times=mxlen) + if (length(sldbd ) %in% c(1)) sldbd = rep(x=sldbd ,times=mxlen) + if (length(slhydro ) %in% c(1)) slhydro = rep(x=slhydro ,times=mxlen) + #------------------------------------------------------------------------------------# + + + #----- Use mapply to run the function. ----------------------------------------------# + ans = mapply( FUN = soil.params + , ntext = as.list(ntext ) + , isoilflg = as.list(isoilflg) + , slxsand = as.list(slxsand ) + , slxclay = as.list(slxclay ) + , slsoc = as.list(slsoc ) + , slph = as.list(slph ) + , slcec = as.list(slcec ) + , sldbd = as.list(sldbd ) + , slhydro = as.list(slhydro ) + , MoreArgs = list(out.dfr=out.dfr) + , SIMPLIFY = FALSE + )#end mapply + if (out.dfr) ans = do.call(what="rbind",args=ans) + return(ans) + #------------------------------------------------------------------------------------# + }#end if (any(ulen > 1)) + #---------------------------------------------------------------------------------------# + + + #----- Define some prescribed fractions. -----------------------------------------------# xsand.def = c( 0.920, 0.825, 0.660, 0.200, 0.410, 0.590 , 0.100, 0.320, 0.520, 0.060, 0.200, 0.200 @@ -142,6 +219,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd slpotst.MPa = 5.e-4 # "saturated" soil approximation for van Genuchten [ MPa] slpotth.MPa = 0.01 # soil-water potential: field capacity (Tomasella-Hodnett) [ MPa] slpotsr.MPa = 0.033 # soil-water potential: field capacity (Saxton-Rawls) [ MPa] + slpotdg.MPa = 5.0 # soil-water potential: air dry soil (van Genuchten) [ MPa] slpotcp.MPa = 3.1 # soil-water potential: air dry soil [ MPa] slpotwp.MPa = 1.5 # soil-water potential: wilting point [ MPa] slpotld.MPa = 0.75 # soil-water potential that plants start dropping leaves [ MPa] @@ -228,7 +306,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Find soil class and sand, silt, and clay fractions. # #---------------------------------------------------------------------------------------# - if (missing(slxsand) || missing(slxclay) || missing(isoilflg)){ + if (is.na(slxsand) || is.na(slxclay) || is.na(isoilflg)){ mysoil$ntext = ntext mysoil$name = soil.name[mysoil$ntext] mysoil$key = soil.key [mysoil$ntext] @@ -236,9 +314,9 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$xclay = xclay.def[ntext] mysoil$xsilt = 1. - mysoil$xsand - mysoil$xclay }else if (isoilflg == 2 & slxsand > 0 & slxclay > 0 & (slxsand + slxclay) < 1 ){ - mysoil$ntext = sclass(slxsand,slxclay) - mysoil$name = soil.name[mysoil$ntext] - mysoil$key = soil.key [mysoil$ntext] + mysoil$ntext = if(is.na(ntext)){sclass(sandfrac=slxsand,clayfrac=slxclay)}else{ntext} + mysoil$name = "User" + mysoil$key = "User" mysoil$xsand = slxsand mysoil$xclay = slxclay mysoil$xsilt = 1. - mysoil$xsand - mysoil$xclay @@ -255,11 +333,11 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #----- Decide which method to use. -----------------------------------------------------# - if ( mysoil$ntext %in% 13){ + if ( slhydro %in% 13){ mysoil$method = "BDRK" - }else if ( (mysoil$ntext %in% c(12)) || isoil.hydro %in% c(0,1)){ + }else if ( slhydro %in% c(0,1,12)){ mysoil$method = "BC64" - }else if (isoil.hydro %in% 2){ + }else if (slhydro %in% 2){ mysoil$method = "vG80" }else{ mysoil$method = "SR06" @@ -272,7 +350,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# if (mysoil$method %in% "vG80"){ #----- Make sure all required variables are provided. -------------------------------# - fine = ! (missing(slsoc) || missing(slph) || missing(slcec) || missing(sldbd)) + fine = ! (is.na(slsoc) || is.na(slph) || is.na(slcec) || is.na(sldbd)) if (fine){ #----- Copy values from inputs. --------------------------------------------------# mysoil$slsoc = slsoc @@ -284,10 +362,10 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #----- Missing data, issue an error message. -------------------------------------# cat0("---------------------------------------------------------------------------") cat0(" Missing parameters for isoil.hydro = 2 (Hodnett and Tomasella 2002)! ") - cat0(" Missing \"slsoc\" = ",missing(slsoc),".") - cat0(" Missing \"slph\" = ",missing(slph) ,".") - cat0(" Missing \"slcec\" = ",missing(slcec),".") - cat0(" Missing \"sldbd\" = ",missing(sldbd),".") + cat0(" Missing \"slsoc\" = ",is.na(slsoc),".") + cat0(" Missing \"slph\" = ",is.na(slph) ,".") + cat0(" Missing \"slcec\" = ",is.na(slcec),".") + cat0(" Missing \"sldbd\" = ",is.na(sldbd),".") cat0("---------------------------------------------------------------------------") stop(" Invalid settings for soil.params.") #---------------------------------------------------------------------------------# @@ -295,7 +373,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #------------------------------------------------------------------------------------# }else if (mysoil$method %in% "SR06"){ #----- Make sure all required variables are provided. -------------------------------# - fine = ! (missing(slsoc) || missing(slph) || missing(slcec) || missing(sldbd)) + fine = ! is.na(slsoc) if (fine){ #----- Copy values from inputs. --------------------------------------------------# mysoil$slsoc = slsoc @@ -311,16 +389,16 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #------------------------------------------------------------------------------------# #----- Variables are dummy but we honour the input variables if provided. -----------# - if (! missing(slph )) mysoil$slph = slph - if (! missing(slcec)) mysoil$slcec = slcec - if (! missing(sldbd)) mysoil$sldbd = sldbd + mysoil$slph = slph + mysoil$slcec = slcec + mysoil$sldbd = sldbd #------------------------------------------------------------------------------------# }else{ #----- Variables are dummy but we honour the input variables if provided. -----------# - if (! missing(slsoc)) mysoil$slsoc = slsoc - if (! missing(slph )) mysoil$slph = slph - if (! missing(slcec)) mysoil$slcec = slcec - if (! missing(sldbd)) mysoil$sldbd = sldbd + mysoil$slsoc = slsoc + mysoil$slph = slph + mysoil$slcec = slcec + mysoil$sldbd = sldbd #------------------------------------------------------------------------------------# }#end if (mysoil$method %in% "vG1980") #---------------------------------------------------------------------------------------# @@ -330,11 +408,11 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Set up primary properties. # #---------------------------------------------------------------------------------------# - if (mysoil$ntext == 13){ + if (slhydro == 13){ #----- Bedrock. Most things are zero, because it is an impermeable soil. -----------# mysoil$slcpd = 2130000. #------------------------------------------------------------------------------------# - }else if (mysoil$ntext == 12){ + }else if (slhydro == 12){ #------------------------------------------------------------------------------------# # Peat. High concentration of organic matter. Mineral soil equations don't # # apply here. # @@ -358,7 +436,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 0){ + }else if (slhydro == 0){ #------------------------------------------------------------------------------------# # Mineral soil. Use the standard ED-2.2 equations. # #------------------------------------------------------------------------------------# @@ -386,7 +464,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotfc = smoist2mpot(mysoil$sfldcap, mysoil) mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) - }else if (isoil.hydro == 1){ + }else if (slhydro == 1){ #------------------------------------------------------------------------------------# # Use Tomasella and Hodnett (1998). # #------------------------------------------------------------------------------------# @@ -431,7 +509,8 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 2){ + }else if (slhydro == 2){ + #------------------------------------------------------------------------------------# # Use Hodnett and Tomasella (2002). # #------------------------------------------------------------------------------------# @@ -483,7 +562,7 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd mysoil$slpotwp = - slpotwp.MPa * 1.e6 / ( grav * wdns ) mysoil$soilwp = mpot2smoist(mysoil$slpotwp, mysoil) #------------------------------------------------------------------------------------# - }else if (isoil.hydro == 3){ + }else if (slhydro == 3){ #------------------------------------------------------------------------------------# # Use Saxton and Rawls (2006). # #------------------------------------------------------------------------------------# @@ -542,9 +621,13 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Calculate the derived properties in case this is not bedrock. # #---------------------------------------------------------------------------------------# - if (mysoil$ntext != 13){ + if (slhydro != 13){ mysoil$fhydraul = 2.0 - mysoil$slpotcp = - slpotcp.MPa * 1.e6 / ( wdns * grav ) + if (mysoil$method %in% "vG80"){ + mysoil$slpotcp = - slpotdg.MPa * 1.e6 / ( wdns * grav ) + }else{ + mysoil$slpotcp = - slpotcp.MPa * 1.e6 / ( wdns * grav ) + }#end if (mysoil$method %in% "vG80") mysoil$slpotld = - slpotld.MPa * 1.e6 / ( wdns * grav ) mysoil$slpotfr = - slpotfr.MPa * 1.e6 / ( wdns * grav ) mysoil$soilcp = mpot2smoist(mysoil$slpotcp, mysoil) @@ -584,16 +667,16 @@ soil.params <<- function(ntext,isoilflg,slxsand,slxclay,slsoc,slph,slcec,sldbd #---------------------------------------------------------------------------------------# # Make sure everything makes sense. In case it doesn't, check. # #---------------------------------------------------------------------------------------# - cp.fine = all(mysoil$soilre %<=% mysoil$soilcp ) - wp.fine = all(mysoil$soilcp %<=% mysoil$soilwp ) - fc.fine = all(mysoil$soilwp %<=% mysoil$sfldcap) - po.fine = all(mysoil$sfldcap %<=% mysoil$slmsts ) + cp.fine = all(mysoil$soilre %le% mysoil$soilcp ) + wp.fine = all(mysoil$soilcp %le% mysoil$soilwp ) + fc.fine = all(mysoil$soilwp %le% mysoil$sfldcap) + po.fine = all(mysoil$sfldcap %le% mysoil$slmsts ) if (! (cp.fine && wp.fine && fc.fine && po.fine) ) browser() #---------------------------------------------------------------------------------------# #----- Select the output format according to the users' choice. ------------------------# - if (out.dfr) mysoil = as.data.frame(mysoil,stringsAsFactors=FALSE) + if (out.dfr) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) #---------------------------------------------------------------------------------------# return(mysoil) @@ -618,12 +701,28 @@ sclass <<- function(sandfrac,clayfrac){ silt = 100. - sand - clay #---------------------------------------------------------------------------------------# + + #----- If the fractions are vectors, use mapply to get the answer. ---------------------# + if (length(sand) > 1){ + l.sand = as.list(0.01*sand) + l.clay = as.list(0.01*clay) + ans = mapply( FUN = sclass + , sandfrac = l.sand + , clayfrac = l.clay + , SIMPLIFY = TRUE + )#end mapply + return(ans) + }#end if + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# # Here there is not much we can do other than explore where in the triangle space # # we are. # #---------------------------------------------------------------------------------------# - - if (silt > 100. | silt < 0. | sand > 100. | sand < 0. | clay > 100. | clay < 0. ) { + if ( is.na(silt) || is.na(sand) || is.na(clay) ){ + mysoil = NA_integer_ + }else if (silt > 100. | silt < 0. | sand > 100. | sand < 0. | clay > 100. | clay < 0. ) { print("---------------------------------------------------") print(" At least one of your percentages is screwy...") print(paste0("SAND = ",sprintf("%.2f",sand),"%")) @@ -755,30 +854,77 @@ soil.idx2water <<- function(soil.index,soil){ # Function that converts matric potential (m) into soil moisture (m3/m3). # #------------------------------------------------------------------------------------------# smoist2mpot <<- function(smoist,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "BDRK"){ - #----- Bedrock, ignore. -------------------------------------------------------------# - mpot = 0. - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$soilpo - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - mpot = mysoil$slpotbp * (smfrac^mysoil$slmu - 1.)^(1.-mysoil$slmm) - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "SR06"){ - #----- Saxton and Rawls (2006). -----------------------------------------------------# - smbelow = pmin(1.,smoist/mysoil$sfldcap) - smabove = pmax(0.,smoist - mysoil$sfldcap) - mpot = with(mysoil, slpotfc / smbelow^slbs + slas * smabove) - #------------------------------------------------------------------------------------# - }else{ - #----- Brooks and Corey (1964). -----------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$slmsts - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - mpot = mysoil$slpots / smfrac ^ mysoil$slbs - #------------------------------------------------------------------------------------# - }#end if (mysoil$method %in% "vG80") + + + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nsmoist = length(smoist) + if (nmysoil == 1){ + idx = rep(1,times=nsmoist) + mysoil = mysoil[idx,] + }else if (nmysoil != nsmoist){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between smoist and mysoil!" ) + cat0(" - length(smoist): ",nsmoist ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match smoist length.") + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + mpot = NA_real_ * smoist + smbelow = NA_real_ * smoist + smabove = NA_real_ * smoist + smfrac = NA_real_ * smoist + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + sr06 = mysoil$method %in% "SR06" + bc64 = mysoil$method %in% "BC64" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + mpot[bdrk] = 0. + #---------------------------------------------------------------------------------------# + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac[vg80] = with( mysoil + , (smoist[vg80] - soilre[vg80]) / (soilpo[vg80] - soilre[vg80]) + )#end with + smfrac[vg80] = 0. * smfrac[vg80] + pmax(0.,pmin(1.,smfrac[vg80])) + mpot [vg80] = with( mysoil + , slpotbp[vg80] * (smfrac[vg80]^slmu[vg80] - 1.)^(1.-slmm[vg80]) + )#end with + #----- Saxton and Rawls (2006). --------------------------------------------------------# + smbelow[sr06] = pmin(1.,smoist[sr06] / mysoil$sfldcap[sr06]) + smabove[sr06] = pmax(0.,smoist[sr06] - mysoil$sfldcap[sr06]) + mpot [sr06] = with(mysoil + , slpotfc[sr06] + / smbelow[sr06]^slbs[sr06] + slas[sr06] * smabove[sr06] + )#end with + #---------------------------------------------------------------------------------------# + #----- Brooks and Corey (1964). --------------------------------------------------------# + smfrac[bc64] = with( mysoil + , (smoist[bc64] - soilre[bc64]) / (slmsts[bc64] - soilre[bc64]) + )#end with + smfrac[bc64] = 0. * smfrac[bc64] + pmax(0.,pmin(1.,smfrac[bc64])) + mpot [bc64] = mysoil$slpots[bc64] / smfrac[bc64] ^ mysoil$slbs[bc64] + #---------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------# return(mpot) @@ -796,33 +942,73 @@ smoist2mpot <<- function(smoist,mysoil){ # Function that converts soil moisture (m3/m3) into matric potential (m). # #------------------------------------------------------------------------------------------# mpot2smoist <<- function(mpot,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "BDRK"){ - #----- Bedrock, ignore. -------------------------------------------------------------# - smoist = 0. - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = ( 1. / ( 1. + (mysoil$malpha*mpot)^mysoil$slnm) )^mysoil$slmm - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - smoist = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$soilpo - #------------------------------------------------------------------------------------# - }else if (mysoil$method %in% "SR06"){ - #----- Saxton and Rawls (2006). -----------------------------------------------------# - smoist = with( mysoil - , ifelse( test = mpot %<% slpotfc - , yes = sfldcap * ( slpotfc / mpot ) ^ (1. / slbs ) - , no = sfldcap + ( slpotfc - slpots) / slas - )#end ifelse - )#end with - #------------------------------------------------------------------------------------# - }else{ - #----- Brooks and Corey (1964). -----------------------------------------------------# - smfrac = ( mysoil$slpots / mpot ) ^ mysoil$slnm - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - smoist = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$slmsts - #------------------------------------------------------------------------------------# - }#end if (mysoil$method %in% "vG80") + + + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nmpot = length(mpot ) + if (nmysoil == 1){ + idx = rep(1,times=nmpot) + mysoil = mysoil[idx,] + }else if (nmysoil != nmpot){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between mpot and mysoil!" ) + cat0(" - length(mpot): ",nmpot ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match mpot length." ) + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + smoist = NA_real_ * mpot + smfrac = NA_real_ * mpot + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + sr06 = mysoil$method %in% "SR06" + bc64 = mysoil$method %in% "BC64" + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + smoist[bdrk] = 0. + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac[vg80] = with( mysoil + , ( 1. / ( 1. + (malpha[vg80]*mpot[vg80])^slnm[vg80]) )^slmm[vg80] + )#end with + smfrac[vg80] = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) + smoist[vg80] = (1. - smfrac) * mysoil$soilre + smfrac * mysoil$soilpo + #---------------------------------------------------------------------------------------# + #----- Saxton and Rawls (2006). --------------------------------------------------------# + smoist[sr06] = with( mysoil + , ifelse( test = mpot[sr06] %lt% slpotfc[sr06] + , yes = sfldcap[sr06] + * ( slpotfc[sr06] / mpot[sr06] ) ^ (1. / slbs[sr06] ) + , no = sfldcap[sr06] + + ( slpotfc[sr06] - slpots[sr06]) / slas[sr06] + )#end ifelse + )#end with + #----- Brooks and Corey (1964). --------------------------------------------------------# + smfrac[bc64] = ( mysoil$slpots[bc64] / mpot[bc64] ) ^ mysoil$slnm[bc64] + smfrac[bc64] = 0. * smfrac[bc64] + pmax(0.,pmin(1.,smfrac[bc64])) + smoist[bc64] = with( mysoil + , (1. - smfrac[bc64]) * soilre[bc64] + smfrac[bc64] * slmsts[bc64] + )#end with #---------------------------------------------------------------------------------------# @@ -844,21 +1030,66 @@ mpot2smoist <<- function(mpot,mysoil){ smoist2hydcond <<- function(smoist,mysoil){ - #----- Pick method. --------------------------------------------------------------------# - if (mysoil$method %in% "vG80"){ - #----- van Genuchten (1980). --------------------------------------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$soilpo - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - fibf = 1. - (1. - smfrac^(1./mysoil$slmm))^mysoil$slmm - hydcond = mysoil$slcons * smfrac ^ mysoil$sltt * fibf * fibf - #------------------------------------------------------------------------------------# - }else{ - #----- Saxton and Rawls (2006) or Brooks and Corey (1964). --------------------------# - smfrac = (smoist - mysoil$soilre) / (mysoil$slmsts - mysoil$soilre) - smfrac = 0. * smfrac + pmax(0.,pmin(1.,smfrac)) - hydcond = mysoil$slcons * smfrac ^ mysoil$slmm - #------------------------------------------------------------------------------------# - }#end if + #----- Select the output format according to the users' choice. ------------------------# + if (! is.data.table(mysoil)) mysoil = as.data.table(mysoil,stringsAsFactors=FALSE) + #---------------------------------------------------------------------------------------# + + + + + #---------------------------------------------------------------------------------------# + # Count the number of rows and make sure it either matches smoist or it's a single # + # line. # + #---------------------------------------------------------------------------------------# + nmysoil = nrow (mysoil) + nsmoist = length(smoist) + if (nmysoil == 1){ + idx = rep(1,times=nsmoist) + mysoil = mysoil[idx,] + }else if (nmysoil != nsmoist){ + cat0("----------------------------------------------------------------------") + cat0(" Size mismatch between smoist and mysoil!" ) + cat0(" - length(smoist): ",nsmoist ) + cat0(" - size (mysoil): ",nmysoil ) + cat0("----------------------------------------------------------------------") + stop(" Variable \"mysoil\" should have a single soil or match smoist length.") + }#end if (nmysoil == 1) + #---------------------------------------------------------------------------------------# + + + #------ Initialise matric potential and ancillary variables. ---------------------------# + mpot = NA_real_ * smoist + smfrac = NA_real_ * smoist + hydcond = NA_real_ * smoist + fibf = NA_real_ * smoist + bdrk = mysoil$method %in% "BDRK" + vg80 = mysoil$method %in% "vG80" + cm76 = mysoil$method %in% c("SR06","BC64") + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Check methods. # + #---------------------------------------------------------------------------------------# + #----- Bedrock, ignore. ----------------------------------------------------------------# + hydcond[bdrk] = 0. + #----- van Genuchten (1980). -----------------------------------------------------------# + smfrac [vg80] = with( mysoil + , (smoist[vg80] - soilre[vg80]) / (soilpo[vg80] - soilre[vg80]) + )#end with + smfrac [vg80] = 0. * smfrac[vg80] + pmax(0.,pmin(1.,smfrac[vg80])) + fibf [vg80] = with( mysoil + , 1. - (1. - smfrac[vg80]^(1./slmm[vg80]))^slmm[vg80] + )#end with + hydcond[vg80] = with( mysoil + , slcons[vg80] * smfrac[vg80] ^ sltt[vg80] * fibf[vg80] * fibf[vg80] + )#end with + #----- Saxton and Rawls (2006) or Brooks and Corey (1964). -----------------------------# + smfrac [cm76] = with( mysoil + , (smoist[cm76] - soilre[cm76]) / (soilpo[cm76] - soilre[cm76]) + )#end with + smfrac [cm76] = 0. * smfrac[cm76] + pmax(0.,pmin(1.,smfrac[cm76])) + hydcond[cm76] = with(mysoil,slcons[cm76] * smfrac[cm76] ^ slmm[cm76]) #---------------------------------------------------------------------------------------# hydcond = 0. * hydcond + pmax(hydcond.min,hydcond) diff --git a/R-utils/spei.r b/R-utils/spei.r index 3d9be3db9..73381d870 100644 --- a/R-utils/spei.r +++ b/R-utils/spei.r @@ -128,7 +128,7 @@ spei <<- function( x # Find the standardised values of p3cdf: # #-----------------------------------------------------------------------------------# # P = 1. - cdf - # FS = ifelse( test = P %<=% 0.5, yes = 1.0, no = -1.0) + # FS = ifelse( test = P %le% 0.5, yes = 1.0, no = -1.0) # PUSE = 0.5 - sqrt((P - 0.5)^2) # W = sqrt(-2. * log(PUSE)) #-----------------------------------------------------------------------------------# diff --git a/R-utils/stipples.r b/R-utils/stipples.r index b2aac4aa4..8766b2db3 100644 --- a/R-utils/stipples.r +++ b/R-utils/stipples.r @@ -6,7 +6,7 @@ stipples <<- function(xleft,ybottom,xright,ytop,density=2,pch=".",cex=0.7,col="b #----- Check that coordinates are all provided. ----------------------------------------# stopifnot(! ( missing(xleft) | missing(ybottom) | missing(xright) | missing(ytop)) ) - stopifnot(density %>% 0) + stopifnot(density %gt% 0) #---------------------------------------------------------------------------------------# diff --git a/R-utils/summnum.r b/R-utils/summnum.r index 577474be9..e3c4ce16e 100644 --- a/R-utils/summnum.r +++ b/R-utils/summnum.r @@ -66,7 +66,7 @@ summnum <<- function(x,byrow=FALSE,finite.only=TRUE,neverlog=NULL,is.debug=FALSE #----- Second, ensure that zeroes are relatively rare. ------------------------------# - few.zeroes = ans$min %>=% 0. & ans$q100 %>% 0 + few.zeroes = ans$min %ge% 0. & ans$q100 %gt% 0 #------------------------------------------------------------------------------------# @@ -102,7 +102,7 @@ summnum <<- function(x,byrow=FALSE,finite.only=TRUE,neverlog=NULL,is.debug=FALSE , no = NA_real_ )#end ifelse )#end with - lognorm.is.better = ln.lnorm %>=% ln.norm + lognorm.is.better = ln.lnorm %ge% ln.norm #------------------------------------------------------------------------------------# @@ -146,7 +146,7 @@ summnum.int <<- function(x,finite.only){ if ("try-error" %in% is(wcm.2)){wcm.2 = NA}else if (is.null(wcm.2)){wcm.2 = NA} if ("try-error" %in% is(wcm.1)){wcm.1 = NA}else if (is.null(wcm.1)){wcm.1 = NA} - #if (! all(c(wcm.1,wcm.2,wcm.3) %==% c("lapply","sapply","summnum"))){ + #if (! all(c(wcm.1,wcm.2,wcm.3) %eq% c("lapply","sapply","summnum"))){ # stop(" Function summnum.int is internal, and must be called through summnum","\n") #}#end if #---------------------------------------------------------------------------------------# @@ -181,7 +181,7 @@ summnum.int <<- function(x,finite.only){ , skew = skew(x,na.rm=TRUE) , kurt = kurt(x,na.rm=TRUE) , navl = sum (! is.na(x)) - , npos = sum (x %<% 0) + , npos = sum (x %lt% 0) , ntot = nx )#end c }else{ @@ -244,7 +244,7 @@ lnlike.comp <<- function(x,xlab="nothing"){ if ("try-error" %in% is(wcm.2)){wcm.2 = NA}else if (is.null(wcm.2)){wcm.2 = NA} if ("try-error" %in% is(wcm.1)){wcm.1 = NA}else if (is.null(wcm.1)){wcm.1 = NA} - #if (! all(c(wcm.1,wcm.2,wcm.3) %==% c("lapply","sapply","summnum"))){ + #if (! all(c(wcm.1,wcm.2,wcm.3) %eq% c("lapply","sapply","summnum"))){ # stop(" Function sw.pvalue is internal and must be called through summnum","\n") #}#end if #---------------------------------------------------------------------------------------# @@ -258,7 +258,7 @@ lnlike.comp <<- function(x,xlab="nothing"){ #----- Make sure x is a simple vector. Keep only the positive terms. ------------------# x = as.numeric(unlist(c(x))) - lnx = ifelse(test=x %>% 0,yes=log(x),no=NA_real_) + lnx = ifelse(test=x %gt% 0,yes=log(x),no=NA_real_) sel = is.finite(lnx) x = x [sel] lnx = lnx[sel] diff --git a/R-utils/sw.test.r b/R-utils/sw.test.r index 82e6dea01..a58db67b2 100644 --- a/R-utils/sw.test.r +++ b/R-utils/sw.test.r @@ -46,7 +46,7 @@ sw.test <<- function(x){ #-------------------------------------------------------------------------------------# # Decide which method to use based on the kurtosis. # #-------------------------------------------------------------------------------------# - if (kurt(x) %>% 3){ + if (kurt(x) %gt% 3){ #----------------------------------------------------------------------------------# # Use Shapiro-Francia as the sample is leptokurtic. The Shapiro-Francia # # statistic W is calculated to avoid excessive rounding errors for W close to 1 # diff --git a/R-utils/taxonutils.r b/R-utils/taxonutils.r index 1a87b6d67..e4fc97b57 100644 --- a/R-utils/taxonutils.r +++ b/R-utils/taxonutils.r @@ -5,8 +5,9 @@ unknown.wildcard <<- c("aff","cf","deleteme","ind","indet","na","ni","sp","s ,paste0("spb" ,sequence(99)) ,paste0("spp" ,sequence(99)) ,paste0("sp" ,sequence(99),"cay-atdn") - ,paste0("sp" ,sequence(99),"guyafor") - ,paste0("spfg",sequence(99),"-holst") + ,paste0("sp" ,sequence(99),"-cay" ) + ,paste0("sp" ,sequence(99),"guyafor" ) + ,paste0("spfg",sequence(99),"-holst" ) )#end c unknown.common <<- "mato" unk.liana.common <<- "cipo" @@ -73,7 +74,7 @@ standard.common.name <<- function(x){ x = gsub(pattern="^quina-quina" ,replacement="quinaquina" ,x=x) x = gsub(pattern="^tamarino" ,replacement="tamarindo" ,x=x) x = gsub(pattern="^taxi" ,replacement="tachi" ,x=x) - x = gsub(pattern="^uchi" ,replacement="uxi" ,x=x) + x = gsub(pattern="^uxi" ,replacement="uchi" ,x=x) x = gsub(pattern="verdadiera" ,replacement="verdadeira" ,x=x) x = gsub(pattern="^xixua" ,replacement="chichua" ,x=x) #---------------------------------------------------------------------------------------# @@ -83,7 +84,10 @@ standard.common.name <<- function(x){ #----- Full replacements. --------------------------------------------------------------# sel = (x %in% "?" ); x[sel] = NA_character_ sel = (x %in% "abacaba" ); x[sel] = "bacaba" + sel = (x %in% "abacabeira" ); x[sel] = "bacaba" sel = (x %in% "abicuiba" ); x[sel] = "ucuuba" + sel = (x %in% "abirana" ); x[sel] = "abiurana" + sel = (x %in% "abirana branca" ); x[sel] = "abiurana branca" sel = (x %in% "abirana rosadinha" ); x[sel] = "abiu rosadinho" sel = (x %in% "abil fura fura" ); x[sel] = "abiu-fura-fura" sel = (x %in% "abiui" ); x[sel] = "abiu" @@ -96,12 +100,16 @@ standard.common.name <<- function(x){ sel = (x %in% "abiu guajara" ); x[sel] = "abiu-guajara" sel = (x %in% "abiu goiabao" ); x[sel] = "abiu-goiabao" sel = (x %in% "abiu mangabinha" ); x[sel] = "abiu-mangabinha" + sel = (x %in% "abiu rosadinha" ); x[sel] = "abiu rosadinho" sel = (x %in% "abiu tauari" ); x[sel] = "tauari" sel = (x %in% "abiu vermelha" ); x[sel] = "abiu vermelho" sel = (x %in% "abiurana vermelho" ); x[sel] = "abiurana vermelha" sel = (x %in% "abiurana vermlho" ); x[sel] = "abiurana vermelha" sel = (x %in% "abiuarana" ); x[sel] = "abiurana" sel = (x %in% "abiurana rosadinha" ); x[sel] = "abiu rosadinho" + sel = (x %in% "acaizeiro" ); x[sel] = "acai" + sel = (x %in% "acariguara" ); x[sel] = "acariquara" + sel = (x %in% "acariguarana" ); x[sel] = "acariquarana" sel = (x %in% "acoita cavalo" ); x[sel] = "acoita-cavalo" sel = (x %in% "algodao brabo" ); x[sel] = "algodao-bravo" sel = (x %in% "algodao bravo" ); x[sel] = "algodao-bravo" @@ -139,16 +147,19 @@ standard.common.name <<- function(x){ sel = (x %in% "baubarana" ); x[sel] = "embaubarana" sel = (x %in% "breu/louro preto?" ); x[sel] = NA_character_ sel = (x %in% "breu aroeira" ); x[sel] = "breu-aroeira" + sel = (x %in% "breu brrote" ); x[sel] = "breu barrote" sel = (x %in% "breu sucuruba" ); x[sel] = "breu-sucuruba" sel = (x %in% "breu sucuruba branco" ); x[sel] = "breu-sucuruba branco" sel = (x %in% "breu sucurubinha" ); x[sel] = "breu-sucurubinha" + sel = (x %in% "brteu branco" ); x[sel] = "breu branco" sel = (x %in% "babao" ); x[sel] = "macauba" sel = (x %in% "bolao" ); x[sel] = "fava-bolota" sel = (x %in% "bombeira" ); x[sel] = "pau-pombo" sel = (x %in% "brau" ); x[sel] = "breu" - sel = (x %in% "brejauba" ); x[sel] = "brejauva" - sel = (x %in% "breu sucuuba" ); x[sel] = "breu sucuruba" - sel = (x %in% "cabeca de urubu" ); x[sel] = "cabeca-de-urubu" + sel = (x %in% "brejauba" ); x[sel] = "brejauva" + sel = (x %in% "breu sucuuba" ); x[sel] = "breu sucuruba" + sel = (x %in% "burra leteira" ); x[sel] = "burra leiteira" + sel = (x %in% "cabeca de urubu" ); x[sel] = "cabeca-de-urubu" sel = (x %in% "cabela" ); x[sel] = "louro canela" sel = (x %in% "cabriuva" ); x[sel] = "cabreuva" sel = (x %in% "cabriuna" ); x[sel] = "cabreuva" @@ -156,8 +167,9 @@ standard.common.name <<- function(x){ sel = (x %in% "cabreuba" ); x[sel] = "cabreuva" sel = (x %in% "caca piolho" ); x[sel] = "mata-piolho" sel = (x %in% "cacau bravo" ); x[sel] = "cacaui" - sel = (x %in% "cacau da mata" ); x[sel] = "cacau" - sel = (x %in% "cacaurana" ); x[sel] = "cacau" + sel = (x %in% "cacau da mata" ); x[sel] = "cacau" + sel = (x %in% "cacau do mato" ); x[sel] = "cacau" + sel = (x %in% "cacaurana" ); x[sel] = "cacau" sel = (x %in% "cachixa" ); x[sel] = "caxixa" sel = (x %in% "cachudinha" ); x[sel] = "cascudinha" sel = (x %in% "cagaca" ); x[sel] = "abiurana-cagaca" @@ -183,7 +195,9 @@ standard.common.name <<- function(x){ sel = (x %in% "capueiro branco" ); x[sel] = "capueiro" sel = (x %in% "caqui branco" ); x[sel] = "caqui" sel = (x %in% "caqui folha grande" ); x[sel] = "caqui" - sel = (x %in% "carobia" ); x[sel] = "caroba" + sel = (x %in% "carana" ); x[sel] = NA_character_ + sel = (x %in% "carape" ); x[sel] = "caripe" + sel = (x %in% "carobia" ); x[sel] = "caroba" sel = (x %in% "cascudinho" ); x[sel] = "cascudinha" sel = (x %in% "cascudo" ); x[sel] = "cascudinha" sel = (x %in% "castanha do brasil" ); x[sel] = "castanha-do-para" @@ -196,7 +210,8 @@ standard.common.name <<- function(x){ sel = (x %in% "castanha de sapocaia" ); x[sel] = "castanha-sapucaia" sel = (x %in% "castanha de sapucaia" ); x[sel] = "castanha-sapucaia" sel = (x %in% "castanha sapocaia" ); x[sel] = "castanha-sapucaia" - sel = (x %in% "castanheira" ); x[sel] = "castanha-do-para" + sel = (x %in% "castanha sapucaia" ); x[sel] = "castanha-sapucaia" + sel = (x %in% "castanheira" ); x[sel] = "castanha-do-para" sel = (x %in% "cauba" ); x[sel] = "macacauba" sel = (x %in% "cauxo" ); x[sel] = "caucho" sel = (x %in% "caxeta" ); x[sel] = "caixeta" @@ -263,8 +278,9 @@ standard.common.name <<- function(x){ sel = (x %in% "envira cabo de rodo" ); x[sel] = "envira cabo-de-rodo" sel = (x %in% "envira caju" ); x[sel] = "envira-caju" sel = (x %in% "envira conduru" ); x[sel] = "envira-conduru" - sel = (x %in% "envira cunauaru" ); x[sel] = "envira-cunauaru" - sel = (x %in% "envira de caju" ); x[sel] = "envira-jacu" + sel = (x %in% "envira cunacaru" ); x[sel] = "envira-cunauaru" + sel = (x %in% "envira cunauaru" ); x[sel] = "envira-cunauaru" + sel = (x %in% "envira de caju" ); x[sel] = "envira-jacu" sel = (x %in% "envira de jacu" ); x[sel] = "envira-jacu" sel = (x %in% "envira-mao-de-onca" ); x[sel] = "envira mao-de-onca" sel = (x %in% "envira molia branco" ); x[sel] = "envira-molia branco" @@ -304,19 +320,25 @@ standard.common.name <<- function(x){ sel = (x %in% "fava orelha" ); x[sel] = "fava orelha-de-macaco" sel = (x %in% "fava orelha de macaco" ); x[sel] = "fava orelha-de-macaco" sel = (x %in% "fava paricarana" ); x[sel] = "fava-paricana" + sel = (x %in% "fava rosa" ); x[sel] = "fava-de-rosca" sel = (x %in% "fava saboeira" ); x[sel] = "fava-saboeira" - sel = (x %in% "fava tambori" ); x[sel] = "fava-tamboril" + sel = (x %in% "fava saboeiro" ); x[sel] = "fava-saboeira" + sel = (x %in% "fava tambori" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamburi" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamboril" ); x[sel] = "fava-tamboril" sel = (x %in% "fava tamboriu" ); x[sel] = "fava-tamboril" - sel = (x %in% "favera amargosa" ); x[sel] = "fava amargosa" - sel = (x %in% "faveira branca" ); x[sel] = "fava branca" - sel = (x %in% "feijo branco" ); x[sel] = "freijo branco" + sel = (x %in% "faveira" ); x[sel] = "fava" + sel = (x %in% "faveira amargosa" ); x[sel] = "fava amargosa" + sel = (x %in% "faveira branca" ); x[sel] = "fava branca" + sel = (x %in% "faveira rosa" ); x[sel] = "fava-de-rosca" + sel = (x %in% "favera amargosa" ); x[sel] = "fava amargosa" + sel = (x %in% "feijo branco" ); x[sel] = "freijo branco" sel = (x %in% "ferdinandusa elliptica" ); x[sel] = "bacabinha quina" sel = (x %in% "figado de preguisa" ); x[sel] = "figado-de-preguica" sel = (x %in% "figueira brava" ); x[sel] = "figueira" - sel = (x %in% "gameleiro" ); x[sel] = "gameleira" - sel = (x %in% "gapeba" ); x[sel] = "guapeva" + sel = (x %in% "gaivota" ); x[sel] = "gaivotinha" + sel = (x %in% "gameleiro" ); x[sel] = "gameleira" + sel = (x %in% "gapeba" ); x[sel] = "guapeva" sel = (x %in% "guapeba" ); x[sel] = "guapeva" sel = (x %in% "gema de ovo" ); x[sel] = "gema-de-ovo" sel = (x %in% "geniparana" ); x[sel] = "jeniparana" @@ -369,6 +391,7 @@ standard.common.name <<- function(x){ sel = (x %in% "jacariuba" ); x[sel] = "jacareuba" sel = (x %in% "jambo" ); x[sel] = "jambo-do-mato" sel = (x %in% "jara" ); x[sel] = "jarana" + sel = (x %in% "jarana vermelha" ); x[sel] = "jarana" sel = (x %in% "jaruma" ); x[sel] = "taruma" sel = (x %in% "jauari" ); x[sel] = "tauari" sel = (x %in% "jenita" ); x[sel] = "janita" @@ -401,9 +424,11 @@ standard.common.name <<- function(x){ sel = (x %in% "mafim" ); x[sel] = "marfim" sel = (x %in% "mamao jacatia" ); x[sel] = "jacaratia" sel = (x %in% "mamica de porca" ); x[sel] = "mamica-de-porca" - sel = (x %in% "mamonini" ); x[sel] = "mamoninha" + sel = (x %in% "mamominho" ); x[sel] = "mamoninha" + sel = (x %in% "mamonini" ); x[sel] = "mamoninha" sel = (x %in% "mandioqueiro" ); x[sel] = "mandioqueira" sel = (x %in% "mandioqueiro escamoso" ); x[sel] = "mandioqueira" + sel = (x %in% "manguirana" ); x[sel] = "manguerana" sel = (x %in% "mangueira" ); x[sel] = "manguerana" sel = (x %in% "manguerano" ); x[sel] = "manguerana" sel = (x %in% "maparajuba" ); x[sel] = "parajuba" @@ -413,8 +438,10 @@ standard.common.name <<- function(x){ sel = (x %in% "maquira" ); x[sel] = "muiratinga" sel = (x %in% "maracata" ); x[sel] = "marassacaca" sel = (x %in% "maracatia" ); x[sel] = "muiracatiara" + sel = (x %in% "maracatiara rajada" ); x[sel] = "maracatiara" sel = (x %in% "maracacaca" ); x[sel] = "marassacaca" sel = (x %in% "marasacaca" ); x[sel] = "marassacaca" + sel = (x %in% "marauba" ); x[sel] = NA_character_ sel = (x %in% "marimari" ); x[sel] = "fava-marimari" sel = (x %in% "massaranduba" ); x[sel] = "macaranduba" sel = (x %in% "mata fome" ); x[sel] = "mata-fome" @@ -426,9 +453,11 @@ standard.common.name <<- function(x){ sel = (x %in% "mata pau+jito" ); x[sel] = "gito" sel = (x %in% "mata caldo" ); x[sel] = "mata-calado" sel = (x %in% "melanciera" ); x[sel] = "melancieira" + sel = (x %in% "mirapiranga" ); x[sel] = "muirapiranga" sel = (x %in% "morto" ); x[sel] = "morta" sel = (x %in% "morango de macaco" ); x[sel] = "morango-de-macaco" sel = (x %in% "morango de morcego" ); x[sel] = "morango-de-macaco" + sel = (x %in% "muiracacaco" ); x[sel] = NA_character_ sel = (x %in% "muiratinga folha grande/amapa" ); x[sel] = "muiratinga folha grande" sel = (x %in% "muiratinga fura fura" ); x[sel] = "muiratinga fura-fura" sel = (x %in% "mulatero" ); x[sel] = "mulateiro" @@ -441,6 +470,8 @@ standard.common.name <<- function(x){ sel = (x %in% "mutama" ); x[sel] = "mutambo" sel = (x %in% "mutamba" ); x[sel] = "mutambo" sel = (x %in% "mututiassu" ); x[sel] = "mututi-acu" + sel = (x %in% "nao identificada" ); x[sel] = NA_character_ + sel = (x %in% "nao indetificada" ); x[sel] = NA_character_ sel = (x %in% "ni" ); x[sel] = NA_character_ sel = (x %in% "orelha de burro" ); x[sel] = "orelha-de-burro" sel = (x %in% "orelha de macaco" ); x[sel] = "fava orelha-de-macaco" @@ -474,7 +505,7 @@ standard.common.name <<- function(x){ sel = (x %in% "pau de rego" ); x[sel] = "pau-de-remo" sel = (x %in% "pau de remo" ); x[sel] = "pau-de-remo" sel = (x %in% "pau de sangue" ); x[sel] = "pau-sangue" - sel = (x %in% "pau doce" ); x[sel] = "pau-doce" + sel = (x %in% "pau-doce" ); x[sel] = "pau doce" sel = (x %in% "pau jacare" ); x[sel] = "pau-jacare" sel = (x %in% "pau marfim" ); x[sel] = "pau-marfim" sel = (x %in% "pau mulato" ); x[sel] = "pau-mulato" @@ -488,6 +519,7 @@ standard.common.name <<- function(x){ sel = (x %in% "pau rego" ); x[sel] = "pau-de-remo" sel = (x %in% "pau sangue" ); x[sel] = "pau-sangue" sel = (x %in% "pereauna" ); x[sel] = "perebuna" + sel = (x %in% "pedra ume" ); x[sel] = "pedra ume-caa" sel = (x %in% "pedra umi" ); x[sel] = "pedra ume-caa" sel = (x %in% "pelo de cutia" ); x[sel] = "pelo-de-cutia" sel = (x %in% "pente de macaco" ); x[sel] = "pente-de-macaco" @@ -496,19 +528,23 @@ standard.common.name <<- function(x){ sel = (x %in% "pepino do mato" ); x[sel] = "pepino-do-mato" sel = (x %in% "pepino-do-mato" ); x[sel] = "pepino-do-mato" sel = (x %in% "perna de moca" ); x[sel] = "perna-de-moca" - sel = (x %in% "piqui" ); x[sel] = "piquia" + sel = (x %in% "pincel de macaco" ); x[sel] = "pente-de-macaco" + sel = (x %in% "piqui" ); x[sel] = "piquia" sel = (x %in% "piqui rosa" ); x[sel] = "piquia" sel = (x %in% "piquiazeiro" ); x[sel] = "piquia" sel = (x %in% "pitomba da mata" ); x[sel] = "pitomba-da-mata" + sel = (x %in% "pocoro" ); x[sel] = NA_character_ sel = (x %in% "pororoca" ); x[sel] = "jutai-pororoca" sel = (x %in% "prapara" ); x[sel] = "parapara" sel = (x %in% "pratudo" ); x[sel] = "pau-para-tudo" + sel = (x %in% "puriu" ); x[sel] = "purui" sel = (x %in% "puruirana/purui branco" ); x[sel] = "purui branco" sel = (x %in% "quaiquara" ); x[sel] = "acariquara" sel = (x %in% "quariquara" ); x[sel] = "acariquara" sel = (x %in% "quariquarana" ); x[sel] = "acariquara" sel = (x %in% "quariquari" ); x[sel] = "acariquara" - sel = (x %in% "quari quari" ); x[sel] = "acariquara" + sel = (x %in% "quari quari" ); x[sel] = "acariquara" + sel = (x %in% "quariuba" ); x[sel] = "quaruba" sel = (x %in% "quaruba cedro" ); x[sel] = "quaruba-cedro" sel = (x %in% "quebrado" ); x[sel] = NA_character_ sel = (x %in% "quina" ); x[sel] = "quinarana" @@ -536,7 +572,9 @@ standard.common.name <<- function(x){ sel = (x %in% "seringa branco" ); x[sel] = "seringueira" sel = (x %in% "seringa verdadeira" ); x[sel] = "seringueira" sel = (x %in% "seringarana preta" ); x[sel] = "seringarana" - sel = (x %in% "seritinga" ); x[sel] = "seringueira" + sel = (x %in% "seringuarana" ); x[sel] = "seringarana" + sel = (x %in% "seritinga" ); x[sel] = "seringueira" + sel = (x %in% "sorvao" ); x[sel] = "sorva" sel = (x %in% "sorveira" ); x[sel] = "sorva" sel = (x %in% "sorveira leite" ); x[sel] = "sorva" sel = (x %in% "sorvo" ); x[sel] = "sorva" @@ -551,13 +589,18 @@ standard.common.name <<- function(x){ sel = (x %in% "tachi preto ???" ); x[sel] = "tachi preto" sel = (x %in% "tachi preto folh" ); x[sel] = "tachi preto" sel = (x %in% "tachi vermelha" ); x[sel] = "tachi vermelho" - sel = (x %in% "talquari" ); x[sel] = "tauari" - sel = (x %in% "tamaquarao" ); x[sel] = "tamaquare" + sel = (x %in% "taguari" ); x[sel] = "taquari" + sel = (x %in% "talquari" ); x[sel] = "taquari" + sel = (x %in% "tamaguare" ); x[sel] = "tamaquare" + sel = (x %in% "tamaquarao" ); x[sel] = "tamaquare" sel = (x %in% "tamarindu" ); x[sel] = "tamarindo" sel = (x %in% "tamauma" ); x[sel] = "sumauma" sel = (x %in% "tamboril" ); x[sel] = "fava-tamboril" sel = (x %in% "tamboriul" ); x[sel] = "fava-tamboril" sel = (x %in% "tanari roxo" ); x[sel] = "tauari" + sel = (x %in% "tanenbuco" ); x[sel] = "tanimbuca" + sel = (x %in% "tanenbuco amarelo" ); x[sel] = "tanimbuca amarela" + sel = (x %in% "tanibuca" ); x[sel] = "tanimbuca" sel = (x %in% "tangarana" ); x[sel] = "tangirana" sel = (x %in% "tanimbuca" ); x[sel] = "tanibuca" sel = (x %in% "tapiririca" ); x[sel] = "tatapiririca" @@ -565,25 +608,35 @@ standard.common.name <<- function(x){ sel = (x %in% "tatapiririca verm." ); x[sel] = "tatapiririca vermelha" sel = (x %in% "taturana" ); x[sel] = "taturuba" sel = (x %in% "tauri" ); x[sel] = "tauari" + sel = (x %in% "tento cachua" ); x[sel] = "tento caxua" sel = (x %in% "tento folha" ); x[sel] = "tento" sel = (x %in% "tento foha grauda" ); x[sel] = "tento folha grauda" - sel = (x %in% "tintero" ); x[sel] = "tinteiro" + sel = (x %in% "timbora" ); x[sel] = "timborana" + sel = (x %in% "tintero" ); x[sel] = "tinteiro" sel = (x %in% "titiriba" ); x[sel] = "cucutitiriba" sel = (x %in% "tucuma acu" ); x[sel] = "tucuma-acu" - sel = (x %in% "ucuarana" ); x[sel] = "urucurana" - sel = (x %in% "ucuuba da varzea" ); x[sel] = "ucuuba-da-varzea" + sel = (x %in% "uchi coroa" ); x[sel] = "uchi-curua" + sel = (x %in% "ucuarana" ); x[sel] = "urucurana" + sel = (x %in% "ucurana" ); x[sel] = "urucurana" + sel = (x %in% "ucuuba da varzea" ); x[sel] = "ucuuba-da-varzea" sel = (x %in% "ucuuba da terra firme" ); x[sel] = "ucuuba terra-firme" + sel = (x %in% "ucuuba folha grande" ); x[sel] = "ucuuba" sel = (x %in% "ucuuba terra firme" ); x[sel] = "ucuuba terra-firme" sel = (x %in% "ucuuba tf" ); x[sel] = "ucuuba terra-firme" - sel = (x %in% "ucuuba vermelho" ); x[sel] = "ucuuba vermelha" + sel = (x %in% "ucuuba t.f" ); x[sel] = "ucuuba terra-firme" + sel = (x %in% "ucuuba vermelho" ); x[sel] = "ucuuba vermelha" sel = (x %in% "umbia" ); x[sel] = "goiabarana" sel = (x %in% "unha de vaca" ); x[sel] = "pata-de-vaca" sel = (x %in% "uruci" ); x[sel] = "muruci" sel = (x %in% "urucu" ); x[sel] = "urucum" + sel = (x %in% "urucurana branco" ); x[sel] = "urucurana branca" sel = (x %in% "urucuri" ); x[sel] = "urucum" sel = (x %in% "uruucurana" ); x[sel] = "urucurana" sel = (x %in% "virola" ); x[sel] = "ucuuba" + sel = (x %in% "virola(ucuuba)" ); x[sel] = "ucuuba" + sel = (x %in% "virola/ucuuba preta" ); x[sel] = "ucuuba preta" sel = (x %in% "xaonoquito" ); x[sel] = "pau vermelho" + sel = (x %in% "zaguari" ); x[sel] = "taquari" #---------------------------------------------------------------------------------------# return(x) @@ -629,6 +682,29 @@ standard.scientific.name <<- function(dat,nafill=TRUE){ , stringsAsFactors = FALSE )#end read.csv nsynonym = nrow(synonym) + #---------------------------------------------------------------------------------------# + # Make sure there is no circularity in the synonym table. # + #---------------------------------------------------------------------------------------# + circular = which(synonym$accepted %in% synonym$synonym) + if (length(circular) %gt% 0L){ + toshow = synonym[circular,,drop=FALSE] + toshow$line = circular + toshow = toshow[,c("line","synonym","accepted"),drop=FALSE] + cat0("-----------------------------------------------------------") + cat0(" Circularity detected in file \"synonym_taxon.csv\":") + cat0(" ") + print(toshow,quote=FALSE) + cat0("-----------------------------------------------------------") + cat0(" ") + browser() + }#end if (length(circular) %gt% 0L) + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Replace synonyms with accepted names. # + #---------------------------------------------------------------------------------------# idx = match(g.s,synonym$synonym) sel = is.finite(idx) g.s[sel] = synonym$accepted[idx[sel]] @@ -692,7 +768,7 @@ standard.scientific.name <<- function(dat,nafill=TRUE){ #---------------------------------------------------------------------------------------# return(dat) -}#end function standard.common.name +}#end function standard.scientific.name #==========================================================================================# #==========================================================================================# @@ -879,7 +955,7 @@ standard.order.phylum.name <<- function(datum,nafill=TRUE){ #---------------------------------------------------------------------------------------# idx = which( ( ! (is.na(datum$family) | (datum$family %in% unknown.family) ) ) & ( ! datum$family %in% f2o$family ) - & ( regexpr(pattern=unknown.family,text=datum$family,ignore.case=T) %==% -1) + & ( regexpr(pattern=unknown.family,text=datum$family,ignore.case=T) %eq% -1) )#end which if (length(idx) > 0){ tofill.fam = t(t(sort(unique(datum$family[idx])))) @@ -1541,7 +1617,7 @@ find.wood.density <<- function( datum }else if (is.character(weight) && (length(weight) == 1)){ #----- Character with column name was provided. -------------------------------------# if (weight %in% names(datum)){ - wgtfac = ifelse(datum[[weight]] %>% 0, datum[[weight]], 0) + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) }else{ stop(paste0(" Weight Variable name (",weight,") not found in datum!")) }#end if @@ -1551,13 +1627,13 @@ find.wood.density <<- function( datum if (! (weight %wr% c(1,ncol(datum)))){ stop(paste0(" Weight column index (",weight,") doesn't make sense")) }else if (is.numeric(datum[,weight])){ - wgtfac = ifelse(datum[,weight] %>% 0, datum[,weight], 0) + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) }else{ stop(paste0(" Column ",weight," of data frame is not numeric!")) }#end if #------------------------------------------------------------------------------------# }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ - wgtfac = ifelse(weight %>% 0, weight, 0) + wgtfac = ifelse(weight %gt% 0, weight, 0) }else{ stop("Variable weight is not properly set!") }#end if (is.null(weight)) @@ -2004,7 +2080,7 @@ find.trait <<- function( datum }else if (is.character(weight) && (length(weight) == 1)){ #----- Character with column name was provided. -------------------------------------# if (weight %in% names(datum)){ - wgtfac = ifelse(datum[[weight]] %>% 0, datum[[weight]], 0) + wgtfac = ifelse(datum[[weight]] %gt% 0, datum[[weight]], 0) }else{ stop(paste0(" Weight Variable name (",weight,") not found in datum!")) }#end if @@ -2014,13 +2090,13 @@ find.trait <<- function( datum if (! (weight %wr% c(1,ncol(datum)))){ stop(paste0(" Weight column index (",weight,") doesn't make sense")) }else if (is.numeric(datum[,weight])){ - wgtfac = ifelse(datum[,weight] %>% 0, datum[,weight], 0) + wgtfac = ifelse(datum[,weight] %gt% 0, datum[,weight], 0) }else{ stop(paste0(" Column ",weight," of data frame is not numeric!")) }#end if #------------------------------------------------------------------------------------# }else if (is.numeric(weight) && (length(weight) == nrow(datum))){ - wgtfac = ifelse(weight %>% 0, weight, 0) + wgtfac = ifelse(weight %gt% 0, weight, 0) }else{ stop("Variable weight is not properly set!") }#end if (is.null(weight)) @@ -2044,6 +2120,8 @@ find.trait <<- function( datum # Read data base to fill traits. # #---------------------------------------------------------------------------------------# tdb = read.csv(file=tdb.csv,header=TRUE,stringsAsFactors=FALSE) + keep = is.finite(tdb[[trait]]) + tdb = tdb[keep,,drop=FALSE] #---------------------------------------------------------------------------------------# @@ -2677,6 +2755,10 @@ keep.gen.spe.only <<- function(x,out=c("both","genus","species"),is.debug=FALSE) x = gsub(pattern="_form2$",replacement=" form2",x=x) #------------------------------------------------------------------------------------# + #----- Remove "indet" that may appear in from of an unknown genus. ------------------# + x = gsub(pattern="^indet",replacement="",x=x) + #------------------------------------------------------------------------------------# + #----- Split words, and remove stuff like sp, cf, etc. ------------------------------# ans = unlist(strsplit(unlist(c(tolower(x))),split=" ")) diff --git a/R-utils/taylor.plot.r b/R-utils/taylor.plot.r index f25e98ccb..baff7b1f1 100644 --- a/R-utils/taylor.plot.r +++ b/R-utils/taylor.plot.r @@ -152,8 +152,8 @@ taylor.plot <<- function ( obs #---------------------------------------------------------------------------------------# R = sapply(X = mod, FUN = cor, x = obs, use = "pairwise") if (is.na(pos.corr)){ - pos.corr = ! any(R %<% 0.) - }else if (pos.corr && any(R %<% 0)){ + pos.corr = ! any(R %lt% 0.) + }else if (pos.corr && any(R %lt% 0)){ warning(" There are negative correlations, but you've asked positive side only!") }#end if #---------------------------------------------------------------------------------------# diff --git a/R-utils/test.goodness.r b/R-utils/test.goodness.r index a940dfc54..f0306e704 100644 --- a/R-utils/test.goodness.r +++ b/R-utils/test.goodness.r @@ -44,8 +44,8 @@ test.goodness <<- function(x.mod,x.obs,x.sigma=NULL,n.parameters=NULL,out.dfr=FA #----- Find associated weights, and re-create the vectors x.mod and x.obs. ----------# - x.wgt = ifelse(x.sigma %>% 0, 1. / x.sigma^2, 0) - sel = x.wgt %>% 0 + x.wgt = ifelse(x.sigma %gt% 0, 1. / x.sigma^2, 0) + sel = x.wgt %gt% 0 x.obs.orig = x.obs x.mod.orig = x.mod x.obs = x.obs[sel] * sqrt(x.wgt[sel]) diff --git a/R-utils/thermlib.r b/R-utils/thermlib.r index 4b0689eb3..9f8213466 100644 --- a/R-utils/thermlib.r +++ b/R-utils/thermlib.r @@ -691,6 +691,32 @@ idealdenssh <<- function(pres,temp,qvpr,qtot=NULL){ +#==========================================================================================# +#==========================================================================================# +# This function finds the dry-air molar density (mol/m3), using the ideal gas law. # +#------------------------------------------------------------------------------------------# +idealdmolsh <<- function(pres,temp,qvpr,qtot=NULL){ + + + #----- Find the partial pressure of water vapour. --------------------------------------# + pdry = pres * (1.0 - qvpr / (ep + (1.0 - ep) * qvpr)) + #---------------------------------------------------------------------------------------# + + + #----- Convert using a generalised function. -------------------------------------------# + dmol = pdry / (rmol * temp) + #---------------------------------------------------------------------------------------# + + return(dmol) +}#end if +#==========================================================================================# +#==========================================================================================# + + + + + + #==========================================================================================# #==========================================================================================# # This function computes the pressure at the top of the tower using hydrostatic and # @@ -753,7 +779,7 @@ tower.press <<- function(p0,e0,t0,z0,t1,e1,z1,hum="pvap"){ #---------------------------------------------------------------------------------------# return(p1) -}#end function reducedpress +}#end function tower.press #==========================================================================================# #==========================================================================================# @@ -762,6 +788,65 @@ tower.press <<- function(p0,e0,t0,z0,t1,e1,z1,hum="pvap"){ + +#==========================================================================================# +#==========================================================================================# +# This function computes reduces the pressure from the reference height to the canopy # +# height by assuming hydrostatic equilibrium. For simplicity, we assume that R and cp are # +# constants (in reality they are dependent on humidity). # +#------------------------------------------------------------------------------------------# +reducedpress <<- function(pres,thetaref,shvref,zref,thetacan,shvcan,zcan,fthva_rp=0.5){ + + + #---------------------------------------------------------------------------------------# + # Missing data points. # + #---------------------------------------------------------------------------------------# + any.miss = c(missing(pres),missing(thetaref),missing(shvref),missing(zref) + ,missing(thetacan),missing(shvcan),missing(zcan)) + if (any(any.miss)){ + cat0(" Variable \"pres\" is provided: " ,! missing(pres ),".") + cat0(" Variable \"thetaref\" is provided: ",! missing(thetaref),".") + cat0(" Variable \"shvref\" is provided: ",! missing(shvref ),".") + cat0(" Variable \"zref\" is provided: ",! missing(zrefref ),".") + cat0(" Variable \"thetacan\" is provided: ",! missing(thetacan),".") + cat0(" Variable \"shvcan\" is provided: ",! missing(shvcan ),".") + cat0(" Variable \"zcan\" is provided: ",! missing(zcancan ),".") + stop("All variables above must be provided.") + }#end if (any.miss) + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # First we compute the average virtual potential temperature between the canopy # + # top and the reference level. Because of the equation below, we average the inverse # + # of the potential temperature. # + #---------------------------------------------------------------------------------------# + thvref = thetaref * (1.0 + epim1 * shvref) + thvcan = thetacan * (1.0 + epim1 * shvcan) + thvbar = thvref * thvcan / ( ( 1.0 - fthva_rp ) * thvref + fthva_rp * thvcan ) + #---------------------------------------------------------------------------------------# + + + + #----- Then, we find the pressure gradient scale. --------------------------------------# + pinc = grav * p00k * (zref - zcan) / (cpdry * thvbar) + #---------------------------------------------------------------------------------------# + + + + #----- And we can find the reduced pressure. -------------------------------------------# + ans = (pres**rocp + pinc ) ** cpor + #---------------------------------------------------------------------------------------# + + + return(ans) +}#end function reducedpress +#==========================================================================================# +#==========================================================================================# + + + + + #==========================================================================================# #==========================================================================================# # This subroutine finds the lifting condensation level given the ice-liquid # @@ -1148,3 +1233,30 @@ uextcm2tl <<- function(uext,wmass,dryhcap){ }#end function uextcm2tl #==========================================================================================# #==========================================================================================# + + + + + +#==========================================================================================# +#==========================================================================================# +# Functions that convert between pressure and Exner function. # +#------------------------------------------------------------------------------------------# +press2exner <<- function(pres ){ cpdry * (pres * p00i ) ^ rocp} +exner2press <<- function(exner){ p00 * (exner * cpdryi) ^ cpor} +#==========================================================================================# +#==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Functions that convert between temperature and potential temperature using Exner. # +#------------------------------------------------------------------------------------------# +extemp2theta <<- function(exner,temp ){ cpdry * temp / exner } +extheta2temp <<- function(exner,theta){ cpdryi * theta * exner } +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/time.to.edge.r b/R-utils/time.to.edge.r new file mode 100644 index 000000000..dee8f03df --- /dev/null +++ b/R-utils/time.to.edge.r @@ -0,0 +1,130 @@ +#==========================================================================================# +#==========================================================================================# +# Function time.to.edge. # +# # +# This function computes the time it takes for air to reach the edge, assuming that # +# air moves along the dominant wind. # +# # +#------------------------------------------------------------------------------------------# +time.to.edge <<- function( datum + , emask + , u.vnam + , v.vnam + , xy.m.fac = 1000. + , wmin = 0.05 + , tmax = 5000./wmin + , cosmin = cos(15.*pio180) + ){ + + #------ Fortran code. ------------------------------------------------------------------# + fortran.so = file.path(srcdir,"time_to_edge.so") + #---------------------------------------------------------------------------------------# + + + #---------------------------------------------------------------------------------------# + # Extract wind data from data table. # + #---------------------------------------------------------------------------------------# + uvsel = is.finite(datum[[u.vnam]]) & is.finite(datum[[v.vnam]]) + dsel = datum[uvsel] + nwind = nrow(dsel) + xwind = dsel$x * xy.m.fac + ywind = dsel$y * xy.m.fac + uwind = dsel[[u.vnam]] + vwind = dsel[[v.vnam]] + #---------------------------------------------------------------------------------------# + + + + #---------------------------------------------------------------------------------------# + # Extract wind data from mask table. # + #---------------------------------------------------------------------------------------# + edsel = emask$mask & (! is.na(emask$mask) ) + edge = emask[edsel] + nedge = nrow(edge) + xedge = edge$x * xy.m.fac + yedge = edge$y * xy.m.fac + #---------------------------------------------------------------------------------------# + + #---------------------------------------------------------------------------------------# + # Find the time to edge. # + #---------------------------------------------------------------------------------------# + if ( (nedge*nwind) > 0){ + + + #------ Load Fortran and run code. --------------------------------------------------# + # if (! is.loaded("timetoedge")) dummy = dyn.load(fortran.so) + # tedge = .Fortran( "timetoedge" + # , nwind = as.integer(nwind) + # , xwind = as.double (xwind) + # , ywind = as.double (ywind) + # , uwind = as.double (uwind) + # , vwind = as.double (vwind) + # , nedge = as.integer(nedge) + # , xedge = as.double (xedge) + # , yedge = as.double (yedge) + # , wmin = as.double (wmin) + # , time = as.double (tedge) + # )#end .Fortran + #------------------------------------------------------------------------------------# + + + + + #------ Populate answer. ------------------------------------------------------------# + # ans = rep(NA_real_,times=nrow(datum)) + # ans[uvsel] = pmin(tmax,tedge$time) + # rm(tedge) + #------------------------------------------------------------------------------------# + + + #------------------------------------------------------------------------------------# + # Calculate wind speed and direction. # + #------------------------------------------------------------------------------------# + SPEED = matrix(data=sqrt(uwind*uwind+vwind*vwind),nrow=nwind,ncol=nedge) + OMEGA = matrix(data=atan2(y=vwind,x=uwind) ,nrow=nwind,ncol=nedge) + #------------------------------------------------------------------------------------# + + + #------ Calculate distance from point to edge. --------------------------------------# + DX = -outer(X=xwind,Y=xedge,FUN=`-`) + DY = -outer(X=ywind,Y=yedge,FUN=`-`) + DIST = sqrt(DX*DX+DY*DY) + DELTA = atan2(y=DY,x=DX) + #------------------------------------------------------------------------------------# + + + #----- Find the baseline time to edge. ----------------------------------------------# + WEDGE = matrix(data=pmax(wmin,SPEED * cos(OMEGA - DELTA)),nrow=nwind,ncol=nedge) + #------------------------------------------------------------------------------------# + + + #----- Select the minimum time as the time to edge. ---------------------------------# + TEDGE = DIST / WEDGE + tedge = apply(X=TEDGE,MARGIN=1,FUN=min,na.rm=TRUE) + #------------------------------------------------------------------------------------# + + + + + #------ Populate answer. ------------------------------------------------------------# + ans = rep(NA_real_,times=nrow(datum)) + ans[uvsel] = pmin(tmax,tedge) + rm(SPEED,OMEGA,DX,DY,DIST,WEDGE,TEDGE,tedge) + #------------------------------------------------------------------------------------# + + }else{ + #------ Either wind or edge were completely missing. Return dummy answer. -----------# + ans = ifelse( test = uvsel + , yes = tmax + , no = NA_real_ + )#end ifelse + #------------------------------------------------------------------------------------# + }#end if + #---------------------------------------------------------------------------------------# + + + + return(ans) +}#end time.to.edge +#==========================================================================================# +#==========================================================================================# diff --git a/R-utils/timeutils.r b/R-utils/timeutils.r index 4ac0300cb..f1f00aa5f 100644 --- a/R-utils/timeutils.r +++ b/R-utils/timeutils.r @@ -323,12 +323,12 @@ alltimes <<- function(datin,lon,lat,ed21=TRUE,zeronight=FALSE,meanval=FALSE,imet zenith = ed.zen (when=datout$when,lon=lon,lat=lat,ed21=ed21 ,zeronight=zeronight,meanval=meanval,imetavg=imetavg ,nmean=nmean,...) - datout$cosz = zenith$cosz - datout$zen = zenith$zen - datout$sunhgt = zenith$hgt - datout$nighttime = zenith$night - datout$daytime = zenith$day - datout$twilight = (! zenith$night) & (! zenith$day) + datout$cosz = zenith$cosz + datout$zen = zenith$zen + datout$sunhgt = zenith$hgt + datout$nighttime = zenith$night + datout$daytime = zenith$day + datout$twilight = zenith$twilight datout$diel = as.integer(! datout$nighttime) + as.integer(datout$daytime) datout$highsun = zenith$cosz >= cosz.highsun datout$riseset = zenith$cosz >= cosz.twilight & zenith$cosz < cosz.highsun diff --git a/R-utils/trait.utils.r b/R-utils/trait.utils.r index 1d02412ad..da5675468 100644 --- a/R-utils/trait.utils.r +++ b/R-utils/trait.utils.r @@ -87,7 +87,7 @@ fix.try.lon <<- function(x){ #---------------------------------------------------------------------------------------# #------ Make sure the coordinates are between 180W and 180E. ---------------------------# - subtr = (ans %>=% 180.) & (ans %<=% 360.) + subtr = (ans %ge% 180.) & (ans %le% 360.) ans[subtr] = ans[subtr] - 360. #---------------------------------------------------------------------------------------# diff --git a/R-utils/unitlist.r b/R-utils/unitlist.r index 699717b82..9f336907b 100644 --- a/R-utils/unitlist.r +++ b/R-utils/unitlist.r @@ -3,158 +3,225 @@ # This list contains the list of all commonly used units written in mathematical # # format. # #------------------------------------------------------------------------------------------# -untab <<- list( cm = "c*m" - , cm2m = "c*m^2*m" - , cm2om2 = "c*m^2*m^{-2}" - , cm2opl = "c*m^2*p*l*a*n*t^{-1}" - , cm2om2oyr = "c*m^2*m^{-2}*y*r^{-1}" - , day = "d*a*y" - , deg = "degree" - , degC = "degree*C" - , degCodec = "degree*C*d*e*c*a*d*e^{-1}" - , degE = "degree*E" - , degN = "degree*N" - , degS = "degree*S" - , degW = "degree*W" - , empty = "phantom(1)-phantom(1)" - , gcokgw = "g*C^phantom(1)*k*g*W^{-1}" - , gcokgcbio = "g*C^phantom(1)*k*g[C[b*i*o]]^{-1}" - , gcom2oday = "g*C^phantom(1)*m^{-2}*d*a*y^{-1}" - , Gjom2 = "G*J^phantom(1)*m^{-2}" - , gmt = "G*M*T" - , gom3 = "g^phantom(1)*m^{-3}" - , gocm3 = "g^phantom(1)*c*m^{-3}" - , gwokg = "g*W^phantom(1)*k*g^{-1}" - , gwokgodec = "g*W^phantom(1)*k*g^{-1}*d*e*c*a*d*e^{-1}" - , hpa = "h*P*a" - , hpaodec = "h*P*a^phantom(1)*d*e*c*a*d*e^{-1}" - , hr = "h*o*u*r" - , jokgom2 = "J^phantom(1)*k*g^{-1}*m^{-2}" - , jokgopl = "J^phantom(1)*k*g^{-1}*p*l^{-1}" - , jom2 = "J^phantom(1)*m^{-2}" - , K = "K" - , Kodec = "K^phantom(1)*d*e*c*a*d*e^{-1}" - , k = "K" - , kg = "k*g" - , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" - , kgcokgn = "k*g*C^phantom(1)*k*g*N^{-1}" - , kgcokgp = "k*g*C^phantom(1)*k*g*P^{-1}" - , kgcom2 = "k*g*C^phantom(1)*m^{-2}" - , kgcom2l = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" - , kgcom2loyr = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}" - , kgcom2oday = "k*g*C^phantom(1)*m^{-2}*d*a*y^{-1}" - , kgcom2oyr = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}" - , kgcom2oyrodec = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}*d*e*c*a*d*e^{-1}" - , kgcom3 = "k*g*C^phantom(1)*m^{-3}" - , kgcopl = "k*g*C^phantom(1)*p*l*a*n*t^{-1}" - , kgcoployr = "k*g*C^phantom(1)*p*l*a*n*t^{-1}*y*r^{-1}" - , kgokg = "k*g^phantom(1)*k*g^{-1}" - , kgom2 = "k*g^phantom(1)*m^{-2}" - , kgom2loday = "k*g^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" - , kgom3 = "k*g^phantom(1)*m^{-3}" - , kgnokg = "k*g*N^phantom(1)*k*g^{-1}" - , kgnom2 = "k*g*N^phantom(1)*m^{-2}" - , kgpokg = "k*g*P^phantom(1)*k*g^{-1}" - , kgwokg = "k*g*W^phantom(1)*k*g^{-1}" - , kgpom2 = "k*g*P^phantom(1)*m^{-2}" - , kgwom2 = "k*g*W^phantom(1)*m^{-2}" - , kgwom2l = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}" - , kgwom2oday = "k*g*W^phantom(1)*m^{-2}*d*a*y^{-1}" - , kgwom2ohr = "k*g*W^phantom(1)*m^{-2}*h*r^{-1}" - , kgwom2os = "k*g*W^phantom(1)*m^{-2}*s^{-1}" - , kgwom2loday = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" - , kgwom3oday = "k*g*W^phantom(1)*m^{-3}*d*a*y^{-1}" - , kgwoploday = "k*g*W^phantom(1)*p*l*a*n*t^{-1}*d*a*y^{-1}" - , km = "k*m" - , Kmos = "K^phantom(1)*m^phantom(1)*s^{-1}" - , kpa = "k*P*a" - , m = "m" - , m2 = "m^2" - , mm = "m*m" - , mmodec = "m*m^phantom(1)*d*e*c*a*d*e^{-1}" - , mmoyrodec = "m*m^phantom(1)*y*r^{-1}*d*e*c*a*d*e^{-1}" - , mm2okgw = "m*m^2*k*g*W^{-1}" - , mmoday = "m*m^phantom(1)*d*a*y^{-1}" - , mmohr = "m*m^phantom(1)*h*r^{-1}" - , mmolom2os = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}" - , mmomo = "m*m^phantom(1)*m*o*n*t*h^{-1}" - , molom2 = "m*o*l^phantom(1)*m^{-2}" - , molom2l = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}" - , molcom2 = "m*o*l*C^phantom(1)*m^{-2}" - , month = "m*o*n*t*h" - , mos = "m^phantom(1)*s^{-1}" - , mosodec = "m^phantom(1)*s^{-1}*d*e*c*a*d*e^{-1}" - , m2oha = "m^{2}*h*a^{-1}" - , m2om2 = "m^2*m^{-2}" - , m2om3 = "m^2*m^{-3}" - , m2opl = "m^2*p*l^{-1}" - , m2lokgc = "m[l*e*a*f]^2*k*g*C^{-1}" - , m2lom2 = "m[l*e*a*f]^2*m^{-2}" - , m2lom2odec = "m[l*e*a*f]^2*m^{-2}*d*e*c*a*d*e^{-1}" - , m2lopl = "m[l*e*a*f]^2*p*l^{-1}" - , m2pom2 = "m[l*e*a*f+w*o*o*d]^2*m^{-2}" - , m2popl = "m[l*e*a*f+w*o*o*d]^2*p*l^{-1}" - , m2wom2 = "m[w*o*o*d]^2*m^{-2}" - , m2wopl = "m[w*o*o*d]^2*p*l^{-1}" - , m3oha = "m^3*h*a^{-1}" - , m3om2 = "m^3*m^{-2}" - , m3wom3 = "m[W]^3*m^{-3}" - , Mgcoha = "M*g*C^phantom(1)*h*a^{-1}" - , Mgoha = "M*g^phantom(1)*h*a^{-1}" - , Mgwom2 = "M*g*W^phantom(1)*m^{-2}" - , Mjom2 = "M*J^phantom(1)*m^{-2}" - , mmoyr = "m*m^phantom(1)*y*r^{-1}" - , mpa = "M*P*a" - , nmo.090 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" - , nmo.100 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" - , nmo.110 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" - , nmo.120 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" - , nmo.wdef = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" - , nmolomol = "n*m*o*l^phantom(1)*m*o*l^{-1}" - , oneom = "m^{-1}" - , oneoha = "h*a^{-1}" - , oneom2 = "m^{-2}" - , oneoyr = "y*r^{-1}" - , oneodec = "d*e*c*a*d*e^{-1}" - , pa = "P*a" - , pc = "'%'" - , pcbio = "'%'[b*i*o]" - , pcagboyr = "'%'[A*G*B]^phantom(1)*y*r^{-1}" - , pcagbo50yr = "'%'[A*G*B]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" - , pcareaoyr = "'%'[a*r*e*a]^phantom(1)*y*r^{-1}" - , pcbaoyr = "'%'[B*A]^phantom(1)*y*r^{-1}" - , pcbiooyr = "'%'[b*i*o]^phantom(1)*y*r^{-1}" - , pcdbhoyr = "'%'[D*B*H]^phantom(1)*y*r^{-1}" - , pcetoyr = "'%'[E*T]^phantom(1)*y*r^{-1}" - , pceto50yr = "'%'[E*T]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" - , pcoyr = "'%'^phantom(1)*y*r^{-1}" - , pcpopoyr = "'%'[p*o*p]^phantom(1)*y*r^{-1}" - , pcsat = "'%'[S*a*t]" - , pgc = "P*g*C" - , pgcoyr = "P*g*C^phantom(1)*y*r^{-1}" - , plom2 = "p*l*a*n*t^phantom(1)*m^{-2}" - , ploha = "p*l*a*n*t^phantom(1)*h*a^{-1}" - , s = "s" - , t1e3 = "phantom(1)%*%10^{3}" - , t1e6 = "phantom(1)%*%10^{6}" - , t1e9 = "phantom(1)%*%10^{9}" - , thkm2oyr = "10^{3*phantom(1)}*k*m^{2}*y*r^{-1}" - , umolcom2os = "mu*m*o*l*C^phantom(1)*m^{-2}*s^{-1}" - , umolokgcos = "mu*m*o*l^phantom(1)*k*g*C^{-1}*s^{-1}" - , umolom2 = "mu*m*o*l^phantom(1)*m^{-2}" - , umolom2os = "mu*m*o*l^phantom(1)*m^{-2}*s^{-1}" - , umolom2l = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}" - , umolom2los = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}*s^{-1}" - , umolcom2 = "mu*m*o*l*C^phantom(1)*m^{-2}" - , umolcomol = "mu*m*o*l*C^phantom(1)*m*o*l^{-1}" - , umolomol = "mu*m*o*l^phantom(1)*m*o*l^{-1}" - , utc = "U*T*C" - , wom2 = "W^phantom(1)*m^{-2}" - , wom2l = "W^phantom(1)*m[l*e*a*f]^{-2}" - , wom2oyr = "W^phantom(1)*m^{-2}*y*r^{-1}" - , wom2odec = "W^phantom(1)*m^{-2}*d*e*c*a*d*e^{-1}" - , wopl = "W^phantom(1)*p*l*a*n*t^{-1}" - , yr = "y*r" +untab <<- list( cm = "c*m" + , cmohaoyr = "c*m^phantom(1)*h*a^{-1}*y*r^{-1}" + , cmoyr = "c*m^phantom(1)*y*r^{-1}" + , cm2m = "c*m^2*m" + , cm2om2 = "c*m^2*m^{-2}" + , cm2om2odec = "c*m^2*m^{-2}*d*e*c^{-1}" + , cm2opl = "c*m^2*p*l*a*n*t^{-1}" + , cm2om2oyr = "c*m^2*m^{-2}*y*r^{-1}" + , day = "d*a*y" + , deg = "degree" + , degC = "degree*C" + , degCodec = "degree*C^phantom(1)*d*e*c^{-1}" + , degE = "degree*E" + , degN = "degree*N" + , degS = "degree*S" + , degW = "degree*W" + , empty = "phantom(1)-phantom(1)" + , gcoday = "g*C^phantom(1)*d*a*y^{-1}" + , gcokg = "g*C^phantom(1)*k*g^{-1}" + , gcokgw = "g*C^phantom(1)*k*g*W^{-1}" + , gcokgcbio = "g*C^phantom(1)*k*g[C[b*i*o]]^{-1}" + , gcom2oday = "g*C^phantom(1)*m^{-2}*d*a*y^{-1}" + , Gjom2 = "G*J^phantom(1)*m^{-2}" + , gmpaos = "g^phantom(1)*M*P*a^phantom(1)*s^{-1}" + , gmt = "G*M*T" + , gnokg = "g*N^phantom(1)*k*g^{-1}" + , gom2oday = "g^phantom(1)*m^{-2}*d*a*y^{-1}" + , gom3 = "g^phantom(1)*m^{-3}" + , gocm3 = "g^phantom(1)*c*m^{-3}" + , gocm3odec = "g^phantom(1)*c*m^{-3}*d*e*c^{-1}" + , gokg = "g^phantom(1)*k*g^{-1}" + , gpokg = "g*P^phantom(1)*k*g^{-1}" + , gwokg = "g*W^phantom(1)*k*g^{-1}" + , gwokgodec = "g*W^phantom(1)*k*g^{-1}*d*e*c^{-1}" + , ha = "h*a" + , hpa = "h*P*a" + , hpaodec = "h*P*a^phantom(1)*d*e*c^{-1}" + , hr = "h*o*u*r" + , jokgom2 = "J^phantom(1)*k*g^{-1}*m^{-2}" + , jokgopl = "J^phantom(1)*k*g^{-1}*p*l^{-1}" + , jom2 = "J^phantom(1)*m^{-2}" + , K = "K" + , Kodec = "K^phantom(1)*d*e*c^{-1}" + , k = "K" + , kg = "k*g" + , kgc = "k*g*C" + , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" + , kgcokgn = "k*g*C^phantom(1)*k*g*N^{-1}" + , kgcokgp = "k*g*C^phantom(1)*k*g*P^{-1}" + , kgcom2 = "k*g*C^phantom(1)*m^{-2}" + , kgcom2odec = "k*g*C^phantom(1)*m^{-2}*d*e*c^{-1}" + , kgcom2l = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , kgcom2loyr = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}" + , kgcom2loyrodec = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}*y*r^{-1}*dec^{-1}" + , kgcom2oday = "k*g*C^phantom(1)*m^{-2}*d*a*y^{-1}" + , kgcom2oyr = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}" + , kgcom2oyrodec = "k*g*C^phantom(1)*m^{-2}*y*r^{-1}*d*e*c^{-1}" + , kgcom3 = "k*g*C^phantom(1)*m^{-3}" + , kgcopl = "k*g*C^phantom(1)*p*l*a*n*t^{-1}" + , kgcoployr = "k*g*C^phantom(1)*p*l*a*n*t^{-1}*y*r^{-1}" + , kgcoyr = "k*g*C^phantom(1)*y*r^{-1}" + , kgokg = "k*g^phantom(1)*k*g^{-1}" + , kgom2 = "k*g^phantom(1)*m^{-2}" + , kgom2loday = "k*g^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" + , kgom3 = "k*g^phantom(1)*m^{-3}" + , kgomos2 = "k*g^phantom(1)*m^{-1}*s^{-2}" + , kgnokg = "k*g*N^phantom(1)*k*g^{-1}" + , kgnokgp = "k*g*N^phantom(1)*k*g*P^{-1}" + , kgnom2 = "k*g*N^phantom(1)*m^{-2}" + , kgpokg = "k*g*P^phantom(1)*k*g^{-1}" + , kgwokg = "k*g*W^phantom(1)*k*g^{-1}" + , kgpom2 = "k*g*P^phantom(1)*m^{-2}" + , kgwom2 = "k*g*W^phantom(1)*m^{-2}" + , kgwom2l = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}" + , kgwom2oday = "k*g*W^phantom(1)*m^{-2}*d*a*y^{-1}" + , kgwom2odec = "k*g*W^phantom(1)*m^{-2}*d*e*c^{-1}" + , kgwom2ohr = "k*g*W^phantom(1)*m^{-2}*h*r^{-1}" + , kgwom2os = "k*g*W^phantom(1)*m^{-2}*s^{-1}" + , kgwom2loday = "k*g*W^phantom(1)*m[l*e*a*f]^{-2}*d*a*y^{-1}" + , kgwom3oday = "k*g*W^phantom(1)*m^{-3}*d*a*y^{-1}" + , kgwom3ompa = "k*g*W^phantom(1)*m^{-3}*M*P*a^{-1}" + , kgwomosompa = "k*g*W^phantom(1)*m^{-1}*s^{-1}*M*P*a^{-1}" + , kgwoploday = "k*g*W^phantom(1)*p*l*a*n*t^{-1}*d*a*y^{-1}" + , km = "k*m" + , Kmos = "K^phantom(1)*m^phantom(1)*s^{-1}" + , kpa = "k*P*a" + , kwom = "k*W^phantom(1)*m^{-1}" + , m = "m" + , m2 = "m^2" + , m2ocm2 = "m^2*c*m^{-2}" + , mg = "m*g" + , min = "m*i*n" + , mm = "m*m" + , mmodec = "m*m^phantom(1)*d*e*c^{-1}" + , mmoyrodec = "m*m^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , mm2okgw = "m*m^2*k*g*W^{-1}" + , mmoday = "m*m^phantom(1)*d*a*y^{-1}" + , mmodayodec = "m*m^phantom(1)*d*a*y^{-1}*d*e*c^{-1}" + , mmohr = "m*m^phantom(1)*h*r^{-1}" + , mmolom2os = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}" + , mmolom2osompa = "m*m*o*l^phantom(1)*m^{-2}*s^{-1}*M*P*a^{-1}" + , mmologos = "m*m*o*l^phantom(1)*g^{-1}*s^{-1}" + , mmolokgos = "m*m*o*l^phantom(1)*k*g^{-1}*s^{-1}" + , mmolcokg = "k*g^phantom(1)*m*m*o*l*C^{-1}" + , mmomo = "m*m^phantom(1)*m*o*n*t*h^{-1}" + , mokg = "m^phantom(1)*k*g^{-1}" + , molom2 = "m*o*l^phantom(1)*m^{-2}" + , molom2osompa = "m*o*l^phantom(1)*m^{-2}*s^{-1}*M*P*a^{-1}" + , molom2l = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}" + , molom2lompa = "m*o*l^phantom(1)*m[l*e*a*f]^{-2}*M*P*a^{-1}" + , molcom2 = "m*o*l*C^phantom(1)*m^{-2}" + , molosompa = "m*o*l^phantom(1)*s^{-1}*M*P*a^{-1}" + , month = "m*o*n*t*h" + , monthodec = "m*o*n*t*h^phantom(1)*d*e*c^{-1}" + , mos = "m^phantom(1)*s^{-1}" + , momin = "m^phantom(1)*m*i*n^{-1}" + , mosodec = "m^phantom(1)*s^{-1}*d*e*c^{-1}" + , m2oha = "m^{2}*h*a^{-1}" + , m2ohaoyr = "m^{2}*h*a^{-1}*y*r^{-1}" + , m2okg = "m^2*k*g^{-1}" + , m2om2 = "m^2*m^{-2}" + , m2om3 = "m^2*m^{-3}" + , m2opl = "m^2*p*l^{-1}" + , m2lokg = "m[l*e*a*f]^2*k*g^{-1}" + , m2lokgc = "m[l*e*a*f]^2*k*g*C^{-1}" + , m2lokgcodec = "m[l*e*a*f]^2*k*g*C^{-1}*d*e*c^{-1}" + , m2lom2 = "m[l*e*a*f]^2*m^{-2}" + , m2lom2odec = "m[l*e*a*f]^2*m^{-2}*d*e*c^{-1}" + , m2lopl = "m[l*e*a*f]^2*p*l^{-1}" + , m2pom2 = "m[l*e*a*f+w*o*o*d]^2*m^{-2}" + , m2popl = "m[l*e*a*f+w*o*o*d]^2*p*l^{-1}" + , m2wom2 = "m[w*o*o*d]^2*m^{-2}" + , m2wopl = "m[w*o*o*d]^2*p*l^{-1}" + , m3oha = "m^3*h*a^{-1}" + , m3om2 = "m^3*m^{-2}" + , m3wom3 = "m[W]^3*m^{-3}" + , Mgcoha = "M*g*C^phantom(1)*h*a^{-1}" + , Mgoha = "M*g^phantom(1)*h*a^{-1}" + , Mgwom2 = "M*g*W^phantom(1)*m^{-2}" + , Mjom2 = "M*J^phantom(1)*m^{-2}" + , mmoyr = "m*m^phantom(1)*y*r^{-1}" + , mpa = "M*P*a" + , mpaodec = "M*P*a^phantom(1)*d*e*c^{-1}" + , mwom2ok = "m*W^phantom(1)*m^{-2}*K^{-1}" + , nmo.090 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" + , nmo.100 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" + , nmo.110 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" + , nmo.120 = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" + , nmo.wdef = "m*o*n*t*h*s*phantom(1)*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" + , nmolomol = "n*m*o*l^phantom(1)*m*o*l^{-1}" + , oneoday = "d*a*y^{-1}" + , oneom = "m^{-1}" + , oneoha = "h*a^{-1}" + , oneok = "K^{-1}" + , oneokm2 = "k*m^{-2}" + , oneokm2oday = "k*m^{-2}*d*a*y^{-1}" + , oneokm2omo = "k*m^{-2}*m*o*n*t*h^{-1}" + , oneom2 = "m^{-2}" + , oneoyr = "y*r^{-1}" + , oneodec = "d*e*c^{-1}" + , pa = "P*a" + , pc = "'%'" + , pcoday = "'%'^phantom(1)*d*a*y^{-1}" + , pcodec = "'%'^phantom(1)*d*e*c^{-1}" + , pcbio = "'%'[b*i*o]" + , pcagboyr = "'%'[A*G*B]^phantom(1)*y*r^{-1}" + , pcagboyrodec = "'%'[A*G*B]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcagbo50yr = "'%'[A*G*B]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" + , pcareaoyr = "'%'[a*r*e*a]^phantom(1)*y*r^{-1}" + , pcbaoyr = "'%'[B*A]^phantom(1)*y*r^{-1}" + , pcbiooyr = "'%'[b*i*o]^phantom(1)*y*r^{-1}" + , pcbiooyrodec = "'%'[b*i*o]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcdbhoyr = "'%'[D*B*H]^phantom(1)*y*r^{-1}" + , pcdbhoyrodec = "'%'[D*B*H]^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcetoyr = "'%'[E*T]^phantom(1)*y*r^{-1}" + , pceto50yr = "'%'[E*T]^phantom(1)*group(\"(\",50*y*r,\")\")^{-1}" + , pcoyr = "'%'^phantom(1)*y*r^{-1}" + , pcoyrodec = "'%'^phantom(1)*y*r^{-1}*d*e*c^{-1}" + , pcpopoyr = "'%'[p*o*p]^phantom(1)*y*r^{-1}" + , pcsat = "'%'[S*a*t]" + , pgc = "P*g*C" + , pgcoyr = "P*g*C^phantom(1)*y*r^{-1}" + , plom2 = "p*l*a*n*t^phantom(1)*m^{-2}" + , plom2odec = "p*l*a*n*t^phantom(1)*m^{-2}*d*e*c^{-1}" + , ploha = "p*l*a*n*t^phantom(1)*h*a^{-1}" + , plohaoyr = "p*l*a*n*t^phantom(1)*h*a^{-1}*y*r^{-1}" + , plohaodec = "p*l*a*n*t^phantom(1)*h*a^{-1}*d*e*c^{-1}" + , s = "s" + , t1e3 = "phantom(1)%*%10^{3}" + , t1e6 = "phantom(1)%*%10^{6}" + , t1e9 = "phantom(1)%*%10^{9}" + , thkm2oyr = "10^{3*phantom(1)}*k*m^{2}*y*r^{-1}" + , umolcom2os = "mu*m*o*l*C^phantom(1)*m^{-2}*s^{-1}" + , umologcos = "mu*m*o*l^phantom(1)*g*C^{-1}*s^{-1}" + , umologos = "mu*m*o*l^phantom(1)*g^{-1}*s^{-1}" + , umolokgcos = "mu*m*o*l^phantom(1)*k*g*C^{-1}*s^{-1}" + , umolokgos = "mu*m*o*l^phantom(1)*k*g^{-1}*s^{-1}" + , umolom2 = "mu*m*o*l^phantom(1)*m^{-2}" + , umolom2os = "mu*m*o*l^phantom(1)*m^{-2}*s^{-1}" + , molom2osompa = "m^{2}*s^phantom(1)*M*P*a^phantom(1)*m*o*l^{-1}" + , molom2lompa = "m[l*e*a*f]^{2}*M*P*a^phantom(1)*m*o*l^{-1}" + , molosompa = "s^phantom(1)*M*P*a^phantom(1)*m*o*l^{-1}" + , umolom2l = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}" + , umolom2los = "mu*m*o*l^phantom(1)*m[l*e*a*f]^{-2}*s^{-1}" + , umolcom2 = "mu*m*o*l*C^phantom(1)*m^{-2}" + , umolcomol = "mu*m*o*l*C^phantom(1)*m*o*l^{-1}" + , umolomol = "mu*m*o*l^phantom(1)*m*o*l^{-1}" + , umolomolodec = "mu*m*o*l^phantom(1)*m*o*l^{-1}*d*e*c^{-1}" + , usd = "U*S*D" + , usdoyr = "U*S*D^phantom(1)*y*r^{-1}" + , utc = "U*T*C" + , wom2 = "W^phantom(1)*m^{-2}" + , wom2l = "W^phantom(1)*m[l*e*a*f]^{-2}" + , wom2oyr = "W^phantom(1)*m^{-2}*y*r^{-1}" + , wom2odec = "W^phantom(1)*m^{-2}*d*e*c^{-1}" + , wopl = "W^phantom(1)*p*l*a*n*t^{-1}" + , yr = "y*r" + , zscore = "Z[s*c*o*r*e]" + , zscoreodec = "Z[s*c*o*r*e]^phantom(1)*d*e*c^{-1}" )#end list #==========================================================================================# #==========================================================================================# @@ -170,156 +237,217 @@ untab <<- list( cm = "c*m" # density function are the inverse of the actual units of the quantity, so the integral # # becomes dimensionless. # #------------------------------------------------------------------------------------------# -i.untab <<- list( cm = "c*m^{-1}" - , cm2m = "c*m^{-2}*m^{-1}" - , cm2om2 = "m^2*c*m^{-2}" - , cm2opl = "p*l*a*n*t^phantom(1)*c*m^{-2}" - , cm2om2oyr = "m^2*y*r^phantom(1)*c*m^{-2}" - , day = "d*a*y^{-1}" - , deg = "degree^{-1}" - , degC = "degree*C^{-1}" - , degCodec = "d*e*c*a*d*e^phantom(1)*degree*C^{-1}" - , degE = "degree*E^{-1}" - , degN = "degree*N^{-1}" - , degS = "degree*S^{-1}" - , degW = "degree*W^{-1}" - , empty = "phantom(1)-phantom(1)" - , gcom2oday = "m^{2}*d*a*y^phantom(1)*g*C^{-1}" - , gcokgw = "k*g*W^phantom(1)*g*C^{-1}" - , gcokgcbio = "k*g[C[b*i*o]]^phantom(1)*g*C^{-1}" - , gmt = "G*M*T^{-1}" - , gom3 = "m^3*g^{-1}" - , gocm3 = "c*m^3*g^{-1}" - , gwokg = "k*g^phantom(1)*g*W^{-1}" - , gwokgodec = "k*g^phantom(1)*d*e*c*a*d*e^phantom(1)*k*g*W^{-1}" - , hpa = "h*P*a^{-1}" - , hpaodec = "d*e*c*a*d*e^phantom(1)*h*P*a^{-1}" - , hr = "h*o*u*r^{-1}" - , jokgom2 = "k*g^phantom(1)*m^{-2}*J^{-1}" - , jokgopl = "k*g^phantom(1)*pl^phantom(1)*J^{-1}" - , jom2 = "m^{2}*J^{-1}" - , K = "K^{-1}" - , Kodec = "d*e*c*a*d*e^phantom(1)*K^{-1}" - , k = "K^{-1}" - , kg = "k*g^{-1}" - , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" - , kgcokgn = "k*g*N^phantom(1)*k*g*C^{-1}" - , kgcokgp = "k*g*P^phantom(1)*k*g*C^{-1}" - , kgcom2 = "m^{2}*k*g*C^{-1}" - , kgcom2l = "m[l*e*a*f]^{2}*k*g*C^{-1}" - , kgcom2loyr = "m[l*e*a*f]^{2}*y*r^phantom(1)*k*g*C^{-1}" - , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*C^{-1}" - , kgcom2oyr = "m^{2}*y*r^phantom(1)*k*g*C^{-1}" - , kgcom2oyrodec = "m^{2}*y*r^phantom(1)*d*e*c*a*d*e^phantom(1)*k*g*C^{-1}" - , kgcom3 = "m^{3}*k*g*C^{-1}" - , kgcopl = "p*l*a*n*t^phantom(1)*k*g*C^{-1}" - , kgcoployr = "p*l*a*n*t^phantom(1)*y*r^phantom(1)*k*g*C^{-1}" - , kgokg = "k*g^phantom(1)*k*g^{-1}" - , kgom2 = "m^{2}*k*g^{-1}" - , kgom3 = "m^{3}*k*g^{-1}" - , kgnokg = "k*g^phantom(1)*k*g*N^{-1}" - , kgnom2 = "m^{2}*k*g*N^{-1}" - , kgpokg = "k*g^phantom(1)*k*g*P^{-1}" - , kgwokg = "k*g^phantom(1)*k*g*W^{-1}" - , kgpom2 = "m^{2}*k*g*P^{-1}" - , kgwom2 = "m^{2}*k*g*W^{-1}" - , kgwom2l = "m[l*e*a*f]^{2}*k*g*W^{-1}" - , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwom2ohr = "m^{2}*h*r^phantom(1)*k*g*W^{-1}" - , kgwom2os = "m^{2}*s^phantom(1)*k*g*W^{-1}" - , kgwom2loday = "m[l*e*a*f]^{2}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwom3oday = "m^{-3}*d*a*y^phantom(1)*k*g*W^{-1}" - , kgwoploday = "p*l*a*n*t^phantom(1)*d*a*y^phantom(1)*k*g*W^{-1}" - , km = "k*m^{-1}" - , Kmos = "s^phantom(1)*K^{-1}*m^{-1}" - , kpa = "k*P*a^{-1}" - , m = "m^{-1}" - , m2 = "m^{-2}" - , mm = "m*m^{-1}" - , mmodec = "d*e*c*a*d*e^phantom(1)*m*m^^{-1}" - , mmoyrodec = "y*r^phantom(1)*d*e*c*a*d*e^phantom(1)*m*m^^{-1}" - , mm2okgw = "k*g*W^phantom(1)*m*m^{-2}" - , mmoday = "d*a*y^phantom(1)*m*m^{-1}" - , mmohr = "h*r^phantom(1)*m*m^{-1}" - , mmolom2os = "m^{2}*s^phantom(1)*m*m*o*l^{-1}" - , mmomo = "m*o*n*t*h^phantom(1)*^m*m{-1}" - , molom2 = "m^{2}*m*o*l^{-1}" - , molom2l = "m[l*e*a*f]^{2}*m*o*l^{-1}" - , molcom2 = "m^{2}*m*o*l*C^{-1}" - , month = "m*o*n*t*h^{-1}" - , mos = "s^phantom(1)*m^{-1}" - , mosodec = "s^phantom(1)*d*e*c*a*d*e^phantom(1)*m^{-1}" - , m2oha = "h*a^phantom(1)*m^{-2}" - , m2om2 = "m^2*m^{-2}" - , m2om3 = "m^3*m^{-2}" - , m2opl = "p*l^phantom(1)*m^{-2}" - , m2lokgc = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" - , m2lom2 = "m^2*m[l*e*a*f]^{-2}" - , m2lom2odec = "m^{2}*d*e*c*a*d*e^phantom(1)*m[l*e*a*f]^{-2}" - , m2lopl = "p*l^phantom(1)*m[l*e*a*f]^{-2}" - , m2pom2 = "m^2*m[l*e*a*f+w*o*o*d]^{-2}" - , m2popl = "p*l^phantom(1)*m[l*e*a*f+w*o*o*d]^{-2}" - , m2wom2 = "m^2*m[w*o*o*d]^{-2}" - , m2wopl = "p*l^phantom(1)*m[w*o*o*d]^{-2}" - , m3oha = "h*a^phantom(1)*m^{-3}" - , m3om2 = "m^2*m^{-3}" - , m3wom3 = "m^3*m[W]^{-3}" - , Mgcoha = "h*a^phantom(1)*M*g*C^{-1}" - , Mgoha = "h*a^phantom(1)*M*g^{-1}" - , Mgwom2 = "m^{2}*M*g*W^{-1}" - , Mjom2 = "m^{2}*M*J^{-1}" - , mmoyr = "y*r^phantom(1)*m*m^{-1}" - , mpa = "M*P*a^{-1}" - , nmo.090 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" - , nmo.100 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" - , nmo.110 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" - , nmo.120 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" - , nmo.wdef = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" - , nmolomol = "m*o*l^phantom(1)*n*m*o*l^{-1}" - , oneom = "m" - , oneoha = "h*a" - , oneom2 = "m^{2}" - , oneoyr = "y*r" - , oneodec = "d*e*c*a*d*e" - , pa = "P*a^{-1}" - , pc = "'%'^{-1}" - , pcbio = "'%'[b*i*o]^{-1}" - , pcagboyr = "y*r^phantom(1)*'%'[A*G*B]^{-1}" - , pcagbo50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[A*G*B]^{-1}" - , pcareaoyr = "y*r^phantom(1)*'%'[a*r*e*a]^{-1}" - , pcbaoyr = "y*r^phantom(1)*'%'[B*A]^{-1}" - , pcbiooyr = "y*r^phantom(1)*'%'[b*i*o]^{-1}" - , pcdbhoyr = "y*r^phantom(1)*'%'[D*B*H]^{-1}" - , pcetoyr = "y*r^phantom(1)*'%'[E*T]^{-1}" - , pceto50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[E*T]^{-1}" - , pcoyr = "y*r^phantom(1)*'%'^{-1}" - , pcpopoyr = "y*r^phantom(1)*'%'[p*o*p]^{-1}" - , pcsat = "'%'[S*a*t]^{-1}" - , pgc = "P*g*C^{-1}" - , pgcoyr = "y*r^phantom(1)*P*g*C^{-1}" - , plom2 = "m^2*p*l*a*n*t^{-1}" - , ploha = "h*a^phantom(1)*p*l*a*n*t^{-1}" - , s = "s^{-1}" - , t1e3 = "phantom(1)%*%10^{-3}" - , t1e6 = "phantom(1)%*%10^{-6}" - , t1e9 = "phantom(1)%*%10^{-9}" - , thkm2oyr = "y*r^phantom(1)*10^{-3*phantom(1)}*k*m^{-2}" - , umolcom2os = "m^2*s^phantom(1)*mu*m*o*l*C^{-1}" - , umolokgcos = "k*g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" - , umolom2 = "m^2*mu*m*o*l^{-1}" - , umolom2os = "m^2*s^phantom(1)*mu*m*o*l^{-1}" - , umolom2l = "m[l*e*a*f]^2*mu*m*o*l^{-1}" - , umolom2los = "m[l*e*a*f]^2*s^phantom(1)*mu*m*o*l^{-1}" - , umolcom2 = "m^2*mu*m*o*l*C^{-1}" - , umolcomol = "m*o*l^phantom(1)*mu*m*o*l*C^{-1}" - , umolomol = "m*o*l^phantom(1)*mu*m*o*l^{-1}" - , utc = "U*T*C^{-1}" - , wom2 = "m^2*W^{-1}" - , wom2l = "m[l*e*a*f]^{2}*W^phantom(1)" - , wom2oyr = "m^{2}*y*r^phantom(1)*W^{-1}" - , wom2odec = "m^{2}*d*e*c*a*d*e^phantom(1)*W^{-1}" - , wopl = "p*l*a*n*t^phantom(1)*W^{-1}" - , yr = "y*r^{-1}" +i.untab <<- list( cm = "c*m^{-1}" + , cmohaoyr = "h*a^phantom(1)*y*r^phantom(1)*c*m^{-1}" + , cmoyr = "y*r^phantom(1)*c*m^{-1}" + , cm2m = "c*m^{-2}*m^{-1}" + , cm2om2 = "m^2*c*m^{-2}" + , cm2om2odec = "d*e*c^phantom(1)*m^2*c*m^{-2}" + , cm2opl = "p*l*a*n*t^phantom(1)*c*m^{-2}" + , cm2om2oyr = "m^2*y*r^phantom(1)*c*m^{-2}" + , day = "d*a*y^{-1}" + , deg = "degree^{-1}" + , degC = "degree*C^{-1}" + , degCodec = "d*e*c^phantom(1)*degree*C^{-1}" + , degE = "degree*E^{-1}" + , degN = "degree*N^{-1}" + , degS = "degree*S^{-1}" + , degW = "degree*W^{-1}" + , empty = "phantom(1)-phantom(1)" + , gcoday = "d*a*y^phantom(1)*g*C^{-1}" + , gcokg = "k*g^phantom(1)*g*C^{-1}" + , gcom2oday = "m^{2}*d*a*y^phantom(1)*g*C^{-1}" + , gcokgw = "k*g*W^phantom(1)*g*C^{-1}" + , gcokgcbio = "k*g[C[b*i*o]]^phantom(1)*g*C^{-1}" + , gmpaos = "s^phantom(1)*g^{-1}*M*P*a^{-1}" + , gmt = "G*M*T^{-1}" + , gnokg = "k*g^phantom(1)*g*N^{-1}" + , gom2oday = "m^{2}*d*a*y^phantom(1)*g^{-1}" + , gom3 = "m^3*g^{-1}" + , gocm3 = "c*m^3*g^{-1}" + , gocm3odec = "d*e*c^phantom(1)*c*m^3*g^{-1}" + , gokg = "k*g^phantom(1)*g^{-1}" + , gpokg = "k*g^phantom(1)*g*P^{-1}" + , gwokg = "k*g^phantom(1)*g*W^{-1}" + , gwokgodec = "k*g^phantom(1)*d*e*c^phantom(1)*k*g*W^{-1}" + , ha = "h*a^{-1}" + , hpa = "h*P*a^{-1}" + , hpaodec = "d*e*c^phantom(1)*h*P*a^{-1}" + , hr = "h*o*u*r^{-1}" + , jokgom2 = "k*g^phantom(1)*m^{-2}*J^{-1}" + , jokgopl = "k*g^phantom(1)*pl^phantom(1)*J^{-1}" + , jom2 = "m^{2}*J^{-1}" + , K = "K^{-1}" + , Kodec = "d*e*c^phantom(1)*K^{-1}" + , k = "K^{-1}" + , kg = "k*g^{-1}" + , kgc = "k*g*C^{-1}" + , kgcokgc = "k*g*C^phantom(1)*k*g*C^{-1}" + , kgcokgn = "k*g*N^phantom(1)*k*g*C^{-1}" + , kgcokgp = "k*g*P^phantom(1)*k*g*C^{-1}" + , kgcom2 = "m^{2}*k*g*C^{-1}" + , kgcom2odec = "d*e*c^phantom(1)*m^{2}*k*g*C^{-1}" + , kgcom2l = "m[l*e*a*f]^{2}*k*g*C^{-1}" + , kgcom2loyr = "m[l*e*a*f]^{2}*y*r^phantom(1)*k*g*C^{-1}" + , kgcom2loyrodec = "m[l*e*a*f]^{2}*y*r^phantom(1)*d*e*c^phantom(1)*k*g*C^{-1}" + , kgcom2oday = "m^{2}*d*a*y^phantom(1)*k*g*C^{-1}" + , kgcom2oyr = "m^{2}*y*r^phantom(1)*k*g*C^{-1}" + , kgcom2oyrodec = "m^{2}*y*r^phantom(1)*d*e*c^phantom(1)*k*g*C^{-1}" + , kgcom3 = "m^{3}*k*g*C^{-1}" + , kgcopl = "p*l*a*n*t^phantom(1)*k*g*C^{-1}" + , kgcoployr = "p*l*a*n*t^phantom(1)*y*r^phantom(1)*k*g*C^{-1}" + , kgcoyr = "y*r^phantom(1)*k*g*C^{-1}" + , kgokg = "k*g^phantom(1)*k*g^{-1}" + , kgom2 = "m^{2}*k*g^{-1}" + , kgom3 = "m^{3}*k*g^{-1}" + , kgomos2 = "m^phantom(1)*s^{2}*k*g^{-1}" + , kgnokg = "k*g^phantom(1)*k*g*N^{-1}" + , kgnokgp = "k*g*P^phantom(1)*k*g*N^{-1}" + , kgnom2 = "m^{2}*k*g*N^{-1}" + , kgpokg = "k*g^phantom(1)*k*g*P^{-1}" + , kgwokg = "k*g^phantom(1)*k*g*W^{-1}" + , kgpom2 = "m^{2}*k*g*P^{-1}" + , kgwom2 = "m^{2}*k*g*W^{-1}" + , kgwom2l = "m[l*e*a*f]^{2}*k*g*W^{-1}" + , kgwom2oday = "m^{2}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom2odec = "m^{2}*d*e*c^phantom(1)*k*g*W^{-1}" + , kgwom2ohr = "m^{2}*h*r^phantom(1)*k*g*W^{-1}" + , kgwom2os = "m^{2}*s^phantom(1)*k*g*W^{-1}" + , kgwom2loday = "m[l*e*a*f]^{2}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom3oday = "m^{-3}*d*a*y^phantom(1)*k*g*W^{-1}" + , kgwom3ompa = "m^{-3}*M*P*a^phantom(1)*k*g*W^{-1}" + , kgwomosompa = "m^phantom(1)*s^phantom(1)*M*P*a^phantom(1)*kg^{-1}" + , kgwoploday = "p*l*a*n*t^phantom(1)*d*a*y^phantom(1)*k*g*W^{-1}" + , km = "k*m^{-1}" + , Kmos = "s^phantom(1)*K^{-1}*m^{-1}" + , kpa = "k*P*a^{-1}" + , kwom = "m^phantom(1)*k*W^{-1}" + , m = "m^{-1}" + , m2 = "m^{-2}" + , m2ocm2 = "c*m^2*m^{-2}" + , mg = "m*g^{-1}" + , min = "m*i*n^{-1}" + , mm = "m*m^{-1}" + , mmodec = "d*e*c^phantom(1)*m*m^^{-1}" + , mmoyrodec = "y*r^phantom(1)*d*e*c^phantom(1)*m*m^^{-1}" + , mm2okgw = "k*g*W^phantom(1)*m*m^{-2}" + , mmoday = "d*a*y^phantom(1)*m*m^{-1}" + , mmodayodec = "d*a*y^phantom(1)*d*e*c^phantom(1)*m*m^{-1}" + , mmohr = "h*r^phantom(1)*m*m^{-1}" + , mmologos = "g^phantom(1)*s^phantom(1)*m*m*o*l^{-1}" + , mmolokgos = "k*g^phantom(1)*s^phantom(1)*m*m*o*l^{-1}" + , mmolom2os = "m^{2}*s^phantom(1)*m*m*o*l^{-1}" + , mmolom2osompa = "m^{2}*s^phantom(1)*M*P*a^phantom(1)*m*m*o*l^{-1}" + , mmolcokg = "m*m*o*l*C^phantom(1)*k*g^{-1}" + , mmomo = "m*o*n*t*h^phantom(1)*^m*m{-1}" + , mokg = "k*g^phantom(1)*m^{-1}" + , molom2 = "m^{2}*m*o*l^{-1}" + , molom2l = "m[l*e*a*f]^{2}*m*o*l^{-1}" + , molcom2 = "m^{2}*m*o*l*C^{-1}" + , month = "m*o*n*t*h^{-1}" + , monthodec = "d*e*c^phantom(1)*m*o*n*t*h^{-1}" + , mos = "s^phantom(1)*m^{-1}" + , momin = "m*i*n^phantom(1)*m^{-1}" + , mosodec = "s^phantom(1)*d*e*c^phantom(1)*m^{-1}" + , m2oha = "h*a^phantom(1)*m^{-2}" + , m2ohaoyr = "h*a^phantom(1)*m^{2}*y*r^phantom(1)*h*a^{-1}" + , m2okg = "k*g^phantom(1)*m^{-2}" + , m2om2 = "m^2*m^{-2}" + , m2om3 = "m^3*m^{-2}" + , m2opl = "p*l^phantom(1)*m^{-2}" + , m2lokg = "k*g^phantom(1)*m[l*e*a*f]^{-2}" + , m2lokgc = "k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , m2lokgcodec = "d*e*c^phantom(1)*k*g*C^phantom(1)*m[l*e*a*f]^{-2}" + , m2lom2 = "m^2*m[l*e*a*f]^{-2}" + , m2lom2odec = "m^{2}*d*e*c^phantom(1)*m[l*e*a*f]^{-2}" + , m2lopl = "p*l^phantom(1)*m[l*e*a*f]^{-2}" + , m2pom2 = "m^2*m[l*e*a*f+w*o*o*d]^{-2}" + , m2popl = "p*l^phantom(1)*m[l*e*a*f+w*o*o*d]^{-2}" + , m2wom2 = "m^2*m[w*o*o*d]^{-2}" + , m2wopl = "p*l^phantom(1)*m[w*o*o*d]^{-2}" + , m3oha = "h*a^phantom(1)*m^{-3}" + , m3om2 = "m^2*m^{-3}" + , m3wom3 = "m^3*m[W]^{-3}" + , Mgcoha = "h*a^phantom(1)*M*g*C^{-1}" + , Mgoha = "h*a^phantom(1)*M*g^{-1}" + , Mgwom2 = "m^{2}*M*g*W^{-1}" + , Mjom2 = "m^{2}*M*J^{-1}" + , mmoyr = "y*r^phantom(1)*m*m^{-1}" + , mpa = "M*P*a^{-1}" + , mpaodec = "d*e*c^phantom(1)*M*P*a^{-1}" + , mwom2ok = "m^{2}*K^phantom(1)*m*W^{-1}" + , nmo.090 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 90*m*m^phantom(1)*m*o^{-1}" + , nmo.100 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 100*m*m^phantom(1)*m*o^{-1}" + , nmo.110 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 110*m*m^phantom(1)*m*o^{-1}" + , nmo.120 = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(R) < 120*m*m^phantom(1)*m*o^{-1}" + , nmo.wdef = "m*o*n*t*h*s*{-1}*\"|\"*phantom(1)*bar(W*D) > 10*m*m^phantom(1)*m*o^{-1}" + , nmolomol = "m*o*l^phantom(1)*n*m*o*l^{-1}" + , oneoday = "d*a*y" + , oneom = "m" + , oneoha = "h*a" + , oneok = "K" + , oneokm2 = "k*m^{2}" + , oneokm2oday = "k*m^{2}*d*a*y" + , oneokm2omo = "k*m^{2}*m*o*n*t*h" + , oneom2 = "m^{2}" + , oneoyr = "y*r" + , oneodec = "d*e*c" + , pa = "P*a^{-1}" + , pc = "'%'^{-1}" + , pcoday = "d*a*y^phantom(1)*'%'^{-1}" + , pcodec = "d*e*c^phantom(1)*'%'^{-1}" + , pcbio = "'%'[b*i*o]^{-1}" + , pcagboyr = "y*r^phantom(1)*'%'[A*G*B]^{-1}" + , pcagboyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[A*G*B]^{-1}" + , pcagbo50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[A*G*B]^{-1}" + , pcareaoyr = "y*r^phantom(1)*'%'[a*r*e*a]^{-1}" + , pcbaoyr = "y*r^phantom(1)*'%'[B*A]^{-1}" + , pcbiooyr = "y*r^phantom(1)*'%'[b*i*o]^{-1}" + , pcbiooyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[b*i*o]^{-1}" + , pcdbhoyr = "y*r^phantom(1)*'%'[D*B*H]^{-1}" + , pcdbhoyrodec = "d*e*c^phantom(1)*y*r^phantom(1)*'%'[D*B*H]^{-1}" + , pcetoyr = "y*r^phantom(1)*'%'[E*T]^{-1}" + , pceto50yr = "group(\"(\",50*y*r,\")\")^phantom(1)*'%'[E*T]^{-1}" + , pcoyr = "y*r^phantom(1)*'%'^{-1}" + , pcoyrodec = "y*r^phantom(1)*d*e*c^phantom(1)*'%'^{-1}" + , pcpopoyr = "y*r^phantom(1)*'%'[p*o*p]^{-1}" + , pcsat = "'%'[S*a*t]^{-1}" + , pgc = "P*g*C^{-1}" + , pgcoyr = "y*r^phantom(1)*P*g*C^{-1}" + , plom2 = "m^2*p*l*a*n*t^{-1}" + , plom2odec = "d*e*c^phantom(1)*m^2*p*l*a*n*t^{-1}" + , ploha = "h*a^phantom(1)*p*l*a*n*t^{-1}" + , plohaoyr = "h*a^phantom(1)*y*r^phantom(1)*p*l*a*n*t^{-1}" + , plohaodec = "d*e*c^phantom(1)*h*a^phantom(1)*p*l*a*n*t^{-1}" + , s = "s^{-1}" + , t1e3 = "phantom(1)%*%10^{-3}" + , t1e6 = "phantom(1)%*%10^{-6}" + , t1e9 = "phantom(1)%*%10^{-9}" + , thkm2oyr = "y*r^phantom(1)*10^{-3*phantom(1)}*k*m^{-2}" + , umolcom2os = "m^2*s^phantom(1)*mu*m*o*l*C^{-1}" + , umologcos = "g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umologos = "g^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolokgcos = "k*g*C^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolokgos = "k*g^phantom(1)*s^phantom(1)*mu*m*o*l^{-1}" + , umolom2 = "m^2*mu*m*o*l^{-1}" + , umolom2os = "m^2*s^phantom(1)*mu*m*o*l^{-1}" + , umolom2l = "m[l*e*a*f]^2*mu*m*o*l^{-1}" + , umolom2los = "m[l*e*a*f]^2*s^phantom(1)*mu*m*o*l^{-1}" + , umolcom2 = "m^2*mu*m*o*l*C^{-1}" + , umolcomol = "m*o*l^phantom(1)*mu*m*o*l*C^{-1}" + , umolomol = "m*o*l^phantom(1)*mu*m*o*l^{-1}" + , umolomolodec = "d*e*c^phantom(1)*m*o*l^phantom(1)*mu*m*o*l^{-1}" + , usd = "U*S*D^{-1}" + , usdoyr = "y*r^phantom(1)*U*S*D^{-1}" + , utc = "U*T*C^{-1}" + , wom2 = "m^2*W^{-1}" + , wom2l = "m[l*e*a*f]^{2}*W^phantom(1)" + , wom2oyr = "m^{2}*y*r^phantom(1)*W^{-1}" + , wom2odec = "m^{2}*d*e*c^phantom(1)*W^{-1}" + , wopl = "p*l*a*n*t^phantom(1)*W^{-1}" + , yr = "y*r^{-1}" + , zscore = "Z[s*c*o*r*e]^{-1}" + , zscoreodec = "d*e*c^phantom(1)*Z[s*c*o*r*e]^{-1}" )#end list #==========================================================================================# #==========================================================================================# diff --git a/R-utils/vcf.degrad.r b/R-utils/vcf.degrad.r index 0f76b6082..4d526a2b6 100644 --- a/R-utils/vcf.degrad.r +++ b/R-utils/vcf.degrad.r @@ -89,13 +89,13 @@ vcf.degrad <<- function(shrub,tree,bare){ #----- Create vector by classes. -------------------------------------------------------# - vc0 = tree %>=% 0.75 - vc1 = tree %>=% 0.50 & tree %<% 0.75 & bare %<% 0.20 - vc2 = tree %>=% 0.50 & tree %<% 0.75 & bare %>=% 0.20 - vc3 = tree %>=% 0.25 & tree %<% 0.50 & bare %<% 0.20 - vc4 = tree %>=% 0.25 & tree %<% 0.50 & bare %>=% 0.20 & bare %<% 0.50 - vc5 = tree %<% 0.25 & bare %<% 0.50 - vc6 = bare %>=% 0.50 + vc0 = tree %ge% 0.75 + vc1 = tree %ge% 0.50 & tree %lt% 0.75 & bare %lt% 0.20 + vc2 = tree %ge% 0.50 & tree %lt% 0.75 & bare %ge% 0.20 + vc3 = tree %ge% 0.25 & tree %lt% 0.50 & bare %lt% 0.20 + vc4 = tree %ge% 0.25 & tree %lt% 0.50 & bare %ge% 0.20 & bare %lt% 0.50 + vc5 = tree %lt% 0.25 & bare %lt% 0.50 + vc6 = bare %ge% 0.50 #---------------------------------------------------------------------------------------# diff --git a/R-utils/wapply.r b/R-utils/wapply.r index ba6ab446e..eac3503b6 100644 --- a/R-utils/wapply.r +++ b/R-utils/wapply.r @@ -12,7 +12,7 @@ wapply <<- function(X,W,FUN,cyclic=FALSE,...){ #----- Additional sanity checks. -------------------------------------------------------# if (! is.vector(X)) stop ("X must be a vector!") - if (W %>=% length(X)) stop ("W must be less than the length of X") + if (W %ge% length(X)) stop ("W must be less than the length of X") #---------------------------------------------------------------------------------------# diff --git a/R-utils/xy.density.r b/R-utils/xy.density.r index 0c481378e..faa53c275 100644 --- a/R-utils/xy.density.r +++ b/R-utils/xy.density.r @@ -169,7 +169,7 @@ xy.density <<- function( x zdens = 100. * zdens[[3]] / sum(zdens[[3]]) }#end if (method %in% "table") zlwr = zignore * max(zdens,na.rm=TRUE) - zdens = 0. * zdens + ifelse(test=zdens %>=% zlwr,yes=zdens,no=0.) + zdens = 0. * zdens + ifelse(test=zdens %ge% zlwr,yes=zdens,no=0.) #---------------------------------------------------------------------------------------# @@ -436,7 +436,7 @@ xy.density <<- function( x plot.new() plot.window(xlim=xlim,ylim=ylim,log=plog,xaxs=xaxs,yaxs=yaxs,...) zupr = zlim[1] + (1.-sqrt(.Machine$double.eps))*diff(zlim) - zdens = pmin(zupr,zdens) + ifelse(zdens %>% 0,0,NA) + 0. * zdens + zdens = pmin(zupr,zdens) + ifelse(zdens %gt% 0,0,NA) + 0. * zdens xyz = list(x=xdens,y=ydens,z=zdens) image(x=xyz,zlim=zlim,col=ccolours,breaks=clevels,add=TRUE,useRaster=useRaster) #====================================================================================# @@ -447,7 +447,7 @@ xy.density <<- function( x # Plot the main panel on existing box. # #------------------------------------------------------------------------------------# zupr = zlim[1] + (1.-sqrt(.Machine$double.eps))*diff(zlim) - zdens = pmin(zupr,zdens) + ifelse(zdens %>% 0,0,NA) + 0. * zdens + zdens = pmin(zupr,zdens) + ifelse(zdens %gt% 0,0,NA) + 0. * zdens xyz = list(x=xdens,y=ydens,z=zdens) image(x=xyz,zlim=zlim,col=ccolours,breaks=clevels,add=TRUE,useRaster=useRaster) #====================================================================================# diff --git a/R-utils/zen.r b/R-utils/zen.r index 174061bcd..9574bb81b 100644 --- a/R-utils/zen.r +++ b/R-utils/zen.r @@ -143,21 +143,131 @@ ed.zen <<- function (lon,lat,when,ed21=TRUE,zeronight=FALSE,meanval=FALSE,imetav #------ Find the cosine of the zenith angle, the zenith angle, and day/night flag. -----# - COSZ = SLAT * SDEC + CLAT * CDEC * CHRA - cosz = rowMeans(COSZ,...) - zen = acos(cosz) / pio180 - hgt = 90. - zen - declin = rowMeans(DECLIN,...) / pio180 - night = cosz < cosz.twilight - day = cosz >= cosz.min + COSZ = SLAT * SDEC + CLAT * CDEC * CHRA + cosz = rowMeans(COSZ,...) + zen = acos(cosz) / pio180 + hgt = 90. - zen + declin = rowMeans(DECLIN,...) / pio180 + night = cosz < cosz.twilight + day = cosz >= cosz.min + twilight = (! day) & (! night) if (zeronight){ cosz[night] = 0. hgt [night] = 0. zen [night] = 90. }#end if - ans = data.frame(cosz=cosz,zen=zen,hgt=hgt,declin=declin,day=day,night=night) + ans = data.frame( cosz = cosz + , zen = zen + , hgt = hgt + , declin = declin + , day = day + , night = night + , twilight = twilight + )#end data.frame return(ans) }#end function ed.zen #==========================================================================================# #==========================================================================================# + + + + + + +#==========================================================================================# +#==========================================================================================# +# Fast version to obtain the cosine of zenith angle, when no averaging is needed. This # +# accepts either one entry for longitude/latitude, and multiple times, or it takes the # +# same number of longitudes, latitudes and times. # +# # +# Input variables: # +# - lon, lat - Longitudes and latitudes. Either single values or vectors with the # +# the same length as when (see below). # +# - when - time. Mandatory, one point only or a vector. # +# - ed21 - I shall use ED-2.1 method (TRUE/FALSE). Default is TRUE # +# - zeronight - The cosine of zenith angle shall be set to zero at night. # +# Default is FALSE # +# # +# The output is going to be a vector with cosines of with the following values: # +#------------------------------------------------------------------------------------------# +fast.zen <<- function (lon,lat,when,ed21=TRUE,zeronight=FALSE){ + #------ Constants. ---------------------------------------------------------------------# + dcoeff = c( 0.006918, -0.399912, 0.070257, -0.006758, 0.000907, -0.002697, 0.001480) + #---------------------------------------------------------------------------------------# + + + #------ Ensure longitude and latitude sizes are compatible with times. -----------------# + nlon = length(lon) + nlat = length(lat) + nwhen = length(when) + if (! ( (nlon %in% c(1,nwhen)) && (nlat %in% c(1,nwhen)) ) ){ + cat0(" - Longitude size:",nlon ) + cat0(" - Latitude size: ",nlat ) + cat0(" - Time size: ",nwhen) + stop(" Longitude/latidude should be either scalars of vectors consistent with when!") + }#end if (length(unique(c(nlon,lat,nwhen))) != 1) + if (nlon == 1) lon = rep(lon,times=nwhen) + if (nlat == 1) lat = rep(lat,times=nwhen) + #---------------------------------------------------------------------------------------# + + + + #------ Find the day of year, list of leap year times, and sun hour. -------------------# + doy = dayofyear(when) + leap = is.leap (when) + fracday = hms2frac (when) + sunhr = (fracday * day.hr + lon / 15. + day.hr) %% day.hr + #---------------------------------------------------------------------------------------# + + + + #------ Find the hour angle and its cosine. --------------------------------------------# + hrangle = 15 * (sunhr - 12) * pio180 + chra = cos(hrangle) + #---------------------------------------------------------------------------------------# + + + + #------ Find the declination. ----------------------------------------------------------# + if (ed21){ + doyfun = ifelse( test = leap + , yes = 2 * pi * (doy - shsummer) / 366. + , no = 2 * pi * (doy - shsummer) / 365. + )#end ifelse + declin = capri * cos(doyfun) + }else{ + doyfun = ifelse( test = leap + , yes = 2 * pi * (doy - 1) / 366. + , no = 2 * pi * (doy - 1) / 365 + )#end ifelse + + declin = ( dcoeff[1] + + dcoeff[2] * cos(1.*doyfun) + dcoeff[3] * sin(1.*doyfun) + + dcoeff[4] * cos(2.*doyfun) + dcoeff[5] * sin(2.*doyfun) + + dcoeff[6] * cos(3.*doyfun) + dcoeff[7] * sin(3.*doyfun) ) + }#end if + #---------------------------------------------------------------------------------------# + + + #------ Find the cosine and sine of latitude and declination. --------------------------# + clat = cos(pio180*lat) + slat = sin(pio180*lat) + cdec = cos(declin) + sdec = sin(declin) + #---------------------------------------------------------------------------------------# + + + + #------ Find the cosine of the zenith angle, the zenith angle, and day/night flag. -----# + cosz = slat * sdec + clat * cdec * chra + if (zeronight){ + cosz = 0. * cosz + pmax(0.,cosz) + }#end if + #---------------------------------------------------------------------------------------# + + rm(clat,slat,cdec,sdec,doy,leap,fracday,sunhr,hrangle,chra,doyfun,declin) + return(cosz) +}#end function fast.zen +#==========================================================================================# +#==========================================================================================# diff --git a/count_lines.sh b/count_lines.sh index 749a11e1c..9af307bdf 100755 --- a/count_lines.sh +++ b/count_lines.sh @@ -16,11 +16,13 @@ do ;; *) echo -n " - Directory ${dir}: " - files=$(/bin/ls -1 ${model}/src/${dir}) + files=$(/bin/ls -1 ${model}/src/${dir}/*.F90 2> /dev/null) + files="${files} $(/bin/ls -1 ${model}/src/${dir}/*.f90 2> /dev/null)" + files="${files} $(/bin/ls -1 ${model}/src/${dir}/*.c 2> /dev/null)" dirlines=0 for file in ${files} do - nlines=$(sed '/^ *$/ d' ${model}/src/${dir}/${file} | wc -l) + nlines=$(sed '/^ *$/ d' ${file} | wc -l | awk '{print $1}') let dirlines=${dirlines}+${nlines} done echo "${dirlines} lines"