EcaIndices.cc 57.5 KB
Newer Older
1
2
3
4
/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
5
  Copyright (C) 2006 Brockmann Consult
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

/*
      MODULE      OPERATOR     INDEX    DESCRIPTION
      
      EcaCfd      eca_cfd      CFD      maximum number of consecutive frost days
      EcaCsu      eca_csu      CSU      maximum number of consecutive summer days
      EcaCwdi     eca_cwdi     CWDI     cold wave duration index
      EcaCwfi     eca_cwfi     CWFI     number of cold-spell days
      EcaEtr      eca_etr      ETR      intra-period extreme temperature range
      EcaFd       eca_fd       FD       number of frost days
      EcaGsl      eca_gsl      GSL      growing season length
      EcaHd       eca_hd       HD       heating degree days
      EcaHwdi     eca_hwdi     HWDI     heat wave duration index
      EcaHwfi     eca_hwfi     HWFI     number of warm-spell days
      EcaId       eca_id       ID       number of ice days
      EcaSu       eca_su       SU       number of summer days
      EcaTg10p    eca_tg10p    TG10p    percent of time TX < 10th percentile of daily mean temperature
      EcaTg90p    eca_tg90p    TG90p    percent of time TX > 90th percentile of daily mean temperature
      EcaTn10p    eca_tn10p    TN10p    percent of time TX < 10th percentile of daily minimum temperature   
      EcaTn90p    eca_tn90p    TN90p    percent of time TX > 90th percentile of daily minimum temperature
      EcaTr       eca_tr       TR       number of tropical nights
      EcaTx10p    eca_tx10p    TX10p    percent of time TX < 10th percentile of daily maximum temperature
      EcaTx90p    eca_tx90p    TX90p    percent of time TX > 90th percentile of daily maximum temperature

      EcaCdd      eca_cdd      CDD      maximum number of consecutive dry days
      EcaCwd      eca_cwd      CWD      maximum number of consecutive wet days
      EcaR10mm    eca_r10mm    R10mm    number of days with precipitation >= 10 mm
      EcaR20mm    eca_r20mm    R20mm    number of days with precipitation >= 20 mm
      EcaR75p     eca_r75p     R75p     Percent of time RR > 75th percentile of daily precipitation amount 
      EcaR75ptot  eca_r75ptot  R75pTOT  Percentage of annual total precipitation due to events wit RR > 75th percentile of daily precipitation amount
      EcaR90p     eca_r90p     R90p     Percent of time RR > 90th percentile of daily precipitation amount
      EcaR90ptot  eca_r90ptot  R90pTOT  Percentage of annual total precipitation due to events wit RR > 90th percentile of daily precipitation amount
      EcaR95p     eca_r95p     R95p     Percent of time RR > 95th percentile of daily precipitation amount
      EcaR95ptot  eca_r95ptot  R95pTOT  Percentage of annual total precipitation due to events wit RR > 95th percentile of daily precipitation amount
      EcaR99p     eca_r99p     R99p     Percent of time RR > 75th percentile of daily precipitation amount
      EcaR99ptot  eca_r99ptot  R99pTOT  Percentage of annual total precipitation due to events wit RR > 99th percentile of daily precipitation amount
      EcaRr1      eca_rr1      RR1      number of wet days
      EcaSdii     eca_sdii     SDII     simple daily intensity index
      
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
      Fdns        fdns                  frost days without surface snow 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57

Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
59
60
61
      Strwin      strwin                number of strong-wind days
      Strbre      strbre                number of strong-breeze days 
      Strgal      strgal                number of strong-gale days 
      Hurr        hurr                  number of hurricane days 
62
63
*/

Oliver Heidmann's avatar
Oliver Heidmann committed
64

65
#include "cdo_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
#include "ecacore.h"
67
68
69
#include "ecautil.h"


Uwe Schulzweida's avatar
Uwe Schulzweida committed
70
#define TO_DEG_CELSIUS(x) ((x) - 273.15)
71
72
#define TO_KELVIN(x) ((x) + 273.15)

Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
// clang-format off
74

Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
static const char CFD_NAME[]         = "consecutive_frost_days_index_per_time_period";
static const char CFD_LONGNAME[]     = "Consecutive frost days index is the greatest number of consecutive frost days in a given time period. Frost days is the number of days where minimum of temperature is below 0 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
//static const char CFD_UNITS[]        = "No.";
78
79
static const char CFD_NAME2[]        = "number_of_cfd_periods_with_more_than_%ddays_per_time_period";
static const char CFD_LONGNAME2[]    = "Number of cfd periods in given time period with more than %d days. The time period should be defined by the bounds of the time coordinate.";
80
static const char CFD_UNITS2[]       = "No.";
81

Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
83
static const char CSU_NAME[]         = "consecutive_summer_days_index_per_time_period";
static const char CSU_LONGNAME[]     = "Consecutive summer days index is the greatest number of consecutive summer days in a given time period. Summer days is the number of days where maximum of temperature is above 25 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
//static const char CSU_UNITS[]        = "No.";
85
86
static const char CSU_NAME2[]        = "number_of_csu_periods_with_more_than_%ddays_per_time_period";
static const char CSU_LONGNAME2[]    = "Number of csu periods in given time period with more than %d days. The time period should be defined by the bounds of the time coordinate.";
87
static const char CSU_UNITS2[]       = "No.";
88

Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
90
91
92
93
94
static const char CWDI_NAME[]        = "cold_wave_duration_index_wrt_mean_of_reference_period";
static const char CWDI_LONGNAME[]    = "This is the number of days per time period where in intervals of at least %d consecutive days the daily minimum temperature is more than %1.0f degrees below a reference value. The reference value is calculated  as the mean of minimum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char CWDI_UNITS[]       = "No.";
static const char CWDI_NAME2[]       = "cold_waves_per_time_period";
static const char CWDI_LONGNAME2[]   = "Number of cold waves per time period. The time period should be defined by the bounds of the time coordinate.";
static const char CWDI_UNITS2[]      = "No.";
95

Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
98
99
100
101
static const char CWFI_NAME[]        = "cold_spell_days_index_wrt_10th_percentile_of_reference_period";
static const char CWFI_LONGNAME[]    = "This is the number of days per time period where in intervals of at least %d consecutive days the daily mean temperature is below a reference value. The reference value is calculated  as the 10th percentile of daily mean temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char CWFI_UNITS[]       = "No.";
static const char CWFI_NAME2[]       = "cold_spell_periods_per_time_period";
static const char CWFI_LONGNAME2[]   = "Number of cold spell periods per time period. The time period should be defined by the bounds of the time coordinate.";
static const char CWFI_UNITS2[]      = "No.";
102
103

