Field3D
Field3DInputFile Class Reference

Provides reading of .f3d (internally, hdf5) files.Refer to using_files for examples of how to use this in your code. More...

#include <Field3DFile.h>

Inheritance diagram for Field3DInputFile:
Field3DFileBase

List of all members.

Public Member Functions

bool open (const std::string &filename)
 Opens the given file.
bool readGroupMembership (GroupMembershipMap &gpMembershipMap)
 Read the group membership for the partitions.
Constructors & destructor
 Field3DInputFile ()
virtual ~Field3DInputFile ()
Reading layers from disk
template<class Data_T >
Field< Data_T >::Vec readScalarLayers (const std::string &layerName=std::string("")) const
 Retrieves all the layers of scalar type and maintains their on-disk data types.
template<class Data_T >
Field< Data_T >::Vec readScalarLayers (const std::string &partitionName, const std::string &layerName) const
 This one allows the allows the partitionName to be passed in.
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T >
>::Vec 
readVectorLayers (const std::string &layerName=std::string("")) const
 Retrieves all the layers of vector type and maintains their on-disk data types.
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T >
>::Vec 
readVectorLayers (const std::string &partitionName, const std::string &layerName) const
 This version allows you to pass in the partition name.
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec readScalarLayersAs (const std::string &layerName=std::string("")) const
 Retrieves all layers for all partitions. Converts it to the given template type if needed.
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec readScalarLayersAs (const std::string &partitionName, const std::string &layerName) const
 Retrieves a layers given their and its parent partition's name. Converts it to the given template type if needed.
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec readVectorLayersAs (const std::string &layerName=std::string("")) const
 Retrieves a layers for all partitions. Converts it to the given template type if needed.
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec readVectorLayersAs (const std::string &partitionName, const std::string &layerName) const
 Retrieves a layers given their and its parent partition's name. Converts it to the given template type if needed.
Reading proxy data from disk
template<class Data_T >
EmptyField< Data_T >::Vec readProxyLayer (const std::string &partitionName, const std::string &layerName, bool isVectorLayer) const
 Retrieves a proxy version (EmptyField) of each layer .
template<class Data_T >
EmptyField< Data_T >::Vec readProxyScalarLayers (const std::string &name=std::string("")) const
 Retrieves a proxy version (EmptyField) of each scalar layer.
template<class Data_T >
EmptyField< Data_T >::Vec readProxyVectorLayers (const std::string &name=std::string("")) const
 Retrieves a proxy version (EmptyField) of each vector layer.
Internal utility methods
herr_t parsePartition (hid_t loc_id, const std::string partitionName)
 Gets called from parsePartitions. Not intended for any other use.
herr_t parseLayer (hid_t loc_id, const std::string &partitionName, const std::string &layerName)
 Gets called from parsePartitions. Not intended for any other use.

Private Member Functions

template<class Data_T >
Field< Data_T >::Ptr readLayer (const std::string &intPartitionName, const std::string &layerName, bool isVectorLayer) const
 This call does the actual reading of a layer. Notice that it expects a unique -internal- partition name.
bool readMetadata (hid_t metadata_id, FieldBase::Ptr field) const
 Read metadata for this layer.
bool readMetadata (hid_t metadata_id)
 Read global metadata for this file.
bool readPartitionAndLayerInfo ()
 Sets up all the partitions and layers, but does not load any data.
template<class Data_T >
Field< Data_T >::Ptr readScalarLayer (const std::string &intPartitionName, const std::string &layerName) const
 Retrieves a single layer given its and its parent partition's name. Maintains the on-disk data types.
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T >
>::Ptr 
readVectorLayer (const std::string &intPartitionName, const std::string &layerName) const
 Retrieves a single layer given its and its parent partition's name. Maintains the on-disk data types.

Private Attributes

std::string m_filename
 Filename, only to be set by open().

Detailed Description

Provides reading of .f3d (internally, hdf5) files.

Refer to using_files for examples of how to use this in your code.

Note:
We distinguish between scalar and vector layers even though both are templated. A scalarField<float> layer is interchangeable with a scalarField<double> (conceptually) but not with a scalar<V3f>, and thus not with vectorField<float>.

Definition at line 431 of file Field3DFile.h.


Constructor & Destructor Documentation

Field3DInputFile::Field3DInputFile ( )

Definition at line 561 of file Field3DFile.cpp.

{ 
  // Empty
}
Field3DInputFile::~Field3DInputFile ( ) [virtual]

Definition at line 568 of file Field3DFile.cpp.

References Field3DFileBase::clear().

{ 
  clear(); 
}

