IDS (IdsNs::Ids) API

class Ids

Abstract base class for all IDS classes. All methods defined here are available on all concrete IDS objects.

std::string serialize(int protocol = DEFAULT_SERIALIZER_PROTOCOL)

Serialize the contents of this IDS into binary data.

There are currently two different serialization protocols. The ASCII protocol serializes the data though the ASCII backend. This is a simpler human readable protocol, but it’s also less efficient than the (newer) Flexbuffers protocol. The latter is the default and should be preferred.

The ID of the used serializer protocol is kept in the header of the serialized buffer, such that specifying the protocol is not necessary when deserializing.

Parameters:
int protocol = DEFAULT_SERIALIZER_PROTOCOL

Which serialization protocol to use. Available options are:

Returns:

Binary representation of this IDS.

Example:
IdsNs::IDS::pf_active ids;
// populate the IDS
// ...
auto binary_data = ids.serialize();

// move the binary data around, for example to another process using
// memory communication, then deserialize

IdsNs::IDS::pf_active ids2;
ids2.deserialize(binary_data);
int deserialize(std::string &data)

Deserialize the provided binary data into this IDS.

Parameters:
std::string &data

data representing a serialized IDS.

Returns:

Status code: 0 on success, <0 on failure.

Example:

See serialize().

void setPulseCtx(int pulseCtx)

Set the pulse context used for database operations (get(), getSlice(), put(), putSlice()).

Parameters:
int pulseCtx

Pulse context ID obtained through IDS::getPulseCtx().

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {
    // Create the database entry
    IdsNs::IDS ids;
    ids.open("imas:hdf5?path=my-data", FORCE_CREATE_PULSE);

    // Create an empty pf_active IDS
    IdsNs::IDS::pf_active pf_active;
    // Set the mandatory ids_properties.homogeneous_time field
    pf_active.ids_properties.homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS;
    // Continue filling the pf_active IDS here
    // ...

    // Associate the pf_active IDS with our data entry
    pf_active.setPulseCtx(ids.getPulseCtx());
    // And store it
    pf_active.put();

    // Alternatively, store the pf_active IDS as occurrence 1
    pf_active.put(1);

    return 0;
}
int get(int occurrence = 0)

Read the contents of the an IDS into memory.

This method fetches the IDS in its entirety, with all time slices it may contain. See getSlice() for reading a specific time slice.

Empty fields within the IDS in the Data Entry are returned with the default values indicated in Default values.

Parameters:
int occurrence = 0

Which occurrence of the IDS to read.

Returns:

Status code: 0 on success, <0 on failure.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {
    // Create a new IDS object
    IdsNs::IDS ids;
    // Open the database entry by providing an IMAS URI
    ids.open("imas:mdsplus?user=public;pulse=131024;run=41;database=ITER;version=3", OPEN_PULSE);

    // Load the core_profiles IDS, occurrence 0
    ids._core_profiles.get();
    // Load the core_profiles IDS, occurrence 1, beware
    // that this overwrites the contents of occurrence 0!
    ids._core_profiles.get(1);

    return 0;
}
int getSlice(double inTime, char interpolMode)

Same as int Ids::getSlice(int, double, char), but with occurrence = 0.

int getSlice(int occurrence, double inTime, char interpolMode)

Read a single time slice from an IDS in this Database Entry.

This method fetches the IDS object with all constant/static data filled. The dynamic data is interpolated on the requested time slice. This means that the size of the time dimension in the returned data is 1.

Parameters:
int occurrence

Which occurrence of the IDS to read.

double inTime

Requested time slice.

char interpolMode

Interpolation method to use, see Load a single time slice of an IDS.

Returns:

Status code: 0 on success, <0 on failure.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {
    // Open the database entry
    IdsNs::IDS ids;
    ids.open("imas:mdsplus?user=public;pulse=131024;run=41;database=ITER;version=3", OPEN_PULSE);

    // Retrieve the time slice just before t=370 of the core_profiles IDS
    ids._core_profiles.getSlice(370, PREVIOUS_SAMPLE);

    return 0;
}
int getSample(int occurrence, double tmin, double tmax, const std::vector<double> &dtime, int interpolMode)

Read a range of time slices from an IDS in this Database Entry.

