GammaLib 2.1.0.dev
Loading...
Searching...
No Matches
GApplicationPar.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GApplicationPar.cpp - Application parameter *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2021 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GApplicationPar.cpp
23 * @brief Application parameter class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#ifdef HAVE_LIBREADLINE
32#include <cstdio> //!< Needed for declaration of FILE in readline
33#include <readline/readline.h>
34#endif
35#include <climits> //!< Needed for declaration of LONG_MAX
36#include "GException.hpp"
37#include "GTools.hpp"
38#include "GFilename.hpp"
39#include "GTime.hpp"
40#include "GApplicationPar.hpp"
41
42/* __ Method name definitions ____________________________________________ */
43#define G_STRING_SET "GApplicationPar::string(std::string&)"
44#define G_FILENAME_SET "GApplicationPar::filename(GFilename&)"
45#define G_TIME_SET "GApplicationPar::time(GTime&)"
46#define G_BOOLEAN_SET "GApplicationPar::boolean(bool&)"
47#define G_INTEGER_SET "GApplicationPar::integer(int&)"
48#define G_REAL_SET "GApplicationPar::real(double&)"
49#define G_STRING_GET "GApplicationPar::string()"
50#define G_FILENAME_GET "GApplicationPar::filename()"
51#define G_TIME_GET "GApplicationPar::time()"
52#define G_BOOLEAN_GET "GApplicationPar::boolean()"
53#define G_INTEGER_GET "GApplicationPar::integer()"
54#define G_REAL_GET "GApplicationPar::real()"
55#define G_CHECK_TYPE "GApplicationPar::check_type(std::string)"
56#define G_CHECK_MODE "GApplicationPar::check_mode(std::string)"
57#define G_CHECK_VALUE_BOOL "GApplicationPar::check_value_bool(std::string)"
58#define G_CHECK_VALUE_INT "GApplicationPar::check_value_int(std::string&)"
59#define G_CHECK_VALUE_REAL "GApplicationPar::check_value_real(std::string&)"
60#define G_CHECK_OPTIONS "GApplicationPar::check_options(std::string&)"
61
62/* __ Macros _____________________________________________________________ */
63
64/* __ Coding definitions _________________________________________________ */
65
66/* __ Debug definitions __________________________________________________ */
67
68
69/*==========================================================================
70 = =
71 = Constructors/destructors =
72 = =
73 ==========================================================================*/
74
75/***********************************************************************//**
76 * @brief Void constructor
77 ***************************************************************************/
79{
80 // Initialise members
82
83 // Return
84 return;
85}
86
87
88/***********************************************************************//**
89 * @brief Parameter constructor
90 *
91 * @param[in] name Parameter name.
92 * @param[in] type Parameter type.
93 * @param[in] mode Parameter mode.
94 * @param[in] value Parameter value.
95 * @param[in] min Parameter minimum.
96 * @param[in] max Parameter maximum.
97 * @param[in] prompt Parameter prompt string.
98 *
99 * Constructs a parameter from parameter attributes.
100 ***************************************************************************/
101GApplicationPar::GApplicationPar(const std::string& name,
102 const std::string& type,
103 const std::string& mode,
104 const std::string& value,
105 const std::string& min,
106 const std::string& max,
107 const std::string& prompt)
108{
109 // Initialise members
110 init_members();
111
112 // Set parameter attributes
113 m_name = name;
114 this->mode(mode);
115 this->type(type);
116 m_min = min;
117 m_max = max;
118 this->value(value);
120
121 // Since the call to the value method stops the query, we reset the
122 // queried flag so that the parameter will get queried.
123 m_queried = false;
124
125 // Return
126 return;
127}
128
129
130/***********************************************************************//**
131 * @brief Copy constructor
132 *
133 * @param[in] par Parameter.
134 ***************************************************************************/
136{
137 // Initialise members
138 init_members();
139
140 // Copy members
141 copy_members(par);
142
143 // Return
144 return;
145}
146
147
148/***********************************************************************//**
149 * @brief Destructor
150 ***************************************************************************/
152{
153 // Free members
154 free_members();
155
156 // Return
157 return;
158}
159
160
161/*==========================================================================
162 = =
163 = Operators =
164 = =
165 ==========================================================================*/
166
167/***********************************************************************//**
168 * @brief Assignment operator
169 *
170 * @param[in] par Parameter.
171 * @return Parameter.
172 ***************************************************************************/
174{
175 // Execute only if object is not identical
176 if (this != &par) {
177
178 // Free members
179 free_members();
180
181 // Initialise private members for clean destruction
182 init_members();
183
184 // Copy members
185 copy_members(par);
186
187 } // endif: object was not identical
188
189 // Return
190 return *this;
191}
192
193
194/*==========================================================================
195 = =
196 = Public methods =
197 = =
198 ==========================================================================*/
199
200/***********************************************************************//**
201 * @brief Clear parameter
202 ***************************************************************************/
204{
205 // Free members
206 free_members();
207
208 // Initialise members
209 init_members();
210
211 // Return
212 return;
213}
214
215
216/***********************************************************************//**
217 * @brief Clone parameter
218 *
219 * @return Pointer to deep copy of parameter.
220 ***************************************************************************/
222{
223 return (new GApplicationPar(*this));
224}
225
226
227/***********************************************************************//**
228 * @brief Set parameter type
229 *
230 * @param[in] type Parameter type.
231 *
232 * Sets the parameter type. Valid parameter types are:
233 * b,i,r,s,f,fr,fw,fe,fn,t.
234 ***************************************************************************/
235void GApplicationPar::type(const std::string& type)
236{
237 // Verify that type is valid
239
240 // Set type
241 m_type = type;
242
243 // Return
244 return;
245}
246
247
248/***********************************************************************//**
249 * @brief Set parameter mode
250 *
251 * @param[in] mode Parameter mode.
252 *
253 * Sets the parameter model. Valid parameter modes are: a,h,l,q,hl,ql,lh,lq.
254 ***************************************************************************/
255void GApplicationPar::mode(const std::string& mode)
256{
257 // Verify that mode is valid
259
260 // Set mode
261 m_mode = mode;
262
263 // Return
264 return;
265}
266
267
268/***********************************************************************//**
269 * @brief Set parameter value
270 *
271 * @param[in] value Parameter value.
272 *
273 * Sets the parameter value dependent on the parameter type.
274 *
275 * It is a parser method that verifies that the given parameter value is
276 * compatible with the parameter type.
277 ***************************************************************************/
278void GApplicationPar::value(const std::string& value)
279{
280 // Set value
282
283 // Return
284 return;
285}
286
287
288/***********************************************************************//**
289 * @brief Set string parameter value
290 *
291 * @param[in] value Parameter value.
292 *
293 * @exception GException::invalid_value
294 * Parameter is not of string type.
295 *
296 * This method sets a string parameter. The method only applies to parameters
297 * of type "s". Other parameter types will produce an exception.
298 ***************************************************************************/
299void GApplicationPar::string(const std::string& value)
300{
301 // Check if parameter is a string parameter
302 if (m_type != "s") {
303 std::string msg = "Attempt to set "+par_type_string(m_type)+
304 " parameter \""+m_name+"\" with string value.";
306 }
307
308 // Set value
310
311 // Return
312 return;
313}
314
315
316/***********************************************************************//**
317 * @brief Set filename parameter value
318 *
319 * @param[in] value Parameter value.
320 *
321 * @exception GException::invalid_value
322 * Parameter is not of filename type.
323 *
324 * This method sets a filename parameter. The method only applies to filename
325 * parameters. Other parameter types will produce an exception.
326 ***************************************************************************/
328{
329 // Check if parameter is a filename parameter
330 if (!is_filename()) {
331 std::string msg = "Attempt to set "+par_type_string(m_type)+
332 " parameter \""+m_name+"\" with filename value.";
334 }
335
336 // Set value
338
339 // Return
340 return;
341}
342
343
344/***********************************************************************//**
345 * @brief Set time parameter value
346 *
347 * @param[in] value Parameter value.
348 *
349 * @exception GException::invalid_value
350 * Parameter is not of time type.
351 *
352 * This method sets a time parameter with a UTC string. The method only
353 * applies to time parameters. Other parameter types will produce an
354 * exception.
355 ***************************************************************************/
356void GApplicationPar::time(const GTime& value)
357{
358 // Check if parameter is a filename parameter
359 if (m_type != "t") {
360 std::string msg = "Attempt to set "+par_type_string(m_type)+
361 " parameter \""+m_name+"\" with filename value.";
363 }
364
365 // Set value
366 set_value(value.utc());
367
368 // Return
369 return;
370}
371
372
373/***********************************************************************//**
374 * @brief Set bool parameter value
375 *
376 * @param[in] value Parameter value.
377 *
378 * @exception GException::invalid_value
379 * Parameter is not of boolean type.
380 *
381 * This method sets a boolean parameter. The method only applies to parameters
382 * of type "b". Other parameter types will produce an exception.
383 ***************************************************************************/
384void GApplicationPar::boolean(const bool& value)
385{
386 // Check if parameter is boolean
387 if (m_type != "b") {
388 std::string msg = "Attempt to set "+par_type_string(m_type)+
389 " parameter \""+m_name+"\" with boolean value.";
391 }
392
393 // Set value string
394 std::string value_string = (value) ? "yes" : "no";
395
396 // Set value
397 set_value(value_string);
398
399 // Return
400 return;
401}
402
403
404/***********************************************************************//**
405 * @brief Set integer parameter value
406 *
407 * @param[in] value Parameter value.
408 *
409 * @exception GException::invalid_value
410 * Parameter is not of integer type.
411 *
412 * This method sets an integer parameter. The method only applies to
413 * parameters of type "i". Other parameter types will produce an exception.
414 ***************************************************************************/
415void GApplicationPar::integer(const int& value)
416{
417 // Check if parameter is integer
418 if (m_type != "i") {
419 std::string msg = "Attempt to set "+par_type_string(m_type)+
420 " parameter \""+m_name+"\" with integer value.";
422 }
423
424 // Set value string
425 std::string value_string = gammalib::str(value);
426
427 // Set value
428 set_value(value_string);
429
430 // Return
431 return;
432}
433
434
435/***********************************************************************//**
436 * @brief Set real parameter value
437 *
438 * @param[in] value Parameter value.
439 *
440 * @exception GException::invalid_value
441 * Parameter is not of real type.
442 *
443 * This method sets a real parameter. The method only applies to parameters
444 * of type "r". Other parameter types will produce an exception.
445 ***************************************************************************/
446void GApplicationPar::real(const double& value)
447{
448 // Check if parameter is boolean
449 if (m_type != "r") {
450 std::string msg = "Attempt to set "+par_type_string(m_type)+
451 " parameter \""+m_name+"\" with real value.";
453 }
454
455 // Set value string
456 std::string value_string = gammalib::str(value);
457
458 // Set value
459 set_value(value_string);
460
461 // Return
462 return;
463}
464
465
466/***********************************************************************//**
467 * @brief Query parameter if required
468 *
469 * This method queries the parameter from the stardard input if it is needed
470 * to be input by the user.
471 ***************************************************************************/
473{
474 // Continue only if parameter has query mode and it was not yet queried
475 if (is_query() && !was_queried()) {
476
477 // Dump prompt string
478 std::string prompt = m_prompt;
479 if (m_min.length() > 0 && m_max.length() > 0) {
480 prompt += " ("+m_min+"-"+m_max+")";
481 }
482 else if (m_min.length() > 0) {
483 prompt += " ("+m_min+")";
484 }
485 else if (m_max.length() > 0) {
486 prompt += " ("+m_max+")";
487 }
488 prompt += " ["+m_value+"] ";
489
490 // Get value
491 #ifdef HAVE_LIBREADLINE
492 std::string value;
493 char* line = readline(prompt.c_str());
494 if (line != NULL) {
495 value = std::string(line);
496 delete line;
497 }
498 #else
499 std::cout << prompt;
500 char line[1000];
501 std::cin.getline(line, 1000);
502 std::string value = std::string(line);
503 #endif
504
505 // Strip any whitespace from string
507
508 // Update value if value is not the default
509 if (value.length() > 0) {
511 m_update = true;
512 }
513
514 // Don't query parameter again
515 stop_query();
516
517 } // endif: parameter had query mode
518
519 // Return
520 return;
521}
522
523
524/***********************************************************************//**
525 * @brief Returns parameter value as string
526 *
527 * This method queries any parameter and returns it as a string. No parameter
528 * type checking is performed.
529 ***************************************************************************/
530std::string GApplicationPar::value(void)
531{
532 // Query parameter
533 query();
534
535 // Return value
536 return m_value;
537}
538
539
540/***********************************************************************//**
541 * @brief Returns string parameter value
542 *
543 * @exception GException::invalid_value
544 * Parameter is not of string type.
545 *
546 * This method queries and returns a string parameter. The method only
547 * applies to parameters of type "s". Other parameter types will produce an
548 * exception.
549 ***************************************************************************/
550std::string GApplicationPar::string(void)
551{
552 // Check if parameter is a string parameter
553 if (m_type != "s") {
554 std::string msg = "Attempt to read "+par_type_string(m_type)+
555 " parameter \""+m_name+"\" as a string value.";
557 }
558
559 // Query parameter
560 query();
561
562 // Check if parameter is valid
563 if (m_status != ST_VALID) {
564 std::string msg = "Parameter \""+m_name+"\" is "+
565 par_status_string()+". Please specify a valid"
566 " parameter value.";
568 }
569
570 // Return value
571 return m_value;
572}
573
574
575/***********************************************************************//**
576 * @brief Returns filename parameter value
577 *
578 * @exception GException::invalid_value
579 * Parameter is not of filename type.
580 *
581 * This method queries and returns a filename parameter. The method only
582 * applies to filename parameters. Other parameter types will produce an
583 * exception. Any environment variables that are encountered within the
584 * filename are expanded automatically.
585 ***************************************************************************/
587{
588 // Check if parameter is a filename parameter
589 if (!is_filename()) {
590 std::string msg = "Attempt to read "+par_type_string(m_type)+
591 " parameter \""+m_name+"\" as a filename value.";
593 }
594
595 // Query parameter
596 query();
597
598 // Check if parameter is valid
599 if (m_status != ST_VALID) {
600 std::string msg = "Parameter \""+m_name+"\" is "+
601 par_status_string()+". Please specify a valid"
602 " parameter value.";
604 }
605
606 // Return value
607 return (GFilename(m_value));
608}
609
610
611/***********************************************************************//**
612 * @brief Returns time parameter value
613 *
614 * @param[in] ref Time reference system.
615 * @return Time.
616 *
617 * @exception GException::invalid_value
618 * Parameter is not of time type.
619 *
620 * This method queries and returns a time parameter. The method only applies
621 * to time parameters. Other parameter types will produce an exception. If
622 * the time is specified as "Mission Elapsed Time" (MET) the specified
623 * time reference system will be used for conversion.
624 ***************************************************************************/
626{
627 // Check if parameter is a time parameter
628 if (m_type != "t") {
629 std::string msg = "Attempt to read "+par_type_string(m_type)+
630 " parameter \""+m_name+"\" as a time value.";
632 }
633
634 // Query parameter
635 query();
636
637 // Check if parameter is valid
638 if (m_status != ST_VALID) {
639 std::string msg = "Parameter \""+m_name+"\" is "+
640 par_status_string()+". Please specify a valid"
641 " parameter value.";
643 }
644
645 // Return value
646 return (GTime(m_value, ref));
647}
648
649
650/***********************************************************************//**
651 * @brief Returns boolean
652 *
653 * @exception GException::invalid_value
654 * Parameter is not of boolean type.
655 *
656 * This method queries and returns a boolean parameter. The method only
657 * applies to parameters of type "b". Other parameter types will produce an
658 * exception.
659 ***************************************************************************/
661{
662 // Check if parameter is boolean
663 if (m_type != "b") {
664 std::string msg = "Attempt to read "+par_type_string(m_type)+
665 " parameter \""+m_name+"\" as a boolean value.";
667 }
668
669 // Query parameter
670 query();
671
672 // Check if parameter is valid
673 if (m_status != ST_VALID) {
674 std::string msg = "Parameter \""+m_name+"\" is "+
675 par_status_string()+". Please specify a valid"
676 " parameter value.";
678 }
679
680 // Convert boolean value to upper case
681 std::string uvalue = gammalib::toupper(m_value);
682
683 // Set result
684 bool result = (uvalue == "YES" || uvalue == "Y" ||
685 uvalue == "TRUE" || uvalue == "T");
686
687 // Return result
688 return result;
689}
690
691
692/***********************************************************************//**
693 * @brief Returns integer
694 *
695 * @exception GException::invalid_value
696 * Parameter is not of integer type.
697 *
698 * This method queries and returns an integer parameter. The method only
699 * applies to parameters of type "i". Other parameter types will produce an
700 * exception.
701 ***************************************************************************/
703{
704 // Check if parameter is integer
705 if (m_type != "i") {
706 std::string msg = "Attempt to read "+par_type_string(m_type)+
707 " parameter \""+m_name+"\" as a integer value.";
709 }
710
711 // Query parameter
712 query();
713
714 // Check if parameter is valid
715 if (m_status != ST_VALID) {
716 std::string msg = "Parameter \""+m_name+"\" is "+
717 par_status_string()+". Please specify a valid"
718 " parameter value.";
720 }
721
722 // Set result
723 int result = gammalib::toint(m_value);
724
725 // Return result
726 return result;
727}
728
729
730/***********************************************************************//**
731 * @brief Returns real
732 *
733 * @exception GException::invalid_value
734 * Parameter is not of real type.
735 *
736 * This method queries and returns a real parameter. The method only
737 * applies to parameters of type "r". Other parameter types will produce an
738 * exception.
739 ***************************************************************************/
741{
742 // Check if parameter is integer
743 if (m_type != "r") {
744 std::string msg = "Attempt to read "+par_type_string(m_type)+
745 " parameter \""+m_name+"\" as a real value.";
747 }
748
749 // Query parameter
750 query();
751
752 // Check if parameter is valid
753 if (m_status != ST_VALID) {
754 std::string msg = "Parameter \""+m_name+"\" is "+
755 par_status_string()+". Please specify a valid"
756 " parameter value.";
758 }
759
760 // Set result
761 double result = gammalib::todouble(m_value);
762
763 // Return result
764 return result;
765}
766
767
768/***********************************************************************//**
769 * @brief Signals if parameter mode is "learn"
770 *
771 * A parameter is in mode learn when it has one of the following modes:
772 * hl,ql,lh, or lq.
773 ***************************************************************************/
775{
776 // Assign result
777 bool result = (m_mode == "hl" || m_mode == "ql" || m_mode == "lh" ||
778 m_mode == "lq");
779
780 // Return result
781 return result;
782}
783
784
785/***********************************************************************//**
786 * @brief Signals if parameter mode is "query"
787 *
788 * A parameter will be queried when it has one of the following modes:
789 * q, ql, or lq.
790 ***************************************************************************/
792{
793 // Assign result
794 bool result = (m_mode == "q" || m_mode == "ql" || m_mode == "lq");
795
796 // Return result
797 return result;
798}
799
800
801/***********************************************************************//**
802 * @brief Signals if parameter mode is of type "filename"
803 *
804 * A parameter is of type "filename" if it has one of the following types:
805 * f, fr, fw, fe, or fn.
806 ***************************************************************************/
808{
809 // Assign result
810 bool result = (m_type == "f" || m_type == "fr" || m_type == "fw" ||
811 m_type == "fe" || m_type == "fn");
812
813 // Return result
814 return result;
815}
816
817
818/***********************************************************************//**
819 * @brief Signals if parameter is valid
820 ***************************************************************************/
822{
823 // Query parameter
824 query();
825
826 // Return validity
827 return (m_status == ST_VALID);
828}
829
830
831/***********************************************************************//**
832 * @brief Signals if parameter is undefined
833 ***************************************************************************/
835{
836 // Query parameter
837 query();
838
839 // Return validity
840 return (m_status == ST_UNDEFINED);
841}
842
843
844/***********************************************************************//**
845 * @brief Signals if parameter is not a number
846 ***************************************************************************/
848{
849 // Query parameter
850 query();
851
852 // Return validity
853 return (m_status == ST_NAN);
854}
855
856
857/***********************************************************************//**
858 * @brief Set class from pickled string vector
859 *
860 * @param[in] string String vector containing class information.
861 ***************************************************************************/
862void GApplicationPar::pickle(const std::vector<std::string>& string)
863{
864 // Clear object
865 clear();
866
867 // Extract members
868 m_update = (bool)gammalib::toint(string[0]);
869 m_queried = (bool)gammalib::toint(string[1]);
870 m_name = string[2];
871 m_type = string[3];
872 m_mode = string[4];
873 m_value = string[5];
874 m_min = string[6];
875 m_max = string[7];
876 m_prompt = string[8];
877 m_status = (Status)gammalib::toint(string[9]);
878
879 // Return
880 return;
881}
882
883
884/***********************************************************************//**
885 * @brief Return pickled string vector
886 *
887 * @return String vector containing class information.
888 ***************************************************************************/
889std::vector<std::string> GApplicationPar::pickle(void) const
890{
891 // Allocate vector of strings with 10 elements
892 std::vector<std::string> string(10);
893
894 // Set vector elements from class members
895 string[0] = gammalib::str(m_update);
896 string[1] = gammalib::str(m_queried);
897 string[2] = m_name;
898 string[3] = m_type;
899 string[4] = m_mode;
900 string[5] = m_value;
901 string[6] = m_min;
902 string[7] = m_max;
903 string[8] = m_prompt;
904 string[9] = gammalib::str((int)m_status);
905
906 // Return string vector
907 return (string);
908}
909
910
911/***********************************************************************//**
912 * @brief Print parameter
913 *
914 * @param[in] chatter Chattiness.
915 * @return String containing parameter information.
916 ***************************************************************************/
917std::string GApplicationPar::print(const GChatter& chatter) const
918{
919 // Initialise result string
920 std::string result;
921
922 // Continue only if chatter is not silent
923 if (chatter != SILENT) {
924
925 // Write parameter name
926 result = gammalib::parformat(name());
927
928 // Write value (use m_value here to avoid querying when printing)
929 switch (m_status) {
930 case ST_VALID:
931 result.append(m_value);
932 break;
933 case ST_UNDEFINED:
934 result.append("undefined");
935 break;
936 case ST_NAN:
937 result.append("nan");
938 break;
939 case ST_UNDERFLOW:
940 result.append(m_value+" (underflow)");
941 break;
942 case ST_OVERFLOW:
943 result.append(m_value+" (overflow)");
944 break;
945 }
946
947 // Write limits
948 if (min().length() > 0 && max().length() > 0) {
949 result.append(" ("+min()+"-"+max()+")");
950 }
951 else if (min().length() > 0) {
952 result.append(" ("+min()+")");
953 }
954
955 // Write type information
956 result.append(" [t="+type()+", m="+mode()+"]");
957
958 } // endif: chatter was not silent
959
960 // Return result
961 return result;
962}
963
964
965/*==========================================================================
966 = =
967 = Private methods =
968 = =
969 ==========================================================================*/
970
971/***********************************************************************//**
972 * @brief Initialise class members
973 ***************************************************************************/
975{
976 // Initialise members
977 m_update = false;
978 m_queried = false;
979 m_name.clear();
980 m_type.clear();
981 m_mode.clear();
982 m_value.clear();
983 m_min.clear();
984 m_max.clear();
985 m_prompt.clear();
987
988 // Return
989 return;
990}
991
992
993/***********************************************************************//**
994 * @brief Copy class members
995 *
996 * @param[in] par Parameter.
997 ***************************************************************************/
999{
1000 // Copy attributes
1001 m_update = par.m_update;
1002 m_queried = par.m_queried;
1003 m_name = par.m_name;
1004 m_type = par.m_type;
1005 m_mode = par.m_mode;
1006 m_value = par.m_value;
1007 m_min = par.m_min;
1008 m_max = par.m_max;
1009 m_prompt = par.m_prompt;
1010 m_status = par.m_status;
1011
1012 // Return
1013 return;
1014}
1015
1016
1017/***********************************************************************//**
1018 * @brief Delete class members
1019 ***************************************************************************/
1021{
1022 // Return
1023 return;
1024}
1025
1026
1027/***********************************************************************//**
1028 * @brief Test validity of type string
1029 *
1030 * @param[in] type Type string.
1031 *
1032 * @exception GException::invalid_value
1033 * Invalid parameter type.
1034 *
1035 * The parameter type has to be one of b,i,r,s,f,fr,fw,fe,fn,t.
1036 * The fr,fw,fe,fn types test for read access, write access, file existence,
1037 * and file absence, respectively.
1038 ***************************************************************************/
1039void GApplicationPar::check_type(const std::string& type) const
1040{
1041 // Check if type is valid
1042 if (type != "b" && type != "i" && type != "r" && type != "s" &&
1043 type != "f" && type != "fr" && type != "fw" && type != "fe" &&
1044 type != "fn" && type != "t") {
1045 std::string msg = "Invalid parameter type \""+type+"\" encountered"
1046 " for parameter \""+m_name+"\".";
1048 }
1049
1050 // Return
1051 return;
1052}
1053
1054
1055/***********************************************************************//**
1056 * @brief Test validity of mode string
1057 *
1058 * @param[in] mode Mode string.
1059 *
1060 * @exception GException::invalid_value
1061 * Invalid parameter mode.
1062 *
1063 * The parameter mode has to be one of a,h,l,q,hl,ql,lh,lq.
1064 ***************************************************************************/
1065void GApplicationPar::check_mode(const std::string& mode) const
1066{
1067 // Check of mode is valid
1068 if (mode != "a" && mode != "h" && mode != "q" && mode != "hl" &&
1069 mode != "ql" && mode != "lh" && mode != "lq") {
1070 std::string msg = "Invalid parameter mode \""+mode+"\" encountered"
1071 " for parameter \""+m_name+"\".";
1073 }
1074
1075 // Return
1076 return;
1077}
1078
1079
1080/***********************************************************************//**
1081 * @brief Test validity of value string
1082 *
1083 * @param[in] value Value string.
1084 *
1085 * Requires that m_type, m_min and m_max are set. The method does not verify
1086 * if m_type is valid.
1087 ***************************************************************************/
1088void GApplicationPar::check_value(const std::string& value) const
1089{
1090 // Make type dependent check
1091 if (m_type == "b") {
1093 }
1094 else if (m_type == "i") {
1096 }
1097 else if (m_type == "r") {
1099 }
1100 else if (m_type == "s") {
1102 }
1103 else if (m_type == "t") {
1105 }
1106 else if (is_filename()) {
1108 }
1109
1110 // Return
1111 return;
1112}
1113
1114
1115/***********************************************************************//**
1116 * @brief Test validity of boolean value string
1117 *
1118 * @param[in] value Value string.
1119 *
1120 * @exception GException::invalid_value
1121 * Boolean value string is not valid.
1122 *
1123 * The Boolean value string has to be one of y,yes,true,t or n,no,false,f
1124 * (case insensitive).
1125 ***************************************************************************/
1126void GApplicationPar::check_value_bool(const std::string& value) const
1127{
1128 // Turn value to lower case for testing
1129 std::string lvalue = gammalib::tolower(value);
1130
1131 // Test for validity
1132 if (lvalue != "y" && lvalue != "yes" && lvalue != "true" && lvalue != "t" &&
1133 lvalue != "n" && lvalue != "no" && lvalue != "false" && lvalue != "f") {
1134 std::string msg = "Invalid boolean value \""+value+"\" encountered"
1135 " for parameter \""+m_name+"\". Use"
1136 " y/n/yes/no/t/f/true/false";
1138 }
1139
1140 // Return
1141 return;
1142}
1143
1144
1145/***********************************************************************//**
1146 * @brief Test validity of integer parameter value
1147 *
1148 * @param[in] value Parameter value.
1149 *
1150 * @exception GException::invalid_value
1151 * Integer parameter value outside validity range
1152 *
1153 * If either options or a validity range has been specified, check if the
1154 * integer parameter value satisfies the validity constraints.
1155 *
1156 * Requires that m_type, m_status, m_min and m_max are set. The method does
1157 * not verify if m_type is valid.
1158 ***************************************************************************/
1159void GApplicationPar::check_value_int(const std::string& value) const
1160{
1161 // Check only if value is not undefined
1162 if (m_status != ST_UNDEFINED) {
1163
1164 // Check for options
1165 bool has_options = check_options(value);
1166
1167 // If no options check has been done and if there is a m_min and
1168 // m_max value then perform an integer check
1169 if (!has_options && m_min.length() > 0 && m_max.length() > 0) {
1170
1171 // Throw an exception if we have a NAN parameter
1172 if (m_status == ST_NAN) {
1173 std::string msg = "Parameter \""+m_name+"\" value \""+value+
1174 "\" outside validity range ["+m_min+","+
1175 m_max+"].";
1177 }
1178
1179 // Convert value and range to integers
1180 int ivalue = gammalib::toint(value);
1181 int imin = gammalib::toint(m_min);
1182 int imax = gammalib::toint(m_max);
1183
1184 // Check if value is outside range
1185 if (imin > ivalue || imax < ivalue) {
1186 std::string msg = "Parameter \""+m_name+"\" value \""+value+
1187 "\" outside validity range ["+m_min+","+
1188 m_max+"].";
1190 }
1191
1192 } // endif: there was no options check and there was a range specified
1193
1194 } // endif: value was not undefined
1195
1196 // Return
1197 return;
1198}
1199
1200
1201/***********************************************************************//**
1202 * @brief Test validity of real parameter value
1203 *
1204 * @param[in] value Parameter value.
1205 *
1206 * @exception GException::invalid_value
1207 * Real parameter value outside validity range
1208 *
1209 * If either options or a validity range has been specified, check if the
1210 * real parameter value satisfies the validity constraints.
1211 *
1212 * Requires that m_type, m_status, m_min and m_max are set. The method does
1213 * not verify if m_type is valid.
1214 ***************************************************************************/
1215void GApplicationPar::check_value_real(const std::string& value) const
1216{
1217 // Check only if value is not undefined
1218 if (m_status != ST_UNDEFINED) {
1219
1220 // Check for options
1221 bool has_options = check_options(value);
1222
1223 // If no options check has been done and if there is a m_min and
1224 // m_max value then perform an integer check
1225 if (!has_options && m_min.length() > 0 && m_max.length() > 0) {
1226
1227 // Throw an exception if we have a NAN parameter
1228 if (m_status == ST_NAN) {
1229 std::string msg = "Parameter \""+m_name+"\" value \""+value+
1230 "\" outside validity range ["+m_min+","+
1231 m_max+"].";
1233 }
1234
1235 // Convert value and range to doubles
1236 double dvalue = gammalib::todouble(value);
1237 double dmin = gammalib::todouble(m_min);
1238 double dmax = gammalib::todouble(m_max);
1239
1240 // Check if value is outside range
1241 if (dmin > dvalue || dmax < dvalue) {
1242 std::string msg = "Parameter \""+m_name+"\" value \""+value+
1243 "\" outside validity range ["+m_min+","+
1244 m_max+"].";
1246 }
1247
1248 } // endif: there was no options check and there was a range specified
1249
1250 } // endif: value was not undefined
1251
1252 // Return
1253 return;
1254}
1255
1256
1257/***********************************************************************//**
1258 * @brief Test validity of string parameter value
1259 *
1260 * @param[in] value Parameter value.
1261 *
1262 * If options have been specified, check if the string parameter value
1263 * satisfies the options.
1264 *
1265 * Requires that m_type, m_min and m_max are set. The method does not verify
1266 * if m_type is valid.
1267 ***************************************************************************/
1268void GApplicationPar::check_value_string(const std::string& value) const
1269{
1270 // Check for options
1272
1273 // Return
1274 return;
1275}
1276
1277
1278/***********************************************************************//**
1279 * @brief Test validity of filename parameter value
1280 *
1281 * @param[in] value Parameter value.
1282 *
1283 * If options have been specified, check if the filename parameter value
1284 * satisfies the options.
1285 *
1286 * Requires that m_type, m_min and m_max are set. The method does not verify
1287 * if m_type is valid.
1288 *
1289 * @todo NONE is equivalent to an empty string.
1290 ***************************************************************************/
1291void GApplicationPar::check_value_filename(const std::string& value) const
1292{
1293 // Check for options
1295
1296 // Return
1297 return;
1298}
1299
1300
1301/***********************************************************************//**
1302 * @brief Test validity of time parameter value
1303 *
1304 * @param[in] value Parameter value.
1305 *
1306 * If options have been specified, check if the time parameter value
1307 * satisfies the options.
1308 *
1309 * Requires that m_type, m_min and m_max are set. The method does not verify
1310 * if m_type is valid.
1311 ***************************************************************************/
1312void GApplicationPar::check_value_time(const std::string& value) const
1313{
1314 // Check for options
1316
1317 // Return
1318 return;
1319}
1320
1321
1322/***********************************************************************//**
1323 * @brief Test if parameter value satisfies possible options
1324 *
1325 * @param[in] value Parameter value.
1326 * @return True if there were options, false otherwise.
1327 *
1328 * @exception GException::invalid_value
1329 * Value does not satisfy one of the possible options.
1330 *
1331 * In case that the parameter has different options (m_max field not set and
1332 * at least one character chain in m_min field, multiple chains separated by
1333 * pipe symbol), check that the parameter value corresponds to one of the
1334 * values in the m_min field. For strings, and for strings only, the
1335 * parameter check is case insensitive.
1336 ***************************************************************************/
1337bool GApplicationPar::check_options(const std::string& value) const
1338{
1339 // Initialise options flags
1340 bool has_options = false;
1341
1342 // Continue only if the m_max field is not set
1343 if (m_max.length() == 0) {
1344
1345 // Get parameter options
1346 std::vector<std::string> options = gammalib::split(m_min, "|");
1347
1348 // Determine number of options
1349 int num_options = options.size();
1350
1351 // Continue only if there are options
1352 if (num_options > 0) {
1353
1354 // Signal that there were options
1355 has_options = true;
1356
1357 // Initalise found flag
1358 bool found = false;
1359
1360 // Strip whitespace from all options, and for strings, convert
1361 // to upper case
1362 for (int i = 0; i < num_options; ++i) {
1363 options[i] = gammalib::strip_whitespace(options[i]);
1364 if (m_type == "s") {
1365 options[i] = gammalib::toupper(options[i]);
1366 }
1367 }
1368
1369 // Set parameter value
1370 std::string v = (m_type == "s") ? gammalib::toupper(value) : value;
1371
1372 // Now check if we can find one of the options
1373 for (int i = 0; i < num_options; ++i) {
1374 if (options[i] == v) {
1375 found = true;
1376 break;
1377 }
1378 }
1379
1380 // If no option was found then throw exception
1381 if (!found) {
1382 std::string msg = "Parameter \""+m_name+"\" value \""+value+
1383 "\" invalid. Must be one of \""+m_min+"\".";
1385 }
1386
1387 } // endif: there were parameter options
1388
1389 } // endif: the m_max field was not set
1390
1391 // Return options flag
1392 return has_options;
1393}
1394
1395
1396/***********************************************************************//**
1397 * @brief Set parameter status
1398 *
1399 * @param[in] value Parameter value.
1400 * @return Updated parameter value.
1401 *
1402 * Set parameter status depending on the content of the value field.
1403 *
1404 * For an integer parameter, INDEF, NONE, UNDEF or UNDEFINED will result in
1405 * a status of "undefined". INF, INFINITY or NAN will be transformed in the
1406 * maximum long number.
1407 *
1408 * For a real parameter, INDEF, NONE, UNDEF or UNDEFINED will result in a
1409 * status of "undefined", while INF, INFINITY or NAN will result in a status
1410 * of "nan".
1411 *
1412 * For a time parameter, INDEF, NONE, UNDEF or UNDEFINED will result in a
1413 * status of "undefined".
1414 *
1415 * For a filename parameter, an empty string or INDEF, NONE, UNDEF or
1416 * UNDEFINED will result in a status of "undefined".
1417 ***************************************************************************/
1418std::string GApplicationPar::set_status(const std::string& value)
1419{
1420 // Initialise result value
1421 std::string result = value;
1422
1423 // Set integer status. Catch the special values that signal that a
1424 // parameter is undefined. Any infinity or nan is set to the maximum
1425 // long value (APE standard)
1426 if (m_type == "i") {
1427 std::string lvalue = gammalib::tolower(value);
1428 if (lvalue == "indef" ||
1429 lvalue == "none" ||
1430 lvalue == "undef" ||
1431 lvalue == "undefined") {
1433 }
1434 else if (lvalue == "inf" ||
1435 lvalue == "infinity" ||
1436 lvalue == "nan") {
1437 result = gammalib::str(LONG_MAX);
1439 }
1440 else {
1442 }
1443 }
1444
1445 // Set real status. Catch the special values that signal that a
1446 // parameter is undefined, infinity or nan (APE standard).
1447 else if (m_type == "r") {
1448 std::string lvalue = gammalib::tolower(value);
1449 if (lvalue == "indef" ||
1450 lvalue == "none" ||
1451 lvalue == "undef" ||
1452 lvalue == "undefined") {
1454 }
1455 else if (lvalue == "inf" ||
1456 lvalue == "infinity" ||
1457 lvalue == "nan") {
1458 m_status = ST_NAN;
1459 }
1460 else {
1462 }
1463 }
1464
1465 // Set time status. Catch the special values that signal that a parameter
1466 // is undefined.
1467 else if (m_type == "t") {
1468 std::string lvalue = gammalib::tolower(value);
1469 if (lvalue == "indef" ||
1470 lvalue == "none" ||
1471 lvalue == "undef" ||
1472 lvalue == "undefined") {
1474 }
1475 else {
1477 }
1478 }
1479
1480 // Set filename status. Catch the special values that signal that a
1481 // parameter is undefined.
1482 else if (m_type == "f") {
1483 std::string lvalue = gammalib::tolower(value);
1484 if (lvalue == "" ||
1485 lvalue == "indef" ||
1486 lvalue == "none" ||
1487 lvalue == "undef" ||
1488 lvalue == "undefined") {
1490 }
1491 else {
1493 }
1494 }
1495
1496 // Set other status
1497 else {
1499 }
1500
1501 // Return result value
1502 return result;
1503}
1504
1505
1506/***********************************************************************//**
1507 * @brief Set parameter value
1508 *
1509 * @param[in] value Parameter value.
1510 *
1511 * Set parameter value, signal it for update and disable parameter querying.
1512 ***************************************************************************/
1513void GApplicationPar::set_value(const std::string& value)
1514{
1515 // Set parameter status
1516 std::string par_value = set_status(value);
1517
1518 // Check parameter value
1519 check_value(par_value);
1520
1521 // Set parameter value
1522 m_value = par_value;
1523
1524 // Signal update
1525 m_update = true;
1526
1527 // Don't query parameter again
1528 stop_query();
1529
1530 // Return
1531 return;
1532}
1533
1534
1535/***********************************************************************//**
1536 * @brief Don't query parameter again
1537 ***************************************************************************/
1539{
1540 // Don't query parameter again
1541 m_queried = true;
1542
1543 // Return
1544 return;
1545}
1546
1547
1548/***********************************************************************//**
1549 * @brief Return type string
1550 *
1551 * @param[in] type Parameter type.
1552 *
1553 * Translates parameter type character(s) into a human readable type string.
1554 * Valid parameter types are: b,i,r,s,f,fr,fw,fe,fn,t. If the parameter type
1555 * is not valid, the method returns "unknown".
1556 ***************************************************************************/
1557std::string GApplicationPar::par_type_string(const std::string& type) const
1558{
1559 // Initialize empty type string
1560 std::string type_string = "";
1561
1562 // Set type dependent string
1563 if (type == "b") {
1564 type_string.append("boolean");
1565 }
1566 else if (type == "i") {
1567 type_string.append("integer");
1568 }
1569 else if (type == "r") {
1570 type_string.append("real");
1571 }
1572 else if (type == "s") {
1573 type_string.append("string");
1574 }
1575 else if (type == "f" || type == "fr" || type == "fw" ||
1576 type == "fe" || type == "fn") {
1577 type_string.append("filename");
1578 }
1579 else if (type == "t") {
1580 type_string.append("time");
1581 }
1582 else {
1583 type_string.append("unknown");
1584 }
1585
1586 // Return type string
1587 return type_string;
1588}
1589
1590
1591/***********************************************************************//**
1592 * @brief Return status string
1593 *
1594 * @return Returns the parameter status in human readable form.
1595 ***************************************************************************/
1597{
1598 // Allocate status string
1599 std::string status;
1600
1601 // Set status
1602 switch (m_status) {
1603 case ST_VALID:
1604 status.append("valid");
1605 break;
1606 case ST_UNDEFINED:
1607 status.append("undefined");
1608 break;
1609 case ST_NAN:
1610 status.append("NaN");
1611 break;
1612 case ST_UNDERFLOW:
1613 status.append("underflow");
1614 break;
1615 case ST_OVERFLOW:
1616 status.append("overflow");
1617 break;
1618 }
1619
1620 // Return status
1621 return status;
1622}
#define G_BOOLEAN_SET
#define G_CHECK_OPTIONS
#define G_CHECK_VALUE_REAL
#define G_STRING_GET
#define G_TIME_GET
#define G_INTEGER_GET
#define G_FILENAME_GET
#define G_CHECK_VALUE_BOOL
#define G_CHECK_VALUE_INT
#define G_TIME_SET
#define G_INTEGER_SET
#define G_STRING_SET
< Needed for declaration of LONG_MAX
#define G_CHECK_MODE
#define G_FILENAME_SET
#define G_CHECK_TYPE
#define G_BOOLEAN_GET
#define G_REAL_SET
#define G_REAL_GET
Application parameter class definition.
Exception handler interface definition.
Filename class interface definition.
Time class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
double min(const GVector &vector)
Computes minimum vector element.
Definition GVector.cpp:954
double max(const GVector &vector)
Computes maximum vector element.
Definition GVector.cpp:983
Application parameter class.
bool check_options(const std::string &value) const
Test if parameter value satisfies possible options.
std::string m_name
Parameter name.
std::string m_min
Parameter minimum.
void copy_members(const GApplicationPar &par)
Copy class members.
std::vector< std::string > pickle(void) const
Return pickled string vector.
std::string m_value
Parameter value.
void check_value_bool(const std::string &value) const
Test validity of boolean value string.
std::string m_type
Parameter type.
const std::string & mode(void) const
Returns parameter mode.
void check_value_time(const std::string &value) const
Test validity of time parameter value.
void check_value_int(const std::string &value) const
Test validity of integer parameter value.
double real(void)
Returns real.
bool is_learn(void) const
Signals if parameter mode is "learn".
void clear(void)
Clear parameter.
GApplicationPar & operator=(const GApplicationPar &par)
Assignment operator.
const std::string & max(void) const
Returns parameter maximum.
std::string m_mode
Parameter mode.
bool is_valid(void)
Signals if parameter is valid.
GTime time(void)
Return time in native reference system.
std::string string(void)
Returns string parameter value.
void init_members(void)
Initialise class members.
GApplicationPar * clone(void) const
Clone parameter.
void free_members(void)
Delete class members.
bool m_update
Signal value updating.
bool m_queried
Signal that parameter was queried.
std::string par_type_string(const std::string &type) const
Return type string.
std::string print(const GChatter &chatter=NORMAL) const
Print parameter.
std::string m_max
Parameter maximum.
bool is_notanumber(void)
Signals if parameter is not a number.
void check_value_string(const std::string &value) const
Test validity of string parameter value.
GApplicationPar(void)
Void constructor.
void check_type(const std::string &type) const
Test validity of type string.
void query(void)
Query parameter if required.
bool boolean(void)
Returns boolean.
const std::string & name(void) const
Returns parameter name.
std::string value(void)
Returns parameter value as string.
const std::string & type(void) const
Returns parameter type.
std::string par_status_string(void) const
Return status string.
GFilename filename(void)
Returns filename parameter value.
bool is_undefined(void)
Signals if parameter is undefined.
std::string set_status(const std::string &value)
Set parameter status.
void check_mode(const std::string &mode) const
Test validity of mode string.
const std::string & prompt(void) const
Returns parameter prompt.
void set_value(const std::string &value)
Set parameter value.
const std::string & min(void) const
Returns parameter minimum.
bool is_filename(void) const
Signals if parameter mode is of type "filename".
virtual ~GApplicationPar(void)
Destructor.
void check_value_real(const std::string &value) const
Test validity of real parameter value.
void check_value_filename(const std::string &value) const
Test validity of filename parameter value.
Status m_status
Parameter status.
void stop_query(void)
Don't query parameter again.
bool was_queried(void) const
Signals if parameter was queried.
bool is_query(void) const
Signals if parameter mode is "query".
int integer(void)
Returns integer.
void check_value(const std::string &value) const
Test validity of value string.
std::string m_prompt
Parameter prompt.
Filename class.
Definition GFilename.hpp:62
Implements a time reference.
Time class.
Definition GTime.hpp:55
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1162
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508
double todouble(const std::string &arg)
Convert string into double precision value.
Definition GTools.cpp:945
std::string tolower(const std::string &s)
Convert string to lower case.
Definition GTools.cpp:974
int toint(const std::string &arg)
Convert string into integer value.
Definition GTools.cpp:840
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:99
std::vector< std::string > split(const std::string &s, const std::string &sep)
Split string.
Definition GTools.cpp:1002
std::string toupper(const std::string &s)
Convert string to upper case.
Definition GTools.cpp:960