31#include <libdap/Array.h>
32#include <libdap/D4Group.h>
33#include <libdap/Constructor.h>
34#include <libdap/D4Maps.h>
35#include <libdap/InternalErr.h>
37#include "BESStopWatch.h"
39#include "AggregationUtil.h"
40#include "GridAggregationBase.h"
45using libdap::BaseType;
49using libdap::Constructor;
50using libdap::InternalErr;
55#define DEBUG_CHANNEL "agg_util"
56#define prolog std::string("GridAggregationBase::").append(__func__).append("() - ")
59GridAggregationBase::GridAggregationBase(
const libdap::Grid& proto,
const AMDList& memberDatasets,
const DDSLoader& loaderProto) :
60 Grid(proto), _loader(loaderProto.getDHI()), _pSubGridProto(cloneSubGridProto(proto)), _memberDatasets(memberDatasets)
64GridAggregationBase::GridAggregationBase(
const string& name,
const AMDList& memberDatasets,
const DDSLoader& loaderProto) :
65 Grid(name), _loader(loaderProto.getDHI()), _memberDatasets(memberDatasets)
70 Grid(proto), _loader(proto._loader.getDHI())
76GridAggregationBase::~GridAggregationBase()
94GridAggregationBase::transform_to_dap4(D4Group *root, Constructor *container)
96 Grid::transform_to_dap4(root,container);
99 BaseType *btp = array_var()->transform_to_dap4(root, container);
100 Array *coverage =
static_cast<Array*
>(btp);
101 if (!coverage)
throw InternalErr(__FILE__, __LINE__,
"Expected an Array while transforming a Grid (coverage)");
103 coverage->set_parent(container);
108 for (Map_iter i = map_begin(), e = map_end(); i != e; ++i) {
109 btp = (*i)->transform_to_dap4(root, container);
110 Array *map =
static_cast<Array*
>(btp);
111 if (!map)
throw InternalErr(__FILE__, __LINE__,
"Expected an Array while transforming a Grid (map)");
118 if (!root->var(map->name())) {
119 map->set_parent(container);
120 container->add_var_nocopy(map);
122 D4Map *dap4_map =
new D4Map(map->name(), map, coverage);
123 coverage->maps()->add_map(dap4_map);
126 throw InternalErr(__FILE__, __LINE__,
127 "transform_to_dap4() returned a null value where there can be no Grid.");
131 container->add_var_nocopy(coverage);
138 Grid& protoSubGrid =
const_cast<Grid&
>(constProtoSubGrid);
145 Array* pDataArrayTemplate = protoSubGrid.get_array();
146 VALID_PTR(pDataArrayTemplate);
147 set_array(
static_cast<Array*
>(pDataArrayTemplate->ptr_duplicate()));
151 Grid::Map_iter endIt = protoSubGrid.map_end();
152 for (Grid::Map_iter it = protoSubGrid.map_begin(); it != endIt; ++it) {
154 Array* pMap =
dynamic_cast<Array*
>(*it);
165 return _memberDatasets;
171 BESDEBUG_FUNC(DEBUG_CHANNEL, prolog <<
"Function entered..." << endl);
174 BESDEBUG_FUNC(DEBUG_CHANNEL, prolog <<
"read_p() set, early exit!");
183 Array* pAggArray = get_array();
184 VALID_PTR(pAggArray);
187 if (pAggArray->send_p() || pAggArray->is_in_selection()) {
222 BES_STOPWATCH_START(DEBUG_CHANNEL, prolog +
"Timer");
235 Array* pAggArray = get_array();
236 VALID_PTR(pAggArray);
239 if (pAggArray->send_p() || pAggArray->is_in_selection()) {
241 pAggArray->serialize(eval, dds, m, ce_eval);
251 VALID_PTR(pSubGridTemplate);
254 Map_iter mapEndIt = map_end();
255 for (mapIt = map_begin(); mapIt != mapEndIt; ++mapIt) {
256 Array* pOutMap =
static_cast<Array*
>(*mapIt);
260 if (!(pOutMap->send_p() || pOutMap->is_in_selection())) {
269 pOutMap->serialize(eval, dds, m, ce_eval);
278 NCML_ASSERT_MSG(pProtoGridMap,
"Couldn't find map in prototype grid for map name=" + pOutMap->name());
279 BESDEBUG_FUNC(DEBUG_CHANNEL, prolog <<
"Calling read() on prototype map vector name=" << pOutMap->name() <<
" and calling transfer constraints..." << endl);
282 NCML_ASSERT_MSG(pProtoGridMap->read_p(),
"Expected the prototype map to have been read but it wasn't.");
285 NCML_ASSERT_MSG(pOutMap->length() == pProtoGridMap->length(),
286 "Expected the prototype and output maps to have same size() after transfer of constraints, but they were not so we can't copy the data!");
293 pProtoGridMap->serialize(eval, dds, m, ce_eval);
295 pOutMap->reserve_value_capacity();
296 pOutMap->set_value_slice_from_row_major_vector(*pProtoGridMap, 0);
298 pOutMap->set_read_p(
true);
307 status = libdap::Grid::serialize(eval, dds, m, ce_eval);
311 status = libdap::Grid::serialize(eval, dds, m, ce_eval);
323 return _pSubGridProto.get();
330 _pSubGridProto.reset((rhs._pSubGridProto.get()) ? (
static_cast<Grid*
>(rhs._pSubGridProto->ptr_duplicate())) :
nullptr);
332 _memberDatasets = rhs._memberDatasets;
335void GridAggregationBase::cleanup()
339 _memberDatasets.clear();
340 _memberDatasets.resize(0);
356GridAggregationBase::cloneSubGridProto(
const libdap::Grid& proto)
358 return static_cast<Grid*
>(
const_cast<Grid&
>(proto).ptr_duplicate());
361void GridAggregationBase::printConstraints(
const Array& fromArray)
365 BESDEBUG(
"ncml:2", prolog <<
"Constraints for Grid: " << name() <<
": " << oss.str() << endl);
371 VALID_PTR(pSubGridTemplate);
377 pSubGridTemplate->set_send_p(send_p());
378 pSubGridTemplate->set_in_selection(is_in_selection());
381 pSubGridTemplate->read();
384 pSubGridTemplate->set_read_p(
true);
390 VALID_PTR(pSubGridTemplate);
393 Map_iter mapEndIt = map_end();
394 for (mapIt = map_begin(); mapIt != mapEndIt; ++mapIt) {
395 Array* pOutMap =
static_cast<Array*
>(*mapIt);
399 if (!(pOutMap->send_p() || pOutMap->is_in_selection())) {
405 if (pOutMap->name() == aggDim.name) {
413 NCML_ASSERT_MSG(pProtoGridMap,
"Couldn't find map in prototype grid for map name=" + pOutMap->name());
414 BESDEBUG_FUNC(DEBUG_CHANNEL, prolog <<
"Calling read() on prototype map vector name=" << pOutMap->name() <<
" and calling transfer constraints..." << endl);
417 NCML_ASSERT_MSG(pProtoGridMap->read_p(),
"Expected the prototype map to have been read but it wasn't.");
420 NCML_ASSERT_MSG(pOutMap->length() == pProtoGridMap->length(),
421 "Expected the prototype and output maps to have same size() "
422 "after transfer of constraints, but they were not so we can't "
429 pOutMap->reserve_value_capacity();
430 pOutMap->set_value_slice_from_row_major_vector(*pProtoGridMap, 0);
431 pOutMap->set_read_p(
true);
438 THROW_NCML_INTERNAL_ERROR(
"Impl me!");
static const libdap::Array * findMapByName(const libdap::Grid &inGrid, const std::string &findName)
static void printConstraints(std::ostream &os, const libdap::Array &fromArray)
void cleanup()
restore dhi to clean state
BESDataHandlerInterface & getDHI() const
virtual const Dimension & getAggregationDimension() const =0
bool serialize(libdap::ConstraintEvaluator &eval, libdap::DDS &dds, libdap::Marshaller &m, bool ce_eval) override
virtual void readAndAggregateConstrainedMapsHook()
void copyProtoMapsIntoThisGrid(const Dimension &aggDim)
void setShapeFrom(const libdap::Grid &protoSubGrid, bool addMaps)
Grid * getSubGridTemplate()
virtual const AMDList & getDatasetList() const
virtual void transferConstraintsToSubGridHook(Grid *pSubGrid)
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...