EcaIndices.cc 56.3 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
  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
20

21
      EcaCfd      eca_cfd      CFD      maximum number of consecutive frost days
22
23
24
25
26
      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
27
28
29
30
31
      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
32
33
34
35
36
37
38
39
40
      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
41
42
43

      EcaCdd      eca_cdd      CDD      maximum number of consecutive dry days
      EcaCwd      eca_cwd      CWD      maximum number of consecutive wet days
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
      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

      Fdns        fdns                  frost days without surface snow
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
      Strwin      strwin                number of strong-wind days
65
66
67
      Strbre      strbre                number of strong-breeze days
      Strgal      strgal                number of strong-gale days
      Hurr        hurr                  number of hurricane days
68
69
70
*/

#include "cdo_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
#include "ecacore.h"
72
73
#include "ecautil.h"

74
#define TO_DEG_CELSIUS(x) ((x) -273.15)
75
76
#define TO_KELVIN(x) ((x) + 273.15)

Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
// clang-format off
78

Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
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
81
//static const char CFD_UNITS[]        = "No.";
82
83
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.";
84
static const char CFD_UNITS2[]       = "No.";
85

Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
87
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
88
//static const char CSU_UNITS[]        = "No.";
89
90
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.";
91
static const char CSU_UNITS2[]       = "No.";
92

Uwe Schulzweida's avatar
Uwe Schulzweida committed
93
94
95
96
97
98
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.";
99

Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
102
103
104
105
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.";
106
107

static const char ETR_NAME[]         = "intra_period_extreme_temperature_range";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
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
109
//static const char ETR_UNITS[]        = "K";
110

Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
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
113
//static const char FD_UNITS[]         = "No.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114

115
static const char GSL_NAME[]         = "thermal_growing_season_length";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
142
143
144
145
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
146
//static const char SU_UNITS[]         = "No.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
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
173
174
175
176

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";
177
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
178
static const char CDD_UNITS[]        = "No.";
179
180
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
181
182
183
static const char CDD_UNITS2[]       = "No.";

static const char CWD_NAME[]         = "consecutive_wet_days_index_per_time_period";
184
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
185
static const char CWD_UNITS[]        = "No.";
186
187
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
188
189
static const char CWD_UNITS2[]       = "No.";

190
191
192
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
193

Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
195
196
197
198
199
200
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.";
201
202

static const char R75P_NAME[]        = "moderate_wet_days_wrt_75th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
204
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";
205

Uwe Schulzweida's avatar
Uwe Schulzweida committed
206
207
208
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";
209

Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
211
212
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";
213

Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
215
216
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";
217
218

static const char R95P_NAME[]        = "very_wet_days_wrt_95th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
220
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";
221

Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
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";
225
226

static const char R99P_NAME[]        = "extremely_wet_days_wrt_99th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
228
229
230
231
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
232
//static const char R99PTOT_UNITS[]    = "Percent";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233
234

static const char RR1_NAME[]         = "wet_days_index_per_time_period";
235
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
236
237
238
239
240
241
242
243
244
245
246
247
248
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.";

249
static const char SDII_NAME[]        = "simple_daily_intensity_index_per_time_period";
250
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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
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
269
270
271
272
//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
273
274
275
276
277

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.";
278
279
280
281

/* ECA temperature indices */


282
void *EcaCfd(void *process)
283
284
{
  ECA_REQUEST_1 request;
285
286
287
  int ndays = 5;
  char cfd_longname2[1024];
  char cfd_name2[1024];
288
  
289
  cdoInitialize(process);
290
  cdoOperatorAdd("eca_cfd", 0, 31, NULL);
291
  
292
293
294
295
296
297
298
299
300
  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);

301
302
303
304
305
306
307
308
309
310
  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;
311
312
  request.var2.name     = cfd_name2;
  request.var2.longname = cfd_longname2;
313
314
  request.var2.units    = CFD_UNITS2;
  request.var2.h1       = farseleqc;
315
  request.var2.h1arg    = ndays+1;
316
  request.var2.h2       = NULL;
317
  request.var2.h3       = farnum;
318
319
320
321
   
  eca1(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
  return 0;
323
324
325
}


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

337
338
339
340
341
342
343
344
345
  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);
346
347

  request.var1.name     = CSU_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
  request.var1.longname = CSU_LONGNAME;
349
350
351
352
353
354
355
356
  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;
357
358
  request.var2.name     = csu_name2;
  request.var2.longname = csu_longname2;
