Coordinate Systems#

simtools uses multiple coordinate systems for telescope positioning, simulations, and analysis. This document describes the systems and how they are used. Please refer to the CORSIKA and sim_telarray documentation for details on systems used in these simulation tools.

Geospatial Coordinate Systems#

Three coordinate systems define array element positions on Earth, implemented via GeoCoordinates and TelescopePosition classes in simtools.layout. The pyproj library is used for transformations between these systems.

Local Transverse Mercator (WGS84)#

Geographic latitude and longitude

  • Axes: Latitude (x), Longitude (y)

  • Units: Degrees

  • Altitude: Height above sea level (meters)

This implementation uses Latitude=x and Longitude=y, which is unconventional compared to standard GIS and geographic conventions. Most geographic information systems follow (longitude, latitude) or equivalently (x, y) where:

  • x = Longitude (east-west axis)

  • y = Latitude (north-south axis)

UTM (Universal Transverse Mercator) System#

UTM coordinates

  • Axes: Easting (x), Northing (y)

  • Units: Meters

  • Scale factor: \(k_0 = 0.9996\) at central meridian

  • Altitude: Height above sea level (meters)

Ground (Local/sim_telarray) System#

Local Cartesian system centered at array center.

  • Origin: Array center (reference point)

  • Axes: X→North, Y→West, Z→Up (NWU)

  • Units: Meters

  • Projection: Transverse Mercator centered at array

  • Scale factor: \(k_0=(R+altitude)/R\) depends on latitude and altitude (WGS84 ellipsoid; R is the geocentric radius)

  • Z coordinate: position_z, height above a reference altitude (e.g., CORSIKA observation level), in meters

  • Usage: CORSIKA and sim_telarray simulations (native system)

Note the differences between the altitude of the array center and the CORSIKA observation level.

CORSIKA Specifics#

Telescope positions in CORSIKA are defined by their (x, y) coordinates in the ground system and an altitude (z) calculated as:

\[\text{position\_z} = \text{altitude} - \text{corsika\_observation\_level} + \text{telescope\_axis\_height}\]

The CORSIKA observation level must be below the altitude of any telescope to ensure positive position_z values.

CORSIKA uses the ARRANGE card to specify geomagnetic field rotation, aligning the shower coordinate system with geographic North when needed.

Shower Coordinate System#

Local frame aligned with shower propagation direction. Used for ray-tracing and event reconstruction. Transforms ground coordinates based on shower azimuth and zenith angle.

Implementation: simtools.utils.geometry.project_ground_to_corsika_shower_coordinates()

Camera Coordinate Systems#

Pixel Coordinates#

Photosensor positions in the focal plane as read from the sim_telarray camera configuration file, before the Rotate angle is applied.

  • Plane: Focal plane

  • Origin: Camera center

  • Units: Centimeters (cm)

  • Pixel shapes: Hexagonal (codes 1, 3 for different orientation) or Square (code 2)

  • Data source: sim_telarray camera configuration files

Includes pixel position (x, y), ID, on/off status, and diameter. The pixel coordinates define a coordinate basis aligned with the unrotated pixel layout.

Camera Coordinates#

Pixel positions after applying the camera rotation from the Rotate entry in the sim_telarray camera configuration file. simtools.model.camera.Camera applies this rotation during initialization via Camera._rotate_pixels, so the coordinates stored in the Camera class are the rotated camera coordinates. For a rotation angle \(\phi\), simtools uses

\[ x_{cam} = x_{pix}\cos(\phi) - y_{pix}\sin(\phi), \]
\[ y_{cam} = x_{pix}\sin(\phi) + y_{pix}\cos(\phi). \]

Camera plots can additionally transform these coordinates to show the layout from the requested viewpoint. For a single-mirror telescope, the default is the view of an observer facing the camera. In that view, \(x_{cam}\) points down and \(y_{cam}\) points left. The displayed \(x_{pix}\) and \(y_{pix}\) axes show the unrotated pixel basis expressed in this camera view.