Member Function Documentation

template<class Data_T >
Field< Data_T >::Vec Field3DInputFile::readScalarLayers ( const std::string &  layerName = std::string("")) const

Retrieves all the layers of scalar type and maintains their on-disk data types.

Parameters:
layerNameIf a string is passed in, only layers of that name will be read from disk.

Definition at line 769 of file Field3DFile.h.

References Field3DFileBase::getIntPartitionNames(), and Field3DFileBase::getIntScalarLayerNames().

{
  using namespace std;
  
  typedef typename Field<Data_T>::Ptr FieldPtr;
  typedef typename Field<Data_T>::Vec FieldList;

  FieldList ret;
  std::vector<std::string> parts;
  getIntPartitionNames(parts);

  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
    std::vector<std::string> layers;
    getIntScalarLayerNames(layers, *p);
    for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
      // Only read if it matches the name
      if ((name.length() == 0) || (*l == name)) {
        FieldPtr mf = readScalarLayer<Data_T>(*p, *l);
        if (mf) {
          ret.push_back(mf);
        }
      }
    }
  }
  
  return ret;
}
template<class Data_T >
Field< Data_T >::Vec Field3DInputFile::readScalarLayers ( const std::string &  partitionName,
const std::string &  layerName 
) const

This one allows the allows the partitionName to be passed in.

Definition at line 801 of file Field3DFile.h.

References Field3DFileBase::getIntPartitionNames(), Field3DFileBase::getIntScalarLayerNames(), and Field3DFileBase::removeUniqueId().

{
  using namespace std;
  
  typedef typename Field<Data_T>::Ptr FieldPtr;
  typedef typename Field<Data_T>::Vec FieldList;

  FieldList ret;

  if ((layerName.length() == 0) || (partitionName.length() == 0))
    return ret;
  
  std::vector<std::string> parts;
  getIntPartitionNames(parts);
 
  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
    std::vector<std::string> layers;
    getIntScalarLayerNames(layers, *p);
    if (removeUniqueId(*p) == partitionName) {
      for (vector<string>::iterator l = layers.begin(); 
           l != layers.end(); ++l) {
        // Only read if it matches the name
        if (*l == layerName) {
          FieldPtr mf = readScalarLayer<Data_T>(*p, *l);
          if (mf)
            ret.push_back(mf);
        }
      }
    }
  }
  
  return ret;
}
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T > >::Vec Field3DInputFile::readVectorLayers ( const std::string &  layerName = std::string("")) const

Retrieves all the layers of vector type and maintains their on-disk data types.

Parameters:
layerNameIf a string is passed in, only layers of that name will be read from disk.

Definition at line 840 of file Field3DFile.h.

References Field3DFileBase::getIntPartitionNames(), and Field3DFileBase::getIntVectorLayerNames().

{
  using namespace std;
  
  typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr;
  typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList;
  
  FieldList ret;
  
  std::vector<std::string> parts;
  getIntPartitionNames(parts);
  
  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
    std::vector<std::string> layers;
    getIntVectorLayerNames(layers, *p);
    for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
      // Only read if it matches the name
      if ((name.length() == 0) || (*l == name)) {
        FieldPtr mf = readVectorLayer<Data_T>(*p, *l);
        if (mf)
          ret.push_back(mf);
      }
    }
  }
  
  return ret;
}
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T > >::Vec Field3DInputFile::readVectorLayers ( const std::string &  partitionName,
const std::string &  layerName 
) const

This version allows you to pass in the partition name.

Definition at line 872 of file Field3DFile.h.

References Field3DFileBase::getIntPartitionNames(), Field3DFileBase::getIntVectorLayerNames(), and Field3DFileBase::removeUniqueId().

{
  using namespace std;
  
  typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr;
  typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList;
  
  FieldList ret;

  if ((layerName.length() == 0) || (partitionName.length() == 0))
    return ret;
  
  std::vector<std::string> parts;
  getIntPartitionNames(parts);
  
  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
    std::vector<std::string> layers;
    getIntVectorLayerNames(layers, *p);
    if (removeUniqueId(*p) == partitionName) {
      for (vector<string>::iterator l = layers.begin(); 
           l != layers.end(); ++l) {
        // Only read if it matches the name
        if (*l == layerName) {
          FieldPtr mf = readVectorLayer<Data_T>(*p, *l);
          if (mf)
            ret.push_back(mf);
        }
      }
    }
  }
  
  return ret;
}
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec Field3DInputFile::readScalarLayersAs ( const std::string &  layerName = std::string("")) const

Retrieves all layers for all partitions. Converts it to the given template type if needed.

