Field3D
Field3DOutputFile Class Reference

Provides writing of .f3d (internally, hdf5) files. More...

#include <Field3DFile.h>

Inheritance diagram for Field3DOutputFile:
Field3DFileBase

List of all members.

Public Types

enum  CreateMode { OverwriteMode, FailOnExisting }

Public Member Functions

bool create (const std::string &filename, CreateMode cm=OverwriteMode)
 Creates a .f3d file on disk.
template<class Data_T >
File::Partition::Ptr createNewPartition (const std::string &partitionName, const std::string &layerName, typename Field< Data_T >::Ptr field)
 create newPartition given the input config
std::string incrementPartitionName (std::string &pname)
 increment the partition or make it zero if there's not an integer suffix
bool writeGlobalMetadata ()
 This routine is call if you want to write out global metadata to disk.
bool writeGroupMembership ()
 This routine is called just before closing to write out any group membership to disk.
Constructors & destructor
 Field3DOutputFile ()
virtual ~Field3DOutputFile ()
Writing layer to disk
template<class Data_T >
bool writeScalarLayer (const std::string &layerName, typename Field< Data_T >::Ptr layer)
 Writes a scalar layer to the "Default" partition.
template<class Data_T >
bool writeVectorLayer (const std::string &layerName, typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr layer)
 Writes a vector layer to the "Default" partition.
template<class Data_T >
bool writeScalarLayer (const std::string &partitionName, const std::string &layerName, typename Field< Data_T >::Ptr layer)
 Writes a layer to a specific partition. The partition will be created if not specified.
template<class Data_T >
bool writeScalarLayer (typename Field< Data_T >::Ptr layer)
 Writes a layer to a specific partition. The field name and attribute name are used for partition and layer, respectively.
template<class Data_T >
bool writeVectorLayer (const std::string &partitionName, const std::string &layerName, typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr layer)
 Writes a layer to a specific partition. The partition will be created if not specified.
template<class Data_T >
bool writeVectorLayer (typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr layer)
 Writes a layer to a specific partition. The field name and attribute name are used for partition and layer, respectively.

Private Member Functions

template<class Data_T >
bool writeLayer (const std::string &partitionName, const std::string &layerName, bool isVectorLayer, typename Field< Data_T >::Ptr layer)
 Performs the actual writing of the layer to disk.
bool writeMapping (hid_t partitionLocation, FieldMapping::Ptr mapping)
 Writes the mapping to the given hdf5 node. Mappings are assumed to be light-weight enough to be stored as plain attributes under a group.
bool writeMetadata (hid_t metadataGroup, FieldBase::Ptr layer)
 Writes metadata for this layer.
bool writeMetadata (hid_t metadataGroup)
 Writes metadata for this file.

Detailed Description

Provides writing 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 626 of file Field3DFile.h.


Member Enumeration Documentation

Enumerator:
OverwriteMode 
FailOnExisting 

Definition at line 632 of file Field3DFile.h.


Constructor & Destructor Documentation

Field3DOutputFile::Field3DOutputFile ( )

Definition at line 1199 of file Field3DFile.cpp.

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

Definition at line 1206 of file Field3DFile.cpp.

{ 

}

Member Function Documentation

template<class Data_T >
bool Field3DOutputFile::writeScalarLayer ( const std::string &  layerName,
typename Field< Data_T >::Ptr  layer 
) [inline]

Writes a scalar layer to the "Default" partition.

Definition at line 654 of file Field3DFile.h.

  { return writeScalarLayer<Data_T>(layerName, std::string("default"), layer); }
template<class Data_T >
bool Field3DOutputFile::writeVectorLayer ( const std::string &  layerName,
typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr  layer 
) [inline]

Writes a vector layer to the "Default" partition.

Definition at line 660 of file Field3DFile.h.

  { return writeVectorLayer<Data_T>(layerName, std::string("default"), layer); }
