utils.h File Reference

Include file for utilities library. More...

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <gsl/gsl_statistics.h>
#include "utCalendar2_cal.h"
#include <misc.h>
#include <constants.h>
Include dependency graph for utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  tstruct
 Easy time structure. More...

Defines

#define _GNU_SOURCE
 GNU extensions.
#define TRUE   1
 TRUE value macro is 1.
#define FALSE   0
 FALSE value macro is 0.

Functions

void alloc_mmap_shortint (short int **map, int *fd, size_t *byte_size, char *filename, size_t page_size, int size)
 Allocate memory using mmap for a short integer array.
void alloc_mmap_longint (long int **map, int *fd, size_t *byte_size, char *filename, size_t page_size, int size)
 Allocate memory using mmap for a long int array.
void alloc_mmap_int (int **map, int *fd, size_t *byte_size, char *filename, size_t page_size, int size)
 Allocate memory using mmap for an integer array.
void alloc_mmap_float (float **map, int *fd, size_t *byte_size, char *filename, size_t page_size, int size)
 Allocate memory using mmap for a float array.
void alloc_mmap_double (double **map, int *fd, size_t *byte_size, char *filename, size_t page_size, int size)
 Allocate memory using mmap for a double precision floating point array.
int data_to_gregorian_cal_d (double **bufout, double **outtimeval, int *ntimeout, double *bufin, double *intimeval, char *tunits_in, char *tunits_out, char *cal_type, int ni, int nj, int ntimein)
 Convert 360-days or no-leap calendar to standard Gregorian calendar for double input/output buffer.
int data_to_gregorian_cal_f (float **bufout, double **outtimeval, int *ntimeout, float *bufin, double *intimeval, char *tunits_in, char *tunits_out, char *cal_type, int ni, int nj, int ntimein)
 Convert 360-days or no-leap calendar to standard Gregorian calendar for float input/output buffer.
int get_calendar (int *year, int *month, int *day, int *hour, int *minutes, float *seconds, char *tunits, double *timein, int ntime)
 Get year,month,day,hour,min,sec given time in udunits.
int get_calendar_ts (tstruct *timeout, char *tunits, double *timein, int ntime)
 Get year,month,day,hour,min,sec (time structure) given time in udunits.
void change_date_origin (double *timeout, char *tunits_out, double *timein, char *tunits_in, int ntime)
 Change date origin of time expressed in udunits.
void mean_variance_field_spatial (double *buf_mean, double *buf_var, double *buf, short int *mask, int ni, int nj, int ntime)
 Compute mean and variance of a field averaged spatially.
void mean_field_spatial (double *buf_mean, double *buf, short int *mask, int ni, int nj, int ntime)
 Compute the spatial mean of a field.
void normalize_field_2d (double *nbuf, double *buf, double *mean, double *var, int ndima, int ndimb, int ntime)
 Normalize a 3D variable by 2D mean and variance.
void time_mean_variance_field_2d (double *bufmean, double *bufvar, double *buf, int ni, int nj, int nt)
 Compute the time mean and variance of a 2D field.
void covariance_fields_spatial (double *cov, double *buf1, double *buf2, short int *mask, int t1, int t2, int ni, int nj)
 Compute the spatial covariance of two fields.
int sub_period_common (double **buf_sub, int *ntime_sub, double *bufin, int *year, int *month, int *day, int *year_learn, int *month_learn, int *day_learn, int timedim, int ndima, int ndimb, int ntime, int ntime_learn)
 Select a sub period of a vector using a common period over two different time vectors.
void extract_subdomain (double **buf_sub, double **lon_sub, double **lat_sub, int *nlon_sub, int *nlat_sub, double *buf, double *lon, double *lat, double minlon, double maxlon, double minlat, double maxlat, int nlon, int nlat, int ndim)
 Extract subdomain in a variable given latitudes and longitudes.
void extract_subperiod_months (double **buf_sub, int *ntime_sub, double *bufin, int *year, int *month, int *day, int *smonths, int timedim, int ndima, int ndimb, int ntime, int nmonths)
 Extract a sub period of a vector of selected months.
void mask_region (double *buffer, double missing_value, double *lon, double *lat, double minlon, double maxlon, double minlat, double maxlat, int nlon, int nlat, int ndim)
 Mask region in a variable given latitude and longitude coordinates.
void mask_points (double *buffer, double missing_value, short int *mask, int nlon, int nlat, int ndim)
 Mask points in a variable given a mask field.
void normalize_field (double *nbuf, double *buf, double mean, double var, int ndima, int ndimb, int ntime)
 Normalize a 3D variable by a mean and variance.
int comparf (const void *a, const void *b)
 Compare two float values to sort descending.
double distance_point (double lon1, double lat1, double lon2, double lat2)
 Compute distance in meters for two latitude and longitude points.
int find_str_value (char *str, char **str_vect, int nelem)
 Find string in vector and return index.
short int is_leap_year (int year)
 Find string in vector and return index.
void alt_to_press (double *pres, double *alt, int ni, int nj)
 Compute standard atmosphere pressure given altitude.
void spechum_to_hr (double *hr, double *tas, double *hus, double *pmsl, double fillvalue, int ni, int nj)
 Compute relative humidity from specific humidity.
void calc_etp_mf (double *etp, double *tas, double *hus, double *rsds, double *rlds, double *uvas, double *pmsl, double fillvalue, int ni, int nj)
 Compute Potential Evapotranspiration (ETP) from Meteo-France formulation.

Detailed Description

Include file for utilities library.

Definition in file utils.h.


Define Documentation

#define _GNU_SOURCE

GNU extensions.

Definition at line 55 of file utils.h.

#define FALSE   0

FALSE value macro is 0.

Definition at line 102 of file utils.h.

#define TRUE   1

TRUE value macro is 1.

Definition at line 100 of file utils.h.


Function Documentation

void alloc_mmap_double ( double **  map,
int *  fd,
size_t *  byte_size,
char *  filename,
size_t  page_size,
int  size 
)

Allocate memory using mmap for a double precision floating point array.

Parameters:
[in,out] map Pointer to a double precision array.
[in] fd File unit previously opened with open().
[in] byte_size Number of bytes allocated.
[in] filename Filename to use to store allocated mmap virtual memory.
[in] page_size The paging size of the operating system in bytes.
[in] size Number of elements in map array.

Definition at line 58 of file alloc_mmap_double.c.

00058                                                                                                         {
00068   int result; /* Return status of functions */
00069   size_t total_size; /* Total size in bytes, not taking into account the page size */
00070 
00071   /* Open a file for writing.
00072    *  - Creating the file if it doesn't exist.
00073    *  - Truncating it to 0 size if it already exists. (not really needed)
00074    *
00075    * Note: "O_WRONLY" mode is not sufficient when mmaping.
00076    */
00077   *fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00078   if (*fd == -1) {
00079     (void) perror("alloc_mmap_double: ERROR: Error opening file for writing");
00080     (void) kill(getpid(), 5);
00081   }
00082   
00083   total_size = size * sizeof(double);
00084   *byte_size = total_size / page_size * page_size + page_size;
00085 
00086   /* Stretch the file size to the size of the (mmapped) array */
00087   result = ftruncate(*fd, (off_t) *byte_size);
00088   if (result != 0) {
00089     (void) close(*fd);
00090     (void) perror("alloc_mmap_double: ERROR: Error calling ftruncate() to 'stretch' the file");
00091     (void) kill(getpid(), 5);
00092   }
00093   
00094   /* Now the file is ready to be mmapped. */
00095   *map = (double *) mmap(NULL, *byte_size, ( PROT_READ | PROT_WRITE ), MAP_SHARED, *fd, 0);
00096   if (*map == (double *) MAP_FAILED) {
00097     (void) close(*fd);
00098     (void) perror("alloc_mmap_double: ERROR: Error mmapping the file");
00099     (void) kill(getpid(), 5);
00100   }
00101 }

void alloc_mmap_float ( float **  map,
int *  fd,
size_t *  byte_size,
char *  filename,
size_t  page_size,
int  size 
)

Allocate memory using mmap for a float array.

Parameters:
[in,out] map Pointer to a floating-point array.
[in] fd File unit previously opened with open().
[in] byte_size Number of bytes allocated.
[in] filename Filename to use to store allocated mmap virtual memory.
[in] page_size The paging size of the operating system in bytes.
[in] size Number of elements in map array.

Definition at line 58 of file alloc_mmap_float.c.

00058                                                                                                       {
00068   int result; /* Return status of functions */
00069   size_t total_size; /* Total size in bytes, not taking into account the page size */
00070 
00071   /* Open a file for writing.
00072    *  - Creating the file if it doesn't exist.
00073    *  - Truncating it to 0 size if it already exists. (not really needed)
00074    *
00075    * Note: "O_WRONLY" mode is not sufficient when mmaping.
00076    */
00077   *fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00078   if (*fd == -1) {
00079     (void) perror("alloc_mmap_float: ERROR: Error opening file for writing");
00080     (void) kill(getpid(), 5);
00081   }
00082   
00083   total_size = size * sizeof(float);
00084   *byte_size = total_size / page_size * page_size + page_size;
00085 
00086   /* Stretch the file size to the size of the (mmapped) array */
00087   result = ftruncate(*fd, (off_t) *byte_size);
00088   if (result != 0) {
00089     (void) close(*fd);
00090     (void) perror("alloc_mmap_float: ERROR: Error calling ftruncate() to 'stretch' the file");
00091     (void) kill(getpid(), 5);
00092   }
00093   
00094   /* Now the file is ready to be mmapped to the array. */
00095   *map = (float *) mmap(NULL, *byte_size, ( PROT_READ | PROT_WRITE ), MAP_SHARED, *fd, 0);
00096   if (*map == (float *) MAP_FAILED) {
00097     (void) close(*fd);
00098     (void) perror("alloc_mmap_float: ERROR: Error mmapping the file");
00099     (void) kill(getpid(), 5);
00100   }
00101 }

void alloc_mmap_int ( int **  map,
int *  fd,
size_t *  byte_size,
char *  filename,
size_t  page_size,
int  size 
)

Allocate memory using mmap for an integer array.

Parameters:
[in,out] map Pointer to an integer array.
[in] fd File unit previously opened with open().
[in] byte_size Number of bytes allocated.
[in] filename Filename to use to store allocated mmap virtual memory.
[in] page_size The paging size of the operating system in bytes.
[in] size Number of elements in map array.

Definition at line 58 of file alloc_mmap_int.c.

00058                                                                                                   {
00068   int result; /* Return status of functions */
00069   size_t total_size; /* Total size in bytes, not taking into account the page size */
00070 
00071   /* Open a file for writing.
00072    *  - Creating the file if it doesn't exist.
00073    *  - Truncating it to 0 size if it already exists. (not really needed)
00074    *
00075    * Note: "O_WRONLY" mode is not sufficient when mmaping.
00076    */
00077   *fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00078   if (*fd == -1) {
00079     (void) perror("alloc_mmap_int: ERROR: Error opening file for writing");
00080     (void) kill(getpid(), 5);
00081   }
00082   
00083   total_size = size * sizeof(int);
00084   *byte_size = total_size / page_size * page_size + page_size;
00085 
00086   /* Stretch the file size to the size of the (mmapped) array */
00087   result = ftruncate(*fd, (off_t) *byte_size);
00088   if (result != 0) {
00089     (void) close(*fd);
00090     (void) perror("alloc_mmap_int: ERROR: Error calling ftruncate() to 'stretch' the file");
00091     (void) kill(getpid(), 5);
00092   }
00093   
00094   /* Now the file is ready to be mmapped. */
00095   *map = (int *) mmap(NULL, *byte_size, ( PROT_READ | PROT_WRITE ), MAP_SHARED, *fd, 0);
00096   if (*map == (int *) MAP_FAILED) {
00097     (void) close(*fd);
00098     (void) perror("alloc_mmap_int: ERROR: Error mmapping the file");
00099     (void) kill(getpid(), 5);
00100   }
00101 }

