EcaIndices.cc 69.7 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
  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.
*/

18
// clang-format off
19
20
/*
      MODULE      OPERATOR     INDEX    DESCRIPTION
21

22
      EcaCfd      eca_cfd      CFD      maximum number of consecutive frost days
23
24
25
26
27
28
      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
29
30
31
32
33
      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
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
      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 with 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 with 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 with 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 with RR > 99th percentile of daily precipitation amount
      EcaRr1      eca_rr1      RR1      number of wet days
      EcaSdii     eca_sdii     SDII     simple daily intensity index
56
57

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

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

66
#include "process_int.h"
Oliver Heidmann's avatar
Oliver Heidmann committed
67
#include "cdo_options.h"
68
#include "param_conversion.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
#include "ecacore.h"
70
#include "ecautil.h"
71
#include "util_date.h"
72
#include "pmlist.h"
73

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
static const char CWFI_NAME[]        = "cold_spell_days_index_wrt_10th_percentile_of_reference_period";
101
static const char CWFI_NAME_ET[]     = "csdiETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
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.";
103
static const char CWFI_LONGNAME_ET[] = "Cold Spell Duration Index";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
static const char CWFI_UNITS[]       = "No.";
105
static const char CWFI_UNITS_ET[]    = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
106
107
108
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.";
109
110

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
static const char FD_NAME[]          = "frost_days_index_per_time_period";
115
static const char FD_NAME_ET[]       = "fdETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
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.";
117
static const char FD_LONGNAME_ET[]   = "Number of Frost Days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
//static const char FD_UNITS[]         = "No.";
119
static const char FD_UNITS_ET[]      = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120

121
static const char GSL_NAME[]         = "thermal_growing_season_length";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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";
140
static const char HWFI_NAME_ET[]     = "wsdiETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141
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.";
142
static const char HWFI_LONGNAME_ET[] = "Warm Spell Duration Index";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
static const char HWFI_UNITS[]       = "No.";
144
static const char HWFI_UNITS_ET[]    = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
146
147
148
149
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";
150
static const char ID_NAME_ET[]       = "idETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
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.";
152
static const char ID_LONGNAME_ET[]   = "Number of Icing Days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
153
static const char ID_UNITS[]         = "No.";
154
static const char ID_UNITS_ET[]      = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
156

static const char SU_NAME[]          = "summer_days_index_per_time_period";
157
static const char SU_NAME_ET[]       = "suETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
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.";
159
static const char SU_LONGNAME_ET[]   = "Number of Summer Days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
//static const char SU_UNITS[]         = "No.";
161
static const char SU_UNITS_ET[]      = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162
163

static const char TG10P_NAME[]       = "cold_days_percent_wrt_10th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
166
167
static const char TG10P_UNITS[]      = "Percent";

static const char TG90P_NAME[]       = "warm_days_percent_wrt_90th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
169
170
171
static const char TG90P_UNITS[]      = "Percent";

static const char TN10P_NAME[]       = "cold_nights_percent_wrt_10th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
174
175
static const char TN10P_UNITS[]      = "Percent";

static const char TN90P_NAME[]       = "warm_nights_percent_wrt_90th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
177
178
179
static const char TN90P_UNITS[]      = "Percent";

static const char TR_NAME[]          = "tropical_nights_index_per_time_period";
180
static const char TR_NAME_ET[]       = "trETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
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.";
182
static const char TR_LONGNAME_ET[]   = "Number of Tropical Nights";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
static const char TR_UNITS[]         = "No.";
184
static const char TR_UNITS_ET[]      = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
186

static const char TX10P_NAME[]       = "very_cold_days_percent_wrt_10th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
189
190
static const char TX10P_UNITS[]      = "Percent";

static const char TX90P_NAME[]       = "very_warm_days_percent_wrt_90th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
193
194
static const char TX90P_UNITS[]      = "Percent";

static const char CDD_NAME[]         = "consecutive_dry_days_index_per_time_period";
195
static const char CDD_NAME_ET[]      = "cddETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
196
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.";
197
static const char CDD_LONGNAME_ET[]  = "Maximum Number of Consecutive Days with Less Than 1mm of Precipitation [days]";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
static const char CDD_UNITS[]        = "No.";
199
static const char CDD_UNITS_ET[]      = "days";
200
201
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
202
203
204
static const char CDD_UNITS2[]       = "No.";

static const char CWD_NAME[]         = "consecutive_wet_days_index_per_time_period";
205
static const char CWD_NAME_ET[]      = "cwdETCCDI";
206
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.";
207
static const char CWD_LONGNAME_ET[]  = "Maximum Number of Consecutive Days with At Least 1mm of Precipitation";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
static const char CWD_UNITS[]        = "No.";
209
static const char CWD_UNITS_ET[]     = "days";
210
211
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
212
213
static const char CWD_UNITS2[]       = "No.";

214
static const char PD_NAME[]          = "precipitation_days_index_per_time_period";
215
static const char PD_NAME_ET[]       = "r1mmETCCDI";
216
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.";
217
static const char PD_LONGNAME_ET[]   = "Count of Days with At Least 1mm of Precipitation";
218
static const char PD_UNITS[]         = "No.";
219
static const char PD_UNITS_ET[]      = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220

Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
static const char R10MM_NAME[]       = "heavy_precipitation_days_index_per_time_period";
222
static const char R10MM_NAME_ET[]    = "r10mmETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
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.";
224
static const char R10MM_LONGNAME_ET[]= "Count of Days with At Least 10mm of Precipitation";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
static const char R10MM_UNITS[]      = "No.";
226
static const char R10MM_UNITS_ET[]   = "days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
228

static const char R20MM_NAME[]       = "very_heavy_precipitation_days_index_per_time_period";
229
static const char R20MM_NAME_ET[]    = "r20mmETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230
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.";
231
static const char R20MM_LONGNAME_ET[]= "Count of Days with At Least 20mm of Precipitation";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
232
static const char R20MM_UNITS[]      = "No.";
233
static const char R20MM_UNITS_ET[]   = "days";
234
235

static const char R75P_NAME[]        = "moderate_wet_days_wrt_75th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237
static const char R75P_UNITS[]       = "Percent";
238

Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
static const char R75PTOT_NAME[]     = "precipitation_percent_due_to_R75p_days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
241
static const char R75PTOT_UNITS[]    = "Percent";
242

Uwe Schulzweida's avatar
Uwe Schulzweida committed
243
static const char R90P_NAME[]        = "wet_days_wrt_90th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
static const char R90P_UNITS[]       = "Percent";
246

Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
static const char R90PTOT_NAME[]     = "precipitation_percent_due_to_R90p_days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
static const char R90PTOT_UNITS[]    = "Percent";
250
251

static const char R95P_NAME[]        = "very_wet_days_wrt_95th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
static const char R95P_UNITS[]       = "Percent";
254

Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
static const char R95PTOT_NAME[]     = "precipitation_percent_due_to_R95p_days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
static const char R95PTOT_UNITS[]    = "Percent";
258
259

static const char R99P_NAME[]        = "extremely_wet_days_wrt_99th_percentile_of_reference_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
262
263
static const char R99P_UNITS[]       = "Percent";

static const char R99PTOT_NAME[]     = "precipitation_percent_due_to_R99p_days";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
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
265
//static const char R99PTOT_UNITS[]    = "Percent";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266
267

static const char RR1_NAME[]         = "wet_days_index_per_time_period";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
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
269
270
271
static const char RR1_UNITS[]        = "No.";

static const char RX1DAY_NAME[]      = "highest_one_day_precipitation_amount_per_time_period";
272
static const char RX1DAY_NAME_ET[]   = "rx1dayETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
273
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.";
274
static const char RX1DAY_LONGNAME_ET[]= "Maximum 1-day Precipitation";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
static const char RX1DAY_UNITS[]     = "mm per day";
276
static const char RX1DAY_UNITS_ET[]  = "mm";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
278

static const char RX5DAY_NAME[]      = "highest_five_day_precipitation_amount_per_time_period";
279
static const char RX5DAY_NAME_ET[]   = "rx5dayETCCDI";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280
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.";
281
static const char RX5DAY_LONGNAME_ET[]= "Maximum Consecutive 5-day Precipitation";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
282
static const char RX5DAY_UNITS[]     = "mm per 5 day";
283
static const char RX5DAY_UNITS_ET[]  = "mm";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
285
286
287
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.";

288
static const char SDII_NAME[]        = "simple_daily_intensity_index_per_time_period";
289
static const char SDII_NAME_ET[]     = "sdiiETCCDI";
290
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.";
291
static const char SDII_LONGNAME_ET[] = "Simple Precipitation Intensity Index";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
static const char SDII_UNITS[]       = "mm";
293
static const char SDII_UNITS_ET[]    = "mm d-1";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
294

Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
296
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.";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
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
311
312
313
314
//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
315
316
317
318
319

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.";
320

Uwe Schulzweida's avatar
Uwe Schulzweida committed
321
322
// clang-format on

323
324
/* ECA temperature indices */