Definition at line 990 of file Field3DFile.h.

References field_dynamic_cast().

{
  typedef typename Field<Data_T>::Vec FieldList;
  typedef typename Field_T<Data_T>::Vec TypedFieldList;

  // First, read the layers as-is
  FieldList originals;
  originals = readScalarLayers<Data_T>(layerName);
  
  // Loop over fields, converting if needed
  TypedFieldList output;
  typename FieldList::iterator i = originals.begin();
  for (; i != originals.end(); ++i) {
    typename Field_T<Data_T>::Ptr targetField;
    targetField = field_dynamic_cast<Field_T<Data_T> >(*i);
    if (targetField) {
      output.push_back(targetField);
    } else {
      typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>);
      newTarget->name = (*i)->name;
      newTarget->attribute = (*i)->attribute;
      newTarget->copyMetadata(*i);
      newTarget->copyFrom(*i);
      output.push_back(newTarget);
    }
  }

  return output;
}
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec Field3DInputFile::readScalarLayersAs ( const std::string &  partitionName,
const std::string &  layerName 
) const

Retrieves a layers given their and its parent partition's name. Converts it to the given template type if needed.

Definition at line 1024 of file Field3DFile.h.

References field_dynamic_cast().

{
  typedef typename Field<Data_T>::Vec FieldList;
  typedef typename Field_T<Data_T>::Vec TypedFieldList;

  // First, read the layers as-is
  FieldList originals;
  originals = readScalarLayers<Data_T>(partitionName, layerName);
  
  // Loop over fields, converting if needed
  TypedFieldList output;
  typename FieldList::iterator i = originals.begin();
  for (; i != originals.end(); ++i) {
    typename Field_T<Data_T>::Ptr targetField;
    targetField = field_dynamic_cast<Field_T<Data_T> >(*i);
    if (targetField) {
      output.push_back(targetField);
    } else {
      typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>);
      newTarget->name = (*i)->name;
      newTarget->attribute = (*i)->attribute;
      newTarget->copyMetadata(**i);
      newTarget->copyFrom(*i);
      output.push_back(newTarget);
    }
  }

  return output;
}
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec Field3DInputFile::readVectorLayersAs ( const std::string &  layerName = std::string("")) const

Retrieves a layers for all partitions. Converts it to the given template type if needed.

Definition at line 1059 of file Field3DFile.h.

References field_dynamic_cast().

{
  typedef typename Field<Data_T>::Vec FieldList;
  typedef typename Field_T<Data_T>::Vec TypedFieldList;

  // First, read the layers as-is
  FieldList originals;
  originals = readVectorLayers<Data_T>(layerName);
  
  // Loop over fields, converting if needed
  TypedFieldList output;
  typename FieldList::iterator i = originals.begin();
  for (; i != originals.end(); ++i) {
    typename Field_T<Data_T>::Ptr targetField;
    targetField = field_dynamic_cast<Field_T<Data_T> >(*i);
    if (targetField) {
      output.push_back(targetField);
    } else {
      typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>);
      newTarget->name = (*i)->name;
      newTarget->attribute = (*i)->attribute;
      newTarget->copyMetadata(*i);
      newTarget->copyFrom(*i);
      output.push_back(newTarget);
    }
  }

  return output;
}
template<template< typename T > class Field_T, class Data_T >
Field_T< Data_T >::Vec Field3DInputFile::readVectorLayersAs ( const std::string &  partitionName,
const std::string &  layerName 
) const

Retrieves a layers given their and its parent partition's name. Converts it to the given template type if needed.

Definition at line 1093 of file Field3DFile.h.

References field_dynamic_cast().

{
  typedef typename Field<Data_T>::Vec FieldList;
  typedef typename Field_T<Data_T>::Vec TypedFieldList;

  // First, read the layers as-is
  FieldList originals;
  originals = readVectorLayers<Data_T>(partitionName, layerName);
  
  // Loop over fields, converting if needed
  TypedFieldList output;
  typename FieldList::iterator i = originals.begin();
  for (; i != originals.end(); ++i) {
    typename Field_T<Data_T>::Ptr targetField;
    targetField = field_dynamic_cast<Field_T<Data_T> >(*i);
    if (targetField) {
      output.push_back(targetField);
    } else {
      typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>);
      newTarget->name = (*i)->name;
      newTarget->attribute = (*i)->attribute;
      newTarget->copyMetadata(*i);
      newTarget->copyFrom(*i);
      output.push_back(newTarget);
    }
  }

  return output;
}
template<class Data_T >
EmptyField< Data_T >::Vec Field3DInputFile::readProxyLayer ( const std::string &  partitionName,
const std::string &  layerName,
bool  isVectorLayer 
) const