void alloc_mmap_longint ( long int **  map,
int *  fd,
size_t *  byte_size,
char *  filename,
size_t  page_size,
int  size 
)

Allocate memory using mmap for a long int array.

Parameters:
[in,out] map Pointer to a long int array.
[in] fd File unit previously opened with open().
[in] byte_size Number of bytes allocated.
[in] filename Filename to use to store allocated mmap virtual memory.
[in] page_size The paging size of the operating system in bytes.
[in] size Number of elements in map array.

Definition at line 58 of file alloc_mmap_longint.c.

00058                                                                                                            {
00068   int result; /* Return status of functions */
00069   size_t total_size; /* Total size in bytes, not taking into account the page size */
00070 
00071   /* Open a file for writing.
00072    *  - Creating the file if it doesn't exist.
00073    *  - Truncating it to 0 size if it already exists. (not really needed)
00074    *
00075    * Note: "O_WRONLY" mode is not sufficient when mmaping.
00076    */
00077   *fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00078   if (*fd == -1) {
00079     (void) perror("alloc_mmap_longint: ERROR: Error opening file for writing");
00080     (void) kill(getpid(), 5);
00081   }
00082   
00083   total_size = size * sizeof(long int);
00084   *byte_size = total_size / page_size * page_size + page_size;
00085 
00086   /* Stretch the file size to the size of the (mmapped) array */
00087   result = ftruncate(*fd, (off_t) *byte_size);
00088   if (result != 0) {
00089     (void) close(*fd);
00090     (void) perror("alloc_mmap_longint: ERROR: Error calling ftruncate() to 'stretch' the file");
00091     (void) kill(getpid(), 5);
00092   }
00093   
00094   /* Now the file is ready to be mmapped. */
00095   *map = (long int *) mmap(NULL, *byte_size, ( PROT_READ | PROT_WRITE ), MAP_SHARED, *fd, 0);
00096   if (*map == (long int *) MAP_FAILED) {
00097     (void) close(*fd);
00098     (void) perror("alloc_mmap_longint: ERROR: Error mmapping the file");
00099     (void) kill(getpid(), 5);
00100   }
00101 }

void alloc_mmap_shortint ( short int **  map,
int *  fd,
size_t *  byte_size,
char *  filename,
size_t  page_size,
int  size 
)

Allocate memory using mmap for a short integer array.

Parameters:
[in,out] map Pointer to a short integer array.
[in] fd File unit previously opened with open().
[in] byte_size Number of bytes allocated.
[in] filename Filename to use to store allocated mmap virtual memory.
[in] page_size The paging size of the operating system in bytes.
[in] size Number of elements in map array.

Definition at line 58 of file alloc_mmap_shortint.c.

00058                                                                                                              {
00068   int result; /* Return status of functions */
00069   size_t total_size; /* Total size in bytes, not taking into account the page size */
00070 
00071   /* Open a file for writing.
00072    *  - Creating the file if it doesn't exist.
00073    *  - Truncating it to 0 size if it already exists. (not really needed)
00074    *
00075    * Note: "O_WRONLY" mode is not sufficient when mmaping.
00076    */
00077   *fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00078   if (*fd == -1) {
00079     (void) perror("alloc_mmap_shortint: ERROR: Error opening file for writing");
00080     (void) kill(getpid(), 5);
00081   }
00082   
00083   total_size = size * sizeof(short int);
00084   *byte_size = total_size / page_size * page_size + page_size;
00085 
00086   /* Stretch the file size to the size of the (mmapped) array */
00087   result = ftruncate(*fd, (off_t) *byte_size);
00088   if (result != 0) {
00089     (void) close(*fd);
00090     (void) perror("alloc_mmap_shortint: ERROR: Error calling ftruncate() to 'stretch' the file");
00091     (void) kill(getpid(), 5);
00092   }
00093   
00094   /* Now the file is ready to be mmapped. */
00095   *map = (short int *) mmap(NULL, *byte_size, ( PROT_READ | PROT_WRITE ), MAP_SHARED, *fd, 0);
00096   if (*map == (short int *) MAP_FAILED) {
00097     (void) close(*fd);
00098     (void) perror("alloc_mmap_shortint: ERROR: Error mmapping the file");
00099     (void) kill(getpid(), 5);
00100   }
00101 }

void alt_to_press ( double *  pres,
double *  alt,
int  ni,
int  nj 
)

Compute standard atmosphere pressure given altitude.

Parameters:
[out] pres Standard pressure in hPa
[in] alt Input 2D altitude in meters
[in] ni First dimension
[in] nj Second dimension

Definition at line 58 of file alt_to_press.c.

References K_GMR.

Referenced by output_downscaled_analog().

00058                                                         {
00059 
00067   /*
00068     ;   Convert an array of (pressure-) altitudes (m) into an array of 
00069     ;       pressures (hPa) using the ICAO standard atmosphere definition
00070     ;
00071     ;       See <A HREF="http://www.pdas.com/coesa.htm">exact definition
00072     ;       here<\A>
00073     ;       
00074     ;       The 7 layers of the US standard atmosphere are:
00075     ;
00076     ;        h1   h2     dT/dh    h1,h2 geopotential alt in km
00077     ;         0   11     -6.5     dT/dh in K/km
00078     ;        11   20      0.0
00079     ;        20   32      1.0
00080     ;        32   47      2.8
00081     ;        47   51      0.0
00082     ;        51   71     -2.8   
00083     ;        71   84.852 -2.0
00084   */
00085 
00086 #define NLAYERS 7 
00088   int i; /* Loop counter */
00089   int layr; /* Loop counter */
00090 
00091   double limits[NLAYERS+1];
00092   double lapse_rate[NLAYERS];
00093   int isoth[NLAYERS];
00094   double presb[NLAYERS];
00095   double tb[NLAYERS];
00096 
00097   int layer = 0;
00098 
00099   /* Layer boundaries in m */
00100   limits[0] = 0.0;
00101   limits[1] = 11.0 * 1000.0;
00102   limits[2] = 20.0 * 1000.0;
00103   limits[3] = 32.0 * 1000.0;
00104   limits[4] = 47.0 * 1000.0;
00105   limits[5] = 51.0 * 1000.0;
00106   limits[6] = 71.0 * 1000.0;
00107   limits[7] = 84.852 * 1000.0;
00108 
00109   /* Lapse rates in each layer (9 means 0) */
00110   lapse_rate[0] = -6.5 / 1000.0;
00111   lapse_rate[1] = 9.0;
00112   lapse_rate[2] = 1.0 / 1000.0;
00113   lapse_rate[3] = 2.8 / 1000.0;
00114   lapse_rate[4] = 9.0;
00115   lapse_rate[5] = -2.8 / 1000.0;
00116   lapse_rate[6] = -2.0 / 1000.0;
00117   
00118   /* Flag for isothermal layers */
00119   isoth[0] = 0;
00120   isoth[1] = 1;
00121   isoth[2] = 0;
00122   isoth[3] = 0;
00123   isoth[4] = 1;
00124   isoth[5] = 0;
00125   isoth[6] = 0;
00126 
00127   presb[0] = 1013.25;
00128   tb[0] = 288.15;
00129 
00130   /* Loop over layers and get pressures and temperatures at level tops */
00131   for (i=0; i<(NLAYERS-1); i++) {
00132     tb[i+1] = tb[i] + (1-isoth[i]) * lapse_rate[i] * (limits[i+1] - limits[i]);
00133     presb[i+1] = (1-isoth[i]) * presb[i] * exp(log(tb[i]/tb[i+1]) * K_GMR / lapse_rate[i]) +
00134       isoth[i] * presb[i] * exp(-K_GMR * (limits[i+1]-limits[i]) / tb[i]);
00135   }
00136 
00137   for (i=0; i<(ni*nj); i++) {
00138     /* Now calculate which layer each value belongs to */
00139     for (layr=0; layr<NLAYERS; layr++) {
00140       if ( (limits[layr] - alt[i]) > 0.0 ) {
00141         layer = layr - 1;
00142         layr = NLAYERS + 1;
00143       }
00144     }
00145     if (layer < 0) layer = 0;
00146     if (layer > (NLAYERS-1)) layer = NLAYERS - 1;
00147     
00148     /* Corresponding pressure */
00149     pres[i] = isoth[layer] * presb[layer] * exp(-K_GMR * (alt[i] - limits[layer]) / tb[layer]) +
00150       (1-isoth[layer]) * presb[layer] * pow( ( tb[layer] / ( tb[layer] + lapse_rate[layer] *
00151                                                              (alt[i] - limits[layer]) ) ), (K_GMR/lapse_rate[layer]) );
00152   }
00153   
00154 }

void calc_etp_mf ( double *  etp,
double *  tas,
double *  hus,
double *  rsds,
double *  rlds,
double *  uvas,
double *  pmsl,
double  fillvalue,
int  ni,
int  nj 
)

Compute Potential Evapotranspiration (ETP) from Meteo-France formulation.

Parameters:
[out] etp Potential Evaportranspiration (mm)
[in] tas Input 2D temperature (K)
[in] hus Input 2D specific humidity (kg/kg)
[in] rsds Input 2D shortwave incoming radiation
[in] rlds Input 2D longwave incoming radiation
[in] uvas Input 2D wind module
[in] pmsl Input 2D mean sea-level standard atmosphere pressure
[in,out] fillvalue Missing Value for temperature and relative humidity
[in] ni First dimension
[in] nj Second dimension

Definition at line 58 of file calc_etp_mf.c.

References K_TKELVIN.

Referenced by output_downscaled_analog().