template<class Data_T >
bool Field3DOutputFile::writeScalarLayer ( const std::string &  partitionName,
const std::string &  layerName,
typename Field< Data_T >::Ptr  layer 
)

Writes a layer to a specific partition. The partition will be created if not specified.

Definition at line 1511 of file Field3DFile.h.

{
  return writeLayer<Data_T>(partitionName, layerName, false, field);
}
template<class Data_T >
bool Field3DOutputFile::writeScalarLayer ( typename Field< Data_T >::Ptr  layer)

Writes a layer to a specific partition. The field name and attribute name are used for partition and layer, respectively.

Definition at line 1522 of file Field3DFile.h.

References FieldBase::attribute, FieldBase::name, Msg::print(), and Msg::SevWarning.

{
  if (layer->name.size() == 0) {
    Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: "
               "Tried to write a scalar layer with no name");
    return false;
  }
  if (layer->attribute.size() == 0) {
    Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: "
               "Tried to write a scalar layer with no attribute name");
    return false;
  }
  return writeScalarLayer<Data_T>(layer->name, layer->attribute, layer);
}
template<class Data_T >
bool Field3DOutputFile::writeVectorLayer ( const std::string &  partitionName,
const std::string &  layerName,
typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr  layer 
)

Writes a layer to a specific partition. The partition will be created if not specified.

Definition at line 1542 of file Field3DFile.h.

{
  return writeLayer<FIELD3D_VEC3_T<Data_T> >(partitionName, layerName, 
                                             true, field);
}
template<class Data_T >
bool Field3DOutputFile::writeVectorLayer ( typename Field< FIELD3D_VEC3_T< Data_T > >::Ptr  layer)

Writes a layer to a specific partition. The field name and attribute name are used for partition and layer, respectively.

Definition at line 1555 of file Field3DFile.h.

References Msg::print(), and Msg::SevWarning.

{
  if (layer->name.size() == 0) {
    Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: "
               "Tried to write a vector layer with no name");
    return false;
  }
  if (layer->attribute.size() == 0) {
    Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: "
               "Tried to write a vector layer with no attribute name");
    return false;
  }
  return writeVectorLayer<Data_T>(layer->name, layer->attribute, layer);
}
bool Field3DOutputFile::create ( const std::string &  filename,
CreateMode  cm = OverwriteMode 
)

Creates a .f3d file on disk.

bool Field3DOutputFile::writeGlobalMetadata ( )

This routine is call if you want to write out global metadata to disk.

Definition at line 1455 of file Field3DFile.cpp.

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

{

  // Add metadata group and write it out  
  H5ScopedGcreate metadataGroup(m_file, "field3d_global_metadata");
  if (metadataGroup.id() < 0) {
    Msg::print(Msg::SevWarning, "Error creating group: file metadata");
    return false;
  }  
  if (!writeMetadata(metadataGroup.id())) {
    Msg::print(Msg::SevWarning, "Error writing file metadata.");
    return false;
  }    
 
  return true;
}
bool Field3DOutputFile::writeGroupMembership ( )

This routine is called just before closing to write out any group membership to disk.

Definition at line 1475 of file Field3DFile.cpp.

References Field3DFileBase::m_file, Field3DFileBase::m_groupMembership, Msg::print(), Msg::SevWarning, and Hdf5Util::writeAttribute().

{
  using namespace std;
  using namespace Hdf5Util;

  if (!m_groupMembership.size())
    return true;

  H5ScopedGcreate group(m_file, "field3d_group_membership");
  if (group < 0) {
    Msg::print(Msg::SevWarning, 
               "Error creating field3d_group_membership group.");      
    return false;
  } 

  if (!writeAttribute(group, "is_field3d_group_membership", "1")) {
    Msg::print(Msg::SevWarning, 
               "Failed to write field3d_group_membership attribute.");
    return false;
  }    

  std::map<std::string, std::string>::const_iterator iter = 
    m_groupMembership.begin();
  std::map<std::string, std::string>::const_iterator iEnd = 
    m_groupMembership.end();
  
  for (; iter != iEnd; ++iter) {
    if (!writeAttribute(group, iter->first, iter->second)) {
      Msg::print(Msg::SevWarning, 
                 "Failed to write groupMembership string: "+ iter->first);
      return false;
    }        
  }
  
  return true;
}
std::string Field3DOutputFile::incrementPartitionName ( std::string &  pname)

