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>
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. |
Include file for utilities library.
Definition in file utils.h.
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.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
[in] | a | First input value |
[in] | b | Second input value |
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.
[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.
[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.
[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.
[in] | lon0 | First point longitude |
[in] | lat0 | First point latitude |
[in] | lon1 | Second point longitude |
[in] | lat1 | Second point latitude |
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.
[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.
[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.
[in] | str | String value to search |
[in] | str_vect | Vector of strings |
[in] | nelem | Number of elements in str_vect |
Definition at line 58 of file find_str_value.c.
Referenced by output_downscaled_analog(), and read_obs_period().
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.
[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.
[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.
[in] | year | Year to test |
Definition at line 58 of file is_leap_year.c.
Referenced by find_the_days().
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.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
[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 }