325
326
static int
addWithFrequency(std::vector<std::string> &params, const char *operatorName, size_t defaultDays)
327
{
328
  int opID = 0;
329
330

  KVList kvlist;
331
332
333
334
  if (kvlist.parseArguments(1, params) != 0) cdoAbort("Argument parse error!"); 
  auto kv = kvlist.search("freq");
  if (kv && kv->nvalues > 0 )
    { 
335
      if (kv->values[0] == "month")
336
        opID = cdoOperatorAdd(operatorName, 0, 8, nullptr);
337
      else if (kv->values[0] == "year")
338
        opID = cdoOperatorAdd(operatorName, 0, 10, nullptr);
339
340
      else
        cdoAbort("Frequency '%s' unknown.", kv->values[0]);
341
342
    }
  else
343
    opID = cdoOperatorAdd(operatorName, 0, defaultDays, nullptr);
344

345
  return opID;
346
}
347

348
void *EcaCfd(void *process)
349
{
350
  int ndays = 5;
351
  
352
  cdoInitialize(process);
353
354
355
356
357
358

  if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
  if ( operatorArgc() > 1 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 1, params.end());
359
      addWithFrequency(params, "eca_cfd", 31);
360
361
362
363
364
365
    }
  else
    {
      if ( operatorArgc() > 0 ) ndays = parameter2int(cdoOperatorArgv(0));
      cdoOperatorAdd("eca_cfd", 0, 31, nullptr);
    }
