UNS(05 Dec 2011)

NAME
UNSIOF -- Unified Nbody Snapshot Library (fortran version).

DESCRIPTION
UNSIOF is a high level C++ library which allows
 Input operations in a generic way on Nbody snapshot files, from a FORTRAN program. Currently, NEMO, Gadget 1 and 2 little and bigendian, and list of separated snapshots in a text file are supported. The use of this set of functions is very simple and doesn't require any knowledge of the internal file structure of the snapshot.
 The library can manage multiple reading of different snapshots in the same program. Every snapshots is identified by a unique identifier provided by the library.

 The process to read data is done in 3 steps:
 1) Initialisation of the library
 2) Data loading
 3) Data extracting

INITIALISATION

integer uns_init(filename, selected_component, selected_time)
     It returns an integer as a unique identifier. A returned value less than 0 means that the simulation does not exist or a file format unknown. filename: (character * (*))
     Is the input simulation filename. It can be an absolute filename path or just a simulation name (eg "gas001"). In the later case, all the parameters of the simulation, if it exists, will be automatically collected from the simulation database filename stored in the usual place (/pil/programs/DB/simulation.dbl). selected_component: (character * (*))
     select components or range of particles that you want to load. The following data can be requested:disk,gas,halo,bulge,stars,bndry,all. A range with the value "0:299999" select the particles between 0 and 299999. For NEMO simulation, range and components of the selected simulation will be taken from the file /pil/programs/DB/simulation.dbl.
     You can request several data separated with a "," like this: "disk,gas". The order of your selection will be respected when you will get the data. selected_time: (character * (*))
     select a range of time from where you want to select the particles. You can request several range of times separated with a ",".
     Example: "700:750,800:900" will only proceed on particles in the time range [700:750] and [800:900]. integer uns_sim_type(ident)
     This function return an integer matching to the type of the snaphot identified by the integer ident.
     It returns "0" for nemo snapshot, "1" for gadget snapshot.

DATA LOADING

integer uns_load(ident)
     This function load the next time step of the snaphot identified by the integer ident.
     It returns "1" if the snapshot has been successfully loaded or "0" at the end of the snapshot.

integer uns_load_opt(ident,selected_values)
     This is an optimized version of the uns_load() function.
     This function load the next time step of the snaphot identified by the integer ident.
     It returns "1" if the snapshot has been successfully loaded or "0" at the end of the snapshot. selected_values: (character * (*))
     The extra variable selected_values allows to restrict the loading of
     selected values only. It can speedup the file
     loading and reduce the memory footprint. Each value is specified by a
     character. Here is all the possibilities :
      'm' mass
      'x' position
      'v' velolcity
      'p' potential
      'a' acceleration
      'e' softening
      'k' keys array (from nemo)
      'X' aux array (from nemo)
      'R' density
      'I' particles's Id
      'U' Internal energy
      'M' metallicity
      'A' stars's age
      'H' hsml
      'T' temperature
     example: "mxR" will load mass, position and density only.

DATA EXTRACTING (uns_get_value/ uns_get_array)
In the following text, we assume that character variable component can take the following values:
 "all","gas","disk","halo","stars","bulge","bndry" Each functions return 1 if success or 0 if it fails.
 There is a set of uns_get_value functions to get data value (float or integer) from the snapshot. Each functions take as first parameter an integer ident, returned by the function uns_init(...). function integer uns_get_value_i(ident,tag,data) Put in the integer variable data, the requested tag value. Tag is a string variable. tag="nsel" => set data with number of particles selected function integer uns_get_value_f(ident,tag,data) Put in the real*4 variable data, the requested tag value. Tag is a string variable. tag="time" => set data with snapshot time
tag="redshift"  => set data with snapshot redshift
function integer uns_get_array_i(ident,component,tag,data,n)
Put in the integer array variable data(n), the requested  combination of tag value and component. Tag and component are string  variables.
tag="id"        => set data array with component ids
tag="nbody"     => set n value with component nbody
function integer uns_get_array_f(ident,component,tag,data,n)
 Put in the real*4 array variable data(n), the requested combination of tag value and component. Tag and component are string  variables.