increment the partition or make it zero if there's not an integer suffix

Definition at line 1515 of file Field3DFile.cpp.

References Field3DFileBase::m_partitionCount, Field3DFileBase::makeIntPartitionName(), and Field3DFileBase::removeUniqueId().

{
  std::string myPartitionName = removeUniqueId(partitionName);
  int nextIdx = -1;
  if (m_partitionCount.find(myPartitionName) != m_partitionCount.end()) {
    nextIdx = ++m_partitionCount[myPartitionName];
  } else {
    nextIdx = 0;
    m_partitionCount[myPartitionName] = 0;
  }

  return makeIntPartitionName(myPartitionName, nextIdx);
}
template<class Data_T >
File::Partition::Ptr Field3DOutputFile::createNewPartition ( const std::string &  partitionName,
const std::string &  layerName,
typename Field< Data_T >::Ptr  field 
)

create newPartition given the input config

Todo:
We should probably remove the group on disk if we can't write the mapping

Definition at line 1317 of file Field3DFile.h.

References Field3DFileBase::m_file, Field3DFileBase::m_partitions, FieldRes::mapping(), Field3DFileBase::partition(), Msg::print(), Msg::SevWarning, and Hdf5Util::writeAttribute().

{
  using namespace Hdf5Util;
  using namespace Exc;
  
  File::Partition::Ptr newPart(new File::Partition);

  newPart->name = partitionName;

  H5ScopedGcreate partGroup(m_file, newPart->name.c_str());
  if (partGroup.id() < 0) {
    Msg::print(Msg::SevWarning, 
               "Error creating partition: " + newPart->name);
    return File::Partition::Ptr();
  } 
    
  m_partitions.push_back(newPart);

  // Pick up new pointer
  File::Partition::Ptr  part = partition(partitionName);
  
  // Add mapping group to the partition
  try {
    if (!writeMapping(partGroup.id(), field->mapping())) {
      Msg::print(Msg::SevWarning, 
                 "writeMapping returned false for an unknown reason ");
      return File::Partition::Ptr();
    }
  }
  catch (WriteMappingException &e) {
    Msg::print(Msg::SevWarning, "Couldn't write mapping for partition: " 
               + partitionName);
    return File::Partition::Ptr();
  }
  catch (...) {
    Msg::print(Msg::SevWarning, 
               "Unknown error when writing mapping for partition: " 
               + partitionName);
    return File::Partition::Ptr();    
  }

  // Set the mapping of the partition. Since all layers share their 
  // partition's mapping, we can just pick this first one. All subsequent
  // additions to the same partition are checked to have the same mapping
  part->mapping = field->mapping();

  // Tag node as partition
  // Create a version attribute on the root node
  if (!writeAttribute(partGroup.id(), "is_field3d_partition", "1")) {
    Msg::print(Msg::SevWarning, "Adding partition string.");
    return File::Partition::Ptr();    
  }

  return part;
}
bool Field3DOutputFile::writeMapping ( hid_t  partitionLocation,
FieldMapping::Ptr  mapping 
) [private]

Writes the mapping to the given hdf5 node. Mappings are assumed to be light-weight enough to be stored as plain attributes under a group.

Definition at line 1271 of file Field3DFile.cpp.

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

