Example

Here we show an example of a directory tree structure with the terminus data directory, the terminus service directory and the terminus job directory. Let us assume we configured Terminus with those values (see Terminus configuration) :

> terminus data directory : /local/home/user1/terminus_example/data
> terminus job directory : /local/home/user1/terminus_example/jobs
> terminus service directory : /local/home/user1/terminus_example/services
${HOME}/terminus_example
├── data
|   └── GAL_FORMATION
|       └── TEST_GALAXY
|           └── SIMU_1
|               └── output_00003
├── services
|   └── density_map
|       ├── density_map.py
|       └── service.json
└── jobs
    ├── 124_density_map
    |   └── out
    └── 126_density_map
        └── out

Let us assume that we published on Galactica a RAMSES simulation at the following url: https://authenticated.galactica-simulations.eu/db/GAL_FORMATION/TEST_GALAXY/SIMU_1 . The different simulation snapshots, if connected to any Terminus data processing service, must have their raw data located on the Terminus server filesystem within the same directory hierarchy as the Galactica web page url, assuming the configured Terminus data directory as the root of the hierarchy. In our example, the snapshot data directories must be stored in /local/home/user1/terminus_example/data/GAL_FORMATION/TEST_GALAXY/SIMU_1 .

As for the data processing services, there is only one available service called density_map with the associated density_map.py python script. A JSON service.json file must be stored in the service directory.

The density_map.py has been written according to the script template given at the section How to create new post-processing services ?

# -*- coding: utf-8 -*-
import matplotlib
matplotlib.use("Agg")

import sys
from pymses import RamsesOutput
from pymses.analysis.slicing import SliceMap
from pymses.analysis import Camera, ScalarOperator
from pymses.analysis.plot import PlainPNGImage, Plot2D

def run(data_path, data_ref, xcenter=0.5, ycenter=0.5, zcenter=0.5, depth=0.0, los_axis='z', up_vect='y'):
    """
    :param data_path: path to Ramses output directory (string)
    :param data_ref: output directory ref number (int)
    :param xcenter:
    :param ycenter:
    :param zcenter:
    :param depth:
    :param los_axis: line of sight
    :param up_vect: up vector
    :return:
    """

    if not os.path.isdir(data_path):
      raise IOError("Simulation data directory not found")

    # Ramses outuput number
    ioutput = int(data_ref)
    ro = RamsesOutput(data_path, ioutput)

    # AMR data source
    amr = ro.amr_source(["rho"])

    # Defining a Camera object
    center = [xcenter, ycenter, zcenter]
    msize = 2**ro.info["levelmax"] # size defined to max level
    cam  = Camera(center, los_axis, region_size=[1., 1.], up_vector=up_vect, map_max_size=msize)

    # Density field access operator
    rho_op = ScalarOperator(lambda dset: dset["rho"], ro.info["unit_density"])

    # Slice map computation
    slice_map = SliceMap(amr, cam, rho_op, z=depth) # create a density slice map at z=0.5 depth position

    fname = "out/density_out-%d_%s" % (ioutput, los_axis)

    slice_map.save_HDF5(fname)

    color_map = "viridis"

    img_gen = PlainPNGImage(cmap=color_map, discrete=False, force_log_scale=False, alpha_mask=True)
    slice_map.save_PNG(img_gen=img_gen, img_fname=fname+"-PNG.png")

    plot2D_gen = Plot2D( cmap=color_map, discrete=False, force_log_scale=False, axis_unit=None, map_unit=None)
    slice_map.save_plot(plot_gen=plot2D_gen, plot_fname=fname+"-PLOT2D.png", fraction=0.0, verbose=False)

__all__ = ["run"]

We sent by email the signature of the run function to Galactica admin

def run(data_path, data_ref, xcenter=0.5, ycenter=0.5, zcenter=0.5, depth=0.0, los_axis='z', up_vect='y')

as well as the range for the involved parameters: xcenter, ycenter, zcenter, depth varies between [0.0,1.0] and los_axis, up_vect can only takes one of those value {‘x’,’y’,’z’}. The service is now available on the webpage of our simulation.

Once a job request is made, a directory will be created in the terminus job directory with the reference number of the request. As shown, in the directory tree above, we received two jobs requests for the service density_map, directory 124_density_map and 126_density_map. Once the job will be finished, the results of the job request which are in a directory named out/ under the temporary job request directory will be compressed and sent to Galactica. And finally, those temporary job request directories will be removed.