EcaIndices.cc 67.8 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.var2.name     = cfd_name2;
  request.var2.longname = cfd_longname2;
383
  request.var2.units    = CFD_UNITS2;
384
  request.var2.h1       = vfarseleqc;
385
  request.var2.h1arg    = ndays+1;
386
  request.var2.h3       = vfarnum;
387
388
   
  eca1(&request);
389

390
391
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
  return 0;
393
394
395
}


396
void *EcaCsu(void *process)
397
{
398
399
  double argT = 25.0;
  int ndays = 5;
400
  
401
  cdoInitialize(process);
402

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

424
425
  ECA_REQUEST_1 request;

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


448
void *EcaCwdi(void *process)
449
450
451
452
{
  int argN = 6;
  double argT = 5.0;
  
453
  cdoInitialize(process);
454

455
456
457
458
  if ( operatorArgc() > 2 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 2, params.end());
459
      addWithFrequency(params, "eca_cwdi", 31);
460
461
462
463
464
465
466
467
468
469
      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);
    } 
 
470
471
472
473
  std::vector<char> longname(strlen(CWDI_LONGNAME) + 80);
  sprintf(longname.data(), CWDI_LONGNAME, argN, argT);

  ECA_REQUEST_2 request;
474
475

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


500
void *EcaCwfi(void *process)
501
502
503
{
  int argN = 6;
  
504
  cdoInitialize(process);
505

506
  int OPID_ECA = 0, OPID_ETC = 0;
507
508
509
510
  if ( operatorArgc() > 1 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 1, params.end());
511
512
      OPID_ECA = addWithFrequency(params, "eca_cwfi", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_csdi", 10);
513
514
515
516
517
      argN = parameter2int(cdoOperatorArgv(0));
    }
  else
    {
      if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
518
519
      OPID_ECA = cdoOperatorAdd("eca_cwfi", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_csdi", 0, 10, nullptr);
520
    }
521

522
523
  std::vector<char> longname(strlen(CWFI_LONGNAME) + 40);
  sprintf(longname.data(), CWFI_LONGNAME, argN);
524

525
  ECA_REQUEST_2 request;
526

Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
  if (OPID_ECA == cdoOperatorID())
528
529
    {
      request.var1.name     = CWFI_NAME;
530
      request.var1.longname = longname.data();
531
532
533
      request.var1.refdate  = 19550101;
      request.var1.units    = CWFI_UNITS;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
  else if (OPID_ETC == cdoOperatorID())
535
536
537
538
539
540
541
    {
      request.var1.name     = CWFI_NAME_ET;
      request.var1.longname = CWFI_LONGNAME_ET;
      request.var1.units    = CWFI_UNITS_ET;
      request.var1.refdate  = 18500101;
    }

542
543
544
  request.var1.f3       = vfarsellt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
545
546
547
  request.var1.f5arg    = argN;
  request.var2.name     = CWFI_NAME2;
  request.var2.longname = CWFI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
  request.var2.units    = CWFI_UNITS2;
549
  request.var2.h1       = vfarseleqc;
550
  request.var2.h1arg    = argN;
551
  request.var2.h2       = vfarnum;
552
553
   
  eca2(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
  
555
556
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
557
  return 0;
558
559
560
}


561
void *EcaEtr(void *process)
562
{  
563
  cdoInitialize(process);
564

Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
  cdoOperatorAdd("eca_etr", 0, 31, nullptr);
566
  
567
568
  ECA_REQUEST_3 request;

569
570
  request.name     = ETR_NAME;
  request.longname = ETR_LONGNAME;
571
  request.refdate  = 19550101;
572
573
574
  request.f1       = vfarmax; 
  request.f2       = vfarmin;
  request.f3       = vfarsub;
575
576
577
578
   
  eca3(&request);
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
579
  return 0;
580
581
582
}


583
void *EcaFd(void *process)
584
{  
585
  cdoInitialize(process);
586

587
  int OPID_ECA = 0, OPID_ETC = 0;
588
589
590
  if ( operatorArgc() > 0 )
    {
      auto params = cdoGetOperArgv();
591
592
      OPID_ECA = addWithFrequency(params, "eca_fd", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_fd", 10);
593
594
    }
  else
595
596
597
598
    {
      OPID_ECA = cdoOperatorAdd("eca_fd", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_fd", 0, 10, nullptr);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599

600
601
  ECA_REQUEST_1 request;

602
603
604
605
606
607
  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
608
  else if (OPID_ETC == cdoOperatorID())
609
610
611
612
613
614
    {
      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
615

616
  request.var1.f1       = vfarselltc; 
617
  request.var1.f1arg    = TO_KELVIN(0.0);
618
  request.var1.f2       = vfarnum;
619
620
   
  eca1(&request);
621

622
623
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
  return 0;
625
626
627
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
/*
629
630
631
632
 * 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
633
634
 * ATTENTION: Year of the northern hemisphere starts in january to
 * december, whereas for the southern hemisphere is goes from july to june!
635
 * Hence, at least 18 Month of data is needed for computing the gsl of the whole earth.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
636
*/
637
void *EcaGsl(void *process)
638
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
  int argN = 6; 
640
  double argT = 5.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
  double minLandFraction = 0.5;
642
  
643
  cdoInitialize(process);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
  cdoOperatorAdd("eca_gsl", 0, 10, nullptr);
645
  
646
647
648
  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
649

650
651
652
653
  std::vector<char> longname(strlen(GSL_LONGNAME) + 160);
  sprintf(longname.data(), GSL_LONGNAME, argN, argT, argN, argT);

  ECA_REQUEST_4 request;
654

655
  request.name      = GSL_NAME;
656
  request.longname  = longname.data();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
  request.units     = GSL_UNITS;
658
659
  request.name2     = GSL_NAME2;
  request.longname2 = GSL_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
  request.units2    = GSL_UNITS2;
661
  request.s1        = vfarselgtc; 
662
  request.s1arg     = TO_KELVIN(argT);
663
  request.s2        = vfarselltc;
664
  request.s2arg     = TO_KELVIN(argT);
665
  request.s3        = vfarselgec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
  request.s3arg     = minLandFraction;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
  request.consecutiveDays = argN;    
668
669
   
  eca4(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
670

671
672
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
  return 0;
674
675
676
}


677
void *EcaHd(void *process)
678
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
680
  double argX = 17.0;
  double argA = 17.0;
681
  
682
  cdoInitialize(process);
683

Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
  cdoOperatorAdd("eca_hd", 0, 31, nullptr);
685
686
687

  if ( operatorArgc() > 0 ) 
    {
688
      argX = parameter2double(cdoOperatorArgv(0));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689
      argA = argX;
690
691
    }
  if ( operatorArgc() > 1 ) 
692
    argA = parameter2double(cdoOperatorArgv(1));
693
  
694
695
  ECA_REQUEST_1 request;

696
697
  request.var1.name     = HD_NAME;
  request.var1.longname = HD_LONGNAME;
698
  request.var1.refdate  = 19550101;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
  request.var1.units    = HD_UNITS;
700
  request.var1.f1       = vfarselltc; 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
  request.var1.f1arg    = TO_KELVIN(argA);
702
  request.var1.f2       = vfarsum;
703
  request.var1.mulc     = -1.0;    
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
  request.var1.addc     = TO_KELVIN(argX);
705
706
   
  eca1(&request);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707

708
709
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
  return 0;
711
712
713
}


714
void *EcaHwdi(void *process)
715
716
717
718
{
  int argN = 6;
  double argT = 5.0;
  
719
  cdoInitialize(process);
720

721
722
723
724
  if ( operatorArgc() > 2 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 2, params.end());
725
      addWithFrequency(params, "eca_hwdi", 31);
726
727
728
729
730
731
732
733
734
      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);
    }
735
  
736
737
  std::vector<char> longname(strlen(HWDI_LONGNAME) + 80);
  sprintf(longname.data(), HWDI_LONGNAME, argN, argT);
738
  
739
740
  ECA_REQUEST_2 request;

741
  request.var1.name     = HWDI_NAME;
742
  request.var1.longname = longname.data();
743
  request.var1.refdate  = 19550101;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
  request.var1.units    = HWDI_UNITS;
745
  request.var1.f2       = vfarcadd;
746
  request.var1.f2arg    = argT;
747
748
749
  request.var1.f3       = vfarselgt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
750
751
752
  request.var1.f5arg    = argN;
  request.var2.name     = HWDI_NAME2;
  request.var2.longname = HWDI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
753
  request.var2.units    = HWDI_UNITS2;
754
  request.var2.h1       = vfarseleqc;
755
  request.var2.h1arg    = argN;
756
  request.var2.h2       = vfarnum;
757
758
   
  eca2(&request);
759

760
761
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
  return 0;
763
764
765
}


766
void *EcaHwfi(void *process)
767
768
769
{
  int argN = 6;
  
770
  cdoInitialize(process);
771

772
  int OPID_ECA = 0, OPID_ETC = 0;
773
774
775
776
  if ( operatorArgc() > 1 )
    {
      auto params = cdoGetOperArgv();
      params = std::vector<std::string>(params.begin() + 1, params.end());
777
778
      OPID_ECA = addWithFrequency(params, "eca_hwfi", 31);
      OPID_ETC = addWithFrequency(params, "etccdi_wsdi", 10);
779
780
781
782
783
      argN = parameter2int(cdoOperatorArgv(0));
    }
  else
    {
      if ( operatorArgc() > 0 ) argN = parameter2int(cdoOperatorArgv(0));
784
785
      OPID_ECA = cdoOperatorAdd("eca_hwfi", 0, 31, nullptr);
      OPID_ETC = cdoOperatorAdd("etccdi_wsdi", 0, 10, nullptr);
786
    }
787

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

791
792
793
  ECA_REQUEST_2 request;

  if (OPID_ECA == cdoOperatorID()) 
794
795
    {
      request.var1.name     = HWFI_NAME;
796
      request.var1.longname = longname.data();
797
798
799
      request.var1.refdate  = 19550101;
      request.var1.units    = HWFI_UNITS;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
  else if (OPID_ETC == cdoOperatorID())
801
802
803
804
805
806
807
    {
      request.var1.name     = HWFI_NAME_ET;
      request.var1.longname = HWFI_LONGNAME_ET;
      request.var1.refdate  = 18500101;
      request.var1.units    = HWFI_UNITS_ET;
    }

808
809
810
  request.var1.f3       = vfarselgt;
  request.var1.f4       = vfarnum2;
  request.var1.f5       = vfarnum3;
811
812
813
  request.var1.f5arg    = argN;
  request.var2.name     = HWFI_NAME2;
  request.var2.longname = HWFI_LONGNAME2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
  request.var2.units    = HWFI_UNITS2;
815
  request.var2.h1       = vfarseleqc;
816
  request.var2.h1arg    = argN;
817
  request.var2.h2       = vfarnum;
818
819
   
  eca2(&request);
820

821
822
  cdoFinish();
  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
  return 0;
824
825
826
}


827
void *EcaId(void *process)
828
{  
829
  cdoInitialize</