Retrieves a proxy version (EmptyField) of each layer .

Note:
Although the call is templated, all fields are read, regardless of bit depth.
Parameters:
nameIf a string is passed in, only layers of that name will be read from disk.

Definition at line 1128 of file Field3DFile.h.

References FieldBase::attribute, Field3DFileBase::getIntPartitionNames(), Field3DFileBase::getIntScalarLayerNames(), Field3DFileBase::getIntVectorLayerNames(), Field3DFileBase::m_file, FieldBase::name, File::Layer::name, File::Layer::parent, Field3DFileBase::partition(), Msg::print(), Hdf5Util::readAttribute(), readMetadata(), Field3DFileBase::removeUniqueId(), FieldRes::setMapping(), ResizableField< Data_T >::setSize(), and Msg::SevWarning.

{
  using namespace boost;
  using namespace std;
  using namespace Hdf5Util;

  // Instantiate a null pointer for easier code reading
  typename EmptyField<Data_T>::Vec emptyList, output;

  if ((layerName.length() == 0) || (partitionName.length() == 0))
    return emptyList;

  std::vector<std::string> parts, layers;
  getIntPartitionNames(parts);
 
  bool foundPartition = false;

  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
    if (removeUniqueId(*p) == partitionName) {
      foundPartition = true;
      if (isVectorLayer) {
        getIntVectorLayerNames(layers, *p);
      } else {
        getIntScalarLayerNames(layers, *p);
      }
      for (vector<string>::iterator l = layers.begin(); 
           l != layers.end(); ++l) {
        if (*l == layerName) {
          // Find the partition
          File::Partition::Ptr part = partition(*p);
          if (!part) {
            Msg::print(Msg::SevWarning, "Couldn't find partition: " + *p);
            return emptyList;
          }
          // Find the layer
          const File::Layer *layer;
          if (isVectorLayer)
            layer = part->vectorLayer(layerName);
          else
            layer = part->scalarLayer(layerName);
          if (!layer) {
            Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName);
            return emptyList;
          }
          // Open the layer group
          string layerPath = layer->parent + "/" + layer->name;
          H5ScopedGopen layerGroup(m_file, layerPath.c_str());
          if (layerGroup.id() < 0) {
            Msg::print(Msg::SevWarning, "Couldn't find layer group " 
                      + layerName + " in .f3d file ");
            return emptyList;
          }
          // Read the extents and data window
          Box3i extents, dataW;
          if (!readAttribute(layerGroup, "extents", 6, extents.min.x)) {
            return emptyList;
          }
          if (!readAttribute(layerGroup, "data_window", 6, dataW.min.x)) {
            return emptyList;
          } 
          // Construct the field and load the data
          typename EmptyField<Data_T>::Ptr field(new EmptyField<Data_T>);
          field->setSize(extents, dataW);

          // read the metadata 
          string metadataPath = layerPath + "/metadata";
          H5ScopedGopen metadataGroup(m_file, metadataPath.c_str());
          if (metadataGroup.id() > 0) {    
            readMetadata(metadataGroup.id(), field);
          }

          // ... Set the name of the field so it's possible to 
          // ... re-create the file
          field->name = partitionName;
          field->attribute = layerName;
          field->setMapping(part->mapping);
          // Add field to output
          output.push_back(field);
        }
      }
    }
  }

  if (!foundPartition) {
    Msg::print(Msg::SevWarning, "Couldn't find partition: " + partitionName);
    return emptyList;    
  }
  
  return output;
}
template<class Data_T >
EmptyField< Data_T >::Vec Field3DInputFile::readProxyScalarLayers ( const std::string &  name = std::string("")) const

Retrieves a proxy version (EmptyField) of each scalar layer.

Note:
Although the call is templated, all fields are read, regardless of bit depth.
Parameters:
nameIf a string is passed in, only layers of that name will be read from disk.

Definition at line 1225 of file Field3DFile.h.

References Field3DFileBase::getPartitionNames(), and Field3DFileBase::getScalarLayerNames().

{
  using namespace std;

  typedef typename EmptyField<Data_T>::Ptr FieldPtr;
  typedef std::vector<FieldPtr> FieldList;
  
  FieldList ret;
  
  std::vector<std::string> parts;
  getPartitionNames(parts);
  
  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
  std::vector<std::string> layers;
    getScalarLayerNames(layers, *p);
    for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
      // Only read if it matches the name
      if ((name.length() == 0) || (*l == name)) {
        FieldList f = readProxyLayer<Data_T>(*p, *l, false);
        for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) {
          if (*i) {
            ret.push_back(*i);
          }
        }
      }
    }
  }
  
  return ret;
}
template<class Data_T >
EmptyField< Data_T >::Vec Field3DInputFile::readProxyVectorLayers ( const std::string &  name = std::string("")) const