359
360
  request.var2.units    = CSU_UNITS2;
  request.var2.h1       = farseleqc;
361
  request.var2.h1arg    = ndays+1;
362
  request.var2.h2       = NULL;
363
  request.var2.h3       = farnum;
364
365
  
  eca1(&request);
366
  
367
368
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
  return 0;
370
371
372
}


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

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

  request.var1.name     = CWDI_NAME;
  request.var1.longname = longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
  request.var1.units    = CWDI_UNITS;
392
393
394
395
396
397
398
399
400
401
  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
402
  request.var2.units    = CWDI_UNITS2;
403
404
405
406
407
408
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
  
409
  Free(longname);
410
411
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412
  return 0;
413
414
415
}


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

425
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
426

427
  longname = (char*) Malloc(strlen(CWFI_LONGNAME) + 40);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
428
429
  sprintf(longname, CWFI_LONGNAME, argN);

430
  request.var1.name     = CWFI_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
432
  request.var1.longname = longname;
  request.var1.units    = CWFI_UNITS;
433
434
435
436
437
438
439
440
441
  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
442
  request.var2.units    = CWFI_UNITS2;
443
444
445
446
447
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448
  
449
  Free(longname);
450
451
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
452
  return 0;
453
454
455
}


456
void *EcaEtr(void *process)
457
458
459
{
  ECA_REQUEST_3 request;
  
460
  cdoInitialize(process);
461
  cdoOperatorAdd("eca_etr", 0, 31, NULL);
462
463
464
465
466
467
468
469
470
471
472
  
  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
473
  return 0;
474
475
476
}


477
void *EcaFd(void *process)
478
479
480
{
  ECA_REQUEST_1 request;
  
481
  cdoInitialize(process);
482
  cdoOperatorAdd("eca_fd", 0, 31, NULL);
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
  
  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
500
  return 0;
501
502
503
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
/*
505
506
507
508
 * 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
509
510
 * ATTENTION: Year of the northern hemisphere starts in january to
 * december, whereas for the southern hemisphere is goes from july to june!
511
512
 * Hence, at least 18 Month of data is needed for computing the gsl of the
 * whole earth.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
*/
514
void *EcaGsl(void *process)
515
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
  int argN = 6; 
517
  double argT = 5.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
  double minLandFraction = 0.5;
519
520
  ECA_REQUEST_4 request;
  
521
  cdoInitialize(process);
522
  cdoOperatorAdd("eca_gsl", 0, 10, NULL);
523
  
524
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
525
526
  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
  if ( operatorArgc() > 2 ) minLandFraction = parameter2double(operatorArgv()[2]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527

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

549
550
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
  return 0;
552
553
554
}


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

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

587
588
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
  return 0;
590
591
592
}


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

603
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
604
  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
605
  
606
  longname = (char*) Malloc(strlen(HWDI_LONGNAME) + 80);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
  sprintf(longname, HWDI_LONGNAME, argN, argT);
608
609
610
  
  request.var1.name     = HWDI_NAME;
  request.var1.longname = longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
  request.var1.units    = HWDI_UNITS;
612
613
614
615
616
617
618
619
620
621
  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
622
  request.var2.units    = HWDI_UNITS2;
623
624
625
626
627
628
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
  
629
  Free(longname);
630
631
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
  return 0;
633
634
635
}


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

645
  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
646

647
  longname = (char*) Malloc(strlen(HWFI_LONGNAME) + 40);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649
  sprintf(longname, HWFI_LONGNAME, argN);

650
  request.var1.name     = HWFI_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
652
  request.var1.longname = longname;
  request.var1.units    = HWFI_UNITS;
653
654
655
656
657
658
659
660
661
  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
662
  request.var2.units    = HWFI_UNITS2;
663
664
665
666
667
  request.var2.h1       = farseleqc;
  request.var2.h1arg    = argN;
  request.var2.h2       = farnum;
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
  
669
  Free(longname);
670
671
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672
  return 0;
673
674
675
}


676
void *EcaId(void *process)
677
678
679
{
  ECA_REQUEST_1 request;
  
680
  cdoInitialize(process);
681
  cdoOperatorAdd("eca_id", 0, 31, NULL);
682
683
684

  request.var1.name     = ID_NAME;
  request.var1.longname = ID_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
  request.var1.units    = ID_UNITS;
686
687
688
689
690
691
692
693
694
695
696
697
698
  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
699
  return 0;
700
701
702
}


