Detector Dump

Dumping the sensor position and orientation for easier analysis.

dump detector parameters for analysis

Global

hps_align.detdump._global.global_coord(detname: str = <typer.models.ArgumentInfo object>, input_file: ~pathlib.Path = <typer.models.ArgumentInfo object>, run_number: int = <typer.models.ArgumentInfo object>, jar: ~pathlib.Path = <typer.models.OptionInfo object>, output_file: str = <typer.models.OptionInfo object>)

dump coordinates of sensors in global frame

This is done by running a specific driver in hps-java and then processing its output. Since we are running hps-java there are a few required inputs.

Run Number Look-Up-Table

Each year has a different set of “base” conditions that need to be used; otherwise, the hps-java run isn’t able to get to the geometry construction.

  • 2015: 5772

  • 2016: 7800 (7000-8999)

  • 2019: 10716

  • 2021: 14166

Since the 2019 and 2021 conditions have the same “shape”, we can use the same (somewhat arbitrary) run number if desired.

Auto-Deduced java Arguments

java args

we aren’t doing any strong processing or using GBL so we just have a default set of java arguments

steering file

we use the steering file that is stored in this module

outputFile

nothing is written to it so we just supply a dummy name

number of events

we just need one to trigger the functionality of loading the detector

param detname:

The name of the detector to load

type detname:

str

param input_file:

the driver does not look at any of the events in the slcio file so it just needs to be /any/ slcio file with at least one event in it.

type input_file:

Path

param run_number:

The run number needs to be a valid run number for that year so that hps-java can pull down condition databases, but it doesn’t need to pertain to the detector being used

type run_number:

int

param jar:

the PrintGeometryDriver has been on hps-java master for awhile so this does not need to be incredibly recent. The default is the path to the 5.2-SNAPSHOT located in the user’s home maven repository.

type jar:

Path, optional

Local

hps_align.detdump._local.local_coord(detpath: ~pathlib.Path = <typer.models.ArgumentInfo object>, output_file: str = <typer.models.OptionInfo object>)

dump coordinates in local frame

This effectively dumps the alignment parameters since the “local” frame handles the global detector setup and the survey constnats.

Parameters:
  • detpath (str) – path to detector from which to get coordinates

  • output_file (str) – output file to write coordinates to

Data Writing

The backend module for writing this parsed data into a more easily-parsed format (either CSV or JSON).

hps_align.detdump._write.__get_row_default(k, v)

default implementation of getrow

hps_align.detdump._write.write_mapping(output_file, data, *, header=None, getrow=<function __get_row_default>)

write a mapping to an output file as either a CSV or a JSON file

Parameters:
  • output_file (str) – path to output file to write must have a ‘csv’ or ‘json’ extension

  • data (Mapping) – object to write

  • header (List[str]) – list of header rows to write to csv no header written if not provided

  • getrow (callable) – produce a row given a key, val pair from the mapping as arguments. The default is to just write the key and value as two columns __get_row_default()

Plotting

We can also summarize the dumped detector parameters through plots showing the sensor location/orientation in absolute terms or relative to a certain reference detector.

plot detector dumps to compare sensor positions and orientations

class hps_align.detdump.plot.Angle(value)

what angle definition should be used in global coordinate plots

See _angles module for how these definitions are defined.

axis = 'axis'
euler = 'euler'
expected_axis = 'expected_axis'
expected_svt_axis = 'expected_svt_axis'
class hps_align.detdump.plot.Coord(value)

which coordinate system to use

GLOBAL = 'global'

coordinates of sensors in some parent volume holding all of them

LOCAL = 'local'

coordinates relative to each sensor individually i.e. the alignment constants themselves

class hps_align.detdump.plot.Plot(value)

which type of comparison plot to use

ABS = 'abs'

plot all values in absolute terms

DIFF = 'diff'

subtract all values by the reference values

class hps_align.detdump.plot.Position(value)

what position definition should be used in global coordinate plots

HPS = 'hps'

positions relative to entire HPS detector

SVT = 'svt'

