This is an old revision of the document!
I believe that the project has become mature enough to be used by a larger community.
The current version is 1.1 (patch against Asymptote SVN revision 5548). Here is the patch history.
(These are my personal opinions, others may perceive it differently)
myObject->SetLineColor(2);
In Asymptote one just adds
, red
to the draw command.
TCanvas
, one has to go through the list of primitives, find the first convenient object and use GetXaxis()→SetName(“…”)
. This is simply unacceptable for such a primitive and usual operation.“”
flag for the first one, while “same”
for the others. However, when working with graphs, the flag for the first one reads “A”
and is empty for the others. Why should a user bother about all those things?
An example: A plot (the light blue area) with 6 pads (drawn in light yellow) aligned in a grid. The green dots show alignment control points.
I tried to make the ROOT–Asymptote interface as flexible as possible. However, there are some limitations - read the documentation for more information.
Currently, ROOT methods are called from Asymptote via CINT API, namely G_CallFunc::Execute
. It works basically in these steps
?Exec
functions (see documentation) have open signature
, i.e. they can take whatever parameters. Consequently, the Asymptote parser/compiler would never report an error.G_value
is converted into an Asymptote variable, according to which one of the ?Exec
functions was called.See the Doxygen documentation.
A generic ROOT object (any descendant of TObject
) is represented in Asymptote as a rObject
object:
rObject obj;
One can check the validity (i.e. non-emptiness) of a rObject
, test its inheritance path and print the related information:
bool valid = obj.valid; bool inherits = obj.InheritsFrom("some ROOT class name"); obj.Print(); write(obj); write("object properties: ", obj);
A rObject
can be loaded from a ROOT file by
rObject rGetObj(string file, string object_name, bool error=true, bool search=true)
The interface is capable of calling an arbitrary method of a ROOT object. It is implemented via the set of functions:
void rObject.vExec(string method_name, ...); bool rObject.bExec(string method_name, ...); int rObject.iExec(string method_name, ...); real rObject.rExec(string method_name, ...); string rObject.sExec(string method_name, ...); rObject rObject.oExec(string method_name, ...);
All the functions take the method name as the first parameter. Parameters of the method are to follow (they're abbreviated by …). The recognized types are bool, int, real
and string
. All parameters are passed by value. If you want to pass a parameter by reference, create an array with just one element and pass the array, e.g.
real[] x = {2.}; real[] y = {2.}; obj.vExec("GetPoint", 1, x, y);
Currently, only int
and real
parameters can be passed by reference.
Here is a set of commented examples the covers and explains the complete functionality.
The asymptote macros/routines are split into 2 files:
base/root.asy
: contains routines to draw ROOT objectsbase/pad_layout.asy
: pad layout management tools (see the suggested plot structure).
To draw an rObject
, use
void draw(picture pic=currentpicture, rObject obj, string options="", pen pen=currentpen, marker marker=nomarker, Label legend="")
Here is a set of commented examples that demonstrates the available options.
Following the suggested plot structure, all graphics is organized in pads
. To create a new pad (with axes labels), you may use
pad NewPad(bool drawAxes = true, bool axesAbove = false, string xLabel = "", string yLabel = "", ticks xTicks = xTicksDef, ticks yTicks = yTicksDef, bool autoSize = true, explicit real xSize = xSizeDef, explicit real ySize = ySizeDef, explicit int xGridHint, int yGridHint)
The GridHint
parameters can be used to place a pad in given position with a grid. If not specified, the pads placed in a horizontal line (from left to right). Use NewRow()
to start a new row. NewPage()
starts a new page.
The pads are laid out during the shipout procedure (when the output files are created). The default Asymptote's shipout
command outputs just the current picture. That is why this module brings another shipout routine (and makes it default):
void GShipout(string prefix=defaultfilename, pair alignment=(0, 0), real hSkip=1cm, real vSkip=1cm, real margin=1mm, pen p = nullpen, filltype filltype = Fill(white))
All parameters are facultative, so you can just type GShipout()
. And even that is not needed since Asymptote would append it automatically if there is some material to be shiped out. The alignment
parameter gives the point that is used to align pads in rows and columns. For example, if NE
is used, the top left left-hand side corner of your pads would be used for alignment. The Skip
parameters give spacing between rows and columns. All the output is placed into a frame that is by margin
larger that the grid of pads, that is draw by pen p
and filled by filltype
.
Here are some commented examples that may serve as a tutorial.
There is a comprehensive set of commented examples that would guide you through the available features. These examples can be found
examples/kaspi
that is shipped with the .diff
file (see the download section)My PhD thesis can serve as an example too (all figures have been made with Asymptote).
A couple of examples of embedding ROOT data into more complex graphics:
The current version is 1.1 (patch against Asymptote SVN revision 5548).
patch -p0 -i asymptote_root_extension_xx_yy.diff
autoconf; autoheader # if needed ./configure # if you have $ROOTSYS properly set, it will automatically enable the ROOT extension make