Getting started with GlastDetSvc
Leon Rochester

I recently converted TkrGeometrySvc to use GlastDetSvc.  Although everything is more-or-less documented, it required a bit of trial-and-error to get things to work.  I'll summarize what I learned, in the hope that it will make things easier for those who follow.


You start, as usual, by including the header file:

#include "GlastSvc/GlastDetSvc/IGlastDetSvc.h"

and a member to point to the service:

IGlastDetSvc * p_detSvc;

and storing the pointer in the initialization of your service or algorithm:

StatusCode sc = service("GlastDetSvc",p_detSvc);

Named constants

The list of named constants can be found here. A simple call retrieves the constant.

double myConstant;
sc = p_detSvc->getNumericConstantByName("NameOfConstant", &myConstant);

Note that the method takes a pointer to the target constant. The return code tells you whether or not the name exists.

Volume identifiers

To manipulate volume identifiers, include the header file:

#include "idents/VolumeIdentifier.h"

A volume identifier is a sequence of integers that uniquely identifies a volume in the detector.  It's encoded as up to 10 6-bit fields in a 64-bit word, but you don't really need to know this.

The meaning of the fields for the different sub-systems can be found here.

Here's how you make up the volId for a tracker silicon layer. I'll do it in two pieces to show how that works. First the tracker in a tower:

idents::VolumeIdentifier vId_tower;  // create a null VolumeIdentifier

// append stacks the field in order from highest to lowest in the hierarchy; 
// prepend goes the other way.

tower = 10;

...
vId_tower.init(0,0);             // clear the volId if it had something in it.

vId_tower.append(0);           // here we append an integer; 0 means a tower, 1 is ACD
idents::TowerId t(tower); 
vId_tower.append(t.iy());     // tower y index 
vId_tower.append(t.ix());     // tower x index 
vId_tower.append(1);          // 1 means TKR; 0 means CAL

Now the tray part. Note that this piece is not a valid volume identifier as it stands:

tray = 13;
view = 0;
botTop = 1;

idents::VolumeIdentifier vId_tray;
vId_tray.append(tray);       // tray number
vId_tray.append(view);       // view number
vId_tray.append(botTop);     // top or bottom of tray

There's something a bit awkward here: In order to form this piece of the volume id, you need to know both the view (x/y) and the position (top/bottom) of the silicon plane. So you have to utilize secret knowledge that is not readily available in the geometry file. (Or you learn how to visit the geometry, below.) Anyway, onward:

Now to make up a full id of the tray:

idents::VolumeIdentifier vId;  // there is no copy or assign methods; append to a null vId
vId.append(vId_tower);         // append a the tower id part
vId.append(vId_tray);          // append the tray id part

Suppose you have a volId and you want to know what its fields are. Easy. To get the individual fields:

yTower  = vId[1];  // second field
tray    = vId[4];  // fifth field
botTop  = vId[6];  // sixth field
...
layer = tray - 1 + botTop; // not in the id, but easy to get...
or, to get the whole thing as a string:
std::string vId_string = vId.name();

which yields, for this tray: "/0/2/2/1/13/0/1"

Local-to-Global Transformations

Each volume has associated with it a transformation which takes that volume from its local coordinate system, centered at (0,0,0) and moves it to its correct position in the global system. The transformation includes a translation and a rotation.

For example, if I wish to know the spacing between two trays in the tracker, given the volIds of their top silicon planes, the z component of the local-to-global transformation will tell me the z coordinates of each plane:

idents::VolumeIdentifier volId1, volId2;

// for some reason, this worked without my needing to include any CLHEP header files
HepTransform3D T1, T2;
...
p_detSvc->getTransform3DByID(volId1, &T1); // get the transform

// if you want to go the other way for some reason you can get the inverse:
HepTransform3D T1GlobalToLocal = T1.inverse();

p_detSvc->getTransform3DBYID(volId2, &T2);
double deltaZ = (T1.getTranslation()).z() - 
           (T2.getTranslation()).z();

The rotation is obtained similarly. For example:

HepDouble angle;
Hep3Vector axis;
(T1.getRotation()).getAngleAxis(angle, axis);

is supposed to give you the rotation axis and angle of rotation of a volume.  When I try it on my silicon planes, I get a 90 degree rotation around z for every plane.  I don't think this is right. However the actual transformation behaves correctly, that is, the clusters come out in the right place in the tracker. (Except see below.)

There's another problem with the rotations. There seems to be a difference between G4 and the detModel in the way they treat the sense of rotations.  In particular, for the silicon planes that measure y, I have to reverse the local coordinate to get the global one to come out correctly. I think the experts know about this, but they haven't figured out what to do about it yet.

Geometry Visitor

(I haven't actually needed this yet, but I will soon, so I thought I'd try it.)

This is a way to get more information about the volumes. You get the type, name, dimensions, material, and volume id fragment for each volume. To do this, you write a geometry visitor, which inherits from IGeometry.h.  I've written a simple little one called TkrGeometryVisitor (header and implementation). It's job it to retrieve and print out the parameters of the trays in tower 9. It has two methods, pushShape() and popShape().  These methods are called by GlastDetSvc has it traverses the geometry hierarchy, pushShape() when going down the tree, and popShape() when going up. 

To start it up:

TkrGeometryVisitor geom;
p_GlastDetSvc->accept(geom);

That's all there is to it. Your pushShape() now gets called about a million times by GlastDetSvc.  Here's the output of my toy visitor.

A proposed upgrade of VolumeIdentifier will allow you to ask for the name of a field.

Proposed upgrades of IGeometry will allow better control over the traversal, will provide for setting the geometry choice parameter (for level of detail)  and will (possibly optionally) return the complete VolumeIdentifier at each call.


Last Modified: 04/04/02 12:01