{
  try {
    // Make a group under the partition to store the mapping data
    H5ScopedGcreate mappingGroup(partitionGroup, k_mappingStr);
    if (mappingGroup.id() < 0)
      throw CreateGroupException(k_mappingStr);
    // Let FieldMappingIO handle the rest
    if (!writeFieldMapping(mappingGroup.id(), mapping))
      throw WriteMappingException(k_mappingStr);       
  }
  catch (CreateGroupException &e) {
    Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) );
    throw WriteMappingException(k_mappingStr);
  }
  return true;
}
template<class Data_T >
bool Field3DOutputFile::writeLayer ( const std::string &  partitionName,
const std::string &  layerName,
bool  isVectorLayer,
typename Field< Data_T >::Ptr  layer 
) [private]

Performs the actual writing of the layer to disk.

Definition at line 1381 of file Field3DFile.h.

References Field3DFileBase::intPartitionName(), Field3DFileBase::m_file, FieldRes::mapping(), File::Layer::name, Field3DFileBase::partition(), Msg::print(), Msg::SevWarning, Hdf5Util::writeAttribute(), and writeField().

{
  using namespace std;
  using namespace Exc;
  using namespace Hdf5Util;

  if (!field) {
    Msg::print(Msg::SevWarning, 
               "Called writeLayer with null pointer. Ignoring...");
    return false;
  }

  if (m_file < 0) {
    Msg::print(Msg::SevWarning, 
               "Attempting to write layer without opening file first. ");
    return false;
  }

  string partitionName = intPartitionName(userPartitionName, layerName, field);

  // See if the partition already exists or if we need to make it ---

  File::Partition::Ptr part = partition(partitionName);

  if (!part) {
    part = createNewPartition<Data_T>(partitionName,layerName,field);
    if (!part)
      return false;
  } else {

    if (!field->mapping()) {
      Msg::print(Msg::SevWarning, 
                 "Couldn't add layer \"" + layerName + "\" to partition \""
                 + partitionName + "\" because the layer's mapping is null.");
      return false;    
    }
    
    // If the partition already existed, we need to make sure that the layer
    // doesn't also exist
    if (!isVectorLayer) {
      if (part->scalarLayer(layerName)) {
        //need to create a new partition and then add the layer to that
        std::string newPartitionName = incrementPartitionName(partitionName);
        part = createNewPartition<Data_T>(newPartitionName,layerName,field);
        if (!part)
          return false;
      }
    } else {
      if (part->vectorLayer(layerName)) {
        //need to create a new partition and then add the layer to that
        std::string newPartitionName = incrementPartitionName(partitionName);
        part = createNewPartition<Data_T>(newPartitionName,layerName,field);
        if (!part)
          return false;
      }
    }
  }

  if (!part->mapping) {
    Msg::print(Msg::SevWarning, "Severe error - partition mapping is null: " 
              + partitionName);
    return false;    
  }

  // Check that the mapping matches what's already in the Partition
  if (!field->mapping()->isIdentical(part->mapping)) {
    Msg::print(Msg::SevWarning, "Couldn't add layer \"" + layerName 
              + "\" to partition \"" + partitionName 
              + "\" because mapping doesn't match");
    return false;
  }

  // Open the partition
  H5ScopedGopen partGroup(m_file, part->name.c_str(), H5P_DEFAULT);

  // Build a Layer object ---

  File::Layer layer;
  layer.name = layerName;
  layer.parent = partitionName;

  // Add Layer to file ---

  H5ScopedGcreate layerGroup(partGroup.id(), layerName.c_str(),
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

  if (layerGroup.id() < 0) {
    Msg::print(Msg::SevWarning, "Error creating layer: " + layerName);
    return false;
  }

  // Tag as layer
  if (!writeAttribute(layerGroup.id(), "class_type", "field3d_layer")) {
    Msg::print(Msg::SevWarning, "Error adding layer string.");
    return false;
  }    

  // Add metadata group and write it out  
  H5ScopedGcreate metadataGroup(layerGroup.id(), "metadata");
  if (metadataGroup.id() < 0) {
    Msg::print(Msg::SevWarning, "Error creating group: metadata");
    return false;
  }  
  if (!writeMetadata(metadataGroup.id(), field)) {
    Msg::print(Msg::SevWarning, "Error writing metadata.");
    return false;
  }    

  if (!writeField(layerGroup.id(), field)) {
    Msg::print(Msg::SevWarning, "Error writing layer: " + layer.name);
    return false;
  }
  
  // Add layer to partition ---

  if (isVectorLayer)
    part->addVectorLayer(layer);
  else
    part->addScalarLayer(layer);

  return true;  
}
bool Field3DOutputFile::writeMetadata ( hid_t  metadataGroup,
FieldBase::Ptr  layer 
) [private]

Writes metadata for this layer.

Definition at line 1292 of file Field3DFile.cpp.

References FieldMetadata< CallBack_T >::floatMetadata(), FieldMetadata< CallBack_T >::intMetadata(), Msg::print(), Msg::SevWarning, FieldMetadata< CallBack_T >::strMetadata(), FieldMetadata< CallBack_T >::vecFloatMetadata(), FieldMetadata< CallBack_T >::vecIntMetadata(), and Hdf5Util::writeAttribute().

{
  using namespace Hdf5Util;

  {
    FieldMetadata<FieldBase>::StrMetadata::const_iterator i = 
      field->metadata().strMetadata().begin();
    FieldMetadata<FieldBase>::StrMetadata::const_iterator end = 
      field->metadata().strMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
        return false;
      }
    }
  }

  {
    FieldMetadata<FieldBase>::IntMetadata::const_iterator i = 
      field->metadata().intMetadata().begin();
    FieldMetadata<FieldBase>::IntMetadata::const_iterator end = 
      field->metadata().intMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 1, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<FieldBase>::FloatMetadata::const_iterator i = 
      field->metadata().floatMetadata().begin();
    FieldMetadata<FieldBase>::FloatMetadata::const_iterator end = 
      field->metadata().floatMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 1, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<FieldBase>::VecIntMetadata::const_iterator i = 
      field->metadata().vecIntMetadata().begin();
    FieldMetadata<FieldBase>::VecIntMetadata::const_iterator end = 
      field->metadata().vecIntMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator i = 
      field->metadata().vecFloatMetadata().begin();
    FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator end = 
      field->metadata().vecFloatMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }

  }

  return true;

}
bool Field3DOutputFile::writeMetadata ( hid_t  metadataGroup) [private]