Retrieves a proxy version (EmptyField) of each vector layer.

Note:
Although the call is templated, all fields are read, regardless of bit depth.
Parameters:
nameIf a string is passed in, only layers of that name will be read from disk.

Definition at line 1260 of file Field3DFile.h.

References Field3DFileBase::getPartitionNames(), and Field3DFileBase::getVectorLayerNames().

{
  using namespace std;
  
  typedef typename EmptyField<Data_T>::Ptr FieldPtr;
  typedef std::vector<FieldPtr> FieldList;
  
  FieldList ret;
  
  std::vector<std::string> parts;
  getPartitionNames(parts);
  
  for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
  std::vector<std::string> layers;
    getVectorLayerNames(layers, *p);
    for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
      // Only read if it matches the name
      if ((name.length() == 0) || (*l == name)) {
        FieldList f = readProxyLayer<Data_T>(*p, *l, true);
        for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) {
          if (*i) {
            ret.push_back(*i);
          }
        }
      }
    }
  }
  
  return ret;  
}
bool Field3DInputFile::open ( const std::string &  filename)

Opens the given file.

Returns:
Whether successful
herr_t Field3DInputFile::parsePartition ( hid_t  loc_id,
const std::string  partitionName 
)

Gets called from parsePartitions. Not intended for any other use.

Definition at line 784 of file Field3DFile.cpp.

References Field3DFileBase::m_partitionNames.

Referenced by InputFile::parsePartitions().

{
  // Add the partition ---
  
  m_partitionNames.push_back(string(itemName));
  return 0;
}
herr_t Field3DInputFile::parseLayer ( hid_t  layerGroup,
const std::string &  partitionName,
const std::string &  layerName 
)

Gets called from parsePartitions. Not intended for any other use.

Note:
Don't throw exceptions into the hdf5 lib.
Todo:
Set some sort of flag if we fail during this call. We can't throw exceptions inside hdf5.

Definition at line 798 of file Field3DFile.cpp.

References Field3DFileBase::m_layerInfo, Msg::print(), Hdf5Util::readAttribute(), and Msg::SevWarning.

Referenced by InputFile::parseLayers().

{
  int components;
  if (!readAttribute(layerGroup, string("components"), 1, components)) {
    Msg::print(Msg::SevWarning, "Couldn't read components attribute for layer " 
              + partitionName + "/" + layerName);
    return 0;
  }

  LayerInfo linfo(partitionName,layerName,components);

  m_layerInfo.push_back(linfo);

  return 0;
}
bool Field3DInputFile::readGroupMembership ( GroupMembershipMap gpMembershipMap)

Read the group membership for the partitions.

Definition at line 1039 of file Field3DFile.cpp.

References Hdf5Util::H5Base::id(), Field3DFileBase::m_file, Field3DFileBase::m_groupMembership, Msg::print(), Hdf5Util::readAttribute(), Field3DFileBase::removeUniqueId(), and Msg::SevWarning.

{
  if (!H5Lexists(m_file, "field3d_group_membership", H5P_DEFAULT)) {
    return false;
  }

  H5ScopedGopen memberGroup(m_file, "field3d_group_membership");
  if (memberGroup < 0) {
    return false;
  }
  
  typedef boost::tokenizer<boost::char_separator<char> > Tok;

  hsize_t num_attrs = H5Aget_num_attrs(memberGroup);
  if (num_attrs > 0) { 
    
    for (hsize_t idx=0; idx < num_attrs ; ++idx) {
      H5ScopedAopenIdx attrIdx(memberGroup, idx);        
      size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
      if (len>0) {
        char *name = new char[len+1];
        if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {

          if (string(name) == "is_field3d_group_membership")
            continue;

          H5ScopedAopen attr(memberGroup, name, H5P_DEFAULT);
          H5ScopedAget_space attrSpace(attr);
          H5ScopedAget_type attrType(attr);           
          H5T_class_t typeClass = H5Tget_class(attrType);

          if (typeClass == H5T_STRING) { 
            string value;
            if (!readAttribute(memberGroup, name, value)) {
              Msg::print(Msg::SevWarning, 
                         "Failed to read group membership data  " 
                        + string(name));
              continue;
            }

            {
              boost::char_separator<char> sep(" :");
              Tok tok(value, sep);
              string new_value;
              for(Tok::iterator beg=tok.begin(); beg!=tok.end();){

                string fieldgroup = *beg; ++beg;
                fieldgroup = removeUniqueId(fieldgroup) + ":" + *beg; ++beg;
                new_value += fieldgroup + " "; 
              }

              m_groupMembership[name] = value;
              gpMembershipMap[name] = new_value;
            }
          }
        }
      }
    }
  }

  return true;
}
template<class Data_T >
Field< Data_T >::Ptr Field3DInputFile::readScalarLayer ( const std::string &  intPartitionName,
const std::string &  layerName 
) const [private]