positions relative to SVT box

hps_align.detdump.plot.plot(input_file: ~typing.List[~pathlib.Path], out: ~pathlib.Path = <typer.models.OptionInfo object>, coord: ~hps_align.detdump.plot.Coord = <typer.models.OptionInfo object>, angle: ~hps_align.detdump.plot.Angle = <typer.models.OptionInfo object>, pos: ~hps_align.detdump.plot.Position = <typer.models.OptionInfo object>, module: bool = <typer.models.OptionInfo object>, plot: ~hps_align.detdump.plot.Plot = <typer.models.OptionInfo object>)

Plot detector coordinate and orientation data

If the ‘diff’ <plot> is chosen, then all values are subtracted by their reference values which are defined by the first detector provided in the input list.

All detectors are named after the name of the file. Use soft links to rename files to helpful legend names if you wish.

Calculating Angles

module for calculating different angles from coordinate axes

hps_align.detdump.plot._angles.angle_calculator(f)

decorator for registering angle calculators

hps_align.detdump.plot._angles.axis(df: DataFrame)

Calculate the angles relative to the known global axes the local axes are close to.

\[\theta_x = \arccos(v_x)\]
\[\theta_y = \arccos(u_y)\]
\[\theta_z = \arccos(w_z)\]
Parameters:

df (pd.DataFrame) – dataframe with u, v, w coordinate vectors

hps_align.detdump.plot._angles.euler(df: DataFrame)

One definition of the Euler angles

This code is not currently being used by the global loader but it is here for easy drop-in if users wish. Just change which angle_calculator is used when the global loader is being called.

\[\theta_x = \arctan\left(\frac{v_z}{w_z}\right)\]
\[\theta_y = -\arcsin(u_z)\]
\[\theta_z = \arctan\left(\frac{u_y}{u_x}\right)\]
Parameters:

df (pd.DataFrame) – dataframe with u, v, w coordinate vectors

Returns:

the three-tuple of the three euler angles

Return type:

Tuple[pd.Series]

hps_align.detdump.plot._angles.expected_axis(df: DataFrame)

Calculate the angles relative to the known global axes the local axes are close to and applying flips when we expect them to occur.

\[\theta_x = \arccos(\pm v_x)\]
\[\theta_y = \arccos(\pm u_y)\]
\[\theta_z = \arccos(\pm w_z)\]

The +/- sign comes from knowledge of how the detector was built and is summarized the the following tables.

Front

Sensor Type

\(sign(u \cdot y)\)

\(sign(v \cdot x)\)

\(sign(w \cdot z)\)

L12-axial-top

\(+\)

\(+\)

\(-\)

L12-stereo-top

\(+\)

\(-\)

\(+\)

L34-axial-top

\(+\)

\(+\)

\(-\)

L34-stereo-top

\(-\)

\(+\)

\(+\)

L12-axial-bottom

\(-\)

\(+\)

\(+\)

L12-stereo-bottom

\(-\)

\(-\)

\(-\)

L34-axial-bottom

\(-\)

\(+\)

\(+\)

L34-stereo-bottom

\(+\)

\(+\)

\(-\)

Back

Sensor Type

\(sign(u \cdot y)\)

\(sign(v \cdot x)\)

\(sign(w \cdot z)\)

axial-slot-top

\(-\)

\(-\)

\(-\)

axial-hole-top

\(+\)

\(+\)

\(-\)

stereo-slot-top

\(+\)

\(-\)

\(+\)

stereo-hole-top

\(-\)

\(+\)

\(+\)

axial-slot-bottom

\(+\)

\(-\)

\(+\)

axial-hole-bottom

\(-\)

\(+\)

\(+\)

stereo-slot-bottom

\(-\)

\(-\)

\(-\)

stereo-hole-bottom

\(+\)

\(+\)

\(-\)

Parameters:

df (pd.DataFrame) – dataframe with u, v, w coordinate vectors

hps_align.detdump.plot._angles.expected_svt_axis(df: DataFrame)