00058                                                                                                                                              {
00059 
00073   /*
00074     ; Calculate Evapotranspiration
00075     ;!
00076     ;! Calculate ETP:
00077     ;!
00078     ;! Convert original specific humidity (kg/kg) into relative humidity (%)
00079     ;! ISBA F90 method:
00080     ;! (ZPP (Pa), ZQSAT (kg/kg), ZTA_FRC(K))
00081     ;! Method of Etchevers gene_forc_hydro.f
00082     ;!
00083     ;! Donnees d'entree journalieres en unites SI
00084     ;!
00085     ;! ETP = ETP1 + ETP2
00086     ;! ETP1 = desat * Rnet / (desat + gamma) / lambda
00087     ;! ETP2 = (gamma / (desat + gamma)) * 0.26 * (1 + 0.4*U(10m)) * (es - ea) / tau
00088     ;!
00089     ;! ETP en mm/s
00090     ;! Rn = rayonnement Net en W/m2 (albedo 0.2 et emissivite 0.95)
00091     ;! T = temperature a 2 m en K
00092     ;! U(10m) = vitesse du vent a 10 m en m/s
00093     ;! es = pression vapeur d'eau saturation en hPa
00094     ;! ea = pression vapeur d'eau a 2 m en hPa
00095     ;! gamma = constante psychrometrique = 65 Pa/k
00096     ;! lamba = chaleur latente de vaporisation de l'eau = 2.45E6 J/kg
00097     ;! tau = constante de temps = 86400 sec.
00098     ;!
00099     ;! EP1 >= 0 && EP2 >= 0 && EP <= 9 mm/jour
00100     ;!
00101   */
00102 
00103   int i; /* Loop counter */
00104 
00105   double albedo;
00106   double emissivity;
00107   double gamma;
00108   double stefan;
00109   double lvtt;
00110   double avogadro;
00111   double boltz;
00112   double md;
00113   double mv;
00114   double rd;
00115   double rv;
00116   
00117   double pp;
00118   double factd;
00119   double factm;
00120 
00121   double esat;
00122   double wmix;
00123   double epres;
00124   double desat;
00125   double rnet;
00126 
00127   double etp1;
00128   double etp2;
00129   double ea;
00130 
00131   /* Setup some constants */
00132   albedo = 0.20;
00133   emissivity = 0.95;
00134   gamma = 65.0; /*  Pa K^-1 */
00135   /* tau = 86400.0; */
00136 
00137   stefan = 5.6697 * pow(10.0, -8.0); /*  5 670 400.E-8 in  J K^-4 m^-2 s^-1 */
00138   lvtt = 2.5008 * pow(10.0, 6.0); /* units are in J kg^-1 */
00139   avogadro = 6.0221367 * pow(10.0, 23.0); /* units are in mol^-1 */
00140   boltz = 1.380658 * pow(10.0, -23.0); /* units are in J K^-1 */
00141   md = 28.9644 * pow(10.0,-3.0); /* Masse molaire d'air sec (Md = 28.96455E-3 kg mol-1 )  */
00142   mv = 18.0153 * pow(10.0,-3.0); /* Masse molaire de la vapeur d'eau (Mv = 18.01528E-3 kg mol-1 )  */
00143   rd = avogadro * boltz / md; /* Units J kg^-1 K^-1 */
00144   rv = avogadro * boltz / mv; /* Units J kg^-1 K^-1 */
00145 
00146   /*  if (keyword_set(hourly)) then begin
00147       factd = 24.0
00148       factm = 86400.0/factd
00149       endif else begin */
00150 
00151   factd = 86400.0;
00152   factm = 1.0;
00153 
00154   for (i=0; i<(ni*nj); i++) {
00155 
00156     if (tas[i] != fillvalue) {
00157       pp = pmsl[i] * 100.0; /* Pa */
00158       
00159       esat = 610.8 * exp( 17.27 * (tas[i] - K_TKELVIN) / (tas[i] - 35.86) );  /* Pa */
00160       wmix = hus[i] / (1.0 - hus[i]);                                       /* kg/kg */
00161       epres = pp * wmix / ( (rd/rv) + wmix );                         /* Pa */
00162       desat = esat * 4098.0 / pow((tas[i] - 35.86), 2.0);                    /* desat/dT : Pa/K */
00163       rnet = ((1.0 - albedo) * rsds[i]) + (emissivity * rlds[i]) - (emissivity * stefan * pow(tas[i],4.0)); /* W m^-2 */
00164       
00165       /*
00166         ; Pa K^-1 W m^-2 / J kg^-1 Pa K^-1 = W m^-2 J^-1 kg = J s^-1 m^-2 J^-1 kg = kg s^-1 m^-2
00167         ; kg s^-1 m^-2 = mm/s avec densite implicite de 1000 kg m^-3 qui fait la conversion m en mm
00168       */
00169       etp1 = (desat * rnet) / (lvtt * (desat + gamma)) * factm;
00170       
00171       if (etp1 < 0.0) etp1 = 0.0;
00172       
00173       /*
00174         ; We divide by 100.0 because ew must be in hPa for ea to be in mm/day
00175         ; Units kg m^-2 s^-1 = mm/s avec densite implicite de 1000 kg m^-3 qui fait la conversion m en mm
00176         ; si unites SI sont utilisees. Dans ce cas, esat est en Pa, pas en kPa
00177       */
00178       ea = 0.26 * (1.0 + 0.4 * uvas[i]) * (esat - epres) / 100.0;
00179       
00180       etp2 = (gamma * ea) / (desat + gamma) / factd;
00181       if (etp2 < 0.0) etp2 = 0.0;
00182       
00183       /*  etp in mm/s */
00184       etp[i] = etp1 + etp2;
00185       if (etp[i] > 9.0) etp[i] = 9.0;
00186     }
00187     else {
00188       etp[i] = fillvalue;
00189     }
00190   }
00191 }

void change_date_origin ( double *  timeout,
char *  tunits_out,
double *  timein,
char *  tunits_in,
int  ntime 
)

Change date origin of time expressed in udunits.

Parameters:
[out] timeout Output time vector
[out] tunits_out Output time units (udunits)
[in] timein Input time vector
[in] tunits_in Input time units (udunits)
[in] ntime Number of times

Definition at line 58 of file change_date_origin.c.

References alloc_error(), and TRUE.

Referenced by read_large_scale_fields().

00058                                                                                                   {
00059 
00068   int t; /* Time loop counter */
00069   int istat; /* Diagnostic status */
00070 
00071   utUnit dataunit_in; /* Input data time units (udunits) */
00072   utUnit dataunit_out; /* Output data time units (udunits) */
00073 
00074   int *year = NULL; /* Year vector */
00075   int *month = NULL; /* Month vector */
00076   int *day = NULL; /* Day vector */
00077   int *hour = NULL; /* Hour vector */
00078   int *minutes = NULL; /* Minutes vector */
00079   float *seconds = NULL; /* Seconds vector */
00080 
00081   /* Initialize udunits */
00082   if (utIsInit() != TRUE)
00083     istat = utInit("");
00084 
00085   /* Generate time units (udunits) */
00086   istat = utScan(tunits_in,  &dataunit_in);
00087   istat = utScan(tunits_out, &dataunit_out);
00088 
00089   /* Allocate memory */
00090   year = (int *) malloc(ntime * sizeof(int));
00091   if (year == NULL) alloc_error(__FILE__, __LINE__);
00092   month = (int *) malloc(ntime * sizeof(int));
00093   if (month == NULL) alloc_error(__FILE__, __LINE__);
00094   day = (int *) malloc(ntime * sizeof(int));
00095   if (day == NULL) alloc_error(__FILE__, __LINE__);
00096   hour = (int *) malloc(ntime * sizeof(int));
00097   if (hour == NULL) alloc_error(__FILE__, __LINE__);
00098   minutes = (int *) malloc(ntime * sizeof(int));
00099   if (minutes == NULL) alloc_error(__FILE__, __LINE__);
00100   seconds = (float *) malloc(ntime * sizeof(float));
00101   if (seconds == NULL) alloc_error(__FILE__, __LINE__);
00102 
00103   /* Parse all times and convert time info */
00104   for (t=0; t<ntime; t++) {
00105     istat = utCalendar(timein[t], &dataunit_in, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]));
00106     istat = utInvCalendar(year[t], month[t], day[t], hour[t], minutes[t], seconds[t], &dataunit_out, &(timeout[t]));
00107   }
00108 
00109   /* Free memory */
00110   (void) free(year);
00111   (void) free(month);
00112   (void) free(day);
00113   (void) free(hour);
00114   (void) free(minutes);
00115   (void) free(seconds);
00116 
00117   /* Terminate udunits */
00118   (void) utTerm();
00119 }

int comparf ( const void *  a,
const void *  b 
)

Compare two float values to sort descending.

Parameters:
[in] a First input value
[in] b Second input value
Returns:
Comparison result

Definition at line 58 of file comparf.c.

00059 {
00067   /* Cast to float */
00068   float *n1 = (float *) a;
00069   float *n2 = (float *) b;
00070 
00071   /* Descending comparison */
00072   if (*n1 < *n2)
00073     return 1;
00074   else if (*n1 > *n2)
00075     return -1;
00076   else
00077     return 0;
00078 }

void covariance_fields_spatial ( double *  cov,
double *  buf1,
double *  buf2,
short int *  mask,
int  t1,
int  t2,
int  ni,
int  nj 
)

Compute the spatial covariance of two fields.

Parameters:
[out] cov Spatial covariance
[in] buf1 Input 3D buffer 1
[in] buf2 Input 3D buffer 2
[in] mask Input 2D mask
[in] t1 Time index of buf1 to process
[in] t2 Time index of buf2 to process
[in] ni First dimension
[in] nj Second dimension

Definition at line 58 of file covariance_fields_spatial.c.

Referenced by find_the_days().

00058                                                                                                                     {
00059 
00071   int i; /* Loop counter */
00072   int j; /* Loop counter */
00073   int pts = 0; /* Points counter */
00074   int num = 0; /* Elements counter */
00075 
00076   double sum1; /* Temporary sum for buf1 */
00077   double sum2; /* Temporary sum for buf2 */
00078   double mean1; /* Mean for buf1 */
00079   double mean2; /* Mean for buf2 */
00080 
00081   /* Compute spatial covariance, optionally using a mask */
00082   if (mask == NULL) {
00083 
00084     /* Calculate mean of each field */
00085     sum1 = 0.0;
00086     sum2 = 0.0;
00087     for (j=0; j<nj; j++)
00088       for (i=0; i<ni; i++) {
00089         sum1 += buf1[i+j*ni+t1*ni*nj];
00090         sum2 += buf2[i+j*ni+t2*ni*nj];
00091       }
00092     mean1 = sum1 / (double) (ni*nj);
00093     mean2 = sum2 / (double) (ni*nj);
00094 
00095     /* Calculate spatial covariance */
00096     *cov = 0.0;
00097     num = 0;
00098     for (j=0; j<nj; j++)
00099       for (i=0; i<ni; i++) {
00100         /* Sum of the squares (remove mean) */
00101         (*cov) += ( ( (buf1[i+j*ni+t1*ni*nj] - mean1) * (buf2[i+j*ni+t2*ni*nj] - mean2) ) - (*cov)) / (double) (num + 1);
00102         num++;
00103       }
00104   }
00105   else {
00106     /* Calculate mean of each field */
00107     sum1 = 0.0;
00108     sum2 = 0.0;
00109     pts = 0;
00110     for (j=0; j<nj; j++)
00111       for (i=0; i<ni; i++)
00112         if (mask[i+j*ni] == 1) {
00113           sum1 += buf1[i+j*ni+t1*ni*nj];
00114           sum2 += buf2[i+j*ni+t2*ni*nj];
00115           pts++;
00116         }
00117     mean1 = sum1 / (double) (pts);
00118     mean2 = sum2 / (double) (pts);
00119 
00120     /* Calculate spatial covariance */
00121     *cov = 0.0;
00122     num = 0;
00123     for (j=0; j<nj; j++)
00124       for (i=0; i<ni; i++) {
00125         if (mask[i+j*ni] == 1) {
00126           /* Sum of the squares (remove mean) */
00127           (*cov) += ( ( (buf1[i+j*ni+t1*ni*nj] - mean1) * (buf2[i+j*ni+t2*ni*nj] - mean2) ) - (*cov)) / (double) (num + 1);
00128           num++;
00129         }
00130       }
00131   }
00132 }

int data_to_gregorian_cal_d ( double **  bufout,
double **  outtimeval,
int *  ntimeout,
double *  bufin,
double *  intimeval,
char *  tunits_in,
char *  tunits_out,
char *  cal_type,
int  ni,
int  nj,
int  ntimein 
)

Convert 360-days or no-leap calendar to standard Gregorian calendar for double input/output buffer.

Parameters:
[out] bufout Output 3D buffer which have been adjusted to standard Gregorian Calendar
[out] outtimeval Output new time vector adjusted to standard Gregorian Calendar
[out] ntimeout Number of times in new output 3D buffer
[in] bufin Input 3D buffer with non-standard calendar
[in] intimeval Input time vector with non-standard calendar
[in] tunits_in Input time units with non-standard calendar
[out] tunits_out Output time units
[in] cal_type Input calendar type (non-standard calendar)
[in] ni First dimension length
[in] nj Second dimension length
[in] ntimein Input time dimension length with non-standard calendar

Just recopy the data when calendar type is standard or gregorian

Non-standard calendar type

Definition at line 69 of file data_to_gregorian_cal.c.

References alloc_error().

Referenced by main(), and read_large_scale_fields().

