Coordinate Systems

From Daya Bay

Jump to: navigation, search
Offline Documentation: [Offline Category] [FAQ] [Howto] [Reference] [Manual]

Offline Documentation
This article is part
of the Offline Documentation
Other pages...

Offline Category
How Tos
Getting Started
Software Installation

See also...

General Help on this Wiki

The types of coordinate systems used in NuWa are described.


There are many possible coordinate systems one can use in the detector geometry. As far as the software is concerned there is no "special" one except perhaps the Global geometry, which is what must be used to communicate with Geant4, for instance. However for human use it is important to define some conventions and call out some "special" coordinate systems so that we all talk about the same things. They are listed below.

General Geometry

Every logical volume in the geometry has a coordinate system originating at the shapes center. Daughter volumes are placed with respect to the mother's coordinates. It is possible to transform points and directions between mother and daughter coordinates. It is also possible to transform between the logical volume's local and world global coordinates, by iteratively transforming through the mother-daughter connections.


Global coordinate system is set by the geometry and not just a choice of convention. Its origin is the mid site (hall 4). This is done by converting all sites absolute locations based on engineering drawings into ones relative to the mid site. Z points up (assume a flat Earth) and X/Y points East/North respectively.


Each of the three detector sites are positioned and rotated w.r.t. the Global coordinate system as per engineering drawings. Within a Site the local coordinate system has its X/Y origin at the center of the top of the pool, equidistant from the AD's cylinder axes. The Z origin is at the the concrete floor which is coplanar with the ideal water surface. Z points up and X points towards the hall's exit to the tunnel in all cases.

When ADs are placed they undergo no rotations w.r.t. the Site. The local AD coordinate system is centered according to the nominal center of the cylinder defined by the array of PMTs. Local X, Y and Z axes are parallel to their Site counterparts. The first column of PMTs are at 7.5deg (1/2 angular separation of the columns) above the X-axis.

Note, the original AD geometry was rotated by 180 degrees from as-built. To correct this while keeping as much existing offline conventions in place the following was done:

  • Place the AD Envelope (ADE, containing the stainless steel tank (SST), the ACUs and other external details) in the OWS with a rotation of 180 degrees.
  • Place the Mineral Oil in the SST with a rotation of -180 degress.
  • Place the Outer Acrylic Vessel (OAV) in the OIL with a rotation of -180 degrees.
  • Place the cylinder of PMTs in the OIL with a rotation of -180.

The last is done in order for the PMT numbers to match what installation people used. This puts offline column 1,2,3 in installation ladder 1 which is nearest to the RPC garage.

Trac ticket #1187 has more details including before and after drawings (PDF, and password needed).


The CoordSysSvc and PmtGeomInfoSvc are two services that can be used to work with the coordinates.

See this Python Algorithm/Module for an example of how to use the CoordSysSvc.


You can transform between the various coordinate systems.

3-vector types

position like
should be held in a Gaudi::XYZPoint
direction like
should be held in a Gaudi::XYZVector

These obviously transform differently so take care to use the write type to store the right data.

Mother and Daughters

You can transform between the local coordinate system attached to a physical daughter volume and the one attached to its mother using:

IPVolume* pv = ...;
local = pv->toLocal(inMother);
inMother = pv->toMother(local);

There are only transformations for XYZPoint.

DetectorElements and Global

You can transform between global and the local coordinate system of a DetectorElement's volume using:

IGeometryInfo* gi = ...;
local = gi->toLocal(global);
global = gi->toGlobal(local);

methods. There is one each for XYZPoint and XYZVector. To transform between two DetectorElements you must go through an intermediate global coordinate transform.

To get a geometry info you can ask the Transient Detector Store for one based on name. If your code is in a GaudiAlgorithm you just need to do this:

string de_name = "/dd/Structure/Sites/far-rock"; // for example
IDetectorElement* de = getDet<IDetectorElement>(de_name);
IGeometryInfo* gi = de->geometry();


To convert coordinates to the local frame:

# Get vertex information
statshdr = simHdr.unobservableStatistics()
stats = statshdr.stats()
x_global = stats["x_Trk2"].sum()
y_global = stats["y_Trk2"].sum()
z_global = stats["z_Trk2"].sum() 
# Get the geometry of the appropriate detector element de = self.getDet("/dd/Structure/AD/db-ade1/db-sst1/db-oil1")
# Convert to local coordinates Gaudi = PyCintex.makeNamespace("Gaudi") globalpoint = Gaudi.XYZPoint(x_global, y_global, z_global) localpoint = de.geometry().toLocal(globalpoint)
x_local = localpoint.x() / y_local = localpoint.y() / z_local = localpoint.z() /

Where am I in?

You can drill down the structure hierarchy using


See the comments in DetDesc/IGeometryInfo.h for details.

PMT Normal vector

To get the vector that points in the direction that a PMT faces transform a local Z unit vector (0,0,1) from local-PMT coordinate system, to global one and then back to the canonical system (AD or Site) that you care about. This is done for you with the PmtGeomInfoSvc and PmtGeomInfo provided by the Detector/DetHelpers package

First, get the service and save it to a data member of your algorithm:

// in initialize()
m_pgis = svc<IPmtGeomInfoSvc>("PmtGeomInfoSvc");

Later, use it to get an IPmtGeomInfo for a particular PMT

// in execute
// Can also get() by /dd/Structure path or with an IDetectorElement*
IPmtGeomInfo* pgi = m_pgis->get(pmtid);

Finally, get the direction that the PMT faces (in AD coordinates for AD PMTs and in Site coordinates for Pool PMTs):

const CLHEP::Hep3Vector& normal = pgi->localDirection();

For more functionality consult DetHelpers/IPmtGeomInfo.h.

Offline Software Documentation: [Offline Categories] [FAQ] [Offline Reference Category]
Personal tools