bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
GridAggregateOnOuterDimension.cc
1
2// This file is part of the "NcML Module" project, a BES module designed
3// to allow NcML files to be used to be used as a wrapper to add
4// AIS to existing datasets of any format.
5//
6// Copyright (c) 2009 OPeNDAP, Inc.
7// Author: Michael Johnson <m.johnson@opendap.org>
8//
9// For more information, please also see the main website: http://opendap.org/
10//
11// This library is free software; you can redistribute it and/or
12// modify it under the terms of the GNU Lesser General Public
13// License as published by the Free Software Foundation; either
14// version 2.1 of the License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License along with this library; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24//
25// Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26//
27// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29
30#include <sstream>
31#include <memory> // unique_ptr
32
33
34#include <libdap/DataDDS.h> // libdap
35#include <libdap/DDS.h> // libdap
36#include <libdap/Grid.h> // libdap
37
38#include "DDSLoader.h" // agg_util
39#include "Dimension.h" // agg_util
40#include "NCMLDebug.h" // ncml_module
41#include "NCMLUtil.h" // ncml_module
42
43#include "GridAggregateOnOuterDimension.h"
44
45#include "AggregationException.h"
46#include "AggregationUtil.h" // agg_util
47#include <libdap/Array.h> // libdap
48#include "ArrayAggregateOnOuterDimension.h" // agg_util
49
50using libdap::Array;
51using libdap::DataDDS;
52using libdap::DDS;
53using libdap::Grid;
54
55namespace agg_util {
56
57#define DEBUG_CHANNEL "ncml:2"
58
59// Copy local data
60void GridAggregateOnOuterDimension::duplicate(const GridAggregateOnOuterDimension& rhs)
61{
62 _newDim = rhs._newDim;
63}
64
66 const AMDList& memberDatasets, const DDSLoader& loaderProto)
67// this should give us map vectors and the member array rank (without new dim).
68:
69 GridAggregationBase(proto, memberDatasets, loaderProto), _newDim(newDim)
70{
71 BESDEBUG(DEBUG_CHANNEL, "GridAggregateOnOuterDimension() ctor called!" << endl);
72
73 createRep(memberDatasets);
74}
75
77 GridAggregationBase(proto), _newDim()
78{
79 BESDEBUG(DEBUG_CHANNEL, "GridAggregateOnOuterDimension() copy ctor called!" << endl);
80 duplicate(proto);
81}
82
83GridAggregateOnOuterDimension*
84GridAggregateOnOuterDimension::ptr_duplicate()
85{
86 return new GridAggregateOnOuterDimension(*this);
87}
88
90GridAggregateOnOuterDimension::operator=(const GridAggregateOnOuterDimension& rhs)
91{
92 if (this != &rhs) {
93 cleanup();
94 GridAggregationBase::operator=(rhs);
95 duplicate(rhs);
96 }
97 return *this;
98}
99
100GridAggregateOnOuterDimension::~GridAggregateOnOuterDimension()
101{
102 BESDEBUG(DEBUG_CHANNEL, "~GridAggregateOnOuterDimension() dtor called!" << endl);
103 cleanup();
104}
105
107// Helpers
108
109void GridAggregateOnOuterDimension::createRep(const AMDList& memberDatasets)
110{
111 BESDEBUG_FUNC(DEBUG_CHANNEL, "Replacing the Grid's data Array with an ArrayAggregateOnOuterDimension..." << endl);
112
113 // This is the prototype we need. It will have been set in the ctor.
114 const auto pArr = dynamic_cast<Array*>(array_var());
115 NCML_ASSERT_MSG(pArr, "Expected to find a contained data Array but we did not!");
116
117 // Create the Grid version of the read getter and make a new AAOOD from our state.
118 unique_ptr<ArrayGetterInterface> arrayGetter(new TopLevelGridDataArrayGetter());
119
120 // Create the subclass that does the work and replace our data array with it.
121 // Note this ctor will prepend the new dimension itself, so we do not.
122 //
123 // pArr is a prototype, already should be setup properly _without_ the new dim
124 unique_ptr<ArrayAggregateOnOuterDimension> aggDataArray(new ArrayAggregateOnOuterDimension(*pArr,
125 memberDatasets, std::move(arrayGetter), _newDim));
126
127 // Make sure null since sink function
128 // called on the unique_ptr
129 NCML_ASSERT(!(arrayGetter.get()));
130
131 // Replace our data Array with this one. Will delete old one and may throw.
132 set_array(aggDataArray.get());
133
134 // Release here on successful set since set_array uses raw ptr only.
135 // In case we threw then unique_ptr cleans up itself.
136 aggDataArray.release();
137}
138
139void GridAggregateOnOuterDimension::cleanup() const noexcept
140{
141}
142
143/* virtual */
145{
146 VALID_PTR(pSubGrid);
147 transferConstraintsToSubGridMaps(pSubGrid);
148 transferConstraintsToSubGridArray(pSubGrid);
149}
150
151/* virtual */
152const Dimension&
154{
155 return _newDim;
156}
157
158void GridAggregateOnOuterDimension::transferConstraintsToSubGridMaps(Grid* pSubGrid)
159{
160 BESDEBUG(DEBUG_CHANNEL, "Transferring constraints to the subgrid maps..." << endl);
161 Map_iter subGridMapIt = pSubGrid->map_begin();
162 for (Map_iter it = map_begin(); it != map_end(); ++it) {
163 // Skip the new outer dimension
164 if (it == map_begin()) {
165 continue;
166 }
167
168 Array* subGridMap = static_cast<Array*>(*subGridMapIt);
169 Array* superGridMap = static_cast<Array*>(*it);
170 agg_util::AggregationUtil::transferArrayConstraints(subGridMap, *superGridMap, false, // skipFirstDim = false since map sizes consistent
171 false, // same rank, dont skip this one either
172 true, // printDebug
173 DEBUG_CHANNEL); // debugChannel
174 ++subGridMapIt; // keep iterators in sync
175 }
176}
177
178void GridAggregateOnOuterDimension::transferConstraintsToSubGridArray(Grid* pSubGrid)
179{
180 BESDEBUG(DEBUG_CHANNEL, "Transferring constraints to the subgrid array..." << endl);
181
182 Array* pSubGridArray = static_cast<Array*>(pSubGrid->get_array());
183 VALID_PTR(pSubGridArray);
184 Array* pThisArray = static_cast<Array*>(array_var());
185 VALID_PTR(pThisArray);
186
187 // transfer, skipping first dim which is the new one.
188 agg_util::AggregationUtil::transferArrayConstraints(pSubGridArray, // into the prototype
189 *pThisArray, // from the output array (with valid constraints)
190 true, // skipFirstDim: need to skip since the ranks differ
191 false, // but not into the to array
192 true, // printDebug
193 DEBUG_CHANNEL);
194}
195
196} // namespace agg_util
static void transferArrayConstraints(libdap::Array *pToArray, const libdap::Array &fromArray, bool skipFirstFromDim, bool skipFirstToDim, bool printDebug=false, const std::string &debugChannel="agg_util")
virtual const Dimension & getAggregationDimension() const
GridAggregateOnOuterDimension(const Grid &proto, const Dimension &newDim, const AMDList &memberDatasets, const DDSLoader &loaderProto)
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...