Setting a format file¶
In pNbody, defining a new format correspond to adding new methods in the main class
NbodyDefault
. This means, writing a new class called Nbody_yourformat
where
yourformat
is a string you choos giving the name of your new format. In practice, you need
to create a file called:
$HOME/.pNbody/formats/yourformat.py
The latter file must describe a new class derived from the main class NbodyDefault
.
Lets look at the first lines of the Nbody_default
class, used when no format is specified.
If you have used the:
pNbody_ pNbody_copy-defaultconfig
script, you will naturally find this file here:
$HOME/.pNbody/formats/default.py
The class is described with the following lines:
class Nbody_default(NbodyDefault):
"""
This class is usefull to create an empty Nbody object
"""
The NbodyDefault.get_read_fcts()
and NbodyDefault.get_write_fcts()
methods¶
Then you need to redfined important methods.
Fist, start with the
NbodyDefault.get_read_fcts()
and NbodyDefault.get_write_fcts()
ones.
The role of these methods is to return the methods responsible of the reading/writing of your format.
Several routines can be used. By default, these two methods return an empty list.
Secondly, you need of course to defined these methods.
In the Nbody_default
class this is done with the following lines:
def get_read_fcts(self):
"""
returns the functions needed to read a file.
"""
return [self.read_particles]
def get_write_fcts(self):
"""
returns the functions needed to write a file.
"""
return [self.write_particles]
The methods self.read_particles
and self.write_particles
will be the core
the the io. And you will obviously need to define it.
In Nbody_default
class these methods does simply nothing and are defined as follows:
def read_particles(self,f):
"""
Function that read particles.
"""
pass
def write_particles(self,f):
"""
Function that write particles.
"""
pass
Note that the methods must have as an argument the pointer f
corresponding
to the already opend file. Opening the file is done automatically by pNbody
and you do not need to do it.
A very simple example : an ascii format¶
You can easilly read and write ascii files containing the positions, velocities and mass of particles, defining the following methods:
def read_particles(self,f):
"""
Function that read particles.
"""
from pNbody import io
x,y,z,vx,vy,vz,m=io.read_ascii(f,range(7))
self.pos = transpose(array([x,y,z])).astype(float32)
self.vel = transpose(array([vx,vy,vz])).astype(float32)
self.mass = m.astype(float32)
def write_particles(self,f):
"""
Function that write particles.
"""
for i in range(self.nbody):
line = "%g %g %g %g %g %g %g \n" %(self.pos[i][0],self.pos[i][1],self.pos[i][2],self.vel[i][0],self.vel[i][1],self.vel[i][2],self.mass[i])
f.write(line)
Note that way of doing things works but is not recomanded from a performace point of view. Of course, in this form, the format will not allows parallel io. You will have to work a littre bit more to do it.
Let’s try to use this new format. We assume here that you are in the $HOME/pnbody_examples
directory.
First we convert a gadget
binary file to an ascii file
:
>>> from pNbody import *
>>> nb = Nbody('gadget.dat',ftype='gadget')
>>> nb = nb.set_ftype('ascii')
>>> nb.get_ftype()
>>> nb.get_ftype()
'Nbody_ascii'
>>> nb.get_format_file()
'/home/leo/.pNbody/formats/gadget.py'
The last lines are simply used to check that everything works fine Now simply rename and save the file:
>>> nb.rename('ascii.dat')
>>> nb.write()
Out of the python interpreter, you can check the content of the file:
$ head ascii.dat
-7.77545 6.07969 0.0733488 0 0 0 6.10352e-05
3.92681 11.4814 0.327888 0 0 0 6.10352e-05
-2.93326 -1.03464 0.221822 0 0 0 6.10352e-05
-3.81556 -0.322033 0.0146847 0 0 0 6.10352e-05
-1.3225 -6.34532 0.586419 0 0 0 6.10352e-05
0.0257911 0.576679 0.595826 0 0 0 6.10352e-05
-1.71236 1.22864 -0.61255 0 0 0 6.10352e-05
-2.6153 -0.21298 0.0526232 0 0 0 6.10352e-05
-2.1161 -2.47928 -0.193715 0 0 0 6.10352e-05
-4.33257 15.8307 0.0778809 0 0 0 6.10352e-05
Now, open it and display to check:
>>> from pNbody import *
>>> nb = Nbody('ascii.dat',ftype='ascii')
>>> nb.display(size=(30,30))
And you should see an edge-on disk.
Some info on our ascii object¶
When creating an object, it is possible to check the the file that defines it format, using:
To list the content of the variables of an object:
>>> nb.get_list_of_vars()
['Density', 'DesNumNgb', 'Hsml', 'MaxNumNgbDeviation', 'Tree',
'__doc__', '__module__', '_formatfile', 'byteorder', 'defaultparameters',
'ftype', 'localsystem_of_units', 'log', 'mass_tot', 'nbody', 'nbody_tot',
'npart', 'npart_tot', 'p_name', 'p_name_global', 'parameters', 'pio',
'spec_vars', 'spec_vect', 'status', 'unitsfile', 'unitsparameters']
>>> nb.get_list_of_array()
['mass', 'num', 'pos', 'tpe', 'vel']
>>> nb.get_list_of_method()
['A', 'Accel', 'CombiHisto'
...
'zmodes', 'zprof']
>>> nb.get_default_spec_vars()
{}
>>> nb.get_default_spec_array()
{}
‘Density’, ‘DesNumNgb’, ‘Hsml’, ‘MaxNumNgbDeviation’, ‘Tree’
Other important methods¶
- def get_default_spec_vars(self):
“”” Specific variables to this format “”” return {}
- def get_default_spec_array(self):
“”” return specific array default values for the class “”” return {}
Thanks to the magic of the Python interpreted language, creating a new class derived from the main
class NbodyDefault
presents the excellent advantage of letting the opportunity to the user to
add new methods (not related to the reading of writing of the format), dedicated to its new and private
format, without modifying the pNbody source.
It is possible to list all know formats:
>>> from pNbody import main
>>> main.get_known_formats()
>>> main.get_known_formats()
['Nbody_binary', 'Nbody_bnbf', 'Nbody_default', 'Nbody_gadget', 'Nbody_simpleformat', 'Nbody_tipsy', 'Nbody_tipsybig']
The most simple pNbody object is created with the:
>>> from pNbody import *
>>> nb = Nbody()
To check the format:
>>> nb.ftype
'Nbody_default'
To give the directory where format files are read:
>>> FORMATSDIR
'/home/leo/.pNbody/formats'
To get the format file used:
>>> from pNbody import *
>>> nb = Nbody()
>>> nb.get_format_file()
'/home/leo/.pNbody/formats/default.py'
To list the