00070                                                                                                                            {
00085   ut_unit *timeslice; /* Time slicing used to compute the new standard calendar */
00086   double val; /* Temporary value */
00087   double curtime; /* Current time */
00088   double ccurtime; /* Current time in non-standard calendar */
00089   
00090   int ref_year; /* A given year */
00091   int ref_month; /* A given month */
00092   int ref_day; /* A given day */
00093   int ref_hour; /* A given hour */
00094   int ref_minutes; /* A given minute */
00095   float ref_seconds; /* A given second */
00096 
00097   int t; /* Time loop counter */
00098   int tt; /* Time loop counter */
00099   int i; /* Loop counter */
00100   int j; /* Loop counter */
00101   int istat; /* Diagnostic status */
00102 
00103   char *utstring = NULL; /* Time unit string */
00104   ut_system *unitSystem = NULL; /* Unit System (udunits) */
00105   ut_unit *dataunit_in = NULL; /* Input data units (udunits) */
00106   ut_unit *dataunit_out = NULL; /* Output data units (udunits) */
00107   cv_converter *conv_in = NULL; /* Converter for time units (udunits) */
00108   ut_unit *tunit = NULL; /* For calculation of offset by time to Epoch */
00109   ut_unit *usecond = NULL; /* Unit of second handle */
00110   double sec_int, sec_intm1; /* Number of seconds since Epoch */
00111 
00112   int *year = NULL; /* Year time vector */
00113   int *month = NULL; /* Month time vector */
00114   int *day = NULL; /* Day time vector */
00115   int *hour = NULL; /* Hour time vector */
00116   int *minutes = NULL; /* Minutes time vector */
00117   double *seconds = NULL; /* Seconds time vector */
00118 
00119   int cyear; /* A given year */
00120   int cmonth; /* A given month */
00121   int cday; /* A given day */
00122   int chour; /* A given hour */
00123   int cminutes; /* A given minute */
00124   double cseconds; /* A given second */
00125 
00126   int sup = 0; /* To indicate supplemental duplicated timestep for end of period out of weird calendars like 360_day */
00127 
00128   /* Initializing */
00129   *bufout = NULL;
00130   *outtimeval = NULL;
00131   *ntimeout = 0;
00132 
00134   if ( !strcmp(cal_type, "standard") || !strcmp(cal_type, "gregorian") ) {
00135     *ntimeout = ntimein;
00136     /* Allocate memory */
00137     (*bufout) = (double *) malloc(ni*nj*(*ntimeout) * sizeof(double));
00138     if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__);
00139     (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double));
00140     if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__);
00141 
00142     /* Loop over all times and gridpoints */
00143     for (t=0; t<(*ntimeout); t++) {
00144       for (j=0; j<nj; j++)
00145         for (i=0; i<ni; i++)
00146           /* Get value */
00147           (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+t*ni*nj];
00148       /* Construct time vector */
00149       (*outtimeval)[t] = (double) intimeval[t];
00150     }
00151   }
00152   else {
00155     /* Allocate memory */
00156     year = (int *) malloc(ntimein * sizeof(int));
00157     if (year == NULL) alloc_error(__FILE__, __LINE__);
00158     month = (int *) malloc(ntimein * sizeof(int));
00159     if (month == NULL) alloc_error(__FILE__, __LINE__);
00160     day = (int *) malloc(ntimein * sizeof(int));
00161     if (day == NULL) alloc_error(__FILE__, __LINE__);
00162     hour = (int *) malloc(ntimein * sizeof(int));
00163     if (hour == NULL) alloc_error(__FILE__, __LINE__);
00164     minutes = (int *) malloc(ntimein * sizeof(int));
00165     if (minutes == NULL) alloc_error(__FILE__, __LINE__);
00166     seconds = (double *) malloc(ntimein * sizeof(double));
00167     if (seconds == NULL) alloc_error(__FILE__, __LINE__);
00168 
00169     /* Initialize udunits */
00170     ut_set_error_message_handler(ut_ignore);
00171     unitSystem = ut_read_xml(NULL);
00172     ut_set_error_message_handler(ut_write_to_stderr);
00173 
00174     /* Generate time units strings */
00175     dataunit_in = ut_parse(unitSystem, tunits_in, UT_ASCII);
00176     dataunit_out = ut_parse(unitSystem, tunits_out, UT_ASCII);
00177 
00178     /* Loop over all times */
00179     for (t=0; t<ntimein; t++) {
00180       /* Calculate date using non-standard calendar */
00181       istat = utCalendar2_cal(intimeval[t], dataunit_in, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]),
00182                               cal_type);
00183       if (istat < 0) {
00184         (void) free(year);
00185         (void) free(month);
00186         (void) free(day);
00187         (void) free(hour);
00188         (void) free(minutes);
00189         (void) free(seconds);
00190         (void) ut_free(dataunit_in);
00191         (void) ut_free(dataunit_out);
00192         (void) ut_free_system(unitSystem);  
00193         return -1;
00194       }
00195 #if DEBUG > 7
00196       istat = utInvCalendar2_cal((year[t]), (month[t]), (day[t]), (hour[t]), (minutes[t]), (seconds[t]), dataunit_in, &ccurtime, cal_type);
00197       printf("%s: %d %lf %lf %d %d %d %d %d %lf\n",__FILE__,t,intimeval[t],ccurtime,year[t],month[t],day[t],hour[t],minutes[t],seconds[t]);
00198       if (istat < 0) {
00199         (void) free(year);
00200         (void) free(month);
00201         (void) free(day);
00202         (void) free(hour);
00203         (void) free(minutes);
00204         (void) free(seconds);
00205         (void) ut_free(dataunit_in);
00206         (void) ut_free(dataunit_out);
00207         (void) ut_free_system(unitSystem);  
00208         return -1;
00209       }
00210 #endif
00211       /* Check that we really have daily data */
00212       if (t > 0) {
00213         /* Prepare converter for basis seconds since Epoch */
00214         usecond = ut_get_unit_by_name(unitSystem, "second");
00215         tunit = ut_offset_by_time(usecond, ut_encode_time(1970, 1, 1, 0, 0, 0.0));
00216         /* Generate converter */
00217         conv_in = ut_get_converter(dataunit_in, tunit);
00218         /* Seconds since Epoch */
00219         sec_int = cv_convert_double(conv_in, intimeval[t]);
00220         sec_intm1 = cv_convert_double(conv_in, intimeval[t-1]);
00221         if ( (sec_int - sec_intm1) != 86400.0 ) {
00222           (void) fprintf(stderr,
00223                          "%s: Fatal error: only daily data can be an input. Found %d seconds between timesteps %d and %d!\n",
00224                          __FILE__, (int) (sec_int - sec_intm1), t-1, t);          
00225           (void) free(year);
00226           (void) free(month);
00227           (void) free(day);
00228           (void) free(hour);
00229           (void) free(minutes);
00230           (void) free(seconds);
00231           (void) ut_free(usecond);
00232           (void) ut_free(tunit);
00233           (void) ut_free(usecond);
00234           (void) ut_free(dataunit_in);
00235           (void) ut_free(dataunit_out);
00236           (void) cv_free(conv_in);
00237           (void) ut_free_system(unitSystem);
00238           return -10;
00239         }
00240       }
00241     }
00242 
00243     /* For noleap/365-day or 360-day calendar types */
00244     if ( !strcmp(cal_type, "noleap") || !strcmp(cal_type, "365_day") || !strcmp(cal_type, "360_day") ) {
00245 
00246       /* Compute the new output total timesteps (days) in a standard year */
00247       /*
00248        * NB: The following specification gives both
00249        * the start time and the sampling interval (1 day). 
00250        */
00251 
00252       /* Set 1 day as a timestep to compute number of days in standard calendar */
00253       utstring = (char *) malloc(1000 * sizeof(char));
00254       if (utstring == NULL) alloc_error(__FILE__, __LINE__);
00255       (void) sprintf(utstring, "1 day since %d-%d-%d", year[0], month[0], day[0]);
00256       timeslice = ut_parse(unitSystem, utstring, UT_ASCII);
00257       (void) free(utstring);
00258 
00259       /* Set end period date */
00260       ref_year = year[ntimein-1];
00261       ref_month = month[ntimein-1];
00262       ref_day = day[ntimein-1];
00263       /* End Dec 31st and not Dec 30th... for 360-days calendar */
00264       if (!strcmp(cal_type, "360_day") &&
00265           (ref_month == 1 || ref_month == 3 || ref_month == 5 || ref_month == 7 || ref_month == 8 || ref_month == 10 || ref_month == 12)
00266           && ref_day == 30) {
00267         ref_day = 31;
00268         sup = 1;
00269       }
00270       ref_hour = hour[ntimein-1];
00271       ref_minutes = 0;
00272       ref_seconds = 0.0;
00273     
00274       /* Get number of timesteps (days) */
00275       istat = utInvCalendar2(ref_year, ref_month, ref_day, ref_hour, ref_minutes, ref_seconds, timeslice, &val);
00276       *ntimeout = (int) val + 1;
00277 
00278       /* Allocate memory */
00279       (*bufout) = (double *) malloc(ni*nj*(*ntimeout) * sizeof(double));
00280       if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__);
00281       (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double));
00282       if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__);
00283 
00284       /* Set start period date */
00285       ref_year = year[0];
00286       ref_month = month[0];
00287       ref_day = day[0];
00288       ref_hour = hour[0];
00289       ref_minutes = 0;
00290       ref_seconds = 0.0;
00291 
00292       /* Loop over all times */
00293       for (t=0; t<(*ntimeout); t++) {
00294         /* Get current day */
00295         istat = utInvCalendar2(ref_year, ref_month, ref_day+t, ref_hour, ref_minutes, ref_seconds, dataunit_out, &curtime);
00296         /* Get standard calendar date from output time units */
00297         istat = utCalendar2(curtime, dataunit_out, &cyear, &cmonth, &cday, &chour, &cminutes, &cseconds);
00298         /* Get corresponding time units in special calendar type */
00299         istat = utInvCalendar2_cal(cyear, cmonth, cday, chour, cminutes, cseconds, dataunit_in, &ccurtime, cal_type);
00300         /* Find that time in the input time vector */
00301         for (tt=0; tt<ntimein; tt++) {
00302           if ((int) ccurtime == (int) intimeval[tt]) {
00303             /* Found it */
00304             for (j=0; j<nj; j++)
00305               for (i=0; i<ni; i++)
00306                 (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+tt*ni*nj];
00307             /* Get current day with hour, minutes and seconds at 00:00:00 */
00308             istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime);
00309             /* Construct new time vector */
00310             (*outtimeval)[t] = (double) curtime;
00311             /* Exit loop */
00312             tt = ntimein+10;
00313           }
00314         }
00315         if ( (sup == 1) && (tt < (ntimein+10)) ) {
00316           /* Copy it */
00317           for (j=0; j<nj; j++)
00318             for (i=0; i<ni; i++)
00319               (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+(ntimein-1)*ni*nj];
00320           /* Get current day with hour, minutes and seconds at 00:00:00 */
00321           istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime);
00322           /* Construct new time vector */
00323           (*outtimeval)[t] = (double) curtime;
00324           tt = ntimein+10;
00325         }
00326         if (tt < (ntimein+10)) {
00327           /* We didn't found the time in the input time vector... */
00328           (void) fprintf(stderr, "%s: Cannot generate new time vector!! Algorithm internal error!\n", __FILE__);
00329           (void) free(year);
00330           (void) free(month);
00331           (void) free(day);
00332           (void) free(hour);
00333           (void) free(minutes);
00334           (void) free(seconds);
00335           (void) ut_free(timeslice);
00336           (void) ut_free(dataunit_in);
00337           (void) ut_free(dataunit_out);
00338           (void) ut_free_system(unitSystem);  
00339           return -11;
00340         }
00341       }
00342     }
00343     else {
00344       /* Non-supported calendar */
00345       (void) fprintf(stderr, "%s: not-supported calendar. Sorry!\n", __FILE__);
00346       (void) free(year);
00347       (void) free(month);
00348       (void) free(day);
00349       (void) free(hour);
00350       (void) free(minutes);
00351       (void) free(seconds);
00352       (void) ut_free(dataunit_in);
00353       (void) ut_free(dataunit_out);
00354       (void) ut_free_system(unitSystem);  
00355       return -1;
00356     }
00357 
00358     /* Free memory */
00359     (void) free(year);
00360     (void) free(month);
00361     (void) free(day);
00362     (void) free(hour);
00363     (void) free(minutes);
00364     (void) free(seconds);
00365     
00366     /* Terminate udunits */
00367     (void) ut_free(dataunit_in);
00368     (void) ut_free(dataunit_out);
00369     (void) ut_free_system(unitSystem);  
00370   }
00371 
00372   /* Success status */
00373   return 0;
00374 }

