Quick-start guide
This quick-start guide will walk you into the main steps to document your numerical project. If you want to skip the tour and directly see an example, see Full example script.
Project and study
Creation and persistency
To create a Project
and save it into a SimulationStudy
HDF5 file, you may run this minimal Python script :
>>> from astrophysix.simdm import SimulationStudy, Project, ProjectCategory
>>> proj = Project(category=ProjectCategory.Cosmology, project_title="Extreme Horizons cosmology project")
>>> study = SimulationStudy(project=proj)
>>> study.save_HDF5("./EH_study.h5")
Loading a study
To read the SimulationStudy
from your HDF5 file, update it and save the updated study back
in its original file :
>>> from astrophysix.simdm import SimulationStudy
>>> study = SimulationStudy.load_HDF5("./EH_study.h5")
>>> proj = study.project
>>> proj.short_description = "This is a short description (one-liner) of my project."
>>> # Saves your updated study back in the same file './EH_study.h5'
>>> study.save_HDF5()
Study information
A SimulationStudy
object contains details on when it has been created
(creation_time
property) and last modified (last_modification_time
property) :
>>> study.creation_time
datetime.datetime(2020, 9, 4, 14, 05, 21, 84601, tzinfo=datetime.timezone.utc)
>>> study.last_modification_time
datetime.datetime(2020, 9, 18, 15, 12, 27, 14512, tzinfo=datetime.timezone.utc)
Full project initialization example
To initialize a Project
, you only need to set category
and
project_title
properties. Here is a more complete example of a
Project
initialization with all optional attributes :
Available project categories are :
>>> proj = Project(category=ProjectCategory.StarFormation, alias="FRIG",
... project_title="Self-regulated magnetised ISM modelisation",
... short_description="Short description of my 'FRIG' project",
... general_description="""This is a pretty long description for my project spanning over multiple lines
... if necessary""",
... data_description="The data available in this project...",
... acknowledgement="""Please cite this project using the following reference : [<a href='https://doi.org/10.1051/0004-6361/201423392' target='_blank'>Hennebelle & Iffrig 2014</a>].""",
... directory_path="/path/to/project/data/", thumbnail_image="~/images/project_highlight.jpg")
Note
- On the Galactica web application, these properties will be displayed as follows :
the
project_title
property will be displayed in the project page top title bar,the
short_description
andthumbnail_image
properties will be displayed in the project thumbnail panel within the project category listing,the
general_description
anddata_description
properties will be used as the Project page body,the
acknowledgement
property will be displayed in theCite me
window in all the project pages,the
directory_path
optional property will not be displayed on the web application but only used to get to the simulation raw data on the Terminus server.
Warning
Setting the alias
property is necessary only if you wish to upload your study on
the Galactica simulation database. See Why an alias ? and How can I check validity for Galactica ?
See also
SimulationStudy
,Project
andProjectCategory
API references.
Simulation codes and runs
To add a simulation run into your project, the definition of a SimulationCode
is mandatory.
Once defined, you can create a Simulation
based on that simulation code:
>>> from astrophysix.simdm.protocol import SimulationCode
>>> from astrophysix.simdm.experiment import Simulation
>>> ramses = SimulationCode(name="Ramses 3.1 (MHD)", code_name="RAMSES")
>>> simu = Simulation(simu_code=ramses, name="Hydro run full resolution")
To add the simulation to the project, use the Project.simulations
property
(ObjectList
):
>>> proj.simulations.add(simu)
>>> proj.simulations
Simulation list :
+---+---------------------------+----------------------------------------+
| # | Index | Item |
+---+---------------------------+----------------------------------------+
| 0 | Hydro run full resolution | 'Hydro run full resolution' simulation |
+---+---------------------------+----------------------------------------+
| 1 | Hydro run full resolution | 'MHD run full resolution' simulation |
+---+---------------------------+----------------------------------------+
See also
Simulation
,SimulationCode
API references,Protocols detailed section.
Experiments detailed section.
ObjectList
API reference.
Post-processing runs
Optionally, you can add PostProcessingRun
into a Simulation
using the Simulation.post_processing_runs
property
(ObjectList
).
To create a PostProcessingRun
, you must first define a
PostProcessingCode
:
>>> from astrophysix.simdm.protocol import PostProcessingCode
>>> from astrophysix.simdm.experiment import PostProcessingCodeRun
>>>
>>> radmc = PostProcessingCode(name="RADMC-3D", code_name="RADMC-3D", code_version="2.0")
>>> pprun = PostProcessingCodeRun(ppcode=radmc, name="Synthetic observable creation of pre-stellar cores")
>>>
>>> # Add post-pro run into the simulation
>>> simu.post_processing_runs.add(pprun)
See also
PostProcessingRun
,PostProcessingCode
API references,Protocols detailed section.
Experiments detailed section.
ObjectList
API reference.
Results and snapshots
Experiment-wide
You can add results into any simulation or post-processing run. If it is an experiment-wide result, create a
GenericResult
and use the Simulation.generic_results
or PostProcessingRun.generic_results
property
(ObjectList
) to add it into your run :
>>> from astrophysix.simdm.results import GenericResult
>>>
>>> res1 = GenericResult(name="Star formation history", directory_path="/my/path/to/result",
... description="""This is the star formation history during the 2
... Myr of the galaxy major merger""")
>>> simu.generic_results.add(res1)
Time-specific
Otherwise, if it is time-specific result, create a Snapshot
and use the
Simulation.snapshots
or
PostProcessingRun.snapshots
property
(ObjectList
) to add it into your run :
>>> from astrophysix.simdm.results import Snapshot
>>> from astrophysix import units as U
>>> sn34 = Snapshot(name="Third pericenter", time=(254.7, U.Myr),
... directory_path="/my/path/to/simu/outputs/output_00034")
>>> simu.snapshots.add(sn34)
See also
GenericResult
,Snapshot
API references,Experiments detailed section.
Results and associated datafiles detailed section.
ObjectList
API reference.
Object catalogs
New in version 0.5.0
You can add object catalogs into any result (GenericResult
or
Snapshot
), using the
catalogs
property :
>>> from astrophysix.simdm.catalogs import TargetObject, ObjectProperty, Catalog, CatalogField,\
... PropertyFilterFlag
>>> from astrophysix.simdm.utils import DataType
>>> from astrophysix import units as U
>>>
>>> cluster = TargetObject(name="Galaxy cluster")
>>> x = tobj.object_properties.add(ObjectProperty(property_name="x", unit=U.Mpc,
... filter_flag=PropertyFilterFlag.BASIC_FILTER))
>>> y = tobj.object_properties.add(ObjectProperty(property_name="y", unit=U.Mpc,
... filter_flag=PropertyFilterFlag.BASIC_FILTER))
>>> z = tobj.object_properties.add(ObjectProperty(property_name="z", unit=U.Mpc,
... filter_flag=PropertyFilterFlag.BASIC_FILTER))
>>> # You may group properties in a property group
>>> pos = ObjectPropertyGroup(group_name="position")
>>> pos.group_properties.add(x)
>>> pos.group_properties.add(y)
>>> pos.group_properties.add(z)
>>>
>>> m = tobj.object_properties.add(ObjectProperty(property_name="M500", unit=U.Msun,
... filter_flag=PropertyFilterFlag.BASIC_FILTER))
>>>
>>> # Define a catalog
>>> cat = Catalog(target_object=tobj, name="Galaxy cluster catalog")
>>> # Add the catalog fields into the catalog (100 clusters)
>>> cat.catalog_fields.add(CatalogField(x, values=N.random.uniform(size=100)))
>>> cat.catalog_fields.add(CatalogField(y, values=N.random.uniform(size=100)))
>>> cat.catalog_fields.add(CatalogField(z, values=N.random.uniform(size=100)))
>>> cat.catalog_fields.add(CatalogField(m, values=N.random.uniform(size=100)))
>>>
>>> # Add the catalog in the snapshot
>>> sn34.catalogs.add(cat)
See also
Catalog
andCatalogField
API references,TargetObject
,ObjectProperty
andObjectPropertyGroup
API references,Target objects and object catalogs detailed section.
ObjectList
API reference.
Datafiles
You can add Datafile
objects into any
Snapshot
or GenericResult
, or
even (new in version 0.5.0) in an object Catalog
:
>>> from astrophysix.simdm.datafiles import Datafile
>>>
>>> # Add a datafile into a snapshot
>>> imf_df = Datafile(name="Initial mass function",
... description="This is my IMF plot detailed description...")
>>> sn34.datafiles.add(imf_df)
And then embed files from your local filesystem into the Datafile
(the file raw byte
array will be imported along with the original file name and last modification date):
>>> from astrophysix.simdm.datafiles import image
>>> from astrophysix.utils.file import FileType
>>>
>>> # Attach files to datafile
>>> imf_df[FileType.PNG_FILE] = os.path.join("/data", "io", "datafiles", "plot_image_IMF.png")
>>> jpg_fpath = os.path.join("/data", "io", "datafiles", "plot_with_legend.jpg")
>>> imf_df[FileType.JPEG_FILE] = image.JpegImageFile.load_file(jpg_fpath)
>>> imf_df[FileType.HDF5_FILE] = os.path.join("/data", "io", "HDF5", "stars.h5")
Anyone can reopen your SimulationStudy
HDF5 file, read the attached files and re-export them
on their local filesystem to retrieve a carbon copy of your original file:
>>> imf_df[FileType.JPEG_FILE].save_to_disk("/home/user/Desktop/export_plot.jpg")
File '/home/user/Desktop/export_plot.jpg' saved
See also
Datafile
API references,Results and associated datafiles detailed section.
Data-processing services
You can define bindings between Snapshot
objects (or even
Catalog
objects) and Galactica online data-processing
services to allow visitors to request the execution of post-processing jobs on your raw astrophysical simulation data :
>>> from astrophysix.simdm.results import Snapshot
>>> from astrophysix import units as U
>>> from astrophysix.simdm.services import DataProcessingService
>>> sn_Z2 = Snapshot(name="Z~2", data_reference="output_00481")
>>> simu.snapshots.add(sn_Z2)
>>>
>>> # Add data processing services to a snapshot
>>> dps = DataProcessingService(service_name="column_density_map",
... data_host="My_Dept_Cluster")
>>> sn.processing_services.add(dsp)
See also
Data-processing server : see Terminus
Data-processing services detailed section.
Full example script
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of the 'astrophysix' Python package.
#
# Copyright © Commissariat a l'Energie Atomique et aux Energies Alternatives (CEA)
#
# FREE SOFTWARE LICENCING
# -----------------------
# This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free
# software. You can use, modify and/or redistribute the software under the terms of the CeCILL license as circulated by
# CEA, CNRS and INRIA at the following URL: "http://www.cecill.info". As a counterpart to the access to the source code
# and rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty
# and the software's author, the holder of the economic rights, and the successive licensors have only limited
# liability. In this respect, the user's attention is drawn to the risks associated with loading, using, modifying
# and/or developing or reproducing the software by the user in light of its specific status of free software, that may
# mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and
# experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the
# software's suitability as regards their requirements in conditions enabling the security of their systems and/or data
# to be ensured and, more generally, to use and operate it in the same conditions as regards security. The fact that
# you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its terms.
#
#
# COMMERCIAL SOFTWARE LICENCING
# -----------------------------
# You can obtain this software from CEA under other licencing terms for commercial purposes. For this you will need to
# negotiate a specific contract with a legal representative of CEA.
#
from __future__ import print_function, unicode_literals
import os
import numpy as N
from astrophysix.simdm import SimulationStudy, Project, ProjectCategory
from astrophysix.simdm.catalogs import TargetObject, ObjectProperty, PropertySortFlag, PropertyFilterFlag, \
ObjectPropertyGroup, Catalog, CatalogField
from astrophysix.simdm.experiment import Simulation, AppliedAlgorithm, ParameterSetting, ParameterVisibility,\
ResolvedPhysicalProcess
from astrophysix.simdm.protocol import SimulationCode, AlgoType, Algorithm, InputParameter, PhysicalProcess, Physics
from astrophysix.simdm.results import GenericResult, Snapshot
from astrophysix.simdm.datafiles import Datafile, PlotType, PlotInfo, AsciiFile
from astrophysix.simdm.services import DataProcessingService, CatalogDataProcessingService, CatalogFieldBinding
from astrophysix.simdm.utils import DataType
from astrophysix.utils.file import FileType
from astrophysix import units as U
# ----------------------------------------------- Project creation --------------------------------------------------- #
# Available project categories are :
# - ProjectCategory.SolarPhysics
# - ProjectCategory.PlanetaryAtmospheres
# - ProjectCategory.StellarEnvironments
# - ProjectCategory.StarPlanetInteractions
# - ProjectCategory.InterstellarMedium
# - ProjectCategory.StarFormation
# - ProjectCategory.StellarPhysics
# - ProjectCategory.HighEnergyAstrophysics
# - ProjectCategory.MagnetoHydrodynamics
# - ProjectCategory.Supernovae
# - ProjectCategory.GalacticDynamics
# - ProjectCategory.Cosmology
proj = Project(category=ProjectCategory.StarFormation, project_title="Frig",
alias="FRIG", short_description="Short description of my 'FRIG' project",
general_description="""This is a pretty long description for my project""",
data_description="The data available in this project...", directory_path="/path/to/project/data/",
acknowledgement="""<p>Please cite this project using the following reference : </p>
<div><pre>
@ARTICLE{2014A&A...570A..81H,
author = {{Hennebelle}, Patrick and {Iffrig}, Olivier},
title = "{Simulations of magnetized multiphase galactic disc regulated by supernovae explosions}",
journal = {\aap},
keywords = {magnetohydrodynamics (MHD), instabilities, ISM: kinematics and dynamics, ISM: structure, ISM: clouds, stars: formation, Astrophysics - Astrophysics of Galaxies},
year = 2014,
month = oct,
volume = {570},
eid = {A81},
pages = {A81},
doi = {10.1051/0004-6361/201423392},
archivePrefix = {arXiv},
eprint = {1405.7819},
primaryClass = {astro-ph.GA},
adsurl = {https://ui.adsabs.harvard.edu/abs/2014A&A...570A..81H},
adsnote = {Provided by the SAO/NASA Astrophysics Data System}}
</pre></div>""",
thumbnail_image="~/images/proj_235/highlight_thumbnail.jpg")
print(proj) # "[Star formation] 'Frig' project"
# -------------------------------------------------------------------------------------------------------------------- #
# --------------------------------------- Simulation code definition ------------------------------------------------- #
ramses = SimulationCode(name="Ramses 3 (MHD)", code_name="Ramses", code_version="3.10.1", alias="RAMSES_3",
url="https://www.ics.uzh.ch/~teyssier/ramses/RAMSES.html",
description="This is a fair description of the Ramses code")
# => Add algorithms : available algorithm types are :
# - AlgoType.StructuredGrid
# - AlgoType.AdaptiveMeshRefinement
# - AlgoType.VoronoiMovingMesh
# - AlgoType.SpectralMethod
# - AlgoType.SmoothParticleHydrodynamics
# - AlgoType.Godunov
# - AlgoType.PoissonMultigrid
# - AlgoType.PoissonConjugateGradient
# - AlgoType.ParticleMesh
# - AlgoType.NBody
# - AlgoType.FriendOfFriend
# - AlgoType.HLLCRiemann
# - AlgoType.RayTracer
# - AlgoType.RadiativeTransfer
# - AlgoType.RungeKutta
amr = ramses.algorithms.add(Algorithm(algo_type=AlgoType.AdaptiveMeshRefinement, description="AMR descr"))
ramses.algorithms.add(Algorithm(algo_type=AlgoType.Godunov, description="Godunov scheme"))
ramses.algorithms.add(Algorithm(algo_type=AlgoType.HLLCRiemann, description="HLLC Riemann solver"))
ramses.algorithms.add(Algorithm(algo_type=AlgoType.PoissonMultigrid, description="Multigrid Poisson solver"))
ramses.algorithms.add(Algorithm(algo_type=AlgoType.ParticleMesh, description="PM solver"))
# => Add input parameters
ramses.input_parameters.add(InputParameter(key="levelmin", name="Lmin",
description="min. level of AMR refinement"))
lmax = ramses.input_parameters.add(InputParameter(key="levelmax", name="Lmax",
description="max. level of AMR refinement"))
# => Add physical processes : available physics are :
# - Physics.SelfGravity
# - Physics.ExternalGravity
# - Physics.Hydrodynamics
# - Physics.MHD
# - Physics.StarFormation
# - Physics.SupernovaeFeedback
# - Physics.AGNFeedback
# - Physics.SupermassiveBlackHoleFeedback
# - Physics.StellarIonisingRadiation
# - Physics.StellarUltravioletRadiation
# - Physics.StellarInfraredRadiation
# - Physics.ProtostellarJetFeedback
# - Physics.Chemistry
# - Physics.AtomicCooling
# - Physics.DustCooling
# - Physics.MolecularCooling
# - Physics.TurbulentForcing
# - Physics.RadiativeTransfer
ramses.physical_processes.add(PhysicalProcess(physics=Physics.StarFormation, description="descr sf"))
ramses.physical_processes.add(PhysicalProcess(physics=Physics.Hydrodynamics, description="descr hydro"))
grav = ramses.physical_processes.add(PhysicalProcess(physics=Physics.SelfGravity, description="descr self G"))
ramses.physical_processes.add(PhysicalProcess(physics=Physics.SupernovaeFeedback, description="SN feedback"))
# -------------------------------------------------------------------------------------------------------------------- #
# -------------------------------------------- Simulation setup ------------------------------------------------------ #
simu = Simulation(simu_code=ramses, name="My most important simulation", alias="SIMU_1", description="Simu description",
execution_time="2020-03-01 18:45:30", directory_path="/path/to/my/project/simulation/data/",
config_file=AsciiFile.load_file(os.path.join("/run", "cfg", "SIMU_1", "blast_3D.ini")))
proj.simulations.add(simu)
# Add applied algorithms implementation details. Warning : corresponding algorithms must have been added in the 'ramses'
# simulation code.
simu.applied_algorithms.add(AppliedAlgorithm(algorithm=amr, details="My AMR implementation [Teyssier 2002]"))
simu.applied_algorithms.add(AppliedAlgorithm(algorithm=ramses.algorithms[AlgoType.HLLCRiemann.name],
details="My Riemann solver implementation [Teyssier 2002]"))
# Add parameter setting. Warning : corresponding input parameter must have been added in the 'ramses' simulation code.
# Available parameter visibility options are :
# - ParameterVisibility.NOT_DISPLAYED
# - ParameterVisibility.ADVANCED_DISPLAY
# - ParameterVisibility.BASIC_DISPLAY
simu.parameter_settings.add(ParameterSetting(input_param=ramses.input_parameters["Lmin"], value=8,
visibility=ParameterVisibility.BASIC_DISPLAY))
simu.parameter_settings.add(ParameterSetting(input_param=lmax, value=12,
visibility=ParameterVisibility.BASIC_DISPLAY))
# Add resolved physical process implementation details. Warning : corresponding physical process must have been added to
# the 'ramses' simulation code
simu.resolved_physics.add(ResolvedPhysicalProcess(physics=ramses.physical_processes[Physics.StarFormation.name],
details="Star formation specific implementation"))
simu.resolved_physics.add(ResolvedPhysicalProcess(physics=grav, details="self-gravity specific implementation"))
# -------------------------------------------------------------------------------------------------------------------- #
# -------------------------------------- Simulation generic result and snapshots ------------------------------------- #
# Generic result
gres = GenericResult(name="Key result 1 !", description="My description", directory_path="/my/path/to/result")
simu.generic_results.add(gres)
# Simulation snapshot
# In one-line
sn = simu.snapshots.add(Snapshot(name="My best snapshot !", description="My first snapshot description",
time=(125, U.kyr), physical_size=(250.0, U.kpc), directory_path="/path/to/snapshot1",
data_reference="output_00056"))
# Or create snapshot, then add it to the simulation
sn2 = Snapshot(name="My second best snapshot !", description="My second snapshot description", time=(0.26, U.Myr),
physical_size=(0.25, U.Mpc), directory_path="/path/to/snapshot2", data_reference="output_00158")
simu.snapshots.add(sn2)
# -------------------------------------------------------------------------------------------------------------------- #
# ---------------------------------------------------- Result datafiles ---------------------------------------------- #
# Datafile creation
imf_df = sn.datafiles.add(Datafile(name="Initial mass function plot",
description="This is my plot detailed description"))
# Add attached files to a datafile (1 per file type). Available file types are :
# - FileType.HDF5_FILE
# - FileType.PNG_FILE
# - FileType.JPEG_FILE
# - FileType.FITS_FILE
# - FileType.TARGZ_FILE
# - FileType.PICKLE_FILE
# - FileType.JSON_FILE
# - FileType.CSV_FILE
# - FileType.ASCII_FILE
imf_df[FileType.PNG_FILE] = os.path.join("/data", "io", "datafiles", "plot_image_IMF.png")
imf_df[FileType.JPEG_FILE] = os.path.join("/data", "io", "datafiles", "plot_with_legend.jpg")
imf_df[FileType.FITS_FILE] = os.path.join("/data", "io", "datafiles", "cassiopea_A_0.5-1.5keV.fits")
imf_df[FileType.TARGZ_FILE] = os.path.join("/data", "io", "datafiles", "archive.tar.gz")
imf_df[FileType.JSON_FILE] = os.path.join("/data", "io", "datafiles", "test_header_249.json")
imf_df[FileType.ASCII_FILE] = os.path.join("/data", "io", "datafiles", "abstract.txt")
imf_df[FileType.HDF5_FILE] = os.path.join("/data", "io", "HDF5", "study.h5")
imf_df[FileType.PICKLE_FILE] = os.path.join("/data", "io", "datafiles", "dict_saved.pkl")
# Datafile plot information (for plot future updates and online interactive visualisation on Galactica web pages).
# Available plot types are :
# - LINE_PLOT
# - SCATTER_PLOT
# - HISTOGRAM
# - HISTOGRAM_2D
# - IMAGE
# - MAP_2D
imf_df.plot_info = PlotInfo(plot_type=PlotType.LINE_PLOT, xaxis_values=N.array([10.0, 20.0, 30.0, 40.0, 50.0]),
yaxis_values=N.array([1.256, 2.456, 3.921, 4.327, 5.159]), xaxis_log_scale=False,
yaxis_log_scale=False, xaxis_label="Mass", yaxis_label="Probability", xaxis_unit=U.Msun,
plot_title="Initial mass function", yaxis_unit=U.Mpc)
# -------------------------------------------------------------------------------------------------------------------- #
# ----------------------------------------------------- Result products ---------------------------------------------- #
# Target object properties have filter/sort flags to display them in various configurations on Galactica. Available
# flag values are :
# - PropertyFilterFlag.NO_FILTER
# - PropertyFilterFlag.BASIC_FILTER
# - PropertyFilterFlag.ADVANCED_FILTER
# - PropertySortFlag.NO_SORT
# - PropertySortFlag.BASIC_SORT
# - PropertySortFlag.ADVANCED_SORT
tobj = TargetObject(name="Spiral galaxy", description="Disk-like galaxy with spiral arms and sometimes bars")
id_gal = tobj.object_properties.add(ObjectProperty(property_name="gal_id", sort_flag=PropertySortFlag.ADVANCED_SORT,
filter_flag=PropertyFilterFlag.NO_FILTER, dtype=DataType.INTEGER,
description="Galaxy global index"))
x = tobj.object_properties.add(ObjectProperty(property_name="pos_x", sort_flag=PropertySortFlag.ADVANCED_SORT,
unit=U.kpc, filter_flag=PropertyFilterFlag.BASIC_FILTER,
# dtype=DataType.REAL,
description="Galaxy position coordinate along x-axis"))
y = tobj.object_properties.add(ObjectProperty(property_name="pos_y", sort_flag=PropertySortFlag.ADVANCED_SORT,
unit=U.kpc, filter_flag=PropertyFilterFlag.BASIC_FILTER,
# dtype=DataType.REAL,
description="Galaxy position coordinate along y-axis"))
z = tobj.object_properties.add(ObjectProperty(property_name="pos_z", sort_flag=PropertySortFlag.ADVANCED_SORT,
unit=U.kpc, filter_flag=PropertyFilterFlag.BASIC_FILTER,
# dtype=DataType.REAL,
description="Galaxy position coordinate along z-axis"))
# Property group (optional)
pos = tobj.property_groups.add(ObjectPropertyGroup(group_name="pos", description="galaxy position"))
pos.group_properties.add(x)
pos.group_properties.add(y)
pos.group_properties.add(z)
# Target object catalog + field value arrays
cat = sn.catalogs.add(Catalog(target_object=tobj, name="Spiral galaxy filtered catalog",
description="Full description of my catalog containing 200 spiral galaxies."))
fidgal = cat.catalog_fields.add(CatalogField(obj_prop=id_gal, values=N.arange(1, 200)))
fx = cat.catalog_fields.add(CatalogField(obj_prop=x, values=N.random.uniform(size=200)))
fy = cat.catalog_fields.add(CatalogField(obj_prop=y, values=N.random.uniform(size=200)))
fz = cat.catalog_fields.add(CatalogField(obj_prop=z, values=N.random.uniform(size=200)))
# Add datafiles to the catalog if required.
cdf1 = cat.datafiles.add(Datafile(name="My datafile", description="---"))
cdf1[FileType.PNG_FILE] = os.path.join("/data", "io", "datafiles", "plot_image_IMF.png")
cdf2 = cat.datafiles.add(Datafile(name="My datafile (2)", description="---"))
cdf2[FileType.JPEG_FILE] = os.path.join("/data", "io", "datafiles", "plot_with_legend.jpg")
# -------------------------------------------------------------------------------------------------------------------- #
# ---------------------------------------------- Data processing services bindings ----------------------------------- #
# Add data processing services to a snapshot
dps1 = sn.processing_services.add((DataProcessingService(service_name="column_density_map",
data_host="MyDeptCluster")))
dps2 = sn2.processing_services.add((DataProcessingService(service_name="ppv_cube", data_host="Lab_GPU_cluster")))
# Add data processing services to a target object catalog
dps3 = CatalogDataProcessingService(service_name="slice_map", data_host="Lab_Cluster")
cat.processing_services.add(dps3)
# Define catalog field bindings to automatically fill the data processing service parameter value 'pv' with a catalog
# field value 'fv' of one of your catalog's object according to the formula : pv = scale * fv + offset. Default scale
# value is 1.0 and default offset is 0.0.
fbx = dps1.catalog_field_bindings.add(CatalogFieldBinding(catalog_field=fx, param_key="x",
scale=1.0e2, offset=-50.0))
fby = dps1.catalog_field_bindings.add(CatalogFieldBinding(catalog_field=fy, param_key="y",
scale=1.0e2, offset=-50.0))
fbz = dps1.catalog_field_bindings.add(CatalogFieldBinding(catalog_field=fz, param_key="z",
scale=1.0e2, offset=-50.0))
# -------------------------------------------------------------------------------------------------------------------- #
# Save study in HDF5 file
study = SimulationStudy(project=proj)
study.save_HDF5("./frig_study.h5", galactica_checks=True)
# Eventually reload it from HDF5 file to edit its content
# study = SimulationStudy.load_HDF5("./frig_study.h5")