static const char ETR_NAME[]         = "intra_period_extreme_temperature_range";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
static const char ETR_LONGNAME[]     = "Difference between the absolute extreme temperatures in observation period. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
//static const char ETR_UNITS[]        = "K";
106

Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
static const char FD_NAME[]          = "frost_days_index_per_time_period";
static const char FD_LONGNAME[]      = "Frost days index is the number of days where minimum of temperature is below 0 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
109
//static const char FD_UNITS[]         = "No.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110

111
static const char GSL_NAME[]         = "thermal_growing_season_length";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
static const char GSL_LONGNAME[]     = "Counted are the number of days per calendar year between the first occurrence of at least %d consecutive days where the daily mean temperature is above %1.0f degree Celsius and the first occurrence of at least %d consecutive days after 1st of July where the daily mean temperature is below %1.0f degree Celsius. The time period should be defined by the bounds of the time coordinate.";
static const char GSL_UNITS[]        = "No.";
static const char GSL_NAME2[]        = "day_of_year_of_growing_season_start";
static const char GSL_LONGNAME2[]    = "Day of year of growing season start. The time period should be defined by the bounds of the time coordinate.";
static const char GSL_UNITS2[]       = "No.";

static const char HD_NAME[]          = "heating_degree_days_per_time_period";
static const char HD_LONGNAME[]      = "Heating degree days relates the outside temperature with the room temperature during the heating period. It is the sum of the difference between room temperature X and daily mean temperature Y on days where Y is below a given constant A. X is 20 degree Celsius and A is 15 degree Celsius according to VDI guidelines. According to ECAD both X and A are 17 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
static const char HD_UNITS[]         = "No.";

static const char HWDI_NAME[]        = "heat_wave_duration_index_wrt_mean_of_reference_period";
static const char HWDI_LONGNAME[]    = "This is the number of days per time period where in intervals of at least %d consecutive days the daily maximum temperature is more than %1.0f degrees above a reference value. The reference value is calculated  as the mean of maximum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char HWDI_UNITS[]       = "No.";
static const char HWDI_NAME2[]       = "heat_waves_per_time_period";
static const char HWDI_LONGNAME2[]   = "Number of heat waves per time period. The time period should be defined by the bounds of the time coordinate.";
static const char HWDI_UNITS2[]      = "No.";

static const char HWFI_NAME[]        = "warm_spell_days_index_wrt_90th_percentile_of_reference_period";
static const char HWFI_LONGNAME[]    = "This is the number of days per time period where in intervals of at least %d consecutive days the daily mean temperature is above a reference value. The reference value is calculated  as the 90th percentile of daily mean temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char HWFI_UNITS[]       = "No.";
static const char HWFI_NAME2[]       = "warm_spell_periods_per_time_period";
static const char HWFI_LONGNAME2[]   = "Number of warm spell periods per time period. The time period should be defined by the bounds of the time coordinate.";
static const char HWFI_UNITS2[]      = "No.";

static const char ID_NAME[]          = "ice_days_index_per_time_period";
static const char ID_LONGNAME[]      = "Ice days index is the number of days where maximum of temperature is below 0 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
static const char ID_UNITS[]         = "No.";

static const char SU_NAME[]          = "summer_days_index_per_time_period";
static const char SU_LONGNAME[]      = "Summer days index is the number of days where maximum of temperature is above %1.0f degree Celsius. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
//static const char SU_UNITS[]         = "No.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

static const char TG10P_NAME[]       = "cold_days_percent_wrt_10th_percentile_of_reference_period";
static const char TG10P_LONGNAME[]   = "This is the percent of time per time period where daily mean temperature is below a reference value. The reference value is calculated  as the 10th percentile of daily mean temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TG10P_UNITS[]      = "Percent";

static const char TG90P_NAME[]       = "warm_days_percent_wrt_90th_percentile_of_reference_period";
static const char TG90P_LONGNAME[]   = "This is the percent of time per time period where daily mean  temperature is above a reference value. The reference value is calculated  as the 90th percentile of daily mean temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TG90P_UNITS[]      = "Percent";

static const char TN10P_NAME[]       = "cold_nights_percent_wrt_10th_percentile_of_reference_period";
static const char TN10P_LONGNAME[]   = "This is the percent of time per time period where daily minimum  temperature is below a reference value. The reference value is calculated  as the 10th percentile of daily minimum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TN10P_UNITS[]      = "Percent";

static const char TN90P_NAME[]       = "warm_nights_percent_wrt_90th_percentile_of_reference_period";
static const char TN90P_LONGNAME[]   = "This is the percent of time per time period where daily minimum  temperature is above a reference value. The reference value is calculated  as the 90th percentile of daily minimum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TN90P_UNITS[]      = "Percent";