int data_to_gregorian_cal_f ( float **  bufout,
double **  outtimeval,
int *  ntimeout,
float *  bufin,
double *  intimeval,
char *  tunits_in,
char *  tunits_out,
char *  cal_type,
int  ni,
int  nj,
int  ntimein 
)

Convert 360-days or no-leap calendar to standard Gregorian calendar for float input/output buffer.

Parameters:
[out] bufout Output 3D buffer which have been adjusted to standard Gregorian Calendar
[out] outtimeval Output new time vector adjusted to standard Gregorian Calendar
[out] ntimeout Number of times in new output 3D buffer
[in] bufin Input 3D buffer with non-standard calendar
[in] intimeval Input time vector with non-standard calendar
[in] tunits_in Input time units with non-standard calendar
[out] tunits_out Output time units
[in] cal_type Input calendar type (non-standard calendar)
[in] ni First dimension length
[in] nj Second dimension length
[in] ntimein Input time dimension length with non-standard calendar

Just recopy the data when calendar type is standard or gregorian

Non-standard calendar type

Definition at line 378 of file data_to_gregorian_cal.c.

References alloc_error().

Referenced by main().

00379                                                                                                                            {
00394   ut_unit *timeslice; /* Time slicing used to compute the new standard calendar */
00395   double val; /* Temporary value */
00396   double curtime; /* Current time */
00397   double ccurtime; /* Current time in non-standard calendar */
00398   
00399   int ref_year; /* A given year */
00400   int ref_month; /* A given month */
00401   int ref_day; /* A given day */
00402   int ref_hour; /* A given hour */
00403   int ref_minutes; /* A given minute */
00404   double ref_seconds; /* A given second */
00405 
00406   int t; /* Time loop counter */
00407   int tt; /* Time loop counter */
00408   int i; /* Loop counter */
00409   int j; /* Loop counter */
00410   int istat; /* Diagnostic status */
00411 
00412   char *utstring = NULL; /* Time unit string */
00413   ut_system *unitSystem = NULL; /* Unit System (udunits) */
00414   ut_unit *dataunit_in = NULL; /* Input data units (udunits) */
00415   ut_unit *dataunit_out = NULL; /* Output data units (udunits) */
00416   cv_converter *conv_in = NULL; /* Converter for time units (udunits) */
00417   ut_unit *tunit = NULL; /* For calculation of offset by time to Epoch */
00418   ut_unit *usecond = NULL; /* Unit of second handle */
00419   double sec_int, sec_intm1; /* Number of seconds since Epoch */
00420 
00421   int *year = NULL; /* Year time vector */
00422   int *month = NULL; /* Month time vector */
00423   int *day = NULL; /* Day time vector */
00424   int *hour = NULL; /* Hour time vector */
00425   int *minutes = NULL; /* Minutes time vector */
00426   double *seconds = NULL; /* Seconds time vector */
00427 
00428   int cyear; /* A given year */
00429   int cmonth; /* A given month */
00430   int cday; /* A given day */
00431   int chour; /* A given hour */
00432   int cminutes; /* A given minute */
00433   double cseconds; /* A given second */
00434 
00435   int sup = 0; /* To indicate supplemental duplicated timestep for end of period out of weird calendars like 360_day */
00436 
00437   /* Initializing */
00438   *bufout = NULL;
00439   *outtimeval = NULL;
00440   *ntimeout = 0;
00441 
00443   if ( !strcmp(cal_type, "standard") || !strcmp(cal_type, "gregorian") ) {
00444     *ntimeout = ntimein;
00445     /* Allocate memory */
00446     (*bufout) = (float *) malloc(ni*nj*(*ntimeout) * sizeof(float));
00447     if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__);
00448     (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double));
00449     if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__);
00450 
00451     /* Loop over all times and gridpoints */
00452     for (t=0; t<(*ntimeout); t++) {
00453       for (j=0; j<nj; j++)
00454         for (i=0; i<ni; i++)
00455           /* Get value */
00456           (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+t*ni*nj];
00457       /* Construct time vector */
00458       (*outtimeval)[t] = (double) intimeval[t];
00459     }
00460   }
00461   else {
00464     /* Allocate memory */
00465     year = (int *) malloc(ntimein * sizeof(int));
00466     if (year == NULL) alloc_error(__FILE__, __LINE__);
00467     month = (int *) malloc(ntimein * sizeof(int));
00468     if (month == NULL) alloc_error(__FILE__, __LINE__);
00469     day = (int *) malloc(ntimein * sizeof(int));
00470     if (day == NULL) alloc_error(__FILE__, __LINE__);
00471     hour = (int *) malloc(ntimein * sizeof(int));
00472     if (hour == NULL) alloc_error(__FILE__, __LINE__);
00473     minutes = (int *) malloc(ntimein * sizeof(int));
00474     if (minutes == NULL) alloc_error(__FILE__, __LINE__);
00475     seconds = (double *) malloc(ntimein * sizeof(double));
00476     if (seconds == NULL) alloc_error(__FILE__, __LINE__);
00477 
00478     /* Initialize udunits */
00479     ut_set_error_message_handler(ut_ignore);
00480     unitSystem = ut_read_xml(NULL);
00481     ut_set_error_message_handler(ut_write_to_stderr);
00482 
00483     /* Generate time units strings */
00484     dataunit_in = ut_parse(unitSystem, tunits_in, UT_ASCII);
00485     dataunit_out = ut_parse(unitSystem, tunits_out, UT_ASCII);
00486 
00487     /* Loop over all times */
00488     for (t=0; t<ntimein; t++) {
00489       /* Calculate date using non-standard calendar */
00490       istat = utCalendar2_cal(intimeval[t], dataunit_in, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]),
00491                               cal_type);
00492       if (istat < 0) {
00493         (void) free(year);
00494         (void) free(month);
00495         (void) free(day);
00496         (void) free(hour);
00497         (void) free(minutes);
00498         (void) free(seconds);
00499         (void) ut_free(dataunit_in);
00500         (void) ut_free(dataunit_out);
00501         (void) ut_free_system(unitSystem);  
00502         return -1;
00503       }
00504 #if DEBUG > 7
00505       istat = utInvCalendar2_cal((year[t]), (month[t]), (day[t]), (hour[t]), (minutes[t]), (seconds[t]), dataunit_in, &ccurtime, cal_type);
00506       printf("%s: %d %lf %lf %d %d %d %d %d %lf\n",__FILE__,t,intimeval[t],ccurtime,year[t],month[t],day[t],hour[t],minutes[t],seconds[t]);
00507       if (istat < 0) {
00508         (void) free(year);
00509         (void) free(month);
00510         (void) free(day);
00511         (void) free(hour);
00512         (void) free(minutes);
00513         (void) free(seconds);
00514         (void) ut_free(dataunit_in);
00515         (void) ut_free(dataunit_out);
00516         (void) ut_free_system(unitSystem);  
00517         return -1;
00518       }
00519 #endif
00520       /* Check that we really have daily data */
00521       if (t > 0) {
00522         /* Prepare converter for basis seconds since Epoch */
00523         usecond = ut_get_unit_by_name(unitSystem, "second");
00524         tunit = ut_offset_by_time(usecond, ut_encode_time(1970, 1, 1, 0, 0, 0.0));
00525         /* Generate converter */
00526         conv_in = ut_get_converter(dataunit_in, tunit);
00527         /* Seconds since Epoch */
00528         sec_int = cv_convert_double(conv_in, intimeval[t]);
00529         sec_intm1 = cv_convert_double(conv_in, intimeval[t-1]);
00530         if ( (sec_int - sec_intm1) != 86400.0 ) {
00531           (void) fprintf(stderr,
00532                          "%s: Fatal error: only daily data can be an input. Found %d seconds between timesteps %d and %d!\n",
00533                          __FILE__, (int) (sec_int - sec_intm1), t-1, t);          
00534           (void) free(year);
00535           (void) free(month);
00536           (void) free(day);
00537           (void) free(hour);
00538           (void) free(minutes);
00539           (void) free(seconds);
00540           (void) ut_free(usecond);
00541           (void) ut_free(tunit);
00542           (void) ut_free(usecond);
00543           (void) ut_free(dataunit_in);
00544           (void) ut_free(dataunit_out);
00545           (void) cv_free(conv_in);
00546           (void) ut_free_system(unitSystem);
00547           return -10;
00548         }
00549       }
00550     }
00551 
00552     /* For noleap/365-day or 360-day calendar types */
00553     if ( !strcmp(cal_type, "noleap") || !strcmp(cal_type, "365_day") || !strcmp(cal_type, "360_day") ) {
00554 
00555       /* Compute the new output total timesteps (days) in a standard year */
00556       /*
00557        * NB: The following specification gives both
00558        * the start time and the sampling interval (1 day). 
00559        */
00560 
00561       /* Set 1 day as a timestep to compute number of days in standard calendar */
00562       utstring = (char *) malloc(1000 * sizeof(char));
00563       if (utstring == NULL) alloc_error(__FILE__, __LINE__);
00564       (void) sprintf(utstring, "1 day since %d-%d-%d", year[0], month[0], day[0]);
00565       timeslice = ut_parse(unitSystem, utstring, UT_ASCII);
00566       (void) free(utstring);
00567 
00568       /* Set end period date */
00569       ref_year = year[ntimein-1];
00570       ref_month = month[ntimein-1];
00571       ref_day = day[ntimein-1];
00572       /* End Dec 31st and not Dec 30th... for 360-days calendar */
00573       if (!strcmp(cal_type, "360_day") &&
00574           (ref_month == 1 || ref_month == 3 || ref_month == 5 || ref_month == 7 || ref_month == 8 || ref_month == 10 || ref_month == 12) 
00575           && ref_day == 30) {
00576         ref_day = 31;
00577         sup = 1;
00578       }
00579       ref_hour = hour[ntimein-1];
00580       ref_minutes = 0;
00581       ref_seconds = 0.0;
00582     
00583       /* Get number of timesteps (days) */
00584       istat = utInvCalendar2(ref_year, ref_month, ref_day, ref_hour, ref_minutes, ref_seconds, timeslice, &val);
00585       *ntimeout = (int) val + 1;
00586 
00587       /* Allocate memory */
00588       (*bufout) = (float *) malloc(ni*nj*(*ntimeout) * sizeof(float));
00589       if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__);
00590       (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double));
00591       if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__);
00592 
00593       /* Set start period date */
00594       ref_year = year[0];
00595       ref_month = month[0];
00596       ref_day = day[0];
00597       ref_hour = hour[0];
00598       ref_minutes = 0;
00599       ref_seconds = 0.0;
00600 
00601       /* Loop over all times */
00602       for (t=0; t<(*ntimeout); t++) {
00603         /* Get current day */
00604         istat = utInvCalendar2(ref_year, ref_month, ref_day+t, ref_hour, ref_minutes, ref_seconds, dataunit_out, &curtime);
00605         /* Get standard calendar date from output time units */
00606         istat = utCalendar2(curtime, dataunit_out, &cyear, &cmonth, &cday, &chour, &cminutes, &cseconds);
00607         /* Get corresponding time units in special calendar type */
00608         istat = utInvCalendar2_cal(cyear, cmonth, cday, chour, cminutes, cseconds, dataunit_in, &ccurtime, cal_type);
00609         /* Find that time in the input time vector */
00610         for (tt=0; tt<ntimein; tt++) {
00611           if ((int) ccurtime == (int) intimeval[tt]) {
00612             /* Found it */
00613             for (j=0; j<nj; j++)
00614               for (i=0; i<ni; i++)
00615                 (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+tt*ni*nj];
00616             /* Get current day with hour, minutes and seconds at 00:00:00 */
00617             istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime);
00618             /* Construct new time vector */
00619             (*outtimeval)[t] = (double) curtime;
00620             /* Exit loop */
00621             tt = ntimein+10;
00622           }
00623         }
00624         if ( (sup == 1) && (tt < (ntimein+10)) ) {
00625           /* Copy it */
00626           for (j=0; j<nj; j++)
00627             for (i=0; i<ni; i++)
00628               (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+(ntimein-1)*ni*nj];
00629           /* Get current day with hour, minutes and seconds at 00:00:00 */
00630           istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime);
00631           /* Construct new time vector */
00632           (*outtimeval)[t] = (double) curtime;
00633           tt = ntimein+10;
00634         }
00635         if (tt < (ntimein+10)) {
00636           /* We didn't found the time in the input time vector... */
00637           (void) fprintf(stderr, "%s: Cannot generate new time vector!! Algorithm internal error!\n", __FILE__);
00638           (void) free(year);
00639           (void) free(month);
00640           (void) free(day);
00641           (void) free(hour);
00642           (void) free(minutes);
00643           (void) free(seconds);
00644           (void) ut_free(timeslice);
00645           (void) ut_free(dataunit_in);
00646           (void) ut_free(dataunit_out);
00647           (void) ut_free_system(unitSystem);  
00648           return -11;
00649         }
00650       }
00651     }
00652     else {
00653       /* Non-supported calendar */
00654       (void) fprintf(stderr, "%s: not-supported calendar. Sorry!\n", __FILE__);
00655       (void) free(year);
00656       (void) free(month);
00657       (void) free(day);
00658       (void) free(hour);
00659       (void) free(minutes);
00660       (void) free(seconds);
00661       (void) ut_free(dataunit_in);
00662       (void) ut_free(dataunit_out);
00663       (void) ut_free_system(unitSystem);  
00664       return -1;
00665     }
00666 
00667     /* Free memory */
00668     (void) free(year);
00669     (void) free(month);
00670     (void) free(day);
00671     (void) free(hour);
00672     (void) free(minutes);
00673     (void) free(seconds);
00674     
00675     /* Terminate udunits */
00676     (void) ut_free(dataunit_in);
00677     (void) ut_free(dataunit_out);
00678     (void) ut_free_system(unitSystem);  
00679   }
00680 
00681   /* Success status */
00682   return 0;
00683 }

