Exporting data

In this tutorial, we will create an exporter for the following XYZ format: The 1st line: the number of atoms in the file. The 2nd line: arbitraty header line. Next lines contain information on atoms in the following format (coordinates are in angstroms): element_symbol x-coordinate y-coordinate z-coordinate.

Example of the format:

C -6.644 9.967 5.557
C -7.934 9.831 4.773
C -7.934 10.816 3.617
C -8.098 8.407 4.266
N -7.404 9.603 7.84
C -6.46 9.161 6.834
C -5.09 9.488 7.383
O -5.008 10.375 8.245
H -8.382 9.481 7.521
H -7.182 10.599 8.021

Note: SAMSON already has an XYZ Exporter which is installed by default, that's why we are actually going to read files with a exyz extension, even though the contents will still correspond to the xyz format.

The source code for an Extension created in this tutorial can be found at https://github.com/1A-OneAngstrom/SAMSON-Developer-Tutorials.

Generating an Extension

We will start by creating a new SAMSON Extension called EXYZ thanks to the SAMSON Extension generator (please, refer to the SAMSON Extension generator tutorial for a reminder on how to use it):

The SAMSON Extension generator generates an exporter class (derived from the SBIFileExporter class) and a GUI class that implements the user interface of the exporter and is derived from the SBGFileExporter class.

Exporting into a file

In SAMSON, an exporter is created by programming three functions in the exporter class:

Let's open the SEEXYZExporter.cpp file and implement these functions.

Modify the getExtension function to return the extension of the exporter (exyz) as follows:

std::string SEEXYZExporter::getExtension() const {
return std::string("exyz");

Modify the getFilter function to return the filter of the exporter as follows (it should be in the Qt format):

std::string SEEXYZExporter::getFilter() const {
return std::string("EXYZ format (*.exyz)");

We now have to code the exportToFile function to export atoms into a exyz file. To achieve this, we are going to use fstream to create and write into a file, the SAMSON class to get atoms from the active document, and several structural classes. For that, include the following headers in the file:

#include <fstream>
#include "SAMSON.hpp"
#include "SBStructuralModel.hpp"
#include "SBAtom.hpp"

Let's now code inside the exportToFile function:

bool SEEXYZExporter::exportToFile(const SBNodeIndexer& nodeIndexer, const std::string& fileName, const SBList<std::string>* parameters)

First, we find all atoms in the nodes that were passed to the exportToFile function:

// retrieve all atoms
SBNodeIndexer atomIndexer;
SB_FOR(SBNode* node, nodeIndexer) node->getNodes(atomIndexer, SBNode::IsType(SBNode::Atom));

Recall that SBNode::IsType(SBNode::Atom) is a predicate, passed to the getNodes function, that returns true for nodes that are atoms.

If the user saves data via File > Save or File > Save as... it will export all atoms from the active document, if the user saves data via File > Save selection as... it will export all atoms from the selection in the active document.

Then, we create the file and write its header:

// create file
ofstream file;
// write the header
file << atomIndexer.size() << std::endl; // number of atoms
file << "SAMSON Export" << std::endl;

In this tutorial, for simplicity we do not check for errors during the creation and writing of the file.

And we then write the description of each atom to the file:

// write atoms
for (unsigned int i = 0; i < atomIndexer.size(); i++) {
SBAtom* currentAtom = static_cast<SBAtom*>(atomIndexer[i]);
SBPosition3 const& currentAtomPosition = currentAtom->getPosition();
file << SAMSON::getElementSymbol(currentAtom->getElementType())
<< " " << SBQuantity::angstrom(currentAtomPosition.v[0]).getValue()
<< " " << SBQuantity::angstrom(currentAtomPosition.v[1]).getValue()
<< " " << SBQuantity::angstrom(currentAtomPosition.v[2]).getValue() << "\n";

Finally, we close the file and we signal that everything went fine (at least we believe so, since we didn’t test for errors in this tutorial):

// close the file
return true;

That is it. You can now export into exyz format.

If you want for the Exporter to get some parameters/options from the user, please check out to the Importer tutorial: Getting parameters, if not then you can simply disable the options window by replacing the constructor and destructor of SEEXYZExporter as follows:

SEEXYZExporter::SEEXYZExporter() {
// remove the options window
propertyDialog = 0;
SEEXYZExporter::~SEEXYZExporter() {
unsigned int size() const
Returns the number of indexed objects.
Definition: SBCContainerIndexer.hpp:481
Quantity v[3]
The components of the physical vector.
Definition: SBDTypePhysicalVector3.hpp:765
virtual SBElement::Type getElementType() const
Returns the atom's element type.
Definition: SBMStructuralModelNodeAtom.cpp:1336
static std::string getElementSymbol(SBMElement::Type element)
Returns the symbol of the periodic table element corresponding to a given type.
Definition: SAMSON.cpp:795
This class describes a node indexer.
Definition: SBDDataGraphNodeIndexer.hpp:21
@ Atom
Definition: SBDDataGraphNode.hpp:70
A macro to easily write for loops involving containers.
Definition: SBCContainerFor.hpp:83
This class describes an atom in a structural model.
Definition: SBMStructuralModelNodeAtom.hpp:32
This class is the main interface.
Definition: SAMSON.hpp:61
This class is the base class to describe a node in the data graph.
Definition: SBDDataGraphNode.hpp:33
This node predicate compares the node type with a given type.
Definition: SBDDataGraphNode.hpp:505
virtual void getNodes(SBNodeIndexer &nodeIndexer, SBDDataGraphNode::Type nodeType, bool selectedNodesOnly=false, const SBNodePredicate &visitPredicate=SBDDataGraphNode::All(), bool includeDependencies=false) const
Collects nodes into nodeIndexer, based on a nodeType, a selection status and a visitPredicate,...
Definition: SBDDataGraphNode.cpp:1732
SBDQuantityType< SBDQuantityUnitType< SBUnitSystemSI, -10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > > angstrom
The angstrom type.
Definition: SBDQuantity.hpp:81
SBPosition3 const & getPosition() const
Returns the particle's position.
Definition: SBMStructuralModelNodeParticle.cpp:52