366

367
368
  char cfd_longname2[1024];
  char cfd_name2[1024];
369
370
371
  sprintf(cfd_longname2, CFD_LONGNAME2, ndays);
  sprintf(cfd_name2,     CFD_NAME2, ndays);

372
373
  ECA_REQUEST_1 request;

374
375
  request.var1.name     = CFD_NAME;
  request.var1.longname = CFD_LONGNAME;
376
  request.var1.refdate  = 19550101;
377
  request.var1.f1       = vfarselltc;
378
  request.var1.f1arg    = TO_KELVIN(0.0);
379
380
  request.var1.f2       = vfarnum2;
  request.var1.f3       = vfarmax;
381
382
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
383
  request.var1.epilog   = ECA_NONE;
384
385
  request.var2.name     = cfd_name2;
  request.var2.longname = cfd_longname2;
386
  request.var2.units    = CFD_UNITS2;
387
  request.var2.h1       = vfarseleqc;
388
  request.var2.h1arg    = ndays+1;
389
  request.var2.h3       = vfarnum;
390
391
   
  eca1(&request);
392

393
394
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
  return 0;
396
397
398
}


399
void *EcaCsu(void *process)
400
{
401
402
  double argT = 25.0;
  int ndays = 5;
403
  
404
  cdoInitialize(process);
405

406
407
408
409
410
  if ( operatorArgc() > 3 ) cdoAbort("Too many arguments!");
  if ( operatorArgc() > 2 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 2, params.end());
411
      addWithFrequency(params, "eca_csu", 31);
412
    }
413
414
  else if ( operatorArgc() > 0 ) 
    {
415
      cdoOperatorAdd("eca_csu", 0, 31, nullptr);
416
417
      argT = parameter2double(cdoOperatorArgv(0));
      if ( operatorArgc() == 2 ) ndays = parameter2int(cdoOperatorArgv(1));
418
    }
419
420
  else
    cdoOperatorAdd("eca_csu", 0, 31, nullptr);
421
  
422
423
  char csu_longname2[1024];
  char csu_name2[1024];
424
425
  sprintf(csu_longname2, CSU_LONGNAME2, ndays);
  sprintf(csu_name2,     CSU_NAME2, ndays);
426

427
428
  ECA_REQUEST_1 request;