double distance_point ( double  lon0,
double  lat0,
double  lon1,
double  lat1 
)

Compute distance in meters for two latitude and longitude points.

Parameters:
[in] lon0 First point longitude
[in] lat0 First point latitude
[in] lon1 Second point longitude
[in] lat1 Second point latitude
Returns:
Distance in meters between 2 points.

Definition at line 59 of file distance_point.c.

Referenced by wt_learning().

00060 {
00070   /* Earth equatorial radius, meters, Clarke 1866 ellipsoid */
00071   const double r_earth = 6378206.4;
00072   const double degtorad = M_PI / 180.0;
00073 
00074   double coslt1;
00075   double coslt0;
00076   double sinlt1;
00077   double sinlt0;
00078   double cosl0l1;
00079   double cosc;
00080   
00081   coslt1 = cos(lat1 * degtorad);
00082   sinlt1 = sin(lat1 * degtorad);
00083   coslt0 = cos(lat0 * degtorad);
00084   sinlt0 = sin(lat0 * degtorad);
00085     
00086   cosl0l1 = cos((lon1-lon0) * degtorad);
00087   
00088   /* Cos of angle between points */
00089   cosc = sinlt0 * sinlt1 + coslt0 * coslt1 * cosl0l1;
00090   
00091   /* Restrict range between 1 and -1 */
00092   if (cosc > 1.0)
00093     cosc = 1.0;
00094   else if (cosc < -1.0)
00095     cosc = -1.0;
00096 
00097   return (acos(cosc) * r_earth);
00098 }

void extract_subdomain ( double **  buf_sub,
double **  lon_sub,
double **  lat_sub,
int *  nlon_sub,
int *  nlat_sub,
double *  buf,
double *  lon,
double *  lat,
double  minlon,
double  maxlon,
double  minlat,
double  maxlat,
int  nlon,
int  nlat,
int  ndim 
)

Extract subdomain in a variable given latitudes and longitudes.

Parameters:
[out] buf_sub 3D buffer spanning only subdomain
[out] lon_sub Longitude array spanning only subdomain
[out] lat_sub Latitude array spanning only subdomain
[out] nlon_sub Longitude dimension length spanning only subdomain
[out] nlat_sub Latitude dimension length spanning only subdomain
[in] buf 3D input buffer
[in] lon Longitude array
[in] lat Latitude array
[in] minlon Subdomain bounds: minimum longitude
[in] maxlon Subdomain bounds: maximum longitude
[in] minlat Subdomain bounds: minimum latitude
[in] maxlat Subdomain bounds: maximum latitude
[in] nlon Longitude dimension length
[in] nlat Latitude dimension length
[in] ndim Third dimension length

Definition at line 59 of file extract_subdomain.c.

References alloc_error().

Referenced by main(), read_field_subdomain_period(), read_large_scale_eof(), read_large_scale_fields(), wt_downscaling(), and wt_learning().

00061                                                 {
00080   /* Compute subdomain and apply to arrays */
00081   
00082   int i; /* Loop counter */
00083   int j; /* Loop counter */
00084   int t; /* Time loop counter */
00085   int ii; /* Subdomain loop counter */
00086   int jj; /* Subdomain loop counter */
00087   double curlon; /* Current longitude */
00088   double curlat; /* Current latitude */
00089 
00090   /* Initializing */
00091   *nlon_sub = *nlat_sub = 0;
00092 
00093   /* Count latitude dimension length */
00094   for (i=0; i<nlat; i++)
00095     if (lat[i*nlon] >= minlat && lat[i*nlon] <= maxlat)
00096       (*nlat_sub)++;
00097 
00098   /* Count longitude dimension length */
00099   /* Adjust to span -180 to +180 */
00100   for (i=0; i<nlon; i++) {
00101     if (lon[i] > 180.0)
00102       curlon = lon[i] - 360.0;
00103     else
00104       curlon = lon[i];
00105     if (curlon >= minlon && curlon <= maxlon)
00106       (*nlon_sub)++;
00107   }
00108 
00109   /* Allocate memory with dimension lengths */
00110   (*buf_sub) = (double *) malloc((*nlon_sub)*(*nlat_sub)*ndim * sizeof(double));
00111   if ((*buf_sub) == NULL) alloc_error(__FILE__, __LINE__);
00112   (*lon_sub) = (double *) malloc((*nlon_sub)*(*nlat_sub) * sizeof(double));
00113   if ((*lon_sub) == NULL) alloc_error(__FILE__, __LINE__);
00114   (*lat_sub) = (double *) malloc((*nlon_sub)*(*nlat_sub) * sizeof(double));
00115   if ((*lat_sub) == NULL) alloc_error(__FILE__, __LINE__);
00116 
00117   /* Loop over all gridpoints and construct new buffer array spanning only subdomain */
00118   ii = 0;
00119   jj = 0;
00120   /* Loop over latitudes */
00121   for (j=0; j<nlat; j++) {
00122     if (ii > 0)
00123       jj++;
00124     ii = 0;
00125     /* Loop over longitudes */
00126     for (i=0; i<nlon; i++) {
00127       /* Adjust longitude to span -180 to +180 */
00128       if (lon[i] > 180.0)
00129         curlon = lon[i] - 360.0;
00130       else
00131         curlon = lon[i+j*nlon];
00132       curlat = lat[i+j*nlon];
00133       /* Retrieve only gridpoints within bounds */
00134       if (curlon >= minlon && curlon <= maxlon && curlat >= minlat && curlat <= maxlat) {
00135         /* Loop over last dimension to assign all values for this gridpoint */
00136         for (t=0; t<ndim; t++)
00137           (*buf_sub)[ii+jj*(*nlon_sub)+t*(*nlon_sub)*(*nlat_sub)] = buf[i+j*nlon+t*nlon*nlat];
00138         /* Create also latitude and longitude arrays */
00139         (*lon_sub)[ii+jj*(*nlon_sub)] = lon[i+j*nlon];
00140         (*lat_sub)[ii+jj*(*nlon_sub)] = lat[i+j*nlon];
00141         ii++;
00142       }
00143     }
00144   }
00145 }

void extract_subperiod_months ( double **  buf_sub,
int *  ntime_sub,
double *  bufin,
int *  year,
int *  month,
int *  day,
int *  smonths,
int  timedim,
int  ndima,
int  ndimb,
int  ntime,
int  nmonths 
)

Extract a sub period of a vector of selected months.

Parameters:
[out] buf_sub 3D buffer spanning only time subperiod
[out] ntime_sub Number of times in subperiod
[in] bufin 3D input buffer
[in] year Year vector
[in] month Month vector
[in] day Day vector
[in] smonths Selected months vector (values 1-12)
[in] timedim Time dimension position (1 or 3)
[in] ndima First dimension length
[in] ndimb Second dimension length
[in] ntime Time dimension length
[in] nmonths Number of months in smonths vector

Definition at line 58 of file extract_subperiod_months.c.

References alloc_error().

Referenced by wt_downscaling(), and wt_learning().

00059                                                                                                   {
00075   int *buf_sub_i = NULL; /* Temporary buffer */
00076 
00077   int i; /* Loop counter */
00078   int j; /* Loop counter */
00079   int t; /* Time loop counter */
00080   int tt; /* Time subperiod loop counter */
00081 
00082   /* Initializing */
00083   *ntime_sub = 0;
00084   
00085   /* Retrieve time index spanning selected months */
00086   for (t=0; t<ntime; t++)
00087     for (tt=0; tt<nmonths; tt++)
00088       if (month[t] == smonths[tt]) {
00089         buf_sub_i = (int *) realloc(buf_sub_i, ((*ntime_sub)+1) * sizeof(int));
00090         if (buf_sub_i == NULL) alloc_error(__FILE__, __LINE__);
00091         buf_sub_i[(*ntime_sub)++] = t;
00092       }
00093   
00094   /* Allocate memory */
00095   (*buf_sub) = (double *) malloc((*ntime_sub)*ndima*ndimb * sizeof(double));
00096   if ((*buf_sub) == NULL) alloc_error(__FILE__, __LINE__);
00097 
00098   /* Construct new 3D buffer */
00099   if (timedim == 3)
00100     /* Time dimension is the last one */
00101     for (t=0; t<(*ntime_sub); t++)
00102       for (j=0; j<ndimb; j++)
00103         for (i=0; i<ndima; i++)
00104           (*buf_sub)[i+j*ndima+t*ndima*ndimb] = bufin[i+j*ndima+buf_sub_i[t]*ndima*ndimb];
00105   else
00106     /* Time dimension is the first one */
00107     for (t=0; t<(*ntime_sub); t++)
00108       for (j=0; j<ndimb; j++)
00109         for (i=0; i<ndima; i++)
00110           (*buf_sub)[t+i*(*ntime_sub)+j*(*ntime_sub)*ndima] = bufin[buf_sub_i[t]+i*ntime+j*ntime*ndima];
00111   
00112   /* Free memory */
00113   (void) free(buf_sub_i);
00114 }

int find_str_value ( char *  str,
char **  str_vect,
int  nelem 
)

Find string in vector and return index.

