38#include <BESResponseObject.h>
39#include <BESDapResponseBuilder.h>
40#include <BESDataHandlerInterface.h>
43#include <BESDapNames.h>
44#include <BESDataNames.h>
45#include <BESDataDDSResponse.h>
46#include <BESDMRResponse.h>
47#include <BESRequestHandlerList.h>
48#include <BESDapFunctionResponseCache.h>
50#include "FONcRequestHandler.h"
52#include "FONcTransform.h"
54#include "FONcBaseType.h"
55#include "FONcAttributes.h"
56#include "FONcTransmitter.h"
57#include "history_utils.h"
59#include <libdap/DDS.h>
60#include <libdap/DMR.h>
61#include <libdap/D4Group.h>
62#include <libdap/D4Attributes.h>
63#include <libdap/Structure.h>
64#include <libdap/Array.h>
65#include <libdap/Grid.h>
66#include <libdap/Sequence.h>
68#include <BESInternalError.h>
69#include <BESInternalFatalError.h>
71#include "DapFunctionUtils.h"
73using std::ostringstream;
74using std::istringstream;
88 _ncid(0), _dds(nullptr), _dmr(nullptr), d_obj(nullptr), d_dhi(nullptr)
91 string s = (string)
"File out netcdf, " +
"null DDS passed to constructor";
94 if (localfile.empty()) {
95 string s = (string)
"File out netcdf, " +
"empty local file name passed to constructor";
98 _localfile = localfile;
100 _returnAs = ncVersion;
129 _ncid(0), _dds(nullptr), _dmr(nullptr), d_obj(nullptr), d_dhi(nullptr)
132 string s = (string)
"File out netcdf, null DMR passed to constructor";
135 if (localfile.empty()) {
136 string s = (string)
"File out netcdf, " +
"empty local file name passed to constructor";
139 _localfile = localfile;
141 _returnAs = ncVersion;
170 const string &ncVersion) :
171 _ncid(0), _dds(nullptr), _dmr(nullptr), d_obj(obj), d_dhi(dhi), _localfile(localfile),
175 string s = (string)
"File out netcdf, " +
"null BESResponseObject passed to constructor";
178 if (_localfile.empty()) {
179 string s = (string)
"File out netcdf, " +
"empty local file name passed to constructor";
205 for (
auto &b: _fonc_vars) {
208 for (
auto &b: _total_fonc_vars_in_grp) {
217 vector<FONcBaseType *>::iterator i = _fonc_vars.begin();
218 vector<FONcBaseType *>::iterator e = _fonc_vars.end();
231 vector<FONcBaseType *>::iterator i = _total_fonc_vars_in_grp.begin();
232 vector<FONcBaseType *>::iterator e = _total_fonc_vars_in_grp.end();
240 _total_fonc_vars_in_grp.erase(i);
256void FONcTransform::transform()
264 DDS::Vars_iter vi = _dds->var_begin();
265 DDS::Vars_iter ve = _dds->var_end();
266 for (; vi != ve; vi++) {
267 if ((*vi)->send_p()) {
270 BESDEBUG(
"fonc",
"FONcTransform::transform() - Converting variable '" << v->name() <<
"'" << endl);
273 FONcBaseType *fb = FONcUtils::convert(v,FONcTransform::_returnAs,FONcRequestHandler::classic_model);
276 if ( FONcTransform::_returnAs == RETURNAS_NETCDF4 ) {
277 if (FONcRequestHandler::classic_model)
283 _fonc_vars.push_back(fb);
284 vector<string> embed;
291 if ( FONcTransform::_returnAs == RETURNAS_NETCDF4 ) {
292 if (FONcRequestHandler::classic_model){
293 BESDEBUG(
"fonc",
"FONcTransform::transform() - Opening NetCDF-4 cache file in classic mode. fileName: " << _localfile << endl);
294 stax = nc_create(_localfile.c_str(), NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &_ncid);
297 BESDEBUG(
"fonc",
"FONcTransform::transform() - Opening NetCDF-4 cache file. fileName: " << _localfile << endl);
298 stax = nc_create(_localfile.c_str(), NC_CLOBBER|NC_NETCDF4, &_ncid);
302 BESDEBUG(
"fonc",
"FONcTransform::transform() - Opening NetCDF-3 cache file. fileName: " << _localfile << endl);
303 stax = nc_create(_localfile.c_str(), NC_CLOBBER, &_ncid);
306 if (stax != NC_NOERR) {
318 vector<FONcBaseType *>::iterator i = _fonc_vars.begin();
319 vector<FONcBaseType *>::iterator e = _fonc_vars.end();
320 for (; i != e; i++) {
322 BESDEBUG(
"fonc",
"FONcTransform::transform() - Defining variable: " << fbt->name() << endl);
326 if(FONcRequestHandler::no_global_attrs ==
false) {
328 AttrTable &globals = _dds->get_attr_table();
329 BESDEBUG(
"fonc",
"FONcTransform::transform() - Adding Global Attributes" << endl << globals << endl);
330 bool is_netCDF_enhanced =
false;
331 if(FONcTransform::_returnAs == RETURNAS_NETCDF4 && FONcRequestHandler::classic_model==
false)
332 is_netCDF_enhanced =
true;
338 int stax = nc_enddef(_ncid);
342 if (stax != NC_NOERR) {
343 FONcUtils::handle_error(stax,
"File out netcdf, unable to end the define mode: " + _localfile, __FILE__, __LINE__);
347 i = _fonc_vars.begin();
348 e = _fonc_vars.end();
349 for (; i != e; i++) {
351 BESDEBUG(
"fonc",
"FONcTransform::transform() - Writing data for variable: " << fbt->name() << endl);
355 stax = nc_close(_ncid);
356 if (stax != NC_NOERR)
360 (void) nc_close(_ncid);
387 BESDEBUG(
"fonc",
"FONcTransmitter::send_data() - Reading data into DataDDS" << endl);
394 if (!bdds)
throw BESInternalFatalError(
"Expected a BESDataDDSResponse instance", __FILE__, __LINE__);
396 _dds = bdds->get_dds();
402 besDRB.set_async_accepted(d_dhi->
data[ASYNC]);
403 besDRB.set_store_result(d_dhi->
data[STORE_RESULT]);
408 if (bdds->get_ia_flag() ==
false) {
411 besRH->add_attributes(*d_dhi);
414 ConstraintEvaluator &eval = bdds->get_ce();
421 if (!besDRB.get_btp_func_ce().empty()) {
422 BESDEBUG(
"fonc",
"Found function(s) in CE: " << besDRB.get_btp_func_ce() << endl);
426 ConstraintEvaluator func_eval;
428 if (responseCache && responseCache->can_be_cached(_dds, besDRB.get_btp_func_ce())) {
432 func_eval.parse_constraint(besDRB.get_btp_func_ce(), *_dds);
433 fdds = func_eval.eval_function_clauses(*_dds);
445 _dds->mark_all(
false);
456 promote_function_output_structures(_dds);
460 eval.parse_constraint(besDRB.
get_ce(), *_dds);
462 _dds->tag_nested_sequences();
470 for (
auto vi = _dds->var_begin(), ve = _dds->var_end(); vi != ve; vi++) {
471 if ((*vi)->send_p()) {
472 BESDEBUG(
"fonc",
"FONcTransform::transform() - Converting variable '" << (*vi)->name() <<
"'" << endl);
475 FONcBaseType *fb = FONcUtils::convert((*vi), FONcTransform::_returnAs, FONcRequestHandler::classic_model);
477 _fonc_vars.push_back(fb);
478 vector<string> embed;
483 updateHistoryAttributes(_dds, d_dhi->
data[POST_CONSTRAINT]);
487 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4) {
488 if (FONcRequestHandler::classic_model) {
489 BESDEBUG(
"fonc",
"FONcTransform::transform() - Opening NetCDF-4 cache file in classic mode. fileName: "
490 << _localfile << endl);
491 stax = nc_create(_localfile.c_str(), NC_CLOBBER | NC_NETCDF4 | NC_CLASSIC_MODEL, &_ncid);
495 "FONcTransform::transform() - Opening NetCDF-4 cache file. fileName: " << _localfile << endl);
496 stax = nc_create(_localfile.c_str(), NC_CLOBBER | NC_NETCDF4, &_ncid);
500 BESDEBUG(
"fonc",
"FONcTransform::transform() - Opening NetCDF-3 cache file. fileName: " << _localfile << endl);
501 stax = nc_create(_localfile.c_str(), NC_CLOBBER, &_ncid);
504 if (stax != NC_NOERR) {
508 int current_fill_prop_vaule;
510 stax = nc_set_fill(_ncid, NC_NOFILL, ¤t_fill_prop_vaule);
511 if (stax != NC_NOERR) {
512 FONcUtils::handle_error(stax,
"File out netcdf, unable to set fill to NC_NOFILL: " + _localfile, __FILE__, __LINE__);
524 BESDEBUG(
"fonc",
"FONcTransform::transform() - Defining variable: " << fbt->name() << endl);
528 if (FONcRequestHandler::no_global_attrs ==
false) {
530 AttrTable &globals = _dds->get_attr_table();
531 BESDEBUG(
"fonc",
"FONcTransform::transform() - Adding Global Attributes" << endl << globals << endl);
532 bool is_netCDF_enhanced =
false;
533 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4 && FONcRequestHandler::classic_model ==
false)
534 is_netCDF_enhanced =
true;
540 int stax = nc_enddef(_ncid);
544 if (stax != NC_NOERR) {
549 uint64_t byteCount = 0;
551 if (is_streamable()) {
552 byteCount = BESUtil::file_to_stream_helper(_localfile, strm, byteCount);
553 BESDEBUG(
"fonc",
"FONcTransform::transform() - first write data to stream, count: " << byteCount << endl);
557 BESDEBUG(
"fonc",
"FONcTransform::transform() - Writing data for variable: " << fbt->name() << endl);
560 fbt->set_eval(&eval);
566 if (is_streamable()) {
568 byteCount = BESUtil::file_to_stream_helper(_localfile, strm, byteCount);
569 BESDEBUG(
"fonc",
"FONcTransform::transform() - Writing data to stream, count: " << byteCount << endl);
573 stax = nc_close(_ncid);
574 if (stax != NC_NOERR)
577 byteCount = BESUtil::file_to_stream_helper(_localfile, strm, byteCount);
578 BESDEBUG(
"fonc",
"FONcTransform::transform() - after nc_close() count: " << byteCount << endl);
581 (void) nc_close(_ncid);
593bool FONcTransform::is_streamable(){
594 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4){
598 if (_dds !=
nullptr){
599 return is_dds_streamable();
602 return is_dmr_streamable(_dmr->root());
611bool FONcTransform::is_dds_streamable(){
612 for (
auto var = _dds->var_begin(), varEnd = _dds->var_end(); var != varEnd; ++var) {
613 if ((*var)->type() == dods_structure_c) {
626bool FONcTransform::is_dmr_streamable(D4Group *group){
627 for (
auto var = group->var_begin(), varEnd = group->var_end(); var != varEnd; ++var) {
628 if ((*var)->type() == dods_structure_c)
631 if ((*var)->type() == dods_group_c) {
632 D4Group *g =
dynamic_cast<D4Group *
>(*var);
633 if (g !=
nullptr && !is_dmr_streamable(g)) {
653 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() Reading data into DataDMR" << endl);
660 _dmr = responseBuilder.setup_dap4_intern_data(d_obj, *d_dhi).release();
670 besDRB.set_async_accepted(d_dhi->
data[ASYNC]);
671 besDRB.set_store_result(d_dhi->
data[STORE_RESULT]);
678 BESDEBUG(
"fonc",
"Coming into transform_dap4() " << endl);
681 bool support_group = check_group_support();
683 if (
true == support_group) {
687 "FONcTransform::transform_dap4() - Opening NetCDF-4 cache file. fileName: " << _localfile << endl);
688 stax = nc_create(_localfile.c_str(), NC_CLOBBER | NC_NETCDF4, &_ncid);
689 if (stax != NC_NOERR)
692 D4Group *root_grp = _dmr->root();
695 map<string, int> fdimname_to_id;
699 gen_included_grp_list(root_grp);
702 for (std::set<string>::iterator it=_included_grp_names.begin(); it!=_included_grp_names.end(); ++it)
703 BESDEBUG(
"fonc",
"included group list name is: "<<*it<<endl);
707 check_and_obtain_dimensions(root_grp,
true);
711 map<string,unsigned long>:: iterator it;
713 for(it=GFQN_dimname_to_dimsize.begin();it!=GFQN_dimname_to_dimsize.end();++it) {
714 BESDEBUG(
"fonc",
"Final GFQN dim name is: "<<it->first<<endl);
715 BESDEBUG(
"fonc",
"Final GFQN dim size is: "<<it->second<<endl);
718 for(it=VFQN_dimname_to_dimsize.begin();it!=VFQN_dimname_to_dimsize.end();++it) {
719 BESDEBUG(
"fonc",
"Final VFQN dim name is: "<<it->first<<endl);
720 BESDEBUG(
"fonc",
"Final VFQN dim size is: "<<it->second<<endl);
728 map<string, unsigned long>::iterator git, vit;
729 for (git = GFQN_dimname_to_dimsize.begin(); git != GFQN_dimname_to_dimsize.end(); ++git) {
730 for (vit = VFQN_dimname_to_dimsize.begin(); vit != VFQN_dimname_to_dimsize.end(); ++vit) {
731 if (git->first == vit->first) {
732 if (git->second != vit->second)
733 git->second = vit->second;
749 vector<string> root_d4_dimname_list;
750 for (git = GFQN_dimname_to_dimsize.begin(); git != GFQN_dimname_to_dimsize.end(); ++git) {
751 string d4_temp_dimname = git->first.substr(1);
753 if (d4_temp_dimname.find(
'/') == string::npos)
754 root_d4_dimname_list.push_back(d4_temp_dimname);
758 for(
unsigned int i = 0; i <root_d4_dimname_list.size();i++)
759 BESDEBUG(
"fonc",
"root_d4 dim name is: "<<root_d4_dimname_list[i]<<endl);
763 vector<int> root_dim_suffix_nums;
764 for (
unsigned int i = 0; i < root_d4_dimname_list.size(); i++) {
765 if (root_d4_dimname_list[i].size() < 4)
767 else if (root_d4_dimname_list[i].substr(0, 3) !=
"dim")
770 string temp_suffix = root_d4_dimname_list[i].substr(3);
772 bool ignored_suffix =
false;
773 for (
unsigned int j = 0; j < temp_suffix.size(); j++) {
774 if (!isdigit(temp_suffix[j])) {
775 ignored_suffix =
true;
779 if (ignored_suffix ==
true)
782 root_dim_suffix_nums.push_back(atoi(temp_suffix.c_str()));
787 for(
unsigned int i = 0; i <root_dim_suffix_nums.size();i++)
788 BESDEBUG(
"fonc",
"root_dim_suffix_nums: "<<root_dim_suffix_nums[i]<<endl);
791 for(it=GFQN_dimname_to_dimsize.begin();it!=GFQN_dimname_to_dimsize.end();++it) {
792 BESDEBUG(
"fonc",
"RFinal GFQN dim name is: "<<it->first<<endl);
793 BESDEBUG(
"fonc",
"RFinal GFQN dim size is: "<<it->second<<endl);
796 for(it=VFQN_dimname_to_dimsize.begin();it!=VFQN_dimname_to_dimsize.end();++it) {
797 BESDEBUG(
"fonc",
"RFinal VFQN dim name is: "<<it->first<<endl);
798 BESDEBUG(
"fonc",
"RFinal VFQN dim size is: "<<it->second<<endl);
803 transform_dap4_group(root_grp,
true, _ncid, fdimname_to_id, root_dim_suffix_nums);
804 stax = nc_close(_ncid);
805 if (stax != NC_NOERR)
810 transform_dap4_no_group();
820void FONcTransform::transform_dap4_no_group()
823 D4Group *root_grp = _dmr->root();
825 D4Dimensions *root_dims = root_grp->dims();
826 for(D4Dimensions::D4DimensionsIter di = root_dims->dim_begin(), de = root_dims->dim_end(); di != de; ++di) {
827 BESDEBUG(
"fonc",
"transform_dap4() - check dimensions"<< endl);
828 BESDEBUG(
"fonc",
"transform_dap4() - dim name is: "<<(*di)->name()<<endl);
829 BESDEBUG(
"fonc",
"transform_dap4() - dim size is: "<<(*di)->size()<<endl);
830 BESDEBUG(
"fonc",
"transform_dap4() - fully_qualfied_dim name is: "<<(*di)->fully_qualified_name()<<endl);
833 Constructor::Vars_iter vi = root_grp->var_begin();
834 Constructor::Vars_iter ve = root_grp->var_end();
836 for (; vi != ve; vi++) {
837 if ((*vi)->send_p()) {
841 "FONcTransform::transform_dap4_no_group() - Converting variable '" << v->name() <<
"'" << endl);
844 FONcBaseType *fb = FONcUtils::convert(v, FONcTransform::_returnAs, FONcRequestHandler::classic_model);
845 _fonc_vars.push_back(fb);
847 vector<string> embed;
848 fb->convert(embed,
true,
false);
853 if(root_grp->grp_begin() == root_grp->grp_end())
854 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() - No group " << endl);
856 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() - has group " << endl);
857 for (D4Group::groupsIter gi = root_grp->grp_begin(), ge = root_grp->grp_end(); gi != ge; ++gi)
858 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() - group name: " << (*gi)->name() << endl);
861 updateHistoryAttributes(_dmr, d_dhi->
data[POST_CONSTRAINT]);
865 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4) {
866 if (FONcRequestHandler::classic_model) {
868 "FONcTransform::transform_dap4_no_group() - Opening NetCDF-4 cache file in classic mode. fileName: "
869 << _localfile << endl);
870 stax = nc_create(_localfile.c_str(), NC_CLOBBER | NC_NETCDF4 | NC_CLASSIC_MODEL, &_ncid);
874 "FONcTransform::transform_dap4_no_group() - Opening NetCDF-4 cache file. fileName: " << _localfile
876 stax = nc_create(_localfile.c_str(), NC_CLOBBER | NC_NETCDF4, &_ncid);
881 "FONcTransform::transform_dap4_no_group() - Opening NetCDF-3 cache file. fileName: " << _localfile
883 stax = nc_create(_localfile.c_str(), NC_CLOBBER, &_ncid);
886 if (stax != NC_NOERR) {
898 vector<FONcBaseType *>::iterator i = _fonc_vars.begin();
899 vector<FONcBaseType *>::iterator e = _fonc_vars.end();
900 for (; i != e; i++) {
902 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4_no_group() - Defining variable: " << fbt->name() << endl);
907 if (FONcRequestHandler::no_global_attrs ==
false) {
910 D4Group *root_grp = _dmr->root();
911 D4Attributes *d4_attrs = root_grp->attributes();
914 "FONcTransform::transform_dap4_no_group() handle GLOBAL DAP4 attributes " << d4_attrs << endl);
916 for (D4Attributes::D4AttributesIter ii = d4_attrs->attribute_begin(), ee = d4_attrs->attribute_end(); ii != ee; ++ii) {
917 string name = (*ii)->name();
918 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() GLOBAL attribute name is "<<name <<endl);
921 bool is_netCDF_enhanced =
false;
922 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4 && FONcRequestHandler::classic_model ==
false)
923 is_netCDF_enhanced =
true;
929 int stax = nc_enddef(_ncid);
933 if (stax != NC_NOERR) {
939 i = _fonc_vars.begin();
940 e = _fonc_vars.end();
941 for (; i != e; i++) {
944 "FONcTransform::transform_dap4_no_group() - Writing data for variable: " << fbt->name() << endl);
948 stax = nc_close(_ncid);
949 if (stax != NC_NOERR)
953 (void) nc_close(_ncid);
960void FONcTransform::transform_dap4_group(D4Group *grp,
962 int par_grp_id, map<string, int> &fdimname_to_id,
963 vector<int> &root_dim_suffix_nums)
966 bool included_grp =
false;
968 if (_dmr->get_ce_empty()) {
970 "Check-get_ce_empty. FONcTransform::transform_dap4() in group - group name: " << grp->FQN() << endl);
974 else if (is_root_grp ==
true)
978 set<string>::iterator iset;
979 if (_included_grp_names.find(grp->FQN()) != _included_grp_names.end())
985 if (included_grp ==
true)
986 transform_dap4_group_internal(grp, is_root_grp, par_grp_id, fdimname_to_id, root_dim_suffix_nums);
998void FONcTransform::transform_dap4_group_internal(D4Group *grp,
1000 int par_grp_id, map<string, int> &fdimname_to_id,
1001 vector<int> &rds_nums)
1004 BESDEBUG(
"fonc",
"transform_dap4_group_internal() - inside" << endl);
1008 updateHistoryAttributes(_dmr, d_dhi->
data[POST_CONSTRAINT]);
1010 if (is_root_grp ==
true)
1013 stax = nc_def_grp(par_grp_id, (*grp).name().c_str(), &grp_id);
1014 BESDEBUG(
"fonc",
"transform_dap4_group_internal() - group name is " << (*grp).name() << endl);
1015 if (stax != NC_NOERR)
1020 D4Dimensions *grp_dims = grp->dims();
1021 for (D4Dimensions::D4DimensionsIter di = grp_dims->dim_begin(), de = grp_dims->dim_end(); di != de; ++di) {
1024 BESDEBUG(
"fonc",
"transform_dap4() - check dimensions"<< endl);
1025 BESDEBUG(
"fonc",
"transform_dap4() - dim name is: "<<(*di)->name()<<endl);
1026 BESDEBUG(
"fonc",
"transform_dap4() - dim size is: "<<(*di)->size()<<endl);
1027 BESDEBUG(
"fonc",
"transform_dap4() - fully_qualfied_dim name is: "<<(*di)->fully_qualified_name()<<endl);
1030 unsigned long dimsize = (*di)->size();
1033 map<string, unsigned long>::iterator it;
1034 for (it = GFQN_dimname_to_dimsize.begin(); it != GFQN_dimname_to_dimsize.end(); ++it) {
1035 if (it->first == (*di)->fully_qualified_name())
1036 dimsize = it->second;
1041 stax = nc_def_dim(grp_id, (*di)->name().c_str(), dimsize, &g_dimid);
1042 if (stax != NC_NOERR)
1046 fdimname_to_id[(*di)->fully_qualified_name()] = g_dimid;
1049 Constructor::Vars_iter vi = grp->var_begin();
1050 Constructor::Vars_iter ve = grp->var_end();
1052 vector<FONcBaseType *> fonc_vars_in_grp;
1053 for (; vi != ve; vi++) {
1054 if ((*vi)->send_p()) {
1058 "FONcTransform::transform_dap4_group() - Converting variable '" << v->name() <<
"'" << endl);
1062 FONcBaseType *fb = FONcUtils::convert(v, RETURN_AS_NETCDF4,
false, fdimname_to_id, rds_nums);
1064 fonc_vars_in_grp.push_back(fb);
1067 _total_fonc_vars_in_grp.push_back(fb);
1069 vector<string> embed;
1070 fb->convert(embed,
true,
true);
1075 if(grp->grp_begin() == grp->grp_end())
1076 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() - No group " << endl);
1078 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() - has group " << endl);
1087 vector<FONcBaseType *>::iterator i = fonc_vars_in_grp.begin();
1088 vector<FONcBaseType *>::iterator e = fonc_vars_in_grp.end();
1089 for (; i != e; i++) {
1091 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4_group() - Defining variable: " << fbt->name() << endl);
1096 bool is_netCDF_enhanced =
false;
1097 if (FONcTransform::_returnAs == RETURN_AS_NETCDF4 && FONcRequestHandler::classic_model ==
false)
1098 is_netCDF_enhanced =
true;
1101 bool add_attr =
true;
1104 if (FONcRequestHandler::no_global_attrs ==
true && is_root_grp ==
true)
1107 if (
true == add_attr) {
1108 D4Attributes *d4_attrs = grp->attributes();
1109 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4_group() - Adding Group Attributes" << endl);
1115 i = fonc_vars_in_grp.begin();
1116 e = fonc_vars_in_grp.end();
1117 for (; i != e; i++) {
1120 "FONcTransform::transform_dap4_group() - Writing data for variable: " << fbt->name() << endl);
1126 for (D4Group::groupsIter gi = grp->grp_begin(), ge = grp->grp_end(); gi != ge; ++gi) {
1127 BESDEBUG(
"fonc",
"FONcTransform::transform_dap4() in group - group name: " << (*gi)->name() << endl);
1128 transform_dap4_group(*gi,
false, grp_id, fdimname_to_id, rds_nums);
1133 (void) nc_close(_ncid);
1141bool FONcTransform::check_group_support()
1143 if (RETURN_AS_NETCDF4 == FONcTransform::_returnAs &&
false == FONcRequestHandler::classic_model &&
1144 (_dmr->root()->grp_begin() != _dmr->root()->grp_end()))
1151void FONcTransform::gen_included_grp_list(D4Group *grp)
1153 bool grp_has_var =
false;
1155 BESDEBUG(
"fnoc",
"<coming to the D4 group has name " << grp->name() << endl);
1156 BESDEBUG(
"fnoc",
"<coming to the D4 group has fullpath " << grp->FQN() << endl);
1158 if (grp->var_begin() != grp->var_end()) {
1160 BESDEBUG(
"fnoc",
"<has the vars " << endl);
1161 Constructor::Vars_iter vi = grp->var_begin();
1162 Constructor::Vars_iter ve = grp->var_end();
1164 for (; vi != ve; vi++) {
1167 if ((*vi)->send_p()) {
1172 if (grp->FQN() !=
"/")
1173 _included_grp_names.insert(grp->FQN());
1179 for (D4Group::groupsIter gi = grp->grp_begin(), ge = grp->grp_end(); gi != ge; ++gi) {
1180 BESDEBUG(
"fonc",
"obtain included groups - group name: " << (*gi)->name() << endl);
1181 gen_included_grp_list(*gi);
1186 if (grp_has_var ==
true) {
1187 D4Group *temp_grp = grp;
1189 if (temp_grp->get_parent()) {
1190 temp_grp =
static_cast<D4Group *
>(temp_grp->get_parent());
1191 if (temp_grp->FQN() !=
"/")
1192 _included_grp_names.insert(temp_grp->FQN());
1201void FONcTransform::check_and_obtain_dimensions(D4Group *grp,
bool is_root_grp)
1205 bool included_grp =
false;
1207 if (_dmr->get_ce_empty())
1208 included_grp =
true;
1210 else if (is_root_grp ==
true)
1211 included_grp =
true;
1214 set<string>::iterator iset;
1215 if (_included_grp_names.find(grp->FQN()) != _included_grp_names.end())
1216 included_grp =
true;
1219 if (included_grp ==
true)
1220 check_and_obtain_dimensions_internal(grp);
1223void FONcTransform::check_and_obtain_dimensions_internal(D4Group *grp)
1227 D4Dimensions *grp_dims = grp->dims();
1229 for (D4Dimensions::D4DimensionsIter di = grp_dims->dim_begin(), de = grp_dims->dim_end(); di != de; ++di) {
1232 BESDEBUG(
"fonc",
"transform_dap4() - check dimensions"<< endl);
1233 BESDEBUG(
"fonc",
"transform_dap4() - dim name is: "<<(*di)->name()<<endl);
1234 BESDEBUG(
"fonc",
"transform_dap4() - dim size is: "<<(*di)->size()<<endl);
1235 BESDEBUG(
"fonc",
"transform_dap4() - fully_qualfied_dim name is: "<<(*di)->fully_qualified_name()<<endl);
1237 unsigned long dimsize = (*di)->size();
1238 if ((*di)->constrained()) {
1239 dimsize = ((*di)->c_stop() - (*di)->c_start()) / (*di)->c_stride() + 1;
1242 GFQN_dimname_to_dimsize[(*di)->fully_qualified_name()] = dimsize;
1249 Constructor::Vars_iter vi = grp->var_begin();
1250 Constructor::Vars_iter ve = grp->var_end();
1251 for (; vi != ve; vi++) {
1252 if ((*vi)->send_p()) {
1253 if ((*vi)->is_vector_type()) {
1254 Array *t_a =
dynamic_cast<Array *
>(*vi);
1255 Array::Dim_iter dim_i = t_a->dim_begin();
1256 Array::Dim_iter dim_e = t_a->dim_end();
1257 for (; dim_i != dim_e; dim_i++) {
1258 if ((*dim_i).name !=
"") {
1259 D4Dimension *d4dim = t_a->dimension_D4dim(dim_i);
1261 BESDEBUG(
"fonc",
"transform_dap4() check dim- dim name is: " << d4dim->name() << endl);
1262 BESDEBUG(
"fonc",
"transform_dap4() check dim- dim size is: " << d4dim->size() << endl);
1263 BESDEBUG(
"fonc",
"transform_dap4() check dim- fully_qualfied_dim name is: "
1264 << d4dim->fully_qualified_name() << endl);
1266 unsigned long dimsize = t_a->dimension_size(dim_i,
true);
1268 BESDEBUG(
"fonc",
"transform_dap4() check dim- final dim size is: "<< dimsize << endl);
1270 pair<map<string, unsigned long>::iterator,
bool> ret_it;
1271 ret_it = VFQN_dimname_to_dimsize.insert(
1272 pair<string, unsigned long>(d4dim->fully_qualified_name(), dimsize));
1273 if (ret_it.second ==
false && ret_it.first->second != dimsize) {
1274 string err =
"fileout_netcdf-4: dimension found with the same name, but different size";
1280 throw BESInternalError(
"Has dimension name but D4 dimension is NULL", __FILE__, __LINE__);
1290 map<string,unsigned long>:: iterator it;
1291 for(it=GFQN_dimname_to_dimsize.begin();it!=GFQN_dimname_to_dimsize.end();++it) {
1292 BESDEBUG(
"fonc",
"GFQN dim name is: "<<it->first<<endl);
1293 BESDEBUG(
"fonc",
"GFQN dim size is: "<<it->second<<endl);
1296 for(it=VFQN_dimname_to_dimsize.begin();it!=VFQN_dimname_to_dimsize.end();++it) {
1297 BESDEBUG(
"fonc",
"VFQN dim name is: "<<it->first<<endl);
1298 BESDEBUG(
"fonc",
"VFQN dim size is: "<<it->second<<endl);
1304 for (D4Group::groupsIter gi = grp->grp_begin(), ge = grp->grp_end(); gi != ge; ++gi) {
1306 "FONcTransform::check_and_obtain_dimensions() in group - group name: " << (*gi)->name() << endl);
1307 check_and_obtain_dimensions(*gi,
false);
1323 strm << BESIndent::LMarg <<
"FONcTransform::dump - (" << (
void *)
this <<
")" << endl;
1324 BESIndent::Indent();
1325 strm << BESIndent::LMarg <<
"ncid = " << _ncid << endl;
1326 strm << BESIndent::LMarg <<
"temporary file = " << _localfile << endl;
1327 BESIndent::Indent();
1328 vector<FONcBaseType *>::const_iterator i = _fonc_vars.begin();
1329 vector<FONcBaseType *>::const_iterator e = _fonc_vars.end();
1330 for (; i != e; i++) {
1334 BESIndent::UnIndent();
1335 BESIndent::UnIndent();
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Cache the results from server functions.
virtual libdap::DDS * get_or_cache_dataset(libdap::DDS *dds, const std::string &constraint)
Return a DDS loaded with data that can be serialized back to a client.
virtual void set_dataset_name(const std::string _dataset)
Set the dataset pathname.
virtual void split_ce(libdap::ConstraintEvaluator &eval, const std::string &expr="")
virtual std::string get_ce() const
Get the constraint expression.
virtual void set_dap4ce(std::string _ce)
virtual void set_dap4function(std::string _func)
virtual void set_ce(std::string _ce)
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Structure storing information used by the BES to handle the request.
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
void first_container()
set the container pointer to the first container in the containers list
BESContainer * container
pointer to current container in this interface
Abstract exception class for the BES with basic string message.
exception thrown if internal error encountered
exception thrown if an internal error is found and is fatal to the BES
virtual BESRequestHandler * find_handler(const std::string &handler_name)
find and return the specified request handler
Represents a specific data type request handler.
Abstract base class representing a specific set of information in response to a request to the BES.
static void conditional_timeout_cancel()
Checks if the timeout alarm should be canceled based on the value of the BES key BES....
static void add_dap4_attributes(int ncid, int varid, D4Attributes *d4_attrs, const string &var_name, const string &prepend_attr, bool is_netCDF_enhanced)
add_dap4_attributes
static void add_attributes(int ncid, int varid, AttrTable &attrs, const string &var_name, const string &prepend_attr, bool is_netCDF_enhanced)
helper function for add_attributes
A DAP BaseType with file out netcdf information included.
virtual void define(int ncid)
Define the variable in the netcdf file.
virtual void setNC4DataModel(const string &nc4_datamodel)
Identifies the netCDF4 data model (CLASSIC or ENHANCED)
virtual void setVersion(const std::string &version)
Identifies variable with use of NetCDF4 features.
virtual void dump(std::ostream &strm) const =0
dump the contents of this object to the specified ostream
static void handle_error(int stax, const string &err, const string &file, int line)
handle any netcdf errors
static string name_prefix
If a variable name, dimension name, or attribute name begins with a character that is not supported b...
static void reset()
Resets the FONc transformation for a new input and out file.