Retrieves a single layer given its and its parent partition's name. Maintains the on-disk data types.

Definition at line 1295 of file Field3DFile.h.

References Field3DFileBase::intPartitionName().

{
  return readLayer<Data_T>(intPartitionName, layerName, false);
}
template<class Data_T >
Field< FIELD3D_VEC3_T< Data_T > >::Ptr Field3DInputFile::readVectorLayer ( const std::string &  intPartitionName,
const std::string &  layerName 
) const [private]

Retrieves a single layer given its and its parent partition's name. Maintains the on-disk data types.

Definition at line 1305 of file Field3DFile.h.

References Field3DFileBase::intPartitionName().

{
  return readLayer<FIELD3D_VEC3_T<Data_T> >(intPartitionName, layerName, true);
}
template<class Data_T >
Field< Data_T >::Ptr Field3DInputFile::readLayer ( const std::string &  intPartitionName,
const std::string &  layerName,
bool  isVectorLayer 
) const [private]

This call does the actual reading of a layer. Notice that it expects a unique -internal- partition name.

Definition at line 911 of file Field3DFile.h.

References Field3DFileBase::m_file, m_filename, Field3DFileBase::partition(), Msg::print(), Hdf5Util::readAttribute(), readMetadata(), Field3DFileBase::removeUniqueId(), and Msg::SevWarning.

{
  using namespace boost;
  using namespace std;
  using namespace Hdf5Util;

  // Instantiate a null pointer for easier code reading
  typename Field<Data_T>::Ptr nullPtr;

  // Find the partition
  File::Partition::Ptr part = partition(intPartitionName);
  if (!part) {
    Msg::print(Msg::SevWarning, "Couldn't find partition: " + intPartitionName);
    return nullPtr;
  }

  // Find the layer in the partition
  const File::Layer *l;
  if (isVectorLayer)
    l = part->vectorLayer(layerName);
  else
    l = part->scalarLayer(layerName);
  if (!l) {
    Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName );
    return nullPtr;
  }

  // Open the layer group
  string layerPath = l->parent + "/" + l->name;
  H5ScopedGopen layerGroup(m_file, layerPath.c_str());

  if (layerGroup.id() < 0) {
    Msg::print(Msg::SevWarning, "Couldn't find layer group " + layerName 
              + " in .f3d file ");
    return nullPtr;
  }

  // Get the class name
  string className;
  if (!readAttribute(layerGroup.id(), "class_name", className)) {
    Msg::print(Msg::SevWarning, "Couldn't find class_name attrib in layer " + 
              layerName);
    return nullPtr;
  }

  // Construct the field and load the data

  typename Field<Data_T>::Ptr field;
  field = readField<Data_T>(className, layerGroup.id(), m_filename, layerPath);

  if (!field) {
#if 0 // This isn't really an error
    Msg::print(Msg::SevWarning, "Couldn't read the layer data of layer: " 
              + layerName);
#endif
    return nullPtr;
  }

  // read the metadata 
  string metadataPath = layerPath + "/metadata";
  H5ScopedGopen metadataGroup(m_file, metadataPath.c_str());
  if (metadataGroup.id() > 0) {    
    readMetadata(metadataGroup.id(), field);
  }

  // Set the name of the field so it's possible to re-create the file
  field->name = removeUniqueId(intPartitionName);
  field->attribute = layerName;
  field->setMapping(part->mapping);

  return field;
}
bool Field3DInputFile::readPartitionAndLayerInfo ( ) [private]

Sets up all the partitions and layers, but does not load any data.

Definition at line 692 of file Field3DFile.cpp.

References InputFile::ParseLayersInfo::file, Hdf5Util::H5Base::id(), Field3DFileBase::m_file, Field3DFileBase::m_layerInfo, Field3DFileBase::m_partitionNames, Field3DFileBase::m_partitions, File::Layer::name, File::Layer::parent, InputFile::parseLayers(), InputFile::parsePartitions(), Field3DFileBase::partition(), InputFile::ParseLayersInfo::partitionName, Msg::print(), readFieldMapping(), and Msg::SevWarning.