Parameters:
[in] str String value to search
[in] str_vect Vector of strings
[in] nelem Number of elements in str_vect
Returns:
Vector index

Definition at line 58 of file find_str_value.c.

Referenced by output_downscaled_analog(), and read_obs_period().

00058                                                       {
00067   int n; /* Loop counter */
00068   
00069   /* Loop over elements */
00070   for (n=0; n<nelem; n++)
00071     if ( !strcmp(str, str_vect[n]) )
00072       /* Found string */
00073       return n;
00074 
00075   /* String not found */
00076   return -1;
00077 }

int get_calendar ( int *  year,
int *  month,
int *  day,
int *  hour,
int *  minutes,
float *  seconds,
char *  tunits,
double *  timein,
int  ntime 
)

Get year,month,day,hour,min,sec given time in udunits.

Parameters:
[out] year Year vector
[out] month Month vector
[out] day Day vector
[out] hour Hour vector
[out] minutes Minutes vector
[out] seconds Seconds vector
[out] tunits Time units (udunits)
[in] timein Input time vector values
[in] ntime Number of times

Definition at line 58 of file get_calendar.c.

References TRUE.

Referenced by main().

00058                                                                                                                                 {
00059 
00072   int t; /* Time loop counter */
00073   int istat; /* Diagnostic status */
00074 
00075   utUnit dataunit; /* Data time units */
00076 
00077   /* Initialize udunits */
00078   if (utIsInit() != TRUE)
00079     istat = utInit("");
00080   
00081   /* Get time units */
00082   istat = utScan(tunits,  &dataunit);
00083 
00084   /* Loop over times and retrieve day, month, year */
00085   for (t=0; t<ntime; t++) {
00086     istat = utCalendar(timein[t], &dataunit, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]));
00087     if (istat < 0) {
00088       (void) utTerm();
00089       return -1;
00090     }
00091   }
00092   
00093   /* Terminate udunits */
00094   (void) utTerm();
00095 
00096   /* Success status */
00097   return 0;
00098 }

int get_calendar_ts ( tstruct timeout,
char *  tunits,
double *  timein,
int  ntime 
)

Get year,month,day,hour,min,sec (time structure) given time in udunits.

Parameters:
[out] timeout Time structure vector
[out] tunits Time units (udunits)
[in] timein Input time vector values
[in] ntime Number of times

Definition at line 58 of file get_calendar_ts.c.

References TRUE.

Referenced by main(), and remove_clim().

00058                                                                            {
00059 
00067   int t; /* Time loop counter */
00068   int istat; /* Diagnostic status */
00069 
00070   utUnit dataunit; /* Data time units */
00071 
00072   /* Initialize udunits */
00073   if (utIsInit() != TRUE)
00074     istat = utInit("");
00075 
00076   /* Get time units */
00077   istat = utScan(tunits,  &dataunit);
00078   
00079   /* Loop over times and retrieve day, month, year */
00080   for (t=0; t<ntime; t++) {
00081     istat = utCalendar(timein[t], &dataunit, &(timeout[t].year), &(timeout[t].month), &(timeout[t].day), &(timeout[t].hour), &(timeout[t].min), &(timeout[t].sec));
00082     if (istat < 0) {
00083       (void) utTerm();
00084       return -1;
00085     }
00086   }
00087 
00088   /* Terminate udunits */
00089   (void) utTerm();
00090 
00091   /* Success status */
00092   return 0;
00093 }

short int is_leap_year ( int  year  ) 

Find string in vector and return index.

Parameters:
[in] year Year to test
Returns:
Is year a leap year or not

Definition at line 58 of file is_leap_year.c.

Referenced by find_the_days().

00058                        {
00065   if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
00066   {
00067     return 1;
00068   }
00069   else
00070     return 0;
00071 }

void mask_points ( double *  buffer,
double  missing_value,
short int *  mask,
int  nlon,
int  nlat,
int  ndim 
)

Mask points in a variable given a mask field.

Parameters:
[out] buffer 3D buffer
[in] missing_value Missing value
[in] mask Mask 2D array
[in] nlon Longitude dimension length
[in] nlat Latitude dimension length
[in] ndim Third dimension length

Definition at line 58 of file mask_points.c.

Referenced by wt_learning().

00058                                                                                                  {
00068   int i; /* Loop counter */
00069   int j; /* Loop counter */
00070   int t; /* Time loop counter */
00071 
00072   (void) printf("%s: Masking points.\n", __FILE__);
00073 
00074   /* Loop over all gridpoints */
00075 
00076   /* Loop over latitudes */
00077   for (j=0; j<nlat; j++) {
00078     /* Loop over longitudes */
00079     for (i=0; i<nlon; i++) {
00080       /* Mask gridpoints if mask is not 1 */
00081       if (mask[i+j*nlon] != 1) {
00082         /* Loop over last dimension to assign missing value for this gridpoint */
00083         for (t=0; t<ndim; t++)
00084           buffer[i+j*nlon+t*nlon*nlat] = missing_value;
00085       }
00086     }
00087   }
00088 }

void mask_region ( double *  buffer,
double  missing_value,
double *  lon,
double *  lat,
double  minlon,
double  maxlon,
double  minlat,
double  maxlat,
int  nlon,
int  nlat,
int  ndim 
)

Mask region in a variable given latitude and longitude coordinates.

Parameters:
[out] buffer 3D buffer
[in] missing_value Missing value
[in] lon Longitude array
[in] lat Latitude array
[in] minlon Subdomain bounds: minimum longitude
[in] maxlon Subdomain bounds: maximum longitude
[in] minlat Subdomain bounds: minimum latitude
[in] maxlat Subdomain bounds: maximum latitude
[in] nlon Longitude dimension length
[in] nlat Latitude dimension length
[in] ndim Third dimension length

Definition at line 59 of file mask_region.c.

Referenced by wt_learning().

00061                                           {
00076   int i; /* Loop counter */
00077   int j; /* Loop counter */
00078   int t; /* Time loop counter */
00079   double curlon; /* Current longitude */
00080   double curlat; /* Current latitude */
00081 
00082   (void) printf("%s: Masking domain. Longitudes: %lf %lf. Latitudes: %lf %lf.\n", __FILE__, minlon, maxlon, minlat, maxlat);
00083 
00084   /* Loop over all gridpoints */
00085 
00086   /* Loop over latitudes */
00087   for (j=0; j<nlat; j++) {
00088     /* Loop over longitudes */
00089     for (i=0; i<nlon; i++) {
00090       /* Adjust longitude to span -180 to +180 */
00091       if (lon[i] > 180.0)
00092         curlon = lon[i] - 360.0;
00093       else
00094         curlon = lon[i+j*nlon];
00095       curlat = lat[i+j*nlon];
00096       /* Mask only gridpoints within bounds */
00097       if (curlon >= minlon && curlon <= maxlon && curlat >= minlat && curlat <= maxlat) {
00098         /* Loop over last dimension to assign missing value for this gridpoint */
00099         for (t=0; t<ndim; t++)
00100           buffer[i+j*nlon+t*nlon*nlat] = missing_value;
00101       }
00102     }
00103   }
00104 }

void mean_field_spatial ( double *  buf_mean,
double *  buf,
short int *  mask,
int  ni,
int  nj,
int  ntime 
)

Compute the spatial mean of a field.

Parameters:
[out] buf_mean Vector (over time) of spatially averaged data
[in] buf Input 3D buffer
[in] mask Input 2D mask
[in] ni First dimension
[in] nj Second dimension
[in] ntime Time dimension

Definition at line 58 of file mean_field_spatial.c.

Referenced by main(), wt_downscaling(), and wt_learning().

00058                                                                                               {
00059 
00069   double sum; /* Sum used to calculate the mean */
00070   
00071   int t; /* Time loop counter */
00072   int i; /* Loop counter */
00073   int j; /* Loop counter */
00074   int pts = 0; /* Points counter */
00075 
00076   /* Loop over all time and average spatially, optionally using a mask */
00077   if (mask == NULL)
00078     for (t=0; t<ntime; t++) {
00079       sum = 0.0;
00080       for (j=0; j<nj; j++)
00081         for (i=0; i<ni; i++)
00082           sum += buf[i+j*ni+t*ni*nj];
00083       buf_mean[t] = sum / (double) (ni*nj);
00084     }
00085   else {
00086     for (t=0; t<ntime; t++) {
00087       sum = 0.0;
00088       pts = 0;
00089       for (j=0; j<nj; j++)
00090         for (i=0; i<ni; i++)
00091           if (mask[i+j*ni] == 1) {
00092             sum += buf[i+j*ni+t*ni*nj];
00093             pts++;
00094           }
00095       buf_mean[t] = sum / (double) pts;
00096     }
00097   }
00098 }

void mean_variance_field_spatial ( double *  buf_mean,
double *  buf_var,
double *  buf,
short int *  mask,
int  ni,
int  nj,
int  ntime 
)

Compute mean and variance of a field averaged spatially.

Parameters:
[out] buf_mean Mean of spatially averaged field
[out] buf_var Variance of spatially averaged field
[in] buf Input 3D buffer
[in] mask Input 2D mask
[in] ni First dimension
[in] nj Second dimension
[in] ntime Time dimension

Definition at line 59 of file mean_variance_field_spatial.c.

References alloc_error().

Referenced by main(), and wt_downscaling().

00059                                                                                                                         {
00060 
00071   double sum; /* Sum to compute mean */
00072   double *buf_smean = NULL; /* Vector (over time) of spatially averaged data */
00073   
00074   int t; /* Time loop counter */
00075   int i; /* Loop counter */
00076   int j; /* Loop counter */
00077   int pts = 0; /* Points counter */
00078 
00079   /* Allocate memory */
00080   buf_smean = (double *) malloc(ntime * sizeof(double));
00081   if (buf_smean == NULL) alloc_error(__FILE__, __LINE__);
00082 
00083   /* Loop over all times and calculate spatial average, optionally using a mask */
00084   if (mask == NULL)
00085     for (t=0; t<ntime; t++) {
00086       sum = 0.0;
00087       for (j=0; j<nj; j++)
00088         for (i=0; i<ni; i++)
00089           sum += buf[i+j*ni+t*ni*nj];
00090       buf_smean[t] = sum / (double) (ni*nj);
00091     }
00092   else {
00093     for (t=0; t<ntime; t++) {
00094       sum = 0.0;
00095       pts = 0;
00096       for (j=0; j<nj; j++)
00097         for (i=0; i<ni; i++)
00098           if (mask[i+j*ni] == 1) {
00099             sum += buf[i+j*ni+t*ni*nj];
00100             pts++;
00101           }
00102       buf_smean[t] = sum / (double) pts;
00103     }
00104   }
00105   
00106   /* Compute mean and variance over time */
00107   *buf_mean = gsl_stats_mean(buf_smean, 1, ntime);
00108   *buf_var = gsl_stats_variance(buf_smean, 1, ntime);
00109 
00110   /* Free memory */
00111   (void) free(buf_smean);
00112 }

void normalize_field ( double *  nbuf,
double *  buf,
double  mean,
double  var,
int  ndima,
int  ndimb,
int  ntime 
)

Normalize a 3D variable by a mean and variance.

Parameters:
[out] nbuf Normalized 3D buffer
[in] buf Input 3D buffer
[in] mean Mean
[in] var Variance
[in] ndima First dimension
[in] ndimb Second dimension
[in] ntime Time dimension

Definition at line 58 of file normalize_field.c.

Referenced by wt_downscaling(), and wt_learning().

00058                                                                                                      {
00059 
00070   int nt; /* Time loop counter */
00071   int dima; /* First dimension counter */
00072   int dimb; /* Second dimension counter */
00073 
00074   /* Loop over all elements and normalize */
00075   for (nt=0; nt<ntime; nt++)
00076     for (dimb=0; dimb<ndimb; dimb++)
00077       for (dima=0; dima<ndima; dima++)
00078         nbuf[dima+dimb*ndima+nt*ndima*ndimb] = (buf[dima+dimb*ndima+nt*ndima*ndimb] - mean) / sqrt(var);
00079 }