static const char TR_NAME[]          = "tropical_nights_index_per_time_period";
static const char TR_LONGNAME[]      = "Tropical nights index is the number of days where minimum of temperature is above %1.0f degree Celsius. The time period should be defined by the bounds of the time coordinate.";
static const char TR_UNITS[]         = "No.";

static const char TX10P_NAME[]       = "very_cold_days_percent_wrt_10th_percentile_of_reference_period";
static const char TX10P_LONGNAME[]   = "This is the percent of time per time period where daily maximum temperature is below a reference value. The reference value is calculated  as the 10th percentile of daily maximum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TX10P_UNITS[]      = "Percent";

static const char TX90P_NAME[]       = "very_warm_days_percent_wrt_90th_percentile_of_reference_period";
static const char TX90P_LONGNAME[]   = "This is the percent of time per time period where daily maximum  temperature is above a reference value. The reference value is calculated  as the 90th percentile of daily maximum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char TX90P_UNITS[]      = "Percent";

static const char CDD_NAME[]         = "consecutive_dry_days_index_per_time_period";
173
static const char CDD_LONGNAME[]     = "Consecutive dry days is the greatest number of consecutive days per time period with daily precipitation amount  below %g mm. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
174
static const char CDD_UNITS[]        = "No.";
175
176
static const char CDD_NAME2[]        = "number_of_cdd_periods_with_more_than_%ddays_per_time_period";
static const char CDD_LONGNAME2[]    = "Number of cdd periods in given time period with more than %d days. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
177
178
179
static const char CDD_UNITS2[]       = "No.";

static const char CWD_NAME[]         = "consecutive_wet_days_index_per_time_period";
180
static const char CWD_LONGNAME[]     = "Consecutive wet days is the greatest number of consecutive days per time period with daily precipitation above %g mm. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
static const char CWD_UNITS[]        = "No.";
182
183
static const char CWD_NAME2[]        = "number_of_cwd_periods_with_more_than_%ddays_per_time_period";
static const char CWD_LONGNAME2[]    = "Number of cwd periods in given time period with more than %d days. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
185
static const char CWD_UNITS2[]       = "No.";

186
187
188
static const char PD_NAME[]          = "precipitation_days_index_per_time_period";
static const char PD_LONGNAME[]      = "precipitation days is the number of days per time period with daily precipitation sum exceeding %g mm. The time period should be defined by the bounds of the time coordinate.";
static const char PD_UNITS[]         = "No.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189

Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
191
192
193
194
195
196
static const char R10MM_NAME[]       = "heavy_precipitation_days_index_per_time_period";
static const char R10MM_LONGNAME[]   = "Heavy precipitation days is the number of days per time period with daily precipitation sum exceeding 10 mm. The time period should be defined by the bounds of the time coordinate.";
static const char R10MM_UNITS[]      = "No.";

static const char R20MM_NAME[]       = "very_heavy_precipitation_days_index_per_time_period";
static const char R20MM_LONGNAME[]   = "Very heavy precipitation days is the number of days with daily precipitation sum exceeding 20 mm. The time period should be defined by the bounds of the time coordinate.";
static const char R20MM_UNITS[]      = "No.";
197
198

static const char R75P_NAME[]        = "moderate_wet_days_wrt_75th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
200
static const char R75P_LONGNAME[]    = "This is the percent of time per time period of wet days (daily sum at least 1 mm / day) where daily precipitation amount of a wet day is above a reference value. The reference value is calculated  as the 75th percentile of all wet days of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char R75P_UNITS[]       = "Percent";
201

Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
203
204
static const char R75PTOT_NAME[]     = "precipitation_percent_due_to_R75p_days";
static const char R75PTOT_LONGNAME[] = "Percentage of  total precipitation amount per time period due to moderate_wet_days_wrt_75th_percentile_of_reference_period. The time period should be defined by the bounds of the time coordinate.";
static const char R75PTOT_UNITS[]    = "Percent";
205

Uwe Schulzweida's avatar
Uwe Schulzweida committed
206
207
208
static const char R90P_NAME[]        = "wet_days_wrt_90th_percentile_of_reference_period";
static const char R90P_LONGNAME[]    = "This is the percent of time per time period of wet days (daily sum at least 1 mm / day) where daily precipitation amount of a wet day is above a reference value. The reference value is calculated  as the 90th percentile of all wet days of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char R90P_UNITS[]       = "Percent";
209

Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
211
212
static const char R90PTOT_NAME[]     = "precipitation_percent_due_to_R90p_days";
static const char R90PTOT_LONGNAME[] = "Percentage of  total precipitation  amount per time period  due towet_days_wrt_90th_percentile_of_reference_period. The time period should be defined by the bounds of the time coordinate.";
static const char R90PTOT_UNITS[]    = "Percent";
213
214

static const char R95P_NAME[]        = "very_wet_days_wrt_95th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
216
static const char R95P_LONGNAME[]    = "This is the percent of time per time period of wet days (daily sum at least 1 mm / day) where daily precipitation amount of a wet day is above a reference value. The reference value is calculated  as the 95th percentile of all wet days of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char R95P_UNITS[]       = "Percent";
217

Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
219
220
static const char R95PTOT_NAME[]     = "precipitation_percent_due_to_R95p_days";
static const char R95PTOT_LONGNAME[] = "Percentage of  total  precipitation amount per time period  due to  very_wet_days_wrt_95th_percentile_of_reference_period. The time period should be defined by the bounds of the time coordinate.";
static const char R95PTOT_UNITS[]    = "Percent";
221
222

static const char R99P_NAME[]        = "extremely_wet_days_wrt_99th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
224
225
226
227
static const char R99P_LONGNAME[]    = "This is the percent of time per time period of wet days (daily sum at least 1 mm / day) where daily precipitation amount of a wet day is above a reference value. The reference value is calculated  as the 99th percentile of all wet days of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
static const char R99P_UNITS[]       = "Percent";