429
  request.var1.name     = CSU_NAME;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
  request.var1.longname = CSU_LONGNAME;
431
  request.var1.refdate  = 19550101;
432
  request.var1.f1       = vfarselgtc;
433
  request.var1.f1arg    = TO_KELVIN(argT);
434
435
  request.var1.f2       = vfarnum2;
  request.var1.f3       = vfarmax;
436
437
  request.var1.mulc     = 0.0;
  request.var1.addc     = 0.0;
438
  request.var1.epilog   = ECA_NONE;
439
440
  request.var2.name     = csu_name2;
  request.var2.longname = csu_longname2;
441
  request.var2.units    = CSU_UNITS2;
442
  request.var2.h1       = vfarseleqc;
443
  request.var2.h1arg    = ndays+1;
444
  request.var2.h3       = vfarnum;
445
446
  
  eca1(&request);
447
  
448
449
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
450
  return 0;
451
452
453
}


454
void *EcaCwdi(void *process)
455
456
457
458
{
  int argN = 6;
  double argT = 5.0;
  
459
  cdoInitialize(process);
460

461
462
463
464
  if ( operatorArgc() > 2 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 2, params.end());
465
      addWithFrequency(params, "eca_cwdi", 31);
466
467
468
469
470
471
472
473
474
475
      argT = parameter2double(cdoOperatorArgv(1));
      argN = parameter2int(cdoOperatorArgv(0));
    }
  else
    {
      if ( operatorArgc() > 1 ) argT = parameter2double(cdoOperatorArgv(1));
      else if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
      cdoOperatorAdd("eca_cwdi", 0, 31, nullptr);
    } 
 
476
477
478
479
  std::vector<char> longname(strlen(CWDI_LONGNAME) + 80);
  sprintf(longname.data(), CWDI_LONGNAME, argN, argT);

  ECA_REQUEST_2 request;
480
481

  request.var1.name     = CWDI_NAME;
482
  request.var1.longname = longname.data();
483
  request.var1.refdate  = 19550101;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
  request.var1.units    = CWDI_UNITS;
485
  request.var1.f2       = vfarcsub;
486
  request.var1.f2arg    = argT;
487
488
489
  request.var1.f3       = vfarsellt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
490
  request.var1.f5arg    = argN;
491
  request.var1.epilog   = ECA_NONE;
492
493
  request.var2.name     = CWDI_NAME2;
  request.var2.longname = CWDI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
  request.var2.units    = CWDI_UNITS2;
495
  request.var2.h1       = vfarseleqc;
496
  request.var2.h1arg    = argN;
497
  request.var2.h2       = vfarnum;
498
499
500
501
502
   
  eca2(&request);
  
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503
  return 0;
504
505
506
}