Writes metadata for this file.

Definition at line 1373 of file Field3DFile.cpp.

References FieldMetadata< CallBack_T >::floatMetadata(), FieldMetadata< CallBack_T >::intMetadata(), Field3DFileBase::metadata(), Msg::print(), Msg::SevWarning, FieldMetadata< CallBack_T >::strMetadata(), FieldMetadata< CallBack_T >::vecFloatMetadata(), FieldMetadata< CallBack_T >::vecIntMetadata(), and Hdf5Util::writeAttribute().

{
  using namespace Hdf5Util;

  {
    FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator i = 
      metadata().strMetadata().begin();
    FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator end = 
      metadata().strMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
        return false;
      }
    }
  }

  {
    FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator i = 
      metadata().intMetadata().begin();
    FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator end = 
      metadata().intMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 1, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator i = 
      metadata().floatMetadata().begin();
    FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator end = 
      metadata().floatMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 1, i->second))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator i = 
      metadata().vecIntMetadata().begin();
    FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator end = 
      metadata().vecIntMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }
  }

  {
    FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator i = 
      metadata().vecFloatMetadata().begin();
    FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator end = 
      metadata().vecFloatMetadata().end();
    for (; i != end; ++i) {
      if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
      {
        Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
        return false;
      }
    }

  }

  return true;

}

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