703
void *EcaSu(void *process)
704
705
706
707
708
{
  char *longname;
  double argT = 25.0;
  ECA_REQUEST_1 request;
  
709
  cdoInitialize(process);
710
  cdoOperatorAdd("eca_su", 0, 31, NULL);
711

712
  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
713
  longname = (char*) Malloc(strlen(SU_LONGNAME) + 40);
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  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);
  
731
  Free(longname);
732
733
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
  return 0;
735
736
737
}


738
void *EcaTg10p(void *process)
739
740
741
{
  ECA_REQUEST_2 request;
  
742
  cdoInitialize(process);
743
  cdoOperatorAdd("eca_tg10p", 0, 31, NULL);
744
745
746

  request.var1.name     = TG10P_NAME;
  request.var1.longname = TG10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
  request.var1.units    = TG10P_UNITS;
748
749
750
751
752
753
754
755
756
757
758
  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
759
  return 0;
760
761
762
}


763
void *EcaTg90p(void *process)
764
765
766
{
  ECA_REQUEST_2 request;
  
767
  cdoInitialize(process);
768
  cdoOperatorAdd("eca_tg90p", 0, 31, NULL);
769
770
771

  request.var1.name     = TG90P_NAME;
  request.var1.longname = TG90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
  request.var1.units    = TG90P_UNITS;
773
774
775
776
777
778
779
780
781
782
783
  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
784
  return 0;
785
786
787
}


788
void *EcaTn10p(void *process)
789
790
791
{
  ECA_REQUEST_2 request;
  
792
  cdoInitialize(process);
793
  cdoOperatorAdd("eca_tn10p", 0, 31, NULL);
794
795
796

  request.var1.name     = TN10P_NAME;
  request.var1.longname = TN10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
  request.var1.units    = TN10P_UNITS;
798
799
800
801
802
803
804
805
806
807
808
  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
809
  return 0;
810
811
812
}


813
void *EcaTn90p(void *process)
814
815
816
{
  ECA_REQUEST_2 request;
  
817
  cdoInitialize(process);
818
  cdoOperatorAdd("eca_tn90p", 0, 31, NULL);
819
820
821

  request.var1.name     = TN90P_NAME;
  request.var1.longname = TN90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
  request.var1.units    = TN90P_UNITS;
823
824
825
826
827
828
829
830
831
832
833
  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
834
  return 0;
835
836
837
}


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

847
  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
848
849

  sprintf(tr_longname, TR_LONGNAME, argT);
850
851
 
  request.var1.name     = TR_NAME;
852
  request.var1.longname = tr_longname;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
  request.var1.units    = TR_UNITS;
854
855
856
857
858
859
860
861
862
863
864
865
866
867
  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
868
  return 0;
869
870
871
}


872
void *EcaTx10p(void *process)
873
874
875
{
  ECA_REQUEST_2 request;
  
876
  cdoInitialize(process);
877
  cdoOperatorAdd("eca_tx10p", 0, 31, NULL);
878
879
880

  request.var1.name     = TX10P_NAME;
  request.var1.longname = TX10P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
  request.var1.units    = TX10P_UNITS;
882
883
884
885
886
887
888
889
890
891
892
  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
893
  return 0;
894
895
896
}


897
void *EcaTx90p(void *process)
898
899
900
{
  ECA_REQUEST_2 request;
  
901
  cdoInitialize(process);
902
  cdoOperatorAdd("eca_tx90p", 0, 31, NULL);
903
904
905
 
  request.var1.name     = TX90P_NAME;
  request.var1.longname = TX90P_LONGNAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
906
  request.var1.units    = TX90P_UNITS;
907
908
909
910
911
912
913
914
915
916
917
  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
918
  return 0;
919
920
921
922
923
924
}


/* ECA precipitation indices */


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

937
938
939
940
941
942
943
944
945
946
  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);
947

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


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

986
987
988
989
990
991
992
993
994
995
  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);
996

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1033
  // clang-format off
1034
1035
1036
  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
1037
  // clang-format on
1038

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1039
1040
  operatorID = cdoOperatorID();

1041
  if (operatorID == ECA_PD)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1042
    {
1043
      operatorInputArg("daily precipitation amount threshold in [mm]");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1044

1045
1046
      if (operatorArgc() < 1) cdoAbort("Too few arguments!");
      if (operatorArgc() > 1) cdoAbort("Too many arguments!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1047

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

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

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