507
void *EcaCwfi(void *process)
508
509
510
{
  int argN = 6;
  
511
  cdoInitialize(process);
512

513
  int OPID_ECA = 0, OPID_ETC = 0;
514
515
516
517
  if ( operatorArgc() > 1 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 1, params.end());
518
519
      OPID_ECA = addWithFrequency(params, "eca_cwfi", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_csdi", 10);
520
521
522
523
524
      argN = parameter2int(cdoOperatorArgv(0));
    }
  else
    {
      if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
525
526
      OPID_ECA = cdoOperatorAdd("eca_cwfi", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_csdi", 0, 10, nullptr);
527
    }
528

529
530
  std::vector<char> longname(strlen(CWFI_LONGNAME) + 40);
  sprintf(longname.data(), CWFI_LONGNAME, argN);
531

532
  ECA_REQUEST_2 request;
533

Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
  if (OPID_ECA == cdoOperatorID())
535
536
    {
      request.var1.name     = CWFI_NAME;
537
      request.var1.longname = longname.data();
538
539
540
      request.var1.refdate  = 19550101;
      request.var1.units    = CWFI_UNITS;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
  else if (OPID_ETC == cdoOperatorID())
542
543
544
545
546
547
548
    {
      request.var1.name     = CWFI_NAME_ET;
      request.var1.longname = CWFI_LONGNAME_ET;
      request.var1.units    = CWFI_UNITS_ET;
      request.var1.refdate  = 18500101;
    }

549
550
551
  request.var1.f3       = vfarsellt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
552
  request.var1.f5arg    = argN;
553
  request.var1.epilog   = ECA_NONE;
554
555
  request.var2.name     = CWFI_NAME2;
  request.var2.longname = CWFI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556
  request.var2.units    = CWFI_UNITS2;
557
  request.var2.h1       = vfarseleqc;
558
  request.var2.h1arg    = argN;
559
  request.var2.h2       = vfarnum;
560
561
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
562
  
563
564
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
  return 0;
566
567
568
}


569
void *EcaEtr(void *process)
570
{  
571
  cdoInitialize(process);
572

Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
  cdoOperatorAdd("eca_etr", 0, 31, nullptr);
574
  
575
576
  ECA_REQUEST_3 request;

577
578
  request.name     = ETR_NAME;
  request.longname = ETR_LONGNAME;
579
  request.refdate  = 19550101;
580
581
582
  request.f1       = vfarmax; 
  request.f2       = vfarmin;
  request.f3       = vfarsub;
583
584
585
586
   
  eca3(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
  return 0;
588
589
590
}


591
void *EcaFd(void *process)
592
{  
593
  cdoInitialize(process);
594

595
  int OPID_ECA = 0, OPID_ETC = 0;
596
597
598
  if ( operatorArgc() > 0 )
    {
      auto params = cdoGetOperArgv();
599
600
      OPID_ECA = addWithFrequency(params, "eca_fd", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_fd", 10);
601
602
    }
  else
603
604
605
606
    {
      OPID_ECA = cdoOperatorAdd("eca_fd", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_fd", 0, 10, nullptr);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607

608
609
  ECA_REQUEST_1 request;

610
611
612
613
614
615
  if (  OPID_ECA == cdoOperatorID() ) 
    {
      request.var1.name     = FD_NAME;
      request.var1.longname = FD_LONGNAME;
      request.var1.refdate  = 19550101;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
616
  else if (OPID_ETC == cdoOperatorID())
617
618
619
620
621
622
    {
      request.var1.name     = FD_NAME_ET;
      request.var1.longname = FD_LONGNAME_ET;
      request.var1.refdate  = 18500101;
      request.var1.units    = FD_UNITS_ET;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623

624
  request.var1.f1       = vfarselltc; 
625
  request.var1.f1arg    = TO_KELVIN(0.0);
626
  request.var1.f2       = vfarnum;
627
628
  request.var1.mulc     = 0.0;    
  request.var1.addc     = 0.0;
629
  request.var1.epilog   = ECA_NONE;    
630
631
   
  eca1(&request);
632

633
634
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
  return 0;
636
637
638
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
/*
640
641
642
643
 * 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
644
645
 * ATTENTION: Year of the northern hemisphere starts in january to
 * december, whereas for the southern hemisphere is goes from july to june!
646
 * Hence, at least 18 Month of data is needed for computing the gsl of the whole earth.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
647
*/
648
void *EcaGsl(void *process)
649
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
  int argN = 6; 
651
  double argT = 5.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
  double minLandFraction = 0.5;
653
  
654
  cdoInitialize(process);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
  cdoOperatorAdd("eca_gsl", 0, 10, nullptr);
656
  
657
658
659
  if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
  if ( operatorArgc() > 1 ) argT = parameter2double(cdoOperatorArgv(1));
  if ( operatorArgc() > 2 ) minLandFraction = parameter2double(cdoOperatorArgv(2));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660

661
662
663
664
  std::vector<char> longname(strlen(GSL_LONGNAME) + 160);
  sprintf(longname.data(), GSL_LONGNAME, argN, argT, argN, argT);

  ECA_REQUEST_4 request;
665

666
  request.name      = GSL_NAME;
667
  request.longname  = longname.data();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
  request.units     = GSL_UNITS;
669
670
  request.name2     = GSL_NAME2;
  request.longname2 = GSL_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
  request.units2    = GSL_UNITS2;
672
  request.s1        = vfarselgtc; 
673
  request.s1arg     = TO_KELVIN(argT);
674
  request.s2        = vfarselltc;
675
  request.s2arg     = TO_KELVIN(argT);
676
  request.s3        = vfarselgec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
  request.s3arg     = minLandFraction;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
678
  request.consecutiveDays = argN;    
679
680
   
  eca4(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681

682
683
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
  return 0;
685
686
687
}


688
void *EcaHd(void *process)
689
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
  double argX = 17.0;
  double argA = 17.0;
692
  
693
  cdoInitialize(process);
694

Uwe Schulzweida's avatar
Uwe Schulzweida committed
695
  cdoOperatorAdd("eca_hd", 0, 31, nullptr);
696
697
698

  if ( operatorArgc() > 0 ) 
    {
699
      argX = parameter2double(cdoOperatorArgv(0));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
      argA = argX;
701
702
    }
  if ( operatorArgc() > 1 ) 
703
    argA = parameter2double(cdoOperatorArgv(1));
704
  
705
706
  ECA_REQUEST_1 request;

707
708
  request.var1.name     = HD_NAME;
  request.var1.longname = HD_LONGNAME;
709
  request.var1.refdate  = 19550101;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
  request.var1.units    = HD_UNITS;
711
  request.var1.f1       = vfarselltc; 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
712
  request.var1.f1arg    = TO_KELVIN(argA);
713
  request.var1.f2       = vfarsum;
714
  request.var1.mulc     = -1.0;    
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
  request.var1.addc     = TO_KELVIN(argX);
716
  request.var1.epilog   = ECA_NONE;    
717
718
   
  eca1(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
719

720
721
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
  return 0;
723
724
725
}


726
void *EcaHwdi(void *process)
727
728
729
730
{
  int argN = 6;
  double argT = 5.0;
  
731
  cdoInitialize(process);
732

733
734
735
736
  if ( operatorArgc() > 2 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 2, params.end());
737
      addWithFrequency(params, "eca_hwdi", 31);
738
739
740
741
742
743
744
745
746
      argN = parameter2int(cdoOperatorArgv(0));
      argT = parameter2double(cdoOperatorArgv(1));
    }
  else
    {
      if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
      if ( operatorArgc() > 1 ) argT = parameter2double(cdoOperatorArgv(1));
      cdoOperatorAdd("eca_hwdi", 0, 31, nullptr);
    }
747
  
748
749
  std::vector<char> longname(strlen(HWDI_LONGNAME) + 80);
  sprintf(longname.data(), HWDI_LONGNAME, argN, argT);
750
  
751
752
  ECA_REQUEST_2 request;

753
  request.var1.name     = HWDI_NAME;
754
  request.var1.longname = longname.data();
755
  request.var1.refdate  = 19550101;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
  request.var1.units    = HWDI_UNITS;
757
  request.var1.f2       = vfarcadd;
758
  request.var1.f2arg    = argT;
759
760
761
  request.var1.f3       = vfarselgt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
762
  request.var1.f5arg    = argN;
763
  request.var1.epilog   = ECA_NONE;
764
765
  request.var2.name     = HWDI_NAME2;
  request.var2.longname = HWDI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
  request.var2.units    = HWDI_UNITS2;
767
  request.var2.h1       = vfarseleqc;
768
  request.var2.h1arg    = argN;
769
  request.var2.h2       = vfarnum;
770
771
   
  eca2(&request);
772

773
774
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
  return 0;
776
777
778
}


779
void *EcaHwfi(void *process)
780
781
782
{
  int argN = 6;
  
783
  cdoInitialize(process);
784

785
  int OPID_ECA = 0, OPID_ETC = 0;
786
787
788
789
  if ( operatorArgc() > 1 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 1, params.end());
790
791
      OPID_ECA = addWithFrequency(params, "eca_hwfi", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_wsdi", 10);
792
793
794
795
796
      argN = parameter2int(cdoOperatorArgv(0));
    }
  else
    {
      if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
797
798
      OPID_ECA = cdoOperatorAdd("eca_hwfi", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_wsdi", 0, 10, nullptr);
799
    }
800

801
802
  std::vector<char> longname(strlen(HWFI_LONGNAME) + 40);
  sprintf(longname.data(), HWFI_LONGNAME, argN);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803

804
805
806
  ECA_REQUEST_2 request;

  if (OPID_ECA == cdoOperatorID()) 
807
808
    {
      request.var1.name     = HWFI_NAME;
809
      request.var1.longname = longname.data();
810
811
812
      request.var1.refdate  = 19550101;
      request.var1.units    = HWFI_UNITS;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
  else if (OPID_ETC == cdoOperatorID())
Fabian Wachsmann's avatar