static const char R99PTOT_NAME[]     = "precipitation_percent_due_to_R99p_days";
static const char R99PTOT_LONGNAME[] = "percentage of  total  precipitation amount per time period  due to  extremely_wet_days_wrt_99th_percentile_of_reference_period. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
//static const char R99PTOT_UNITS[]    = "Percent";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230

static const char RR1_NAME[]         = "wet_days_index_per_time_period";
231
static const char RR1_LONGNAME[]     = "Wet days index is the number of days per time period with daily precipitation of at least %g mm.  The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
232
233
234
235
236
237
238
239
240
241
242
243
244
static const char RR1_UNITS[]        = "No.";

static const char RX1DAY_NAME[]      = "highest_one_day_precipitation_amount_per_time_period";
static const char RX1DAY_LONGNAME[]  = "Highest one  day precipitation  is the maximum of one day precipitation amount in a given time period. The time period should be defined by the bounds of the time coordinate.";
static const char RX1DAY_UNITS[]     = "mm per day";

static const char RX5DAY_NAME[]      = "highest_five_day_precipitation_amount_per_time_period";
static const char RX5DAY_LONGNAME[]  = "Highest precipitation amount  for five day interval (including the calendar day as the last day). The time period should be defined by the bounds of the time coordinate.";
static const char RX5DAY_UNITS[]     = "mm per 5 day";
static const char RX5DAY_NAME2[]     = "number_of_5day_heavy_precipitation_periods_per_time_period";
static const char RX5DAY_LONGNAME2[] = "Number of 5day periods in given time period with precipitation amount exceeding %1.0f mm / 5 days. The time period should be defined by the bounds of the time coordinate.";
static const char RX5DAY_UNITS2[]    = "No.";

245
static const char SDII_NAME[]        = "simple_daily_intensity_index_per_time_period";
246
static const char SDII_LONGNAME[]    = "Simple daily intensity index is the mean of precipitation amount on wet days. A wet day is a day with precipitation sum of at least %g mm. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
static const char SDII_UNITS[]       = "mm";

static const char FDNS_NAME[]        = "frost_days_where_no_snow_index_per_time_period";       
static const char FDNS_LONGNAME[]    = "Frost days where no snow index is the number of days without snowcover and where the minimum of temperature is below 0 degree Celsius. The time period should be defined by the bounds of the time coordinate.";       
static const char FDNS_UNITS[]       = "No.";

static const char STRWIN_NAME[]      = "strong_wind_days_index_per_time_period";
static const char STRWIN_LONGNAME[]  = "Strong wind days index is the number of days per time period where maximum wind speed is above %1.0f m/s. The time period should be defined by the bounds of the time coordinate.";
static const char STRWIN_UNITS[]     = "No.";
static const char STRWIN_NAME2[]     = "consecutive_strong_wind_days_index_per_time_period";
static const char STRWIN_LONGNAME2[] = "Greatest number of consecutive strong wind days per time period. The time period should be defined by the bounds of the time coordinate.";
static const char STRWIN_UNITS2[]    = "No.";

static const char STRBRE_NAME[]      = "strong_breeze_days_index_per_time_period";
static const char STRBRE_LONGNAME[]  = "Strong breeze days index is the number of days per time period where maximum wind speed is above 10.5 m/s. The time period should be defined by the bounds of the time coordinate.";
static const char STRBRE_NAME2[]     = "consecutive_strong_breeze_days_index_per_time_period";
static const char STRBRE_LONGNAME2[] = "Greatest number of consecutive strong breeze days per time period. The time period should be defined by the bounds of the time coordinate.";

Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
266
267
268
//static const char STRGAL_NAME[]      = "strong_gale_days_index_per_time_period";
//static const char STRGAL_LONGNAME[]  = "Strong gale days index is the number of days per time period where maximum wind speed is above 20.5 m/s. The time period should be defined by the bounds of the time coordinate.";
//static const char STRGAL_NAME2[]     = "consecutive_strong_gale_days_index_per_time_period";
//static const char STRGAL_LONGNAME2[] = "Greatest number of consecutive strong gale days per time period. The time period should be defined by the bounds of the time coordinate.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
269
270
271
272
273

static const char HURR_NAME[]        = "hurricane_days_index_per_time_period";
static const char HURR_LONGNAME[]    = "Hurricane days index is the number of days per time period where maximum wind speed is above 32.5 m/s. The time period should be defined by the bounds of the time coordinate.";
static const char HURR_NAME2[]       = "consecutive_hurricane_days_index_per_time_period";
static const char HURR_LONGNAME2[]   = "Greatest number of consecutive hurricane days per time period. The time period should be defined by the bounds of the time coordinate.";
274
275
276
277

/* ECA temperature indices */


