"Fossies" - the Fresh Open Source Software Archive

Member "fimex-1.4.1/src/metgm/MetGmCDMReaderSlicedImpl.cc" (30 Oct 2019, 10640 Bytes) of package /linux/privat/fimex-1.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "MetGmCDMReaderSlicedImpl.cc" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Fimex
    3  *
    4  * (C) Copyright 2011, met.no
    5  *
    6  * Project Info:  https://wiki.met.no/fimex/start
    7  *
    8  * This library is free software; you can redistribute it and/or modify it
    9  * under the terms of the GNU Lesser General Public License as published by
   10  * the Free Software Foundation; either version 2.1 of the License, or
   11  * (at your option) any later version.
   12  *
   13  * This library is distributed in the hope that it will be useful, but
   14  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
   16  * License for more details.
   17  *
   18  * You should have received a copy of the GNU Lesser General Public
   19  * License along with this library; if not, write to the Free Software
   20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
   21  * USA.
   22  */
   23 
   24 #include "MetGmCDMReaderSlicedImpl.h"
   25 
   26 // private implementation details
   27 //
   28 #include "MetGmUtils.h"
   29 #include "MetGmVersion.h"
   30 #include "MetGmHandlePtr.h"
   31 #include "MetGmGroup1Ptr.h"
   32 #include "MetGmGroup2Ptr.h"
   33 #include "MetGmGroup3Ptr.h"
   34 #include "MetGmGroup5Ptr.h"
   35 #include "MetGmDimensionsTag.h"
   36 #include "MetGmFileHandlePtr.h"
   37 
   38 // METGM C lib
   39 //
   40 #include "metgm.h"
   41 
   42 // fimex
   43 //
   44 #include "fimex/CDM.h"
   45 #include "fimex/CDMAttribute.h"
   46 #include "fimex/CDMDimension.h"
   47 #include "fimex/CDMException.h"
   48 #include "fimex/Data.h"
   49 #include "fimex/StringUtils.h"
   50 #include "fimex/TimeUnit.h"
   51 #include "fimex/Type2String.h"
   52 #include "fimex/XMLDoc.h"
   53 
   54 #include <cassert>
   55 #include <regex>
   56 #include <tuple>
   57 
   58 // libxml2
   59 //
   60 #include <libxml/xinclude.h>
   61 #include <libxml/xpathInternals.h>
   62 
   63 //#define GXDEBUG 1
   64 
   65 namespace MetNoFimex {
   66 
   67 MetGmCDMReaderSlicedImpl::MetGmCDMReaderSlicedImpl(const std::string& mgmsource, const XMLInput& configXML, const std::shared_ptr<CDM>& cdm)
   68     : MetGmCDMReaderImpl(cdm)
   69 {
   70     sourceFileName_ = mgmsource;
   71     configId_ = configXML.id();
   72 
   73     try {
   74         init(configXML);
   75     } catch (std::runtime_error& exp) {
   76         throw CDMException(std::string("MetGmCDMReaderImpl error: ") + exp.what());
   77     }
   78     }
   79 
   80     MetGmCDMReaderSlicedImpl::~MetGmCDMReaderSlicedImpl() { }
   81 
   82     void MetGmCDMReaderSlicedImpl::addVariables()
   83     {
   84         for (const MetGmCDMVariableProfile profile : cdmConfiguration_) {
   85 
   86             int p_id = profile.p_id_;
   87 
   88             std::string fillValue = profile.fillValue_.empty() ? std::string("9999.0") : profile.fillValue_;
   89 
   90             std::vector<CDMAttribute> attributes;
   91 
   92             CDMAttribute metgmPidAttribute("metgm_p_id", "short", type2string<short>(p_id));
   93             attributes.push_back(metgmPidAttribute);
   94 
   95             CDMAttribute cfNameAttribute("standard_name", "string", profile.standardName_);
   96             attributes.push_back(cfNameAttribute);
   97 
   98             CDMAttribute varUnitsAttribute("units", "string", profile.units_);
   99             attributes.push_back(varUnitsAttribute);
  100 
  101             CDMAttribute varFillValueAttribute("_FillValue", "float", fillValue);
  102             attributes.push_back(varFillValueAttribute);
  103 
  104             if(!profile.addOffset_.empty()) {
  105                 CDMAttribute varAddOffsetAttribute("add_offset", "float", profile.addOffset_);
  106                 attributes.push_back(varAddOffsetAttribute);
  107             }
  108 
  109             if(!profile.scaleFactor_.empty()) {
  110                 CDMAttribute varScaleFactorAttribute("scale_factor", "float", profile.scaleFactor_);
  111                 attributes.push_back(varScaleFactorAttribute);
  112             }
  113 
  114             std::vector<std::string> shape;
  115 
  116             shape.push_back(xDim_.getName());
  117             shape.push_back(yDim_.getName());
  118 
  119             if(p_id != 0) {
  120 
  121                 if(!profile.zDimensionName_.empty() && cdm_->hasDimension(profile.zDimensionName_))
  122                     shape.push_back(profile.zDimensionName_);
  123 
  124                 shape.push_back(tDim_.getName());
  125             }
  126 
  127             CDMVariable var(profile.cdmName_, CDM_FLOAT, shape);
  128 
  129             cdm_->addVariable(var);
  130 
  131             for (std::vector<CDMAttribute>::const_iterator attrIt = attributes.begin(); attrIt != attributes.end(); ++attrIt) {
  132                 cdm_->addAttribute(profile.cdmName_, *attrIt);
  133             }
  134         }
  135     }
  136 
  137     DataPtr MetGmCDMReaderSlicedImpl::getDataSlice(const std::string& varName, size_t unLimDimPos)
  138     {
  139         CDMVariable& variable = cdm_->getVariable(varName);
  140 
  141         if(!cdm_->hasVariable(varName))
  142             return DataPtr();
  143 
  144         if(variable.hasData()) {
  145             return getDataSliceFromMemory(variable, unLimDimPos);
  146         } else {
  147             DataPtr data;
  148             cdm_configuration::iterator it = std::find_if(cdmConfiguration_.begin(), cdmConfiguration_.end(), MetGmCDMVariableProfileEqName(varName));
  149             if (it != cdmConfiguration_.end())
  150                 data = createData(it->pTags_->sliceDataSize(), it->pTags_->readDataSlices(unLimDimPos + 1, 1));
  151             return data;
  152         }
  153     }
  154 
  155 #if 0
  156     // this code does not work and was thought to improve performance
  157     // disabled until Alexandar fixes it
  158     DataPtr MetGmCDMReaderSlicedImpl::getDataSlice(const std::string& varName, const SliceBuilder& sb)
  159     {
  160 //        MGM_CHECK_POINT()
  161         using namespace std;
  162         DataPtr retData;
  163         const CDMVariable& variable = cdm_->getVariable(varName);
  164         if (variable.hasData()) {
  165             retData = variable.getData()->slice(sb.getMaxDimensionSizes(), sb.getDimensionStartPositions(), sb.getDimensionSizes());
  166         } else {
  167             if (cdm_->hasUnlimitedDim(variable)) {
  168                 string unLimDim = cdm_->getUnlimitedDim()->getName();
  169                 vector<string> dimNames = sb.getDimensionNames();
  170                 // get the data along the unlimited dimension and join
  171                 // unlimited dimension must be outer=first dimension!
  172                 size_t unLimDimStart = 0;
  173                 size_t unLimDimSize = 0;
  174                 vector<size_t> dimStart;
  175                 vector<size_t> dimSize;
  176                 vector<size_t> maxDimSize;
  177                 const vector<size_t>& orgDimStart = sb.getDimensionStartPositions();
  178                 const vector<size_t>& orgDimSize = sb.getDimensionSizes();
  179                 const vector<size_t>& orgMaxDimSize = sb.getMaxDimensionSizes();
  180                 size_t unLimSliceSize = 1;
  181                 for (size_t i = 0; i < dimNames.size(); ++i) {
  182                     if (dimNames.at(i) == unLimDim) {
  183                         unLimDimStart = orgDimStart.at(i);
  184                         unLimDimSize = orgDimSize.at(i);
  185                     } else {
  186                         dimStart.push_back(orgDimStart.at(i));
  187                         dimSize.push_back(orgDimSize.at(i));
  188                         maxDimSize.push_back(orgMaxDimSize.at(i));
  189                         unLimSliceSize *= orgDimSize.at(i);
  190                     }
  191                 }
  192                 if (unLimDimSize == 0) {
  193                     return createData(variable.getDataType(), 0);
  194                 }
  195 
  196                 cdmNameView& nameView = cdmConfiguration_.get<cdm_name_index>();
  197                 cdmNameView::iterator it = nameView.find(varName);
  198 
  199                 if(it == nameView.end())
  200                     return DataPtr();
  201 
  202                 MetGmCDMVariableProfile profile = *it;
  203                 retData = createData(unLimSliceSize * unLimDimSize, profile.pTags_->readDataSlices(unLimDimStart + 1, unLimDimSize));
  204                 retData = retData->slice(maxDimSize, dimStart, dimSize);
  205                 assert(retData->size() == unLimSliceSize * unLimDimSize);
  206 //                MGM_CHECK_POINT()
  207             } else {
  208                 retData = getData(varName)->slice(sb.getMaxDimensionSizes(), sb.getDimensionStartPositions(), sb.getDimensionSizes());
  209             }
  210         }
  211         return retData;
  212     }
  213 #endif
  214 
  215     void MetGmCDMReaderSlicedImpl::parseMgmFile(const std::string& mgmFileName)
  216     {
  217         pHandle_ = MetGmHandlePtr::createMetGmHandleForReading(mgmFileName);
  218         if(!(*pHandle_))
  219             throw CDMException(std::string("error opening metgm handle"));
  220 
  221         pGroup1_ = MetGmGroup1Ptr::createMetGmGroup1PtrForReading(pHandle_);
  222 
  223         pGroup2_ = MetGmGroup2Ptr::createMetGmGroup2PtrForReading(pHandle_);
  224 
  225         std::shared_ptr<MetGmVerticalTag> prevZTag;
  226 
  227         for(int index = 0; index < pGroup2_->totalnp(); ++index) {
  228 
  229             std::shared_ptr<MetGmTags> tags = MetGmTags::createMetGmTagsForSlicedReading(pGroup1_, pGroup2_, prevZTag);
  230 
  231             prevZTag = tags->zTag();
  232 
  233             std::string kildeName;
  234             std::string standardName;
  235             std::string addOffset;
  236             std::string scaleFactor;
  237             std::string strUnit(mgm_get_param_unit(tags->p_id(), *pHandle_));
  238             std::string fillValue;
  239 
  240             const MetGmConfigurationMappingsEqPId byPId(tags->p_id());
  241             xml_configuration::const_iterator pIt = std::find_if(xmlConfiguration_.begin(), xmlConfiguration_.end(), byPId), nIt;
  242             for (; pIt != xmlConfiguration_.end(); pIt = nIt) {
  243                 nIt = pIt;
  244                 nIt = std::find_if(++nIt, xmlConfiguration_.end(), byPId);
  245                 if (nIt == xmlConfiguration_.end() || (!pIt->units_.empty() && pIt->units_ == strUnit)) {
  246                     kildeName = pIt->cdmName_;
  247                     // strUnit = pIt->units_;
  248                     standardName = pIt->standardName_;
  249                     fillValue = pIt->fillValue_;
  250                     addOffset = pIt->addOffset_;
  251                     scaleFactor = pIt->scaleFactor_;
  252                     break;
  253                 }
  254             }
  255 
  256             if(!kildeName.empty()) {
  257 
  258                 std::string fixedKildeName(kildeName);
  259 
  260                 switch(tags->pr()) {
  261                 case 0:
  262                     if (!ends_with(kildeName, "MSL"))
  263                         fixedKildeName.append("_MSL");
  264                     break;
  265                 case 1:
  266                     if (!ends_with(kildeName, "GND"))
  267                         fixedKildeName.append("_GND");
  268                     break;
  269                 case 2:
  270                     if (!ends_with(kildeName, "Pa"))
  271                         fixedKildeName.append("_Pa");
  272                     break;
  273                 }
  274 
  275                 MetGmCDMVariableProfile profile(tags->p_id(), fixedKildeName, tags);
  276                 profile.standardName_ = standardName;
  277                 profile.units_ = strUnit;
  278                 profile.fillValue_ = fillValue;
  279                 profile.addOffset_ = addOffset;
  280                 profile.scaleFactor_ = scaleFactor;
  281                 cdmConfiguration_.insert(profile);
  282             }
  283         }
  284     }
  285 
  286 }