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