278
void *EcaCfd(void *process)
279
280
{
  ECA_REQUEST_1 request;
281
282
283
  int ndays = 5;
  char cfd_longname2[1024];
  char cfd_name2[1024];
284
  
285
  cdoInitialize(process);
286
  cdoOperatorAdd("eca_cfd", 0, 31, NULL);
287
  
288
289
290
291
292
293
294
295
296
  if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
  else if ( operatorArgc() > 0 ) 
    {
      ndays = parameter2int(operatorArgv()[0]);
    }

  sprintf(cfd_longname2, CFD_LONGNAME2, ndays);
  sprintf(cfd_name2,     CFD_NAME2, ndays);

297
298
299
300
301
302
303
304
305
306
  request.var1.name     = CFD_NAME;
  request.var1.longname = CFD_LONGNAME;
  request.var1.units    = NULL;
  request.var1.f1       = farselltc;
  request.var1.f1arg    = TO_KELVIN(0.0);
  request.var1.f2       = farnum2;
  request.var1.f3       = farmax;
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
  request.var1.epilog   = NONE;
307
308
  request.var2.name     = cfd_name2;
  request.var2.longname = cfd_longname2;
309
310
  request.var2.units    = CFD_UNITS2;
  request.var2.h1       = farseleqc;
311
  request.var2.h1arg    = ndays+1;
312
  request.var2.h2       = NULL;
313
  request.var2.h3       = farnum;
314
315
316
317
   
  eca1(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
  return 0;
319
320
321
}


322
void *EcaCsu(void *process)
323
324
{
  ECA_REQUEST_1 request;
325
326
327
328
  double argT = 25.0;
  int ndays = 5;
  char csu_longname2[1024];
  char csu_name2[1024];
329
  
330
  cdoInitialize(process);
331
  cdoOperatorAdd("eca_csu", 0, 31, NULL);
332

333
334
335
336
337
338
339
340
341
  if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
  else if ( operatorArgc() > 0 ) 
    {
      argT = parameter2double(operatorArgv()[0]);
      if ( operatorArgc() == 2 ) ndays = parameter2int(operatorArgv()[1]);
    }
  
  sprintf(csu_longname2, CSU_LONGNAME2, ndays);
  sprintf(csu_name2,     CSU_NAME2, ndays);
342
343

  request.var1.name     = CSU_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
344
  request.var1.longname = CSU_LONGNAME;
345
346
347
348
349
350
351
352
  request.var1.units    = NULL;
  request.var1.f1       = farselgtc;
  request.var1.f1arg    = TO_KELVIN(argT);
  request.var1.f2       = farnum2;
  request.var1.f3       = farmax;
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
  request.var1.epilog   = NONE;
353
354
  request.var2.name     = csu_name2;
  request.var2.longname = csu_longname2;
355
356
  request.var2.units    = CSU_UNITS2;
  request.var2.h1       = farseleqc;
357
  request.var2.h1arg    = ndays+1;
358
  request.var2.h2       = NULL;
359
  request.var2.h3       = farnum;
360
361
  
  eca1(&request);
362
  
363
364
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
  return 0;
366
367
368
}


369
void *EcaCwdi(void *process)
370
371
372
373
374
375
{
  char *longname;
  int argN = 6;
  double argT = 5.0;
  ECA_REQUEST_2 request;
  
376
  cdoInitialize(process);
377
  cdoOperatorAdd("eca_cwdi", 0, 31, NULL);
378

379
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
380
  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
381
  
382
  longname = (char*) Malloc(strlen(CWDI_LONGNAME) + 80);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
  sprintf(longname, CWDI_LONGNAME, argN, argT);
384
385
386

  request.var1.name     = CWDI_NAME;
  request.var1.longname = longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
  request.var1.units    = CWDI_UNITS;
388
389
390
391
392
393
394
395
396
397
  request.var1.f1       = NULL;
  request.var1.f2       = farcsub;
  request.var1.f2arg    = argT;
  request.var1.f3       = farsellt;
  request.var1.f4       = farnum2;
  request.var1.f5       = farnum3;
  request.var1.f5arg    = argN;
  request.var1.epilog   = NONE;
  request.var2.name     = CWDI_NAME2;
  request.var2.longname = CWDI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
  request.var2.units    = CWDI_UNITS2;
399
400
401
402
403
404
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
  
405
  Free(longname);
406
407
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
  return 0;
409
410
411
}


412
void *EcaCwfi(void *process)
413
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
  char *longname;
415
416
417
  int argN = 6;
  ECA_REQUEST_2 request;
  
418
  cdoInitialize(process);
419
  cdoOperatorAdd("eca_cwfi", 0, 31, NULL);
420

421
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
422

423
  longname = (char*) Malloc(strlen(CWFI_LONGNAME) + 40);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
425
  sprintf(longname, CWFI_LONGNAME, argN);

426
  request.var1.name     = CWFI_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427
428
  request.var1.longname = longname;
  request.var1.units    = CWFI_UNITS;
429
430
431
432
433
434
435
436
437
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farsellt;
  request.var1.f4       = farnum2;
  request.var1.f5       = farnum3;
  request.var1.f5arg    = argN;
  request.var1.epilog   = NONE;
  request.var2.name     = CWFI_NAME2;
  request.var2.longname = CWFI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
  request.var2.units    = CWFI_UNITS2;
439
440
441
442
443
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
444
  
445
  Free(longname);
446
447
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
  return 0;
449
450
451
}


