# MI - Fimex: include/fimex/Utils.h Source File

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

# include/fimex/Utils.h

Go to the documentation of this file.

    00001 /*
    00002  * Fimex
    00003  *
    00004  * (C) Copyright 2008, met.no
    00005  *
    00006  * Project Info:  https://wiki.met.no/fimex/start
    00007  *
    00008  * This library is free software; you can redistribute it and/or modify it
    00009  * under the terms of the GNU Lesser General Public License as published by
    00010  * the Free Software Foundation; either version 2.1 of the License, or
    00011  * (at your option) any later version.
    00012  *
    00013  * This library is distributed in the hope that it will be useful, but
    00014  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00015  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    00016  * License for more details.
    00017  *
    00018  * You should have received a copy of the GNU Lesser General Public
    00019  * License along with this library; if not, write to the Free Software
    00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    00021  * USA.
    00022  */
    00023
    00024 #ifndef UTILS_H_
    00025 #define UTILS_H_
    00026
    00027 #include <vector>
    00028 #include <sstream>
    00029 #include <cmath>
    00030 #include <boost/date_time/posix_time/posix_time_types.hpp>
    00031 #include "fimex/CDMException.h"
    00032
    00033 namespace MetNoFimex
    00034 {
    00038 int round(double num);
    00039
    00044 std::string trim(const std::string& str);
    00045
    00053 template<class InputIterator>
    00054 std::string join(InputIterator start, InputIterator end, std::string delim = ",")
    00055 {
    00056     if (start == end) return "";
    00057     std::ostringstream buffer;
    00058     InputIterator current = start++;
    00059     while (start != end) {
    00060         buffer << *current << delim;
    00061         current = start++;
    00062     }
    00063     buffer << *current;
    00064     return buffer.str();
    00065 }
    00066
    00074 template<class InputIterator>
    00075 std::string joinPtr(InputIterator start, InputIterator end, std::string delim = ",")
    00076 {
    00077     if (start == end) return "";
    00078     std::ostringstream buffer;
    00079     InputIterator current = start++;
    00080     while (start != end) {
    00081         buffer << **current << delim;
    00082         current = start++;
    00083     }
    00084     buffer << **current;
    00085     return buffer.str();
    00086 }
    00087
    00097 std::vector<std::string> tokenize(const std::string& str, const std::string& delimiters = " ");
    00098
    00099
    00103 std::string string2lowerCase(const std::string& str);
    00104
    00108 template<typename T>
    00109 std::string type2string(T in) {
    00110         std::ostringstream buffer;
    00111         buffer << in;
    00112         return buffer.str();
    00113 }
    00114
    00118 template<>
    00119 std::string type2string<double>(double in);
    00120
    00121
    00122 template<typename T>
    00123 T string2type(std::string s) {
    00124         T retVal;
    00125         std::stringstream buffer;
    00126         buffer << s;
    00127         buffer >> retVal;
    00128         return retVal;
    00129 }
    00130
    00131 typedef long epoch_seconds;
    00136 epoch_seconds posixTime2epochTime(const boost::posix_time::ptime& time);
    00137
    00143 template<typename T>
    00144 std::vector<T> tokenizeDotted(const std::string& str, const std::string& delimiter = ",") throw(CDMException)
    00145 {
    00146         std::vector<std::string> tokens = tokenize(str, delimiter);
    00147     std::vector<T> vals;
    00148     for (std::vector<std::string>::iterator tok = tokens.begin(); tok != tokens.end(); ++tok) {
    00149                 std::string current = trim(*tok);
    00150                 if (current == "...") {
    00151             size_t currentPos = vals.size();
    00152             if (currentPos < 2) {
    00153                 throw CDMException("tokenizeDotted: cannot use ... expansion at position " + type2string(currentPos-1) +", need at least two values before");
    00154             }
    00155             T last = vals[currentPos-1];
    00156             T dist = last - vals[currentPos-2];
    00157             T curVal = last + dist;
    00158             if (++tok != tokens.end()) {
    00159                 T afterDotVal = string2type<T>(*tok);
    00160                 // expand the dots until before the afterDotVal, compare against rounding error
    00161                 while (fabs(static_cast<double>(curVal - afterDotVal)) > 1e-5) {
    00162                     vals.push_back(curVal);
    00163                     curVal += dist;
    00164                 }
    00165                 // add the afterDotVal
    00166                 vals.push_back(afterDotVal);
    00167             }
    00168                 } else {
    00169                         T val = string2type<T>(current);
    00170                         vals.push_back(val);
    00171                 }
    00172         }
    00173         return vals;
    00174 }
    00175
    00177 template<typename OUT>
    00178 struct staticCast {
    00179     template<typename IN>
    00180     OUT operator()(const IN& in) { return static_cast<OUT>(in); }
    00181 };
    00182
    00183
    00187 template<typename IN, typename OUT>
    00188 class ScaleValue : public std::unary_function<IN, OUT>
    00189 {
    00190 private:
    00191     IN oldFill_;
    00192     double oldScale_;
    00193     double oldOffset_;
    00194     OUT newFill_;
    00195     double newScale_;
    00196     double newOffset_;
    00197 public:
    00198     ScaleValue(double oldFill, double oldScale, double oldOffset, double newFill, double newScale, double newOffset) :
    00199         oldFill_(static_cast<IN>(oldFill)), oldScale_(oldScale), oldOffset_(oldOffset),
    00200         newFill_(static_cast<OUT>(newFill)), newScale_(newScale), newOffset_(newOffset) {}
    00201     OUT operator()(const IN& in) const {
    00202         if (in == oldFill_ || isinf(static_cast<double>(in))) {
    00203             return newFill_;
    00204         } else {
    00205             return static_cast<OUT>(((oldScale_*in + oldOffset_)-newOffset_)/newScale_);
    00206         }
    00207     }
    00208 };
    00209
    00213 template<typename IN, typename OUT>
    00214 class ChangeMissingValue : public std::unary_function<IN, OUT>
    00215 {
    00216 private:
    00217     IN oldFill_;
    00218     OUT newFill_;
    00219 public:
    00220     ChangeMissingValue(double oldFill, double newFill) :
    00221         oldFill_(static_cast<IN>(oldFill)), newFill_(static_cast<OUT>(newFill)) {}
    00222     OUT operator()(const IN& in) const {
    00223         if (in == oldFill_ || isinf(static_cast<double>(in))) {
    00224             return newFill_;
    00225         } else {
    00226             return static_cast<OUT>(in);
    00227         }
    00228     }
    00229 };
    00230
    00231 }
    00232
    00233 #endif /*UTILS_H_*/