void normalize_field_2d ( double *  nbuf,
double *  buf,
double *  mean,
double *  var,
int  ndima,
int  ndimb,
int  ntime 
)

Normalize a 3D variable by 2D mean and variance.

Parameters:
[out] nbuf Normalized 3D buffer
[in] buf Input 3D buffer
[in] mean Mean 2D
[in] var Variance 2D
[in] ndima First dimension
[in] ndimb Second dimension
[in] ntime Time dimension

Definition at line 58 of file normalize_field_2d.c.

Referenced by wt_downscaling(), and wt_learning().

00058                                                                                                           {
00059 
00070   int nt; /* Time loop counter */
00071   int dima; /* First dimension counter */
00072   int dimb; /* Second dimension counter */
00073 
00074   /* Loop over all elements and normalize */
00075   for (nt=0; nt<ntime; nt++)
00076     for (dimb=0; dimb<ndimb; dimb++)
00077       for (dima=0; dima<ndima; dima++)
00078         nbuf[dima+dimb*ndima+nt*ndima*ndimb] = (buf[dima+dimb*ndima+nt*ndima*ndimb] - mean[dima+dimb*ndima]) / sqrt(var[dima+dimb*ndima]);
00079 }

void spechum_to_hr ( double *  hur,
double *  tas,
double *  hus,
double *  pmsl,
double  fillvalue,
int  ni,
int  nj 
)

Compute relative humidity from specific humidity.

Parameters:
[out] hur Relative humidity (%)
[in] tas Input 2D temperature (K)
[in] hus Input 2D specific humidity (kg/kg)
[in] pmsl Input 2D mean sea-level pressure (hPa)
[in,out] fillvalue Missing Value for temperature and relative humidity
[in] ni First dimension
[in] nj Second dimension

Definition at line 58 of file spechum_to_hr.c.

References K_MD, K_MW, and K_TKELVIN.

Referenced by output_downscaled_analog().

00058                                                                                                      {
00059 
00070   int i; /* Loop counter */
00071 
00072   double curtas; /* Current temperature value */
00073   double curhus; /* Current specific humidity value */
00074   double mixr; /* Mixing ratio */
00075   double es; /* Saturation vapor pressure */
00076   double fact; /* Factor */
00077 
00078   for (i=0; i<(ni*nj); i++) {
00079 
00080     curtas = tas[i];
00081     if (curtas != fillvalue) {
00082       curhus = hus[i] * 1000.0;
00083       
00084       /* Begin by calculating the mixing ratio Q/(1.-Q/1000.) */
00085       mixr = curhus / (1.0 - (curhus / 1000.0));
00086       /* Compute relative humidity from the mixing ratio */
00087       /*                    ;                                     Mw*e              e
00088                             ;  W (mixing ratio) = m_h2o/m_dry = -------- = Mw/Md * ---
00089                             ;                                   Md*(p-e)           p-e
00090                             ;
00091                             ;  RH (rel. hum.)    = e/esat(T)*100.
00092       */
00093       /* Compute saturation vapor pressure in hPa */
00094       /* ; Formula with T = temperature in K
00095          ;    esat = exp( -6763.6/(T+T0) - 4.9283*alog((T+T0)) + 54.2190 )
00096          
00097          ; Formula close to that of Magnus, 1844 with temperature TC in Celsius
00098          ;    ESAT = 6.1078 * EXP( 17.2693882 * TC / (TC + 237.3) ) ; TC in Celsius
00099          
00100          ; or Emanuel's formula (also approximation in form of Magnus' formula,
00101          ; 1844), which was taken from Bolton, Mon. Wea. Rev. 108, 1046-1053, 1980.
00102          ; This formula is very close to Goff and Gratch with differences of
00103          ; less than 0.25% between -50 and 0 deg C (and only 0.4% at -60degC)    
00104          ;    esat=6.112*EXP(17.67*TC/(243.5+TC))
00105          
00106          ; WMO reference formula is that of Goff and Gratch (1946), slightly
00107          ; modified by Goff in 1965:
00108       */
00109       es = 1013.250 * pow( 10.0, ( 10.79586* (1.0-K_TKELVIN/curtas) -
00110                                    5.02808 * log10(curtas/K_TKELVIN) +
00111                                    1.50474 * 0.0001 *
00112                                    (1.0 - pow(10.0, (-8.29692*((curtas/K_TKELVIN)-1.0))) ) +
00113                                    0.42873 * 0.001 *
00114                                    (pow(10.0, (4.76955*(1.0-K_TKELVIN/curtas)))-1.0) - 2.2195983) );
00115       fact = mixr / 1000.0 * (K_MD/K_MW);
00116       /* Use Standard Pressure for now, given altitude.
00117          For more precise values we should use instead a pressure field close to the weather type... */
00118       hur[i] = pmsl[i] / es * fact / (1.0 + fact) * 100.0;
00119       if (hur[i] > 100.0) hur[i] = 100.0;
00120       if (hur[i] < 0.0) hur[i] = 0.0;
00121     }
00122     else
00123       hur[i] = fillvalue;
00124   }
00125 }

int sub_period_common ( double **  buf_sub,
int *  ntime_sub,
double *  bufin,
int *  year,
int *  month,
int *  day,
int *  year_learn,
int *  month_learn,
int *  day_learn,
int  timedim,
int  ndima,
int  ndimb,
int  ntime,
int  ntime_learn 
)

Select a sub period of a vector using a common period over two different time vectors.

Parameters:
[out] buf_sub Output 3D buffer spanning common time period
[out] ntime_sub Number of times for the common time period (time dimension length)
[in] bufin Input 3D buffer (ndima * ndimb * ntime)
[in] year Year vector for the first time vector
[in] month Month vector for the first time vector
[in] day Day vector for the first time vector
[in] year_learn Year vector for the second time vector
[in] month_learn Month vector for the second time vector
[in] day_learn Day vector for the second time vector
[in] timedim Position of the time period dimension (1 or 3)
[in] ndima First dimension
[in] ndimb Second dimension
[in] ntime Time dimension of the first time vector
[in] ntime_learn Time dimension of the second time vector

Definition at line 59 of file sub_period_common.c.

References alloc_error().

Referenced by main(), wt_downscaling(), and wt_learning().

00060                                                                                                                                     {
00078   int *buf_sub_i = NULL; /* Time indexes for common period */
00079 
00080   int dima; /* First dimension */
00081   int dimb; /* Second dimension */
00082   int t; /* Time loop counter */
00083   int tt; /* Time loop counter for second time vector */
00084 
00085   /* Initialize number of common times */
00086   *ntime_sub = 0;
00087 
00088   /* Loop over first time vector and find common day/month/year and store time indexes for these common times */
00089   for (t=0; t<ntime; t++) {
00090     /* Search in all second time vector times for matching date */
00091     for (tt=0; tt<ntime_learn; tt++) {
00092       if (year[t]  == year_learn[tt] &&
00093           month[t] == month_learn[tt] &&
00094           day[t]   == day_learn[tt]) {
00095         /* Found common date, store time index */
00096         buf_sub_i = (int *) realloc(buf_sub_i, ((*ntime_sub)+1) * sizeof(int));
00097         if (buf_sub_i == NULL) alloc_error(__FILE__, __LINE__);
00098         buf_sub_i[(*ntime_sub)++] = t;
00099       }
00100     }
00101   }
00102 
00103   if ( (*ntime_sub) == 0 ) {
00104     (void) fprintf(stderr, "%s: FATAL ERROR: No common subperiod! Maybe a problem in the time representation in the control run file.\nAborting.\n", __FILE__);
00105     (void) printf("MODEL TIMES ntime=%d\n", ntime);
00106     //#if DEBUG > 7
00107     for (t=0; t<ntime; t++)
00108       (void) printf("%d %d %d\n", year[t], month[t], day[t]);
00109     (void) printf("LEARNING TIMES ntime=%d\n", ntime_learn);
00110     for (t=0; t<ntime_learn; t++)
00111       (void) printf("%d %d %d\n", year_learn[t], month_learn[t], day_learn[t]);
00112     //#endif
00113     return -1;
00114   }
00115   
00116   (void) printf("%s: Sub-period: %d %d %d %d %d %d. Indexes: %d %d\n",__FILE__, year[buf_sub_i[0]], month[buf_sub_i[0]],
00117                 day[buf_sub_i[0]], year[buf_sub_i[(*ntime_sub)-1]],month[buf_sub_i[(*ntime_sub)-1]],
00118                 day[buf_sub_i[(*ntime_sub)-1]], buf_sub_i[0], buf_sub_i[(*ntime_sub)-1]);
00119 
00120   /* Allocate memory for output buffer */
00121   (*buf_sub) = (double *) malloc((*ntime_sub)*ndima*ndimb * sizeof(double));
00122   if ((*buf_sub) == NULL) alloc_error(__FILE__, __LINE__);
00123   /* Construct new 3D matrix with common times */
00124   if (timedim == 3)
00125     /* Time dimension is last */
00126     for (t=0; t<(*ntime_sub); t++)
00127       for (dimb=0; dimb<ndimb; dimb++)
00128         for (dima=0; dima<ndima; dima++)
00129           (*buf_sub)[dima+(dimb*ndima)+t*ndima*ndimb] = bufin[dima+dimb*ndima+buf_sub_i[t]*ndima*ndimb];
00130   else if (timedim == 1)
00131     /* Time dimension is first */
00132     for (t=0; t<(*ntime_sub); t++)
00133       for (dimb=0; dimb<ndimb; dimb++)
00134         for (dima=0; dima<ndima; dima++)
00135           (*buf_sub)[t+dima*(*ntime_sub)+dimb*(ndima*(*ntime_sub))] = bufin[buf_sub_i[t]+dima*ntime+dimb*(ndima*ntime)];
00136   else
00137     (void) fprintf(stderr, "%s: Fatal error: timedim argument must be equal to 1 or 3.\n", __FILE__);
00138 
00139   /* Free memory */
00140   (void) free(buf_sub_i);
00141 
00142   /* Success */
00143   return 0;
00144 }

void time_mean_variance_field_2d ( double *  bufmean,
double *  bufvar,
double *  buf,
int  ni,
int  nj,
int  nt 
)

Compute the time mean and variance of a 2D field.

Parameters:
[out] bufmean Time mean of 2D field
[out] bufvar Time variance of 2D field
[in] buf Input 3D buffer
[in] ni First dimension
[in] nj Second dimension
[in] nt Time dimension

Definition at line 58 of file time_mean_variance_field_2d.c.

Referenced by wt_downscaling(), and wt_learning().

00058                                                                                                   {
00059 
00069   int i; /* Loop counter */
00070   int j; /* Loop counter */
00071   int t; /* Loop counter */
00072 
00073   double sum; /* Temporary sum for buf */
00074   double diff; /* Temporary difference for variance calculation */
00075 
00076   /* First calculate mean over time of a 2D field */
00077   for (j=0; j<nj; j++)
00078     for (i=0; i<ni; i++) {
00079       sum = 0.0;
00080       for (t=0; t<nt; t++)
00081         sum += buf[i+j*ni+t*ni*nj];
00082       bufmean[i+j*ni] = sum / (double) nt;
00083     }
00084 
00085   /* Then calculate variance over time of a 2D field */
00086   for (j=0; j<nj; j++)
00087     for (i=0; i<ni; i++) {
00088       sum = 0.0;
00089       for (t=0; t<nt; t++) {
00090         diff = buf[i+j*ni+t*ni*nj] - bufmean[i+j*ni];
00091         sum += (diff * diff);
00092       bufvar[i+j*ni] = sqrtf(sum / (double) (nt-1));
00093       }
00094     }
00095 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1