452
void *EcaEtr(void *process)
453
454
455
{
  ECA_REQUEST_3 request;
  
456
  cdoInitialize(process);
457
  cdoOperatorAdd("eca_etr", 0, 31, NULL);
458
459
460
461
462
463
464
465
466
467
468
  
  request.name     = ETR_NAME;
  request.longname = ETR_LONGNAME;
  request.units    = NULL;
  request.f1       = farmax; 
  request.f2       = farmin;
  request.f3       = farsub;
   
  eca3(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
  return 0;
470
471
472
}


473
void *EcaFd(void *process)
474
475
476
{
  ECA_REQUEST_1 request;
  
477
  cdoInitialize(process);
478
  cdoOperatorAdd("eca_fd", 0, 31, NULL);
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  
  request.var1.name     = FD_NAME;
  request.var1.longname = FD_LONGNAME;
  request.var1.units    = NULL;
  request.var1.f1       = farselltc; 
  request.var1.f1arg    = TO_KELVIN(0.0);
  request.var1.f2       = farnum;
  request.var1.f3       = NULL;
  request.var1.mulc     = 0.0;    
  request.var1.addc     = 0.0;
  request.var1.epilog   = NONE;    
  request.var2.h2       = NULL; 
  request.var2.h3       = NULL; 
   
  eca1(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
  return 0;
497
498
499
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
500
/*
501
502
503
504
 * Definition of GSL: (Thermal) Growing Season Length start at the first span
 * of at least 6 (argN) days with T > 5.0°C (argT) in first half of the year
 * and ends at the first span of ar least 6 (argN) days with T < 5.0°C (argT)
 * in the second half.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
506
 * ATTENTION: Year of the northern hemisphere starts in january to
 * december, whereas for the southern hemisphere is goes from july to june!
507
508
 * Hence, at least 18 Month of data is needed for computing the gsl of the
 * whole earth.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
*/
510
void *EcaGsl(void *process)
511
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
  int argN = 6; 
513
  double argT = 5.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
  double minLandFraction = 0.5;
515
516
  ECA_REQUEST_4 request;
  
517
  cdoInitialize(process);
518
  cdoOperatorAdd("eca_gsl", 0, 10, NULL);
519
  
520
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
521
522
  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
  if ( operatorArgc() > 2 ) minLandFraction = parameter2double(operatorArgv()[2]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523

524
  char *longname = (char*) Malloc(strlen(GSL_LONGNAME) + 160);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
  sprintf(longname, GSL_LONGNAME, argN, argT, argN, argT);
526
527
  
  request.name      = GSL_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
529
  request.longname  = longname;
  request.units     = GSL_UNITS;
530
531
  request.name2     = GSL_NAME2;
  request.longname2 = GSL_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
532
  request.units2    = GSL_UNITS2;
533
534
535
536
  request.s1        = farselgtc; 
  request.s1arg     = TO_KELVIN(argT);
  request.s2        = farselltc;
  request.s2arg     = TO_KELVIN(argT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537
538
  request.s3        = farselgec;
  request.s3arg     = minLandFraction;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
  request.consecutiveDays = argN;    
540
541
   
  eca4(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
  
543
  Free(longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544

545
546
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
547
  return 0;
548
549
550
}


551
void *EcaHd(void *process)
552
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553
554
  double argX = 17.0;
  double argA = 17.0;
555
556
  ECA_REQUEST_1 request;
  
557
  cdoInitialize(process);
558
  cdoOperatorAdd("eca_hd", 0, 31, NULL);
559
560
561

  if ( operatorArgc() > 0 ) 
    {
562
      argX = parameter2double(operatorArgv()[0]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
563
      argA = argX;
564
565
    }
  if ( operatorArgc() > 1 ) 
566
    argA = parameter2double(operatorArgv()[1]);
567
568
569
  
  request.var1.name     = HD_NAME;
  request.var1.longname = HD_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
  request.var1.units    = HD_UNITS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
571
  request.var1.f1       = farselltc; 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
  request.var1.f1arg    = TO_KELVIN(argA);
573
574
575
  request.var1.f2       = farsum;
  request.var1.f3       = NULL;
  request.var1.mulc     = -1.0;    
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
  request.var1.addc     = TO_KELVIN(argX);
577
578
579
580
581
  request.var1.epilog   = NONE;    
  request.var2.h2       = NULL; 
  request.var2.h3       = NULL; 
   
  eca1(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
582

583
584
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
  return 0;
586
587
588
}


589
void *EcaHwdi(void *process)
590
591
592
593
594
595
{
  char *longname;
  int argN = 6;
  double argT = 5.0;
  ECA_REQUEST_2 request;
  
596
  cdoInitialize(process);
597
  cdoOperatorAdd("eca_hwdi", 0, 31, NULL);
598

599
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
600
  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
601
  
602
  longname = (char*) Malloc(strlen(HWDI_LONGNAME) + 80);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
  sprintf(longname, HWDI_LONGNAME, argN, argT);
604
605
606
  
  request.var1.name     = HWDI_NAME;
  request.var1.longname = longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
  request.var1.units    = HWDI_UNITS;
608
609
610
611
612
613
614
615
616
617
  request.var1.f1       = NULL;
  request.var1.f2       = farcadd;
  request.var1.f2arg    = argT;
  request.var1.f3       = farselgt;
  request.var1.f4       = farnum2;
  request.var1.f5       = farnum3;
  request.var1.f5arg    = argN;
  request.var1.epilog   = NONE;
  request.var2.name     = HWDI_NAME2;
  request.var2.longname = HWDI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
618
  request.var2.units    = HWDI_UNITS2;
619
620
621
622
623
624
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
  
625
  Free(longname);
626
627
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
  return 0;
629
630
631
}


632
void *EcaHwfi(void *process)
633
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
  char *longname;
635
636
637
  int argN = 6;
  ECA_REQUEST_2 request;
  
638
  cdoInitialize(process);
639
  cdoOperatorAdd("eca_hwfi", 0, 31, NULL);
640

641
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
642

643
  longname = (char*) Malloc(strlen(HWFI_LONGNAME) + 40);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
  sprintf(longname, HWFI_LONGNAME, argN);

646
  request.var1.name     = HWFI_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
647
648
  request.var1.longname = longname;
  request.var1.units    = HWFI_UNITS;
649
650
651
652
653
654
655
656
657
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farselgt;
  request.var1.f4       = farnum2;
  request.var1.f5       = farnum3;
  request.var1.f5arg    = argN;
  request.var1.epilog   = NONE;
  request.var2.name     = HWFI_NAME2;
  request.var2.longname = HWFI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
  request.var2.units    = HWFI_UNITS2;
659
660
661
662
663
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
  
665
  Free(longname);
666
667
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
  return 0;
669
670
671
}


672
void *EcaId(void *process)
673
674
675
{
  ECA_REQUEST_1 request;
  
676
  cdoInitialize(process);
677
  cdoOperatorAdd("eca_id", 0, 31, NULL);
678
679
680

  request.var1.name     = ID_NAME;
  request.var1.longname = ID_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
  request.var1.units    = ID_UNITS;
682
683
684
685
686
687
688
689
690
691
692
693
694
  request.var1.f1       = farselltc;
  request.var1.f1arg    = TO_KELVIN(0.0);
  request.var1.f2       = farnum;
  request.var1.f3       = NULL;
  request.var1.mulc     = 0.0;    
  request.var1.addc     = 0.0;   
  request.var1.epilog   = NONE; 
  request.var2.h2       = NULL; 
  request.var2.h3       = NULL; 
    
  eca1(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
  return 0;
696
697
698
}


699
void *EcaSu(void *process)
700
701
702
703
704
{
  char *longname;
  double argT = 25.0;
  ECA_REQUEST_1 request;
  
705
  cdoInitialize(process);
706
  cdoOperatorAdd("eca_su", 0, 31, NULL);
707

708
  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
709
  longname = (char*) Malloc(strlen(SU_LONGNAME) + 40);
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
  sprintf(longname, SU_LONGNAME, argT);

  request.var1.name     = SU_NAME;
  request.var1.longname = longname;
  request.var1.units    = NULL;
  request.var1.f1       = farselgtc;
  request.var1.f1arg    = TO_KELVIN(argT);
  request.var1.f2       = farnum;
  request.var1.f3       = NULL;
  request.var1.mulc     = 0.0;    
  request.var1.addc     = 0.0;    
  request.var1.epilog   = NONE; 
  request.var2.h2       = NULL; 
  request.var2.h3       = NULL; 
 
  eca1(&request);
  
727
  Free(longname);
728
729
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
  return 0;
731
732
733
}


734
void *EcaTg10p(void *process)
735
736
737
{
  ECA_REQUEST_2 request;
  
738
  cdoInitialize(process);
739
  cdoOperatorAdd("eca_tg10p", 0, 31, NULL);
740
741
742

  request.var1.name     = TG10P_NAME;
  request.var1.longname = TG10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
743
  request.var1.units    = TG10P_UNITS;
744
745
746
747
748
749
750
751
752
753
754
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farsellt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
    
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
  return 0;
756
757
758
}


759
void *EcaTg90p(void *process)
760
761
762
{
  ECA_REQUEST_2 request;
  
763
  cdoInitialize(process);
764
  cdoOperatorAdd("eca_tg90p", 0, 31, NULL);
765
766
767

  request.var1.name     = TG90P_NAME;
  request.var1.longname = TG90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
  request.var1.units    = TG90P_UNITS;
769
770
771
772
773
774
775
776
777
778
779
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farselgt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
  
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
  return 0;
781
782
783
}


784
void *EcaTn10p(void *process)
785
786
787
{
  ECA_REQUEST_2 request;
  
788
  cdoInitialize(process);
789
  cdoOperatorAdd("eca_tn10p", 0, 31, NULL);
790
791
792

  request.var1.name     = TN10P_NAME;
  request.var1.longname = TN10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
  request.var1.units    = TN10P_UNITS;
794
795
796
797
798
799
800
801
802
803
804
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farsellt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
    
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
  return 0;
806
807
808
}


809
void *EcaTn90p(void *process)
810
811
812
{
  ECA_REQUEST_2 request;
  
813
  cdoInitialize(process);
814
  cdoOperatorAdd("eca_tn90p", 0, 31, NULL);
815
816
817

  request.var1.name     = TN90P_NAME;
  request.var1.longname = TN90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
  request.var1.units    = TN90P_UNITS;
819
820
821
822
823
824
825
826
827
828
829
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farselgt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
    
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
  return 0;
831
832
833
}


834
void *EcaTr(void *process)
835
836
{
  ECA_REQUEST_1 request;
837
838
  double argT = 20.0;
  char tr_longname[1024];
839
  
840
  cdoInitialize(process);
841
  cdoOperatorAdd("eca_tr", 0, 31, NULL);
842

843
  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
844
845

  sprintf(tr_longname, TR_LONGNAME, argT);
846
847
 
  request.var1.name     = TR_NAME;
848
  request.var1.longname = tr_longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
  request.var1.units    = TR_UNITS;
850
851
852
853
854
855
856
857
858
859
860
861
862
863
  request.var1.f1       = farselgtc;
  request.var1.f1arg    = TO_KELVIN(argT);
  request.var1.f2       = farnum;
  request.var1.f3       = NULL;
  request.var1.mulc     = 0.0;    
  request.var1.addc     = 0.0;    
  request.var1.epilog   = NONE; 
  request.var2.h2       = NULL; 
  request.var2.h3       = NULL; 
   
  eca1(&request);
  
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
  return 0;
865
866
867
}


868
void *EcaTx10p(void *process)
869
870
871
{
  ECA_REQUEST_2 request;
  
872
  cdoInitialize(process);
873
  cdoOperatorAdd("eca_tx10p", 0, 31, NULL);
874
875
876

  request.var1.name     = TX10P_NAME;
  request.var1.longname = TX10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
  request.var1.units    = TX10P_UNITS;
878
879
880
881
882
883
884
885
886
887
888
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farsellt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
    
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
  return 0;
890
891
892
}


893
void *EcaTx90p(void *process)
894
895
896
{
  ECA_REQUEST_2 request;
  
897
  cdoInitialize(process);
898
  cdoOperatorAdd("eca_tx90p", 0, 31, NULL);
899
900
901
 
  request.var1.name     = TX90P_NAME;
  request.var1.longname = TX90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
902
  request.var1.units    = TX90P_UNITS;
903
904
905
906
907
908
909
910
911
912
913
  request.var1.f1       = NULL;
  request.var1.f2       = NULL;
  request.var1.f3       = farselgt;
  request.var1.f4       = farnum;
  request.var1.f5       = NULL;
  request.var1.epilog   = PERCENT_OF_TIME;
  request.var2.h2       = NULL;
   
  eca2(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
  return 0;
915
916
917
918
919
920
}


/* ECA precipitation indices */


921
void *EcaCdd(void *process)
922
923
{
  ECA_REQUEST_1 request;
924
  double threshold = 1;
925
926
927
928
  int ndays = 5;
  char cdd_longname[1024];
  char cdd_longname2[1024];
  char cdd_name2[1024];
929
  
930
  cdoInitialize(process);
931
  cdoOperatorAdd("eca_cdd", 0, 31, NULL);
932

933
934
935
936
937
938
939
940
941
942
  if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
  else if ( operatorArgc() > 0 ) 
    {
      threshold = parameter2double(operatorArgv()[0]);
      if ( operatorArgc() == 2 ) ndays = parameter2int(operatorArgv()[1]);
    }
  
  sprintf(cdd_longname,  CDD_LONGNAME, threshold);
  sprintf(cdd_longname2, CDD_LONGNAME2, ndays);
  sprintf(cdd_name2,     CDD_NAME2, ndays);
943

944
  request.var1.name     = CDD_NAME;
945
  request.var1.longname = cdd_longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
  request.var1.units    = CDD_UNITS;
947
  request.var1.f1       = farselltc;
948
  request.var1.f1arg    = threshold;
949
950
951
952
953
  request.var1.f2       = farnum2;
  request.var1.f3       = farmax;
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
  request.var1.epilog   = NONE;
954
955
  request.var2.name     = cdd_name2;
  request.var2.longname = cdd_longname2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
956
  request.var2.units    = CDD_UNITS2;
957
  request.var2.h1       = farseleqc;
958
  request.var2.h1arg    = ndays+1;
959
960
961
962
  request.var2.h2       = NULL;
  request.var2.h3       = farnum;
   
  eca1(&request);
963
  
964
965
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
966
  return 0;
967
968
969
}


970
void *EcaCwd(void *process)
971
972
{
  ECA_REQUEST_1 request;
973
  double threshold = 1;
974
975
976
977
  int ndays = 5;
  char cwd_longname[1024];
  char cwd_longname2[1024];
  char cwd_name2[1024];
978
  
979
  cdoInitialize(process);
980
  cdoOperatorAdd("eca_cwd", 0, 31, NULL);
981

982
983
984
985
986
987
988
989
990
991
  if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
  else if ( operatorArgc() > 0 ) 
    {
      threshold = parameter2double(operatorArgv()[0]);
      if ( operatorArgc() == 2 ) ndays = parameter2int(operatorArgv()[1]);
    }
  
  sprintf(cwd_longname,  CWD_LONGNAME, threshold);
  sprintf(cwd_longname2, CWD_LONGNAME2, ndays);
  sprintf(cwd_name2,     CWD_NAME2, ndays);
992

993
  request.var1.name     = CWD_NAME;
994
  request.var1.longname = cwd_longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
  request.var1.units    = CWD_UNITS;
996
  request.var1.f1       = farselgec;
997
  request.var1.f1arg    = threshold;
998
999
1000
1001
1002
  request.var1.f2       = farnum2;
  request.var1.f3       = farmax;
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
  request.var1.epilog   = NONE;
1003
1004
  request.var2.name     = cwd_name2;
  request.var2.longname = cwd_longname2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
  request.var2.units    = CWD_UNITS2;
1006
  request.var2.h1       = farseleqc;
1007
  request.var2.h1arg    = ndays+1;
1008
1009
1010
1011
  request.var2.h2       = NULL;
  request.var2.h3       = farnum;
   
  eca1(&request);
1012
  
1013
1014
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1015
  return 0;
1016
1017
1018
}


1019
void *EcaPd(void *process)
1020
{
1021
  int ECA_PD, ECA_R10MM, ECA_R20MM;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1022
  int operatorID;
1023
1024
  char lnamebuffer[1024];
  double threshold = 0;
1025
1026
  ECA_REQUEST_1 request;
  
1027
  cdoInitialize(process);
1028

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1029
  // clang-format off
1030
1031
1032
  ECA_PD      = cdoOperatorAdd("eca_pd",      0, 31, NULL);
  ECA_R10MM   = cdoOperatorAdd("eca_r10mm",   0, 31, NULL);
  ECA_R20MM   = cdoOperatorAdd("eca_r20mm",   0, 31, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1033
  // clang-format on
1034

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1035
1036
  operatorID = cdoOperatorID();

1037
  if ( operatorID == ECA_PD )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1038
    {
1039
      operatorInputArg("daily precipitation amount threshold in [mm]");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1040

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1041
      if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1042
1043
      if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");

1044
      threshold = parameter2double(operatorArgv()[0]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1045

1046
      if ( threshold < 0 ) cdoAbort("Parameter out of range: threshold = %g", threshold);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1047

1048
1049
1050
1051
      sprintf(lnamebuffer, PD_LONGNAME, threshold);
      request.var1.name     = PD_NAME;
      request.var1.longname = lnamebuffer;
      request.var1.units    = PD_UNITS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1052
1053
1054
    }
  else if ( operatorID == ECA_R10MM )
    {
1055
      threshold = 10;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056
1057
1058
1059
1060
1061
1062

      request.var1.name     = R10MM_NAME;
      request.var1.longname = R10MM_LONGNAME;
      request.var1.units    = R10MM_UNITS;
    }
  else if ( operatorID == ECA_R20MM )
    {
1063
      threshold = 20;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1064
1065
1066
1067
1068

      request.var1.name     = R20MM_NAME;
      request.var1.longname = R20MM_LONGNAME;
      request.var1.units    = R20MM_UNITS;
    }
1069
  
1070
  if ( cdoVerbose ) cdoPrint("threshold = %g", threshold);
1071
1072

  request.var1.f1       = farselgec;
1073
  request.var1.f1arg    = threshold;
1074
1075
1076