Calculate the angles relative to the known global axes the local axes are close to after applying a 30.5mrad rotation to the uvw coordinate vectors.

See also

expected_axis

the function that does the angle calculation after the 30.5mrad rotation

Parameters:

df (pd.DataFrame) – dataframe with u, v, w coordinate vectors

Loading Dumps

Loading the dumps gives us an opportunity to apply transformations to the coordinate vectors and positions so that the values we look at in the plots are more interpretable by the user. For example, This is where we choose how to calculate angles from the coordinate vectors u, v, and w.

load detector parameters dumped to a file

hps_align.detdump.plot._load._global(f: ~pathlib.Path, angle_calculator=<function axis>)

transform input global detdump into in-memory data table

We also take this opportunity to reformat the sensor names into something more readable and sort the dataframe in a special way so that the order of the sensors in the plot is more natural.

Parameters:
  • f (Path) – file to load global sensor information from

  • angle_calculator (Callable) – calculate the three angles representing the orientation of the sensor. This function is provided the parsed pandas DataFrame and then is expected to set the three columns [thetax, thetay, thetaz] to there calculated values. The default calculator is axis().

Returns:

dataframe holding the global sensor information along with the calculated angles

Return type:

pd.DataFrame

hps_align.detdump.plot._load._global_is2016(df: DataFrame)

check if the input dataframe holdinging geometry information is from 2016 or not

This check is currently only valid for global coordinates.

For global coordinates, the distinguishing factor between 2016 and post-upgrade years is the presence of a 7th layer.

Parameters:

df (pd.DataFrame) – dataframe of sensor coordinates and positions

Returns:

True if dataframe represents a 2016 detector

Return type:

bool

hps_align.detdump.plot._load._local(f: Path)

Load the alignment constants from the input path

Also convert a alignment constant ID number into its t_r and u_v_w for later categorization into different plots. The conversion from ID number into differet categories is listed below.

t_r

acquired by getting the 2nd digit of the 5-digit ID number.

u_v_w

getting the 3rd digit of the 5-digit ID number

individual

True if the last two digits are greater than 0 and less than 23

Parameters:

f (Path) – file to load local alignment constants from

Returns:

dataframe holding the constants and the deduced categorical variables

Return type:

pd.DataFrame

hps_align.detdump.plot._load._local_is2016(df: DataFrame)

determine if a local-coordinate dataframe is 2016

not implemented

Table of Figures

We’ve isolated the matplotlib nonsense for putting together several figures into a “table” of subplots so that it is easier to maintain. This is where stylistic choices are made.

construct different kinds of figures with tables of subplots

hps_align.detdump.plot._table_fig._global(data_items, output_file, title=None, position='hps', angle_title='Angles', ref_line=0.0, **kwargs)

the global coordinate system is plottined in a 3x2 grid where the first column is position and the second column is euler angles. The rows go through x, y, z.

Parameters:
  • data_items (List[Tuple[str,pd.DataFrame]]) – items of data with corresponding names to plot

  • output_file (str | pathlib.Path) – output file to write resulting figure to

  • title (str, optional) – title to add onto legend. Default is None.

  • position (str, optional) – which positional coordinates to use. Default is ‘hps’.

  • angle_title (str, optional) – title to have above the angle columns, useful for defining what angles are being plotted

  • ref_line (float, optional) – where to draw a horizontal reference line, use None to disable drawing

  • **kwargs (dict, optional) – the rest of the keyword arguments are absorbed but then ignored

hps_align.detdump.plot._table_fig._local(data_items, output_file, title=None, **kwargs)

the local coordinate system is plotted in a 2x4 grid where the top row is translations, the bottom row is rotations, and the last entry in the bottom row is for structure constants

Parameters:
  • data_items (List[Tuple[str,pd.DataFrame]]) – items of data with corresponding names to plot

  • output_file (str | pathlib.Path) – output file to write resulting figure to

  • title (str, optional) – title to add onto legend. Default is None.

  • **kwargs (dict, optional) – the rest of the keyword arguments are absorbed but then ignored