Web Analytics Made Easy - Statcounter
Skip to content

Exporting files#

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:

10
SAMSON Export
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 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):

  • launch SAMSON and run the SAMSON Extension Generator;
  • specify the path to a folder where you want to develop your SAMSON Extensions;
  • name the SAMSON Extension as EXYZ and add some description;
  • add an Exporter class (called SEEXYZExporter);
  • generate the SAMSON Extension.

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:

  • getExtension - specifies the extension of a file;
  • getFilter - specifies a filter in Qt format;
  • exportToFile - a function invoked by SAMSON to export into a file with a suitable extension.

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 std::unordered_map<std::string, SBValue>* 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 Home > File > Save or Home > File > Save as... it will export all atoms from the active document, if the user saves data via Home > 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;
file.open(fileName.c_str());

// 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
file.close();

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 = nullptr;

}

SEEXYZExporter::~SEEXYZExporter() {

}