38 #include <AttrTable.h>
48 using libdap::AttrTable;
49 using libdap::BaseType;
50 using libdap::Constructor;
51 using libdap::DataDDS;
62 int AggregationUtil::d_last_added_cv_position = 0;
95 const std::string& name,
96 const libdap::DataDDS& dds,
97 const libdap::Array*
const pConstraintTemplate,
98 const std::string& debugChannel
108 "Did not find a variable named \"" +
109 name +
"\" at the top-level of the DDS!");
114 if (pBT->type() != libdap::dods_array_c)
117 "The top-level DDS variable named \"" +
119 "\" was not of the expected type!"
120 " Expected:Array Found:" + pBT->type_name());
123 libdap::Array* pDatasetArray =
static_cast<libdap::Array*
>(pBT);
126 if (pConstraintTemplate)
131 *pConstraintTemplate,
134 !(debugChannel.empty()),
140 pDatasetArray->set_send_p(
true);
141 pDatasetArray->set_in_selection(
true);
142 pDatasetArray->read();
144 return pDatasetArray;
170 const std::string& name,
171 const libdap::DataDDS& dds,
172 const libdap::Array*
const pConstraintTemplate,
173 const std::string& debugChannel
183 "Did not find a variable named \"" +
184 name +
"\" at the top-level of the DDS!");
189 if (pBT->type() != libdap::dods_grid_c)
192 "The top-level DDS variable named \"" +
194 "\" was not of the expected type!"
195 " Expected:Grid Found:" + pBT->type_name());
199 Grid* pDataGrid =
static_cast<Grid*
>(pBT);
202 pDataGrid->array_var()
207 "The data Array var for variable name=\"" +
209 "\" was unexpectedly null!");
213 if (pConstraintTemplate)
218 *pConstraintTemplate,
221 !(debugChannel.empty()),
232 pDataGrid->set_send_p(
true);
233 pDataGrid->set_in_selection(
true);
237 if (!pDataArray->read_p())
239 pDataArray->set_send_p(
true);
240 pDataArray->set_in_selection(
true);
252 , _gridName(gridName)
271 const std::string& arrayName,
272 const libdap::DataDDS& dds,
273 const libdap::Array*
const pConstraintTemplate,
274 const std::string& debugChannel
284 "Did not find a variable named \"" +
285 _gridName +
"\" at the top-level of the DDS!");
290 if (pBT->type() != libdap::dods_grid_c)
293 "The top-level DDS variable named \"" +
295 "\" was not of the expected type!"
296 " Expected:Grid Found:" + pBT->type_name());
300 Grid* pDataGrid =
static_cast<Grid*
>(pBT);
303 "Expected to find the map with name " + arrayName +
" within the Grid "
304 +
_gridName +
" but failed to find it!");
307 pMap->set_send_p(
true);
308 pMap->set_in_selection(
true);
311 if (pConstraintTemplate)
316 *pConstraintTemplate,
319 !(debugChannel.empty()),
346 vector<const DDS*>::const_iterator endIt = datasetsInOrder.end();
347 vector<const DDS*>::const_iterator it;
348 for (it = datasetsInOrder.begin(); it != endIt; ++it)
350 const DDS* pDDS = *it;
356 const_cast<DDS*>(pDDS)->get_attr_table());
368 AttrTable& fromTable =
const_cast<AttrTable&
>(fromTableIn);
369 AttrTable::Attr_iter endIt = fromTable.attr_end();
370 AttrTable::Attr_iter it;
371 for (it = fromTable.attr_begin(); it != endIt; ++it)
373 const string& name = fromTable.get_name(it);
374 AttrTable::Attr_iter attrInOut;
379 BESDEBUG(
"ncml",
"Union of AttrTable: an attribute named " << name <<
" already exist in output, skipping it..." << endl);
385 if (fromTable.is_container(it))
387 AttrTable* pOrigAttrContainer = fromTable.get_attr_table(it);
389 "AggregationUtil::mergeAttrTables(): expected non-null AttrTable for the attribute container: " + name);
390 AttrTable* pClonedAttrContainer =
new AttrTable(*pOrigAttrContainer);
392 pOut->append_container(pClonedAttrContainer, name);
393 BESDEBUG(
"ncml",
"Union of AttrTable: adding a deep copy of attribute=" << name <<
" to the merged output." << endl);
397 string type = fromTable.get_type(it);
398 vector<string>* pAttrTokens = fromTable.get_attr_vector(it);
401 pOut->append_attr(name, type, pAttrTokens);
410 AttrTable& inTableSemanticConst =
const_cast<AttrTable&
>(inTable);
411 attr = inTableSemanticConst.simple_find(name);
412 return (attr != inTableSemanticConst.attr_end());
418 ConstDDSList::const_iterator endIt = datasetsInOrder.end();
419 ConstDDSList::const_iterator it;
420 for (it = datasetsInOrder.begin(); it != endIt; ++it)
429 DDS& dds =
const_cast<DDS&
>(fromDDS);
430 DDS::Vars_iter endIt = dds.var_end();
432 for (it = dds.var_begin(); it != endIt; ++it)
440 BESDEBUG(
"ncml",
"Variable name=" << var->name() <<
" wasn't in the union yet and was added." << endl);
444 BESDEBUG(
"ncml",
"Variable name=" << var->name() <<
" was already in the union and was skipped." << endl);
457 d_last_added_cv_position = 0;
468 BESDEBUG(
"ncml2",
"AggregationUtil::addCopyOfVariableIfNameIsAvailable: " << varProto.name() << endl);
479 DDS::Vars_iter pos = pOutDDS->var_begin() + d_last_added_cv_position;
481 pOutDDS->insert_var(pos, const_cast<BaseType*>(&varProto));
483 ++d_last_added_cv_position;
487 pOutDDS->add_var(const_cast<BaseType*>(&varProto));
503 pOutDDS->del_var(varProto.name());
507 pOutDDS->add_var(const_cast<BaseType*>(&varProto));
514 DDS& dds =
const_cast<DDS&
>(dds_const);
515 DDS::Vars_iter endIt = dds.var_end();
517 for (it = dds.var_begin(); it != endIt; ++it)
520 if (var && var->name() == name)
529 template <
class LibdapType>
536 return dynamic_cast<LibdapType*
>(pBT);
547 const std::string& joinedArrayName,
548 const std::string& newOuterDimName,
549 const std::vector<libdap::Array*>& fromVars,
552 string funcName =
"AggregationUtil::createOuterDimensionJoinedArray:";
555 funcName +
"Must be at least one Array in input!");
561 " The input arrays must all have the same data type and dimensions but do not!");
565 Array* templateArray = fromVars[0];
567 BaseType* templateVar = templateArray->var();
569 funcName +
"Expected a non-NULL prototype BaseType in the first Array!");
572 pJoinedArray->add_var(templateVar);
574 pJoinedArray->set_name(joinedArrayName);
577 pJoinedArray->set_attr_table(templateArray->get_attr_table());
581 pJoinedArray->append_dim(fromVars.size(), newOuterDimName);
584 for (Array::Dim_iter it = templateArray->dim_begin(); it != templateArray->dim_end(); ++it)
586 int dimSize = templateArray->dimension_size(it);
587 string dimName = templateArray->dimension_name(it);
588 pJoinedArray->append_dim(dimSize, dimName);
594 pJoinedArray->reserve_value_capacity(pJoinedArray->length());
604 const std::vector<libdap::Array*>& arrays,
605 bool enforceMatchingDimNames)
609 Array* pTemplate = 0;
610 for (vector<Array*>::const_iterator it = arrays.begin(); it != arrays.end(); ++it)
637 Array& lhs =
const_cast<Array&
>(lhsC);
638 Array& rhs =
const_cast<Array&
>(rhsC);
639 return (lhs.var() && rhs.var() && lhs.var()->type() == rhs.var()->type());
646 Array& lhs =
const_cast<Array&
>(lhsC);
647 Array& rhs =
const_cast<Array&
>(rhsC);
651 if (lhs.dimensions() != rhs.dimensions())
658 Array::Dim_iter rhsIt = rhs.dim_begin();
659 for (Array::Dim_iter lhsIt = lhs.dim_begin(); lhsIt != lhs.dim_end(); (++lhsIt, ++rhsIt) )
661 valid = (valid && ( lhs.dimension_size(lhsIt) == rhs.dimension_size(rhsIt) ));
665 valid = (valid && ( lhs.dimension_name(lhsIt) == rhs.dimension_name(rhsIt) ));
674 std::vector<Array*>& varArrays,
675 const std::string& collectVarName,
678 unsigned int count = 0;
679 ConstDDSList::const_iterator endIt = datasetsInOrder.end();
680 ConstDDSList::const_iterator it;
681 for (it = datasetsInOrder.begin(); it != endIt; ++it)
683 DDS* pDDS =
const_cast<DDS*
>(*it);
688 varArrays.push_back(pVar);
698 Array* pArr =
dynamic_cast<Array*
>(pBT);
700 (pArr->dimensions() == 1))
703 Array::Dim_iter it = pArr->dim_begin();
704 bool matches = (pArr->dimension_name(it) == pArr->name());
706 "Logic error: NCMLUtil::isCoordinateVariable(): expected one dimension from Array, but got more!");
717 const std::vector<Array*>& varArrays,
719 bool clearDataAfterUse)
724 "AggregationUtil::joinArrayData: the output Array is not of a simple type! Can't aggregate!");
730 unsigned int totalLength = 0;
732 vector<Array*>::const_iterator it;
733 vector<Array*>::const_iterator endIt = varArrays.end();
734 for (it = varArrays.begin(); it != endIt; ++it)
739 totalLength += pArr->length();
743 pAggArray->reserve_value_capacity(totalLength);
747 unsigned int nextElt = 0;
748 vector<Array*>::const_iterator it;
749 vector<Array*>::const_iterator endIt = varArrays.end();
750 for (it = varArrays.begin(); it != endIt; ++it)
754 NCML_ASSERT_MSG(pArr->var() && (pArr->var()->type() == pAggArray->var()->type()),
755 "AggregationUtil::joinArrayData: one of the arrays to join has different type than output! Can't aggregate!");
764 nextElt += pAggArray->set_value_slice_from_row_major_vector(*pArr, nextElt);
766 if (clearDataAfterUse)
768 pArr->clear_local_data();
790 os <<
"Array dimensions: " << endl;
791 Array& theArray =
const_cast<Array&
>(fromArray);
793 Array::Dim_iter endIt = theArray.dim_end();
794 for (it = theArray.dim_begin(); it != endIt; ++it)
796 Array::dimension d = *it;
797 os <<
"Dim = {" << endl;
798 os <<
"name=" << d.name << endl;
799 os <<
"size=" << d.size << endl;
802 os <<
"End Array dimensions." << endl;
808 os <<
"Array constraints: " << endl;
809 Array& theArray =
const_cast<Array&
>(rcArray);
811 Array::Dim_iter endIt = theArray.dim_end();
812 for (it = theArray.dim_begin(); it != endIt; ++it)
814 Array::dimension d = *it;
815 os <<
"Dim = {" << endl;
816 os <<
"name=" << d.name << endl;
817 os <<
"start=" << d.start << endl;
818 os <<
"stride=" << d.stride << endl;
819 os <<
"stop=" << d.stop << endl;
822 os <<
"End Array constraints" << endl;
827 const std::string& debugChannel,
828 const libdap::Array& fromArray)
831 BESDEBUG(debugChannel,
"Printing constraints for Array: " << fromArray.name() <<
": " << oss.str() << endl);
833 BESDEBUG(debugChannel, oss.str() << endl);
838 const Array& fromArrayConst,
839 bool skipFirstFromDim,
842 const std::string& debugChannel )
845 Array& fromArray =
const_cast<Array&
>(fromArrayConst);
848 pToArray->reset_constraint();
851 int skipDelta = ((skipFirstFromDim)?(1):(0));
859 (pToArray->dimensions() + skipDelta !=
860 const_cast<Array&
>(fromArrayConst).dimensions()) )
863 "Mismatched dimensionalities!");
868 BESDEBUG(debugChannel,
"Printing constraints on fromArray name= " <<
870 " before transfer..." <<
878 Array::Dim_iter fromArrIt = fromArray.dim_begin();
879 Array::Dim_iter fromArrEndIt = fromArray.dim_end();
880 Array::Dim_iter toArrIt = pToArray->dim_begin();
882 fromArrIt != fromArrEndIt;
885 if (skipFirstFromDim && (fromArrIt == fromArray.dim_begin()) )
897 "GAggregationUtil::transferArrayConstraints: "
898 "Expected the dimensions to have the same name but they did not.");
899 pToArray->add_constraint(
909 BESDEBUG(debugChannel,
"Printing constrains on pToArray after transfer..." << endl);
918 DDS& dds =
const_cast<DDS&
>(ddsConst);
919 DDS::Vars_iter endIt = dds.var_end();
921 for (it = dds.var_begin(); it != endIt; ++it)
924 if (var && var->name() == name)
940 Constructor& varContainer =
const_cast<Constructor&
>(varContainerConst);
941 Constructor::Vars_iter endIt = varContainer.var_end();
942 Constructor::Vars_iter it;
943 for (it = varContainer.var_begin(); it != endIt; ++it)
946 if (var && var->name() == name)
968 libdap::Array* pArray(0);
971 case libdap::dods_array_c:
972 pArray =
static_cast<libdap::Array*
>(pBT);
975 case libdap::dods_grid_c:
976 pArray =
static_cast<Grid*
>(pBT)->get_array();
989 Grid& grid =
const_cast<Grid&
>(inGrid);
992 Grid::Map_iter endIt = grid.map_end();
993 for (it = grid.map_begin(); it != endIt; ++it)
995 if ( (*it)->name() == findName )
997 pRet =
static_cast<Array*
>(*it);
1006 libdap::Array& oOutputArray,
1007 unsigned int atIndex,
1008 const Array& constrainedTemplateArray,
1009 const std::string& varName,
1012 const std::string& debugChannel
1015 const libdap::DataDDS* pDataDDS = dataset.
getDataDDS();
1016 NCML_ASSERT_MSG(pDataDDS,
"GridAggregateOnOuterDimension::read(): Got a null DataDDS "
1017 "while loading dataset = " + dataset.
getLocation() );
1023 &constrainedTemplateArray,
1025 NCML_ASSERT_MSG(pDatasetArray,
"In aggregation member dataset, failed to get the array! "
1029 if (!pDatasetArray->read_p())
1032 "AggregationUtil::addDatasetArrayDataToAggregationOutputArray: pDatasetArray was not read_p()!");
1039 "Invalid aggregation! "
1040 "AggregationUtil::addDatasetArrayDataToAggregationOutputArray: "
1041 "We found the aggregation variable name=" + varName +
1042 " but it was not of the same type as the prototype variable!");
1049 "Invalid aggregation! "
1050 "AggregationUtil::addDatasetArrayDataToAggregationOutputArray: "
1051 "We found the aggregation variable name=" + varName +
1052 " but it was not of the same shape as the prototype!");
1056 if (constrainedTemplateArray.length() != pDatasetArray->length())
1058 NCML_ASSERT_MSG(constrainedTemplateArray.length() == pDatasetArray->length(),
1059 "AggregationUtil::addDatasetArrayDataToAggregationOutputArray: "
1060 "The prototype array and the loaded dataset array length()'s were not equal, even "
1061 "though their shapes matched. Logic problem.");
1065 oOutputArray.set_value_slice_from_row_major_vector(*pDatasetArray, atIndex);
1071 BaseType& fromVar =
const_cast<BaseType&
>(fromVarC);
1083 pIntoVar->get_attr_table().erase();
1086 pIntoVar->set_attr_table(finalAT);
static void gatherMetadataChangesFrom(libdap::BaseType *pIntoVar, const libdap::BaseType &fromVar)
Union fromVar's AttrTable (initially) with pIntoVar's AttrTable and replace pIntoVar's AttrTable with...
virtual libdap::Array * readAndGetArray(const std::string &name, const libdap::DataDDS &dds, const libdap::Array *const pConstraintTemplate, const std::string &debugChannel) const
Lookup name within the top level of DDS ONLY and return it as an Array* if it is a subclass of Array...
static LibdapType * findTypedVariableAtDDSTopLevel(const libdap::DDS &dds, const string &name)
Template wrapper for findVariableAtDDSTopLevel() which does the find but only return non-NULL if the ...
Abstract helper superclass for allowing lazy access to the DataDDS for an aggregation.
virtual ~TopLevelGridMapArrayGetter()
virtual ~TopLevelArrayGetter()
TopLevelGridDataArrayGetter()
TopLevelGridMapArrayGetter(const std::string &gridName)
virtual libdap::Array * readAndGetArray(const std::string &name, const libdap::DataDDS &dds, const libdap::Array *const pConstraintTemplate, const std::string &debugChannel) const
Find's the Array using name as the name of a map to find within a top level Grid names in the constru...
virtual TopLevelGridDataArrayGetter * clone() const
Virtual constructor idiom.
#define NCML_ASSERT(cond)
static libdap::BaseType * findVariableAtDDSTopLevel(const libdap::DDS &dds, const string &name)
Find a variable with name at the top level of the DDS.
std::vector< const libdap::DDS * > ConstDDSList
static const libdap::Array * findMapByName(const libdap::Grid &inGrid, const std::string &findName)
Find the given map name in the given Grid and return it if found, else NULL.
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
static bool couldBeCoordinateVariable(libdap::BaseType *pBT)
#define NCML_ASSERT_MSG(cond, msg)
static void unionAttrsInto(libdap::AttrTable *pOut, const libdap::AttrTable &fromTable)
Merge any attributes in tableToMerge whose names do not already exist within *pOut into pOut...
static bool validateArrayTypesAndShapesMatch(const std::vector< libdap::Array * > &arrays, bool enforceMatchingDimNames)
Scan all the arrays in arrays using the first as a template and make sure that they all have the same...
static void joinArrayData(libdap::Array *pAggArray, const std::vector< libdap::Array * > &varArrays, bool reserveStorage=true, bool clearDataAfterUse=false)
Copy the simple type data Vector for each Array in varArrays into pAggArray, sequentially, effectively appending all the row major data in each entry in varArray into the row major order of pAggArray.
static void performUnionAggregation(libdap::DDS *pOutputUnion, const ConstDDSList &datasetsInOrder)
Perform an NCML-type union aggregation on the datasets in datasetsInOrder into pOutputUnion.
static void addOrReplaceVariableForName(libdap::DDS *pOutDDS, const libdap::BaseType &varProto)
If a variable with the name varProto.name() doesn't exist, add a copy of varProto to pOutDDS...
Helper class hierarchy for acquiring variable of a certain type from a DDS.
const std::string & getLocation() const
The location to which the AggMemberDataset refers Note: this could be "" for some subclasses if they ...
Concrete impl that simply finds the Array by looking for a variable of the given name at the top leve...
virtual libdap::Array * readAndGetArray(const std::string &name, const libdap::DataDDS &dds, const libdap::Array *const pConstraintTemplate, const std::string &debugChannel) const =0
Find, constrain, read, and return an Array inside the DDS using the given name information (somehow...
static unsigned int collectVariableArraysInOrder(std::vector< libdap::Array * > &varArrays, const std::string &collectVarName, const ConstDDSList &datasetsInOrder)
Fill in varArrays with Array's named collectVarName from each DDS in datasetsInOrder, in that order.
virtual const libdap::DataDDS * getDataDDS()=0
Return the DataDDS for the location, loading it in if it hasn't yet been loaded.
static libdap::BaseType * getVariableNoRecurse(const libdap::DDS &dds, const std::string &name)
Return the variable in dds top level (no recursing, no fully qualified name dot notation) if it exist...
virtual ~TopLevelGridDataArrayGetter()
static void produceOuterDimensionJoinedArray(libdap::Array *pJoinedArray, const std::string &joinedArrayName, const std::string &newOuterDimName, const std::vector< libdap::Array * > &fromVars, bool copyData)
Basic joinNew aggregation into pJoinedArray on the array of inputs fromVars.
static void resetCVInsertionPosition()
Used to reset the class field that tracks where Coordinate Variables (CVs) have been inserted into th...
static bool doTypesMatch(const libdap::Array &lhs, const libdap::Array &rhs)
Do the lhs and rhs have the same data type?
virtual TopLevelGridMapArrayGetter * clone() const
Virtual constructor idiom.
static bool doShapesMatch(const libdap::Array &lhs, const libdap::Array &rhs, bool checkDimNames)
Do the lhs and rhs have the same shapes? Only use size for dimension compares unless checkDimNames...
static void unionAllVariablesInto(libdap::DDS *pOutputUnion, const ConstDDSList &datasetsInOrder)
For each variable within the top level of each dataset in datasetsInOrder (forward iteration) add a c...
static bool findAttribute(const libdap::AttrTable &inTable, const string &name, libdap::AttrTable::Attr_iter &attr)
Lookup the attribute with given name in inTable and place a reference in attr.
virtual TopLevelArrayGetter * clone() const
Virtual constructor idiom.
static void addDatasetArrayDataToAggregationOutputArray(libdap::Array &oOutputArray, unsigned int atIndex, const libdap::Array &constrainedTemplateArray, const string &varName, AggMemberDataset &dataset, const ArrayGetterInterface &arrayGetter, const string &debugChannel)
Load the given dataset's DataDDS.
virtual libdap::Array * readAndGetArray(const std::string &name, const libdap::DataDDS &dds, const libdap::Array *const pConstraintTemplate, const std::string &debugChannel) const
Find the array as the data Array of a TOP-LEVEL Grid with name.
static void transferArrayConstraints(libdap::Array *pToArray, const libdap::Array &fromArray, bool skipFirstFromDim, bool skipFirstToDim, bool printDebug=false, const std::string &debugChannel="agg_util")
Copy the constraints from the from Array into the pToArray in Dim_iter order.
static void printDimensions(std::ostream &os, const libdap::Array &fromArray)
Print out the dimensions name and size for the given Array into os.
static bool addCopyOfVariableIfNameIsAvailable(libdap::DDS *pOutDDS, const libdap::BaseType &varProto, bool add_at_top=false)
If a variable does not exist within pOutDDS (top level) with the same name as varProto, then place a clone of varProto (using virtual ctor ptr_duplicate) into pOutDDS.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Exception class used by AggregationUtil and other agg_util classes to pass generic exceptions upward ...
static libdap::Array * getAsArrayIfPossible(libdap::BaseType *pBT)
If pBT is an Array type, cast and return it as the Array.
virtual ~ArrayGetterInterface()
static void printConstraintsToDebugChannel(const std::string &debugChannel, const libdap::Array &fromArray)
Output using BESDEBUG to the debugChannel channel.
static void printConstraints(std::ostream &os, const libdap::Array &fromArray)
Stream out the current constraints for all the dimensions in the Array.