This method has three different modes, depending on the provided arguments:

  1. No interpolation. This method is selected when dtime is an empty vector (dtime.size() == 0) and interpolMode is 0.

    This mode returns an IDS object with all constant/static data filled. The dynamic data is retrieved for the provided time range [tmin, tmax].

  2. Interpolate dynamic data on a uniform time base. This method is selected when dtime and interpolMode are provided. dtime must be a std::vector<double> of size 1.

    This mode will generate an IDS with a homogeneous time vector [tmin, tmin + dtime, tmin + 2*dtime, ... up to tmax. The chosen interpolation method will have no effect on the time vector, but may have an impact on the other dynamic values. The returned IDS always has ids_properties.homogeneous_time = 1.

  3. Interpolate dynamic data on an explicit time base. This method is selected when dtime and interpolMode are provided. dtime must be a std::vector<double> of size larger than 1.

    This mode will generate an IDS with a homogeneous time vector equal to dtime. tmin and tmax are ignored in this mode. The chosen interpolation method will have no effect on the time vector, but may have an impact on the other dynamic values. The returned IDS always has ids_properties.homogeneous_time = 1.

Parameters:
int occurrence

Which occurrence of the IDS to read.

double tmin

Lower bound of the requested time range

double tmax

Upper bound of the requested time range, must be larger than or equal to tmin

const std::vector<double> &dtime

Interval to use when interpolating, must be a std::vector<double> containing an explicit time base to interpolate.

int interpolMode

Interpolation method to use. Available options:

  • const:

    CLOSEST_INTERP

  • const:

    PREVIOUS_INTERP

  • const:

    LINEAR_INTERP

Returns:

The loaded IDS.

int getSample(double tmin, double tmax, const std::vector<double> &dtime, int interpolMode)

Same as int Ids::getSample(int, double, double, std::vector<double>, int)(), but with occurrence = 0.

int put(int occurrence = 0)

Write the contents of an IDS to the Database Entry.

The IDS is written entirely, with all time slices it may contain.

The IDS object can have none or many empty fields, empty fields are ignored and remain empty in the data entry. Some fields are required to be filled before calling this method, see Mandatory and recommended IDS attributes.

Caution

The put method deletes any previously existing data within the target IDS occurrence in the Database Entry.

Parameters:
int occurrence = 0

Which occurrence of the IDS to write to.

Returns:

Status code: 0 on success, <0 on failure.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {
    // Create the database entry
    IdsNs::IDS ids;
    ids.open("imas:hdf5?path=my-data", FORCE_CREATE_PULSE);

    // Create an empty pf_active IDS
    IdsNs::IDS::pf_active pf_active;
    // Set the mandatory ids_properties.homogeneous_time field
    pf_active.ids_properties.homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS;
    // Continue filling the pf_active IDS here
    // ...

    // Associate the pf_active IDS with our data entry
    pf_active.setPulseCtx(ids.getPulseCtx());
    // And store it
    pf_active.put();

    // Alternatively, store the pf_active IDS as occurrence 1
    pf_active.put(1);

    return 0;
}
int putSlice(int occurrence = 0)

Append a time slice of the provided IDS to the Database Entry.

Time slices must be appended in strictly increasing time order, since the Access Layer is not reordering time arrays. Doing otherwise will result in non-monotonic time arrays, which will create confusion and make subsequent getSlice() commands to fail.

Although being put progressively time slice by time slice, the final IDS must be compliant with the data dictionary. A typical error when constructing IDS variables time slice by time slice is to change the size of the IDS fields during the time loop, which is not allowed but for the children of an array of structure which has time as its coordinate.

The putSlice() command is appending data, so does not modify previously existing data within the target IDS occurrence in the Data Entry.

It is possible possible to append several time slices to a node of the IDS in one putSlice() call, however the user must ensure that the size of the time dimension of the node remains consistent with the size of its timebase.

Parameters:
int occurrence = 0

Which occurrence of the IDS to write to.

Returns:

Status code: 0 on success, <0 on failure.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {
    // Create the database entry
    IdsNs::IDS ids;
    ids.open("imas:hdf5?path=my-data", FORCE_CREATE_PULSE);

    // Create an empty core_profiles IDS
    IdsNs::IDS::core_profiles core_profiles;
    // Set the mandatory ids_properties.homogeneous_time field
    core_profiles.ids_properties.homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS;
    // Continue filling the core_profiles IDS with static values here
    // ...

    // Associate the core_profiles IDS with our data entry
    core_profiles.setPulseCtx(ids.getPulseCtx());
    // Allocate time array
    core_profiles.time.resize(1);

    // Example time integration loop:
    double t = 0.0;
    double t_stop = 60.0;
    double dt = 0.1;
    while (t < t_stop)
    {
        core_profiles.time = t;
        // Fill your time-dependent data in the core_profiles IDS here
        // ...

        // Append the current time slice to the data stored on disk
        core_profiles.putSlice();
        t += dt;
    }

    return 0;
}
int partialGet(int occurrence, const std::string &includes, const std::string &excludes, bool debug = false)

Read the partial contents of an IDS into memory.

This method fetches partially the IDS according to “includes” and “excludes” queries.

Returned data have paths included in a set of paths defined by the “includes” queries minus the paths explicitly removed by the “excludes” queries. A IDS field is returned only if its path matches at least one include query and does not match any exclude query.

Empty fields within the IDS in the Data Entry are returned with the default values indicated in Default values.

Parameters:
int occurrence

Which occurrence of the IDS to read.

Returns:

Status code: 0 on success, <0 on failure.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>

int main(int argc, char *argv[]) {

    // Create a new data entry
    IdsNs::IDS data_entry;
    
    // Open the database entry by providing an IMAS URI
    data_entry.open("imas:mdsplus?user=public;pulse=131024;run=41;database=ITER;version=3", OPEN_PULSE);

    // Define include and exclude queries
   std::string includes = "ids_properties;profiles_1d(1:5:2)/ion(1:4:2)";
   std::string excludes = "";

   data_entry._core_profiles.partialGet(includes, excludes);

   return 0;
}
int partialGet(const std::string &includes, const std::string &excludes, bool debug = false)

Same as int Ids::partialGet(int, std::string, std::string)(), but with occurrence = 0.

bool isDefined()

Verifies if given IDS is ‘defined’ by checking if its field ids_properties.homogeneous_time is set

Returns:

Boolean value true if ids_properties.homogeneous_time is set, false otherwise

Example:
IdsNs::IDS::core_profiles ids;
bool isDefined = false;


isDefined = ids.isDefined(); // false

ids.ids_properties.homogeneous_time = IDS_TIME_MODE_HETEROGENEOUS;

isDefined = ids.isDefined(); // true
void validate()

Validate the cooordinate consistency of the ids.

The method can throw ValidationException. Nothing is thrown if the coordinates are valids.

Example:
// Include the Access Layer
#include "ALClasses.h"
#include <iostream>


int main(int argc, char *argv[]) {
    { // Enter a new scope
        // Create an empty magnetics IDS
        IdsNs::IDS::magnetics magnetics;
        // Fill the IDS ...

        try
        {
            magnetics.validate();
        }
        catch (IdsNs::ValidationException ve)
        {
            std::cout << ve.what() << std::endl;
        }
    }

    return 0;
}