{
  using namespace InputFile;

  // First, find the partitions ---

  herr_t status;
  status = H5Literate(m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, 
                      &parsePartitions, this);

  // Get the partition names to store 
  m_partitions.clear();

  for (size_t i=0; i < m_partitionNames.size(); i++) {
    Partition::Ptr part(new Partition);
    part->name = m_partitionNames[i];    
    m_partitions.push_back(part);
  }
  
  // For each partition, find its mapping ---

  for (PartitionList::iterator i = m_partitions.begin();
       i != m_partitions.end(); ++i) {

    // Open the partition
    H5ScopedGopen partitionGroup(m_file, (**i).name);

    string mappingPath = "/" + (**i).name + "/" + k_mappingStr;

    // Open up the mapping group
    H5ScopedGopen mappingGroup(m_file, mappingPath);
    if (mappingGroup.id() < 0)
      throw MissingGroupException((**i).name + "/" + k_mappingStr);

    // Try to build a mapping from it
    FieldMapping::Ptr mapping;

    mapping = readFieldMapping(mappingGroup.id());
    if (!mapping) {
      Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping");
      throw ReadMappingException((**i).name);
    }
    
    // Attach the mapping to the partition
    (**i).mapping = mapping;

  }

  // ... And then find its layers ---

  for (PartitionList::const_iterator i = m_partitions.begin();
       i != m_partitions.end(); ++i) {

    // Open the partition
    H5ScopedGopen partitionGroup(m_file, (**i).name);
    
    // Set up the info struct for the callback
    ParseLayersInfo info;
    info.file = this;
    info.partitionName = (**i).name;

    m_layerInfo.clear();

    status = H5Literate(partitionGroup.id(), H5_INDEX_NAME, H5_ITER_NATIVE, 
                        NULL, &parseLayers, &info);

    //set the layer information on the partitions here

    for (std::vector<LayerInfo>::iterator i = m_layerInfo.begin();
         i != m_layerInfo.end(); i++) {

      std::string parent = i->parentName;      

      Partition::Ptr part = partition(parent);

      Layer layer;
      layer.name = i->name;
      layer.parent = i->parentName;
      if (i->components == 1) {
        part->addScalarLayer(layer);
      } else if (i->components == 3) {
        part->addVectorLayer(layer);
      }
    }

  }

  return true;
}
bool Field3DInputFile::readMetadata ( hid_t  metadata_id,
FieldBase::Ptr  field 
) const [private]

Read metadata for this layer.

Todo:
Replace char* with std::string

Definition at line 821 of file Field3DFile.cpp.

References Hdf5Util::H5Base::id(), Msg::print(), Hdf5Util::readAttribute(), and Msg::SevWarning.

Referenced by readLayer(), and readProxyLayer().

{

  hsize_t num_attrs = H5Aget_num_attrs(metadata_id);

  if (num_attrs > 0) { 
    for (hsize_t idx=0; idx < num_attrs ; ++idx) {
      H5ScopedAopenIdx attrIdx(metadata_id, idx);
      size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
      if (len > 0) {
        char *name = new char[len+1];
        if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
          H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT);
          H5ScopedAget_space attrSpace(attr);
          H5ScopedAget_type attrType(attr);           
          H5T_class_t typeClass = H5Tget_class(attrType);

          if (typeClass == H5T_STRING) { 
            string value;
            if (!readAttribute(metadata_id, name, value)) {
              Msg::print(Msg::SevWarning, 
                         "Failed to read metadata " + string(name));
              if (name) {
                delete[] name;
              }
              continue;
            }
            field->metadata().setStrMetadata(name, value);
             
          }
          else {

            if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
              Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 
                        + string(name));
              if (name) {
                delete[] name;
              }
              continue;
            }            

            hsize_t dims[1];
            H5Sget_simple_extent_dims(attrSpace, dims, NULL);
 
            if (typeClass == H5T_INTEGER) { 
              if (dims[0] == 1){
                int value;
                if (!readAttribute(metadata_id, name, dims[0], value))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " 
                            + string(name));
                field->metadata().setIntMetadata(name, value);
              }
              else if (dims[0] == 3){
                V3i value;
                if (!readAttribute(metadata_id, name, dims[0], value.x))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " + 
                            string(name) );
                field->metadata().setVecIntMetadata(name, value);
              }
              else {
                Msg::print(Msg::SevWarning, 
                           "Attribute of size " + 
                           boost::lexical_cast<std::string>(dims[0]) 
                           + " is not valid for metadata");
              }
            }
            else if (typeClass == H5T_FLOAT) { 
              if (dims[0] == 1){
                float value;
                if (!readAttribute(metadata_id, name, dims[0], value))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " + 
                            string(name) );
                
                field->metadata().setFloatMetadata(name, value);
              }
              else if (dims[0] == 3){
                V3f value;
                if (!readAttribute(metadata_id, name, dims[0], value.x))
                  Msg::print(Msg::SevWarning, "Failed to read metadata "+ 
                            string(name) );
                field->metadata().setVecFloatMetadata(name, value);
              }
              else {
                Msg::print(Msg::SevWarning, "Attribute of size " +
                           boost::lexical_cast<std::string>(dims[0]) +
                           " is not valid for metadata");
              }
            }
            else {               
              Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 
                        + "' has unsupported data type for metadata");
              
            }
          }
        }
        if (name) {
          delete[] name;
        }
      }
    }
  }

  return true;
}
bool Field3DInputFile::readMetadata ( hid_t  metadata_id) [private]