tag="pos"        => set data array with component position
tag="vel"        => set data array with component velocity
tag="mass"       => set data array with component mass
tag="acc"        => set data array with component acceleration
tag="pot"        => set data array with component potential
tag="rho "       => set data array with component density
tag="u"          => set data array with component internal energy
tag="hsml"       => set data array with component hydro smooth length
tag="age"        => set data array with component age
tag="metal"      => set data array with component metalicity
tag="temp"       => set data array with component temperature

DATA EXTRACTING (uns_get_XXXX)
 There is a set of uns_get_XXXX functions to get data from the snapshot. Each functions take as the first parameter an integer ident returned by the function uns_init(...). subroutine uns_get_nbody(ident,nbody)
 Put in the integer variable nbody the #bodies resquested according to the selected_component variable (Cf uns_init(...) function). subroutine uns_get_time(ident,time)
 Put in the floating variable time the current time of the simulation. subroutine uns_get_pos(ident,pos,size_array)
 Put in the two dimensional floating array pos(3,size_array), all the positions requested. subroutine uns_get_vel(ident,vel,size_array)
 Put in the two dimensional floating array vel(3,size_array), all the velocities requested. subroutine uns_get_mass(ident,mass,size_array)
 Put in the one dimensional floating array mass(size_array), all the masses requested. function integer uns_get_age(ident,age,size_array)
 Put in the one dimensional floating array age(size_array), all the particles with an age (stars). It returns the number of stars particles or 0. function integer uns_get_metal(ident,metal,size_array)
 Put in the one dimensional floating array metal(size_array), all the particles with metalicity (gas+stars) in the respective order gas then stars. It returns the number of gas+stars particles or 0. function integer uns_get_metal_gas(ident,metal,size_array)
 Put in the one dimensional floating array metal(size_array), metalicity of the gas particles. It returns the number of gas particles or 0. function integer uns_get_metal_stars(ident,metal,size_array)
 Put in the one dimensional floating array metal(size_array), metalicity of the stars particles. It returns the number of stars particles or 0. function integer uns_get_u(ident,u,size_array)
 Put in the one dimensional floating array u(size_array), internal energy of the gas particles. It returns the number of gas particles or 0. function integer uns_get_temp(ident,temp,size_array)
 Put in the one dimensional floating array temp(size_array), temperature of the gas particles. It returns the number of gas particles or 0. function integer uns_get_rho(ident,rho,size_array)
 Put in the one dimensional floating array rho(size_array), density of the gas particles. It returns the number of gas particles or 0. integer uns_get_range(ident,component,nbody,first,last)
 This function give the particles's range for a selected component. You give in a string variable component, the name of the component, and the function return an integer variable nbody (#bodies), first and last, the first and the last index of the component in the array. First and last values are given in fortran array convention (starts from index 1).
 It returns "1" if the component exist, and "0" otherwise.
 Example to get halo's particles range:
 status = uns_get_range(ident,"halo",n,first,last) integer uns_get_eps(ident,component,eps)
 This function give the softening for a selected component. You give in a string variable component, the name of the component, and the function return a float variable eps.
 It returns "1" if the softening exist for the component, and "0" otherwise.
 This function will only work if the simulation requested belong to the database file /pil/programs/DB/simulation.dbl.
 Example to get halo's softening:
 status = uns_get_eps(ident,"halo",eps) integer uns_get_cod(ident,component,time,tcod[7])
 This function give the COD for a selected component (or a set of
 components separeted with ","), at the selected time. You give in a string variable component, the name of the component, and the function return a float array tcod[7] filled with respectively
 the time, x,y,z,vx,vy,vz of the COD.
 It returns "1" if the cod exist for the requested component
 and time. It returns "0" if the cod does not exits for the
 requested time. It returns "-1" if the COD file does not exist.
 This function will only work if the simulation requested belong to the database file /pil/programs/DB/simulation.dbl.
 Example to get "disk,stars"'s cod at time=0.1:
 status = uns_get_cod(ident,"disk,stars",0.1,tcod)

