bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
GridJoinExistingAggregation.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) 2010 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#include "GridJoinExistingAggregation.h"
30
31#include "AggregationUtil.h" // agg_util
32#include "ArrayJoinExistingAggregation.h" // agg_util
33#include <libdap/Array.h> // libdap
34#include "DDSLoader.h"
35#include "NCMLDebug.h"
36
37using libdap::Array;
38using libdap::Grid;
39
40#define DEBUG_CHANNEL "ncml:2"
41
42namespace agg_util {
43
44GridJoinExistingAggregation::GridJoinExistingAggregation(const libdap::Grid& proto, const AMDList& memberDatasets,
45 const DDSLoader& loaderProto, const Dimension& joinDim)
46// init WITHOUT a template. We need to do maps specially.
47:
48 GridAggregationBase(proto.name(), memberDatasets, loaderProto), _joinDim(joinDim)
49{
50 createRep(proto, memberDatasets);
51}
52
53GridJoinExistingAggregation::GridJoinExistingAggregation(const GridJoinExistingAggregation& proto) :
54 GridAggregationBase(proto), _joinDim(proto._joinDim)
55{
56 duplicate(proto);
57}
58
59/* virtual */
60GridJoinExistingAggregation::~GridJoinExistingAggregation()
61{
62 cleanup();
63}
64
65/* virtual */
66GridJoinExistingAggregation*
67GridJoinExistingAggregation::ptr_duplicate()
68{
69 return new GridJoinExistingAggregation(*this);
70}
71
72GridJoinExistingAggregation&
73GridJoinExistingAggregation::operator=(const GridJoinExistingAggregation& rhs)
74{
75 if (this != &rhs) {
76 cleanup();
77 GridAggregationBase::operator=(rhs);
78 duplicate(rhs);
79 }
80 return *this;
81}
82
84{
85 BESDEBUG_FUNC(DEBUG_CHANNEL, "Making an aggregated map " << "as a coordinate variable..." << endl);
86 Grid* pGridGranuleTemplate = const_cast<GridJoinExistingAggregation*>(this)->getSubGridTemplate();
87 NCML_ASSERT_MSG(pGridGranuleTemplate, "Expected grid granule template but got null.");
88
89 const Array* pMapTemplate = AggregationUtil::findMapByName(*pGridGranuleTemplate, _joinDim.name);
90 NCML_ASSERT_MSG(pMapTemplate, "Expected to find a dim map for the joinExisting agg but failed!");
91
92 // Make an array getter that pulls out the map array we are interested in.
93 // Use the basic array getter to read and get from top level DDS.
94 // N.B. Must use this->name() ie the gridname since that's what it will search!
96
98 new ArrayJoinExistingAggregation(*pMapTemplate, getDatasetList(), std::move(mapArrayGetter), _joinDim));
99
100 return pNewMap;
101}
102
104// Subclass Impl (Protected)
105
106/* virtual */
108{
109 VALID_PTR(pSubGrid);
110 transferConstraintsToSubGridMaps(pSubGrid);
111 transferConstraintsToSubGridArray(pSubGrid);
112}
113
114/* virtual */
115const Dimension&
117{
118 return _joinDim;
119}
120
122// Private Impl
123
124void GridJoinExistingAggregation::duplicate(const GridJoinExistingAggregation& rhs)
125{
126 _joinDim = rhs._joinDim;
127}
128
129void GridJoinExistingAggregation::cleanup() const noexcept
130{
131}
132
133void GridJoinExistingAggregation::createRep(const libdap::Grid& constProtoSubGrid, const AMDList& memberDatasets)
134{
135 // Semantically const calls below
136 Grid& protoSubGrid = const_cast<Grid&>(constProtoSubGrid);
137
138 // Set up the shape, don't add maps
139 setShapeFrom(protoSubGrid, false);
140
141 // Add the maps by hand, leaving out the first (outer dim) one
142 // since we need to make add that specially.
143 Grid::Map_iter firstIt = protoSubGrid.map_begin();
144 Grid::Map_iter endIt = protoSubGrid.map_end();
145 for (Grid::Map_iter it = firstIt; it != endIt; ++it) {
146 // Skip the first one, assuming it's the join dim
147 if (it == firstIt) {
148 NCML_ASSERT_MSG((*it)->name() == _joinDim.name, "Expected the first map to be the outer dimension "
149 "named " + _joinDim.name + " but it was not! Logic problem.");
150 continue;
151 }
152
153 // Add the others.
154 Array* pMap = dynamic_cast<Array*>(*it);
155 VALID_PTR(pMap);
156 add_map(pMap, true); // add as a copy
157 }
158
159 BESDEBUG_FUNC(DEBUG_CHANNEL, "Replacing the Grid's data Array with an ArrayAggregateOnOuterDimension..." << endl);
160
161 // This is the prototype we need. It will have been set in the ctor.
162 Array* pArr = static_cast<Array*>(array_var());
163 NCML_ASSERT_MSG(pArr, "Expected to find a contained data Array but we did not!");
164
165 // Create the Grid version of the read getter and make a new AAOOD from our state.
166 std::unique_ptr<ArrayGetterInterface> arrayGetter(new TopLevelGridDataArrayGetter());
167
168 // Create the subclass that does the work and replace our data array with it.
169 // Note this ctor will prepend the new dimension itself, so we do not.
170 std::unique_ptr<ArrayJoinExistingAggregation> aggDataArray(new ArrayJoinExistingAggregation(*pArr, // prototype, already should be setup properly _without_ the new dim
171 memberDatasets, std::move(arrayGetter), _joinDim));
172
173 // Make sure null since sink function
174 // called on the unique_ptr
175 NCML_ASSERT(!(arrayGetter.get()));
176
177 // Replace our data Array with this one. Will delete old one and may throw.
178 set_array(aggDataArray.get());
179
180 // Release here on successful set since set_array uses raw ptr only.
181 // In case we threw then unique_ptr cleans up itself.
182 aggDataArray.release();
183}
184
185void GridJoinExistingAggregation::transferConstraintsToSubGridMaps(Grid* pSubGrid)
186{
187 BESDEBUG(DEBUG_CHANNEL, "Transferring constraints to the subgrid maps..." << endl);
188 Map_iter subGridMapIt = pSubGrid->map_begin();
189 for (Map_iter it = map_begin(); it != map_end(); ++it) {
190 // Skip the aggregated outer dimension since handled specially
191 if (it != map_begin()) {
192 Array* subGridMap = static_cast<Array*>(*subGridMapIt);
193 Array* superGridMap = static_cast<Array*>(*it);
194 agg_util::AggregationUtil::transferArrayConstraints(subGridMap, *superGridMap, false, // skipFirstDim = false since inner dim map sizes consistent
195 false, // same rank, don't skip this one either
196 true, // printDebug
197 DEBUG_CHANNEL);
198 }
199 ++subGridMapIt; // keep them in sync
200 }
201}
202
203void GridJoinExistingAggregation::transferConstraintsToSubGridArray(Grid* /* pSubGrid */)
204{
205 // Data array gets the constraints set on it directly since we replaced
206 // the map with an aggregated array variable. Thus it handles its own
207 // constraints.
208 // Leaving the stub here in case this changes in the future.
209}
210
211} // 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")
static const libdap::Array * findMapByName(const libdap::Grid &inGrid, const std::string &findName)
virtual const AMDList & getDatasetList() const
virtual const Dimension & getAggregationDimension() const
virtual void transferConstraintsToSubGridHook(Grid *pSubGrid)
unique_ptr< ArrayJoinExistingAggregation > makeAggregatedOuterMapVector() const
STL class.
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...