Antares Simulator
Power System Simulator
Loading...
Searching...
No Matches
modifiers.hxx
1/*
2** Copyright 2007-2024, RTE (https://www.rte-france.com)
3** See AUTHORS.txt
4** SPDX-License-Identifier: MPL-2.0
5** This file is part of Antares-Simulator,
6** Adequacy and Performance assessment for interconnected energy networks.
7**
8** Antares_Simulator is free software: you can redistribute it and/or modify
9** it under the terms of the Mozilla Public Licence 2.0 as published by
10** the Mozilla Foundation, either version 2 of the License, or
11** (at your option) any later version.
12**
13** Antares_Simulator is distributed in the hope that it will be useful,
14** but WITHOUT ANY WARRANTY; without even the implied warranty of
15** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16** Mozilla Public Licence 2.0 for more details.
17**
18** You should have received a copy of the Mozilla Public Licence 2.0
19** along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
20*/
21#ifndef __ANTARES_TOOLBOX_COMPONENT_DATAGRID_MODIFIERS_HXX__
22#define __ANTARES_TOOLBOX_COMPONENT_DATAGRID_MODIFIERS_HXX__
23
24namespace Antares
25{
26namespace Component
27{
28namespace Datagrid
29{
30namespace // anonymous
31{
32enum ModifierSet
33{
34 modifierValues,
35 modifierDataset,
36 modifierMax
37};
38
39enum OpInputType
40{
41 opInputText = 0, // default
42 opInputVoid, // nothing
43 opInputDate,
44};
45
46// Forward declaration
47template<enum ModifierSet ModifierT>
48struct ModifierOperatorsData;
49
50template<enum ModifierSet ModifierT>
51struct ModifierOperatorsData
52{
53 // nothing
54};
55
56template<>
57struct ModifierOperatorsData<modifierValues>
58{
59 enum Operator
60 {
61 opPlus,
62 opAssign,
63 opMinus,
64 opMult,
65 opDiv,
66 opAbs,
67 opMax
68 };
69
70 static uint OperatorCount()
71 {
72 return (uint)opMax;
73 }
74
75 static const wchar_t* Name()
76 {
77 return L"Values";
78 }
79
80 static const wchar_t* ApplyName(uint)
81 {
82 return L"Apply";
83 }
84 static const wchar_t* OperatorToCString(uint op)
85 {
86 if (op < (uint)opMax)
87 {
88 switch ((Operator)op)
89 {
90 case opPlus:
91 return L"+";
92 case opAssign:
93 return L"=";
94 case opMinus:
95 return L"-";
96 case opMult:
97 return L"*";
98 case opDiv:
99 return L"/";
100 case opAbs:
101 return L"ABS";
102 case opMax:
103 break;
104 }
105 }
106 return L"?";
107 }
108
109 static OpInputType OperatorInputType(uint op)
110 {
111 if (op == (uint)opAbs)
112 return opInputVoid;
113 return opInputText;
114 }
115
116 static void ApplyChanges(uint op, const YString& value, Renderer::IRenderer*, VGridHelper* grid)
117 {
118 if (op >= (uint)opMax)
119 return;
120 double input;
121 if ((Operator)op != opAbs && not value.to(input))
122 {
123 logs.error() << "The value does not seem a valid number";
124 return;
125 }
126 int width = grid->GetNumberCols();
127 int height = grid->GetNumberRows();
128 wxString text;
129
130 switch ((Operator)op)
131 {
132 case opPlus:
133 {
134 if (not Yuni::Math::Zero(input))
135 {
136 for (int w = 0; w < width; ++w)
137 {
138 for (int h = 0; h < height; ++h)
139 {
140 text.clear();
141 double d = grid->GetNumericValue(h, w);
142 grid->SetValue(h, w, text << (d + input));
143 }
144 }
145 }
146 break;
147 }
148 case opAssign:
149 {
150 text.clear();
151 text << input;
152 for (int w = 0; w < width; ++w)
153 {
154 for (int h = 0; h < height; ++h)
155 grid->SetValue(h, w, text);
156 }
157 break;
158 }
159 case opMinus:
160 {
161 if (not Yuni::Math::Zero(input))
162 {
163 for (int w = 0; w < width; ++w)
164 {
165 for (int h = 0; h < height; ++h)
166 {
167 text.clear();
168 double d = grid->GetNumericValue(h, w);
169 grid->SetValue(h, w, text << (d - input));
170 }
171 }
172 }
173 break;
174 }
175 case opMult:
176 {
177 if (Yuni::Math::Zero(input))
178 {
179 text = wxT("0");
180 for (int w = 0; w < width; ++w)
181 {
182 for (int h = 0; h < height; ++h)
183 grid->SetValue(h, w, text);
184 }
185 }
186 else
187 {
188 if (not Yuni::Math::Equals(input, 1.))
189 {
190 for (int w = 0; w < width; ++w)
191 {
192 for (int h = 0; h < height; ++h)
193 {
194 text.clear();
195 double d = grid->GetNumericValue(h, w);
196 grid->SetValue(h, w, text << (d * input));
197 }
198 }
199 }
200 }
201 break;
202 }
203 case opDiv:
204 {
205 if (Yuni::Math::Zero(input))
206 {
207 logs.error() << "divide by zero. aborting.";
208 return;
209 }
210 if (not Yuni::Math::Equals(input, 1.))
211 {
212 for (int w = 0; w < width; ++w)
213 {
214 for (int h = 0; h < height; ++h)
215 {
216 text.clear();
217 double d = grid->GetNumericValue(h, w);
218 grid->SetValue(h, w, text << (d / input));
219 }
220 }
221 }
222 break;
223 }
224 case opAbs:
225 {
226 for (int w = 0; w < width; ++w)
227 {
228 for (int h = 0; h < height; ++h)
229 {
230 double d = grid->GetNumericValue(h, w);
231 if (d < 0) // avoid as much as possible grid->SetValue
232 {
233 text.clear();
234 grid->SetValue(h, w, text << (-d));
235 }
236 }
237 }
238 break;
239 }
240 case opMax:
241 break;
242 }
243 }
244};
245
246template<>
247struct ModifierOperatorsData<modifierDataset>
248{
249 enum Operator
250 {
251 opResizeColumns,
252 opShiftRows,
253 opMax
254 };
255
256 static uint OperatorCount()
257 {
258 return (uint)opMax;
259 }
260
261 static const wchar_t* Name()
262 {
263 return L"Dataset";
264 }
265
266 static const wchar_t* ApplyName(uint)
267 {
268 return L"Apply";
269 }
270
271 static const wchar_t* OperatorToCString(uint op)
272 {
273 if (op < (uint)opMax)
274 {
275 switch ((Operator)op)
276 {
277 case opShiftRows:
278 return L"Shift rows until";
279 case opResizeColumns:
280 return L"Resize columns to";
281 case opMax:
282 break;
283 }
284 }
285 return L"?";
286 }
287
288 static OpInputType OperatorInputType(uint op)
289 {
290 if (op == (uint)opShiftRows)
291 return opInputDate;
292 return opInputText;
293 }
294
295 static void ApplyChanges(uint op,
296 const YString& value,
297 Renderer::IRenderer* renderer,
298 VGridHelper*)
299 {
300 if (op >= (uint)opMax)
301 return;
302
303 switch ((Operator)op)
304 {
305 case opShiftRows:
306 {
307 uint index = 0;
308 uint month = (uint)-1;
309 uint day = 1;
310
311 value.words(" /-.", [&](AnyString& word) -> bool {
312 switch (index)
313 {
314 case 0:
315 month = word.to<uint>();
316 if (month < 1 || month > 12)
317 {
318 logs.error() << "invalid month: got '" << word << "' => " << month;
319 month = (uint)-1;
320 }
321 break;
322 case 1:
323 if (not word.to(day) || day < 1 || day > 31)
324 {
325 logs.error() << "invalid day";
326 day = (uint)-1;
327 }
328 }
329 ++index;
330 return true;
331 });
332
333 --month;
334 --day;
335 if (month < 12 && day < 31)
336 {
337 auto monthname = (MonthName)month;
338 if (not renderer->circularShiftRowsUntilDate(monthname, day))
339 logs.error() << "impossible to perform the row shifting in this dataset";
340 }
341 break;
342 }
343 case opResizeColumns:
344 {
345 uint maxwidth = (uint)renderer->maxWidthResize();
346 uint newwidth = value.to<uint>();
347
348 if (newwidth > 0 && newwidth <= maxwidth)
349 {
350 logs.info() << "Resizing the matrix to " << newwidth << " columns";
351 renderer->resizeMatrixToXColumns(newwidth);
352 }
353 else
354 {
355 if (maxwidth > 0)
356 {
357 switch (newwidth)
358 {
359 case 0:
360 logs.error() << "impossible to resize the matrix";
361 break;
362 case 1:
363 logs.error() << "impossible to resize the matrix to 1 column";
364 break;
365 default:
366 logs.error()
367 << "impossible to resize the matrix to " << newwidth << " columns";
368 }
369 }
370 else
371 logs.error() << "impossible to resize the matrix";
372 }
373 break;
374 }
375 case opMax:
376 break;
377 }
378 }
379};
380
381struct ModifierOperators
382{
383 static uint OperatorCount(ModifierSet modifier)
384 {
385 switch (modifier)
386 {
387 case modifierValues:
388 return ModifierOperatorsData<modifierValues>::OperatorCount();
389 case modifierDataset:
390 return ModifierOperatorsData<modifierDataset>::OperatorCount();
391 case modifierMax:
392 break;
393 }
394 return 0;
395 }
396
397 static const wchar_t* Name(ModifierSet modifier)
398 {
399 switch (modifier)
400 {
401 case modifierValues:
402 return ModifierOperatorsData<modifierValues>::Name();
403 case modifierDataset:
404 return ModifierOperatorsData<modifierDataset>::Name();
405 case modifierMax:
406 break;
407 }
408 return L"?";
409 }
410
411 static const wchar_t* ApplyName(ModifierSet modifier, uint op)
412 {
413 switch (modifier)
414 {
415 case modifierValues:
416 return ModifierOperatorsData<modifierValues>::ApplyName(op);
417 case modifierDataset:
418 return ModifierOperatorsData<modifierDataset>::ApplyName(op);
419 case modifierMax:
420 break;
421 }
422 return L"?";
423 }
424
425 static const wchar_t* OperatorToCString(ModifierSet modifier, uint op)
426 {
427 switch (modifier)
428 {
429 case modifierValues:
430 return ModifierOperatorsData<modifierValues>::OperatorToCString(op);
431 case modifierDataset:
432 return ModifierOperatorsData<modifierDataset>::OperatorToCString(op);
433 case modifierMax:
434 break;
435 }
436 return L"?";
437 }
438
439 static OpInputType OperatorInputType(ModifierSet modifier, uint op)
440 {
441 switch (modifier)
442 {
443 case modifierValues:
444 return ModifierOperatorsData<modifierValues>::OperatorInputType(op);
445 case modifierDataset:
446 return ModifierOperatorsData<modifierDataset>::OperatorInputType(op);
447 case modifierMax:
448 break;
449 }
450 return opInputText;
451 }
452
453 static void ApplyChanges(ModifierSet modifier,
454 uint op,
455 const YString& value,
456 Renderer::IRenderer* renderer,
457 VGridHelper* grid)
458 {
459 if (!renderer)
460 return;
461 switch (modifier)
462 {
463 case modifierValues:
464 ModifierOperatorsData<modifierValues>::ApplyChanges(op, value, renderer, grid);
465 break;
466 case modifierDataset:
467 ModifierOperatorsData<modifierDataset>::ApplyChanges(op, value, renderer, grid);
468 break;
469 case modifierMax:
470 break;
471 }
472 }
473
474}; // class ModifierOperators
475
476} // anonymous namespace
477} // namespace Datagrid
478} // namespace Component
479} // namespace Antares
480
481#endif // __ANTARES_TOOLBOX_COMPONENT_DATAGRID_MODIFIERS_HXX__