EXAMPLE
      ! -----------------------------------------------------------
      program testlib
      implicit none
      integer iargc, lnblnk, narg, uns_init, uns_load, valid, ident,
     $     nbody
      character arg1 * 80, arg2 * 80, arg3 * 80
      narg = command_argument_count()
      if (narg.ne.3) then
         write(0,*) "You must give 3 parameters:"
         write(0,*) "filename selected_component selected_time"
         stop
      endif
      call get_command_argument(1,arg1) ! get filename
      call get_command_argument(2,arg2) ! get selected component
      call get_command_argument(3,arg3) ! get selected time
      ! initialyze UNS engine
      ident=uns_init(arg1, arg2, arg3) ! return identifier for the snaphot
                                       ! ident must be positive
      if (ident.gt.0) then
         valid = 1
         do while (valid .gt. 0) ! loop on all the time step
            valid = uns_load(ident) ! load data belonging to ident snapshot
            if (valid .gt. 0) then  ! it goes fine
               call uns_get_nbody(ident, nbody) ! get #bodies
               call start(ident,nbody)
            endif
         enddo
      endif
      end
      ! -----------------------------------------------------------
      subroutine start(ident,nbody)
      implicit none
! input parameters
      integer ident,nbody
! UNS variable
      integer status
      integer  uns_get_range
      real *4 time, pos(3,nbody), vel(3,nbody), mass(3,nbody)
! various
      integer io_nemo_f
      character * 90 out
      integer n,first,last
      call uns_get_time(ident,time      )  ! read time
      call uns_get_pos (ident,pos ,nbody)  ! read pos
      call uns_get_vel (ident,vel ,nbody)  ! read vel
      call uns_get_mass(ident,mass,nbody)  ! read mass
      status = uns_get_range(ident,"gas",n,first,last) ! gas's range
      out = "nemo.out"
      write(0,*) "nbody=",nbody," time=",time
      status = io_nemo_f(out,80,nbody,"float,save,3n,n,t,x,v,m",
     $     nbody,time,pos,vel,mass)
      end
      ! -----------------------------------------------------------

COMPILATION
 A fortran program which use the UNS library must link against NEMO library (-lnemo) and C++ library (-lstdc++). Here is an example of Makefile using gfortran compiler.
# ----------------------------------------
# MAKEFILE to use UNS
# ----------------------------------------
# find libg2c.a library
LIB_G77 := $(shell g77 -print-libgcc-file-name  2> /dev/null)
LIB_G77 := $(shell dirname $(LIB_G77)           2> /dev/null)
# path for NEMO Library, UNS library and G2C
UNS_LIB_PATH :=  $(LOCAL)/lib
LIBS         := -L$(NEMOLIB) -L$(UNS_LIB_PATH) -L$(LIB_G77)
# - - - - - - - - - - - - - - - - - - - -
# compilation with gfortran compiler
# - - - - - - - - - - - - - - - - - - - -
GFORTFLAGS = -Wall -O2 -ggdb -Wl,-rpath,$(UNS_LIB_PATH)
testlibF : testlib.F
	gfortran $(GFORTFLAGS)  -o $@ testlib.F $(LIBS) \
                  -lnemomaing77 -lunsio -lnemo -lg2c -lstdc++ -lm
# ----------------------------------------

SEE ALSO
nemo(1NEMO), snapshot(5NEMO), gadget2nemo, uns_tonemo, uns_density, uns_2dplot

AUTHOR
Jean-Charles LAMBERT

BUGS and COMMENT
Please, report all bugs and comment to :
Jean-Charles.Lambert@oamp.fr

UPDATE HISTORY
11-Dec-08	created                        JCL
09-Jun-11	a lot of improvement           JCL