Skip to content

Latest commit

 

History

History
140 lines (117 loc) · 8.37 KB

README.md

File metadata and controls

140 lines (117 loc) · 8.37 KB

Geometry

This is a python package for specifying locations and orientations of devices that make up water Cherenkov detectors (WCDs) based on multi-PMT modules (mPMTs). Devices, derived from the Device class, can contain other devices which are placed according to the coordinate system of its container. For example PMT placements are specified in the coordinate system of the mPMT they are contained in, and mPMT placements are specified in the coordinate system of the WCD (or Super Module) they are contained in. The WCD can be placed in a global coordinate system, or it can be used to define the global coordinate system.

The table below shows the active elements, which are classes that inherit from the Device class:

Class Device Kinds currently implemented
HALL Hall none - used to define coordinate system of hall or survey
WCD Water Cherenkov Detector WCTE: full detector
SM Super Module (several mPMTs combined) SSM: simple super module as basis of mPMT test setup
bottom, top, barrel : super modules that make up the WCTE
MPMT Multi-PMT module ME: ex-situ, MI: in-situ, MR: rectangular (for testing)
PMT Photomultiplier Tube P3: normal 3 inch PMT
LED Light Emitting Diode LD: diffuse, LC: collimated
CAMERA Camera C: camera for WCTE
TARGET Target T: target for WCTE

To allow extended functionality beyond geometry, the Device class also includes properties. Class dictionaries of dictionaries store design properties of different kinds of devices, first indexed by the specific "kind" of that device, then by property name. Separate dictionaries store the mean, scale of variations, and distribution of variations for these design properties: Device.design_mean, Device.design_scale, and Device.design_var. The third column in the table above shows the kinds of devices that are currently implemented and the first one indicated is the default kind for that device.

When instantiating a device, the object is assigned "true" properties that are drawn from the design distributions for that kind of device. The (true, design, or estimated) properties of a device can be accessed using the get_properties method with the desired kind of properties as an argument ('true', 'design', or 'est').

It is best to not change the design properties of a device kind after instantiating any devices of that kind, as that would cause you to have devices with different design properties of the same kind. It is possible to change the true properties of a device after it has been instantiated.

    >>> from Geometry.PMT import PMT
    >>> test_pmt = PMT('test_pmt', kind='P3')
    >>> design = test_pmt.get_properties('design')
    >>> for key in design:
            print(key, design[key], PMT.design_desc[key])
        
    fov 1.0 radian field of view (cone half angle)
    size 75 mm diameter
    qe 0.5 quantum efficiency
    gain 2.1 mV per photoelectron
    delay 4.0 ns mean delay of signal wrt pulse
    tts 1.0 ns transit time spread: standard deviation of transit delay

    >>> test_pmt.get_properties('true')
    {'fov': 0.9995023747534968, 'size': 74.78823666698443, 'qe': 0.5153263649689654, 'gain': 2.1558566901071807, 'delay': 3.959916692439508, 'tts': 0.9006637837841815}
    
    >>> PMT.design_mean['P3']['delay'] = 100. # changing the design properties of a device kind after one has already been instantiated as test_pmt (not recommended)
    >>> PMT.design_scale['P3']['delay'] = 10.
    >>> test_pmt2 = PMT('test_pmt2', kind='P3') # instantiating a new 'P3' PMT will use the new design properties
    >>> print(test_pmt2.get_properties('design')['delay'], test_pmt2.get_properties('true')['delay'])
    100.0 95.13212911052935
    >>> print('test_pmt:', test_pmt.get_properties('design')['delay'], test_pmt.get_properties('true')['delay']) # design value for P3 type PMTs has changed after test_pmt was instantiated
    test_pmt: 100.0 4.6118416289470705

    >>> test_pmt.set_property('delay', 200.)
    print('test_pmt:', test_pmt.get_properties('design')['delay'], test_pmt.get_properties('true')['delay'])
    test_pmt: 100.0 200.0

Instantiating a device that contains other devices will also instantiate those devices, and so on recursively. Such devices have placement dictionaries that specify the locations and orientations of the devices they contain. The locations and orientations of the device can be accessed using the get_placement method with arguments specifying the desired kind of placement information as an argument ('true', 'design', or 'est') and the device whose coordinate system you want to use as a reference.

    >>> from Geometry.MPMT import MPMT
    >>> test_mpmt = MPMT('test_mpmt', kind='ME')
    >>> pmt1 = test_mpmt.pmts[1]
    >>> placement = pmt1.get_placement('design', test_mpmt)
    >>> for key in placement:
    ...     print(key, placement[key])
    location [  0.          95.29664979 232.558     ]
    direction_x [1. 0. 0.]
    direction_z [0.         0.29265287 0.95621875]

    >>> from Geometry.WCD import WCD
    >>> wcte = WCD('wcte', kind='WCTE')
    >>> pmt_43_1 = wcte.mpmts[43].pmts[1]
    >>> placement = pmt_43_1.get_placement('design', wcte)
    >>> for key in placement:
    ...     print(key, placement[key])
    location [ 1.11285996e+03  1.92505783e-13 -9.78090146e+02]
    direction_x [ 0. -1.  0.]
    direction_z [-4.69211932e-01 -3.12164882e-16  8.83085592e-01]

Any device object can be serialized, saving all geometry information for that device and all devices it contains, by calling the save_file method with the desired filename as an argument. The device object can be reconstructed later by calling the open_file method with the same filename as an argument. Recommended to use .geo as the file extension. A set of .geo files could act as a historical record of earlier designs, or the files can be used as reference instances of a device in simulation studies. The file format is a pickle of the device object.

    >>> wcte.save_file('wcte_v11.geo')

    >>> from Geometry.Device import Device
    >>> wcte_v11 = Device.open_file('wcte_v11.geo')
    >>> pmt_43_1 = wcte_v11.mpmts[43].pmts[1]
    >>> placement = pmt_43_1.get_placement('design', wcte)

Alternatively, property and placement information for a device (and the devices it contains) can be saved in a json formatted file using the save_json method with the desired filename as an argument. This would be convenient for accessing geometry information in other programming languages.

    >>> wcte.save_json('wcte_v11.json', prop_info='design', place_info='design', devices='mpmts'))

    >>> import json
    >>> info = json.load(open('wcte_v11.json'))
    >>> placement = info['mpmts']['43']['leds']['3']['placement']

Images of the devices can be rendered in 3D. Example jupyter notebooks, using the k3d package, in the examples folder show

  • an MPMT with all its PMTs and LEDs, and baseplate (at z=0) showing the large feedthrough hole and survey holes (labelled cn) and locations of the survey fiducial points (labelled fn)
  • the bottom, barrel, and top supermodules of the WCTE, showing the mPMT baseplates, feedthroughs, and fiducial points
  • the full WCTE with all MPMT baseplates

Also in the examples folder is a jupyter notebook showing how to use the Geometry package to analyze simulated survey data to determine the as-built placements of all MPMTs in the WCTE coordinate system.

Other WCD or Supermodule designs can be defined by extending the WCD or SM classes and adding to the design dictionaries.

Additional functionality for the devices can be incorporated by extending the device classes. The TimeCal package uses the Geometry package to define the geometry of the system being calibrated. For convenience, the device property estimate dictionaries (for mPMTs, PMTs, and LEDs) in this package are used to store the time delay constants.