Read global metadata for this file.

Todo:
Replace char* with std::string

Definition at line 930 of file Field3DFile.cpp.

References Hdf5Util::H5Base::id(), Field3DFileBase::metadata(), Msg::print(), Hdf5Util::readAttribute(), FieldMetadata< CallBack_T >::setFloatMetadata(), FieldMetadata< CallBack_T >::setIntMetadata(), FieldMetadata< CallBack_T >::setStrMetadata(), FieldMetadata< CallBack_T >::setVecFloatMetadata(), FieldMetadata< CallBack_T >::setVecIntMetadata(), and Msg::SevWarning.

{

  hsize_t num_attrs = H5Aget_num_attrs(metadata_id);

  if (num_attrs > 0) { 
    for (hsize_t idx=0; idx < num_attrs ; ++idx) {
      H5ScopedAopenIdx attrIdx(metadata_id, idx);
      size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
      if (len > 0) {
        char *name = new char[len+1];
        if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
          H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT);
          H5ScopedAget_space attrSpace(attr);
          H5ScopedAget_type attrType(attr);           
          H5T_class_t typeClass = H5Tget_class(attrType);

          if (typeClass == H5T_STRING) { 
            string value;
            if (!readAttribute(metadata_id, name, value)) {
              Msg::print(Msg::SevWarning, 
                         "Failed to read metadata " + string(name));
              if (name) {
                delete[] name;
              }
              continue;
            }
            metadata().setStrMetadata(name, value);
             
          }
          else {

            if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
              Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 
                        + string(name));
              if (name) {
                delete[] name;
              }
              continue;
            }            

            hsize_t dims[1];
            H5Sget_simple_extent_dims(attrSpace, dims, NULL);
 
            if (typeClass == H5T_INTEGER) { 
              if (dims[0] == 1){
                int value;
                if (!readAttribute(metadata_id, name, dims[0], value))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " 
                            + string(name));
                metadata().setIntMetadata(name, value);
              }
              else if (dims[0] == 3){
                V3i value;
                if (!readAttribute(metadata_id, name, dims[0], value.x))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " + 
                            string(name) );
                metadata().setVecIntMetadata(name, value);
              }
              else {
                Msg::print(Msg::SevWarning, 
                           "Attribute of size " + 
                           boost::lexical_cast<std::string>(dims[0]) 
                           + " is not valid for metadata");
              }
            }
            else if (typeClass == H5T_FLOAT) { 
              if (dims[0] == 1){
                float value;
                if (!readAttribute(metadata_id, name, dims[0], value))
                  Msg::print(Msg::SevWarning, "Failed to read metadata " + 
                            string(name) );
                
                metadata().setFloatMetadata(name, value);
              }
              else if (dims[0] == 3){
                V3f value;
                if (!readAttribute(metadata_id, name, dims[0], value.x))
                  Msg::print(Msg::SevWarning, "Failed to read metadata "+ 
                            string(name) );
                metadata().setVecFloatMetadata(name, value);
              }
              else {
                Msg::print(Msg::SevWarning, "Attribute of size " +
                           boost::lexical_cast<std::string>(dims[0]) +
                           " is not valid for metadata");
              }
            }
            else {               
              Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 
                        + "' has unsupported data type for metadata");
              
            }
          }
        }
        if (name) {
          delete[] name;
        }
      }
    }
  }

  return true;
}

Member Data Documentation

std::string Field3DInputFile::m_filename [private]

Filename, only to be set by open().

Definition at line 603 of file Field3DFile.h.

Referenced by readLayer().


The documentation for this class was generated from the following files: