In [1]:
from pkg_resources import resource_filename
import os
import warnings
import numpy as np

from cts_core.camera import Camera
from digicampipe.utils import geometry
from digicampipe.io.event_stream import event_stream, add_slow_data

example_file_path = resource_filename(
    'digicampipe',
    os.path.join(
        'tests',
        'resources',
        'example_100_evts.000.fits.fz'
    )
)

digicam_config_file = resource_filename(
    'digicampipe',
    os.path.join(
        'tests',
        'resources',
        'camera_config.cfg'
    )
)

aux_basepath = resource_filename('digicampipe', 'tests/resources/')


digicam = Camera(_config_file=digicam_config_file)
digicam_geometry = geometry.generate_geometry_from_camera(camera=digicam)



data_stream = event_stream(
    file_list=[example_file_path],
    camera_geometry=digicam_geometry,
    camera=digicam,
    max_events=100
)
data_stream = add_slow_data(data_stream, basepath=aux_basepath)
for event in data_stream:
    pass


/home/dneise/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters

In [2]:
event


Out[2]:
digicampipe.io.containers.DataContainer:
                          r0.*: Raw Data
                          r1.*: Raw Common Data
                         dl0.*: DL0 Data Volume Reduced Data
                         dl1.*: DL1 Calibrated image
                         dl2.*: Reconstructed Shower Information
                        inst.*: Instrumental information
                     slow_data: Slow Data Information

In [3]:
# I do not show this, it is VERY long and ugly
# event.slow_data

In [4]:
# slow_data return a `collections.namedtuple` at the moment
# namedtuples tell you their fields with: `._fields`  (yes, it should be keys(), but I did not write it.)
event.slow_data._fields


Out[4]:
('DigicamSlowControl',
 'MasterSST1M',
 'PDPSlowControl',
 'SafetyPLC',
 'DriveSystem')

In [5]:
# each field of `slow_control` at the moment is also a namedtuple namedtuple
# I do not show this, it is long and ugly
# event.slow_data.DigicamSlowControl

In [6]:
event.slow_data.DigicamSlowControl._fields


Out[6]:
('timestamp',
 'Crate1_timestamps',
 'Crate3_T',
 'Crates',
 'Crate2_T',
 'cstSwitches',
 'appStatus',
 'Crate1_status',
 'FadcResync',
 'Crate2_timestamps',
 'Crate1_T',
 'AbsoluteTime',
 'trigger_status',
 'Crate3_status',
 'FadcOffset',
 'triggerParameters',
 'opcuaTime',
 'triggerSwitches',
 'Crate2_status',
 'cstParameters',
 'Crate3_timestamps',
 'LocalTime',
 'trigger_timestamp',
 'triggerStatus')

In [7]:
event.slow_data.DigicamSlowControl.trigger_status


Out[7]:
0

In [8]:
# I do not show this, it is long and ugly
# event.slow_data.DriveSystem

In [9]:
event.slow_data.DriveSystem._fields


Out[9]:
('timestamp',
 'operation_aborted_error_description',
 'no_permission_error_description',
 'system_is_busy_error_rev',
 'current_track_step_pos_el',
 'has_id',
 'operation_stopped_error_rev',
 'invalid_operation_error_ec',
 'recent_error_rev',
 'is_moving',
 'in__v_rel',
 'in__track_step_pos_el',
 'has_remote_mode_requested',
 'has_firmware_release',
 'current_track_step_pos_az',
 'is_tracking',
 'current_track_step_t',
 'is_in_park_position',
 'is_in_parking_zone',
 'is_on_source',
 'in__track_step_pos_az',
 'system_is_busy_error_crit_time',
 'operation_stopped_error_ec',
 'invalid_operation_error_crit_time',
 'current_max_velocity_el',
 'current_max_velocity_az',
 'operation_aborted_error_crit_time',
 'current_position_el',
 'capacity_exceeded_error_ec',
 'invalid_operation_error_rev',
 'system_is_busy_error_ec',
 'invalid_operation_error_description',
 'current_nominal_position_az',
 'capacity_exceeded_error_rev',
 'operation_stopped_error_description',
 'current_time',
 'in__position_az',
 'no_permission_error_ec',
 'capacity_exceeded_error_description',
 'current_position_az',
 'invalid_argument_error_description',
 'has_cache_capacity',
 'in__position_el',
 'operation_stopped_error_crit_time',
 'in__t_after',
 'current_cache_size',
 'current_nominal_position_el',
 'invalid_argument_error_rev',
 'capacity_exceeded_error_crit_time',
 'no_permission_error_crit_time',
 'is_in_start_position',
 'invalid_argument_error_ec',
 'in__track_step_t',
 'operation_aborted_error_ec',
 'operation_aborted_error_rev',
 'system_is_busy_error_description',
 'invalid_argument_error_crit_time',
 'no_permission_error_rev',
 'recent_error_name',
 'current_velocity_el',
 'is_off',
 'has_local_mode_requested',
 'current_velocity_az')

In [10]:
event.slow_data.DriveSystem.current_time


Out[10]:
1509415494066

In [11]:
event.slow_data.DriveSystem.current_position_az


Out[11]:
-166.022

In [12]:
event.slow_data.DriveSystem.current_position_el


Out[12]:
61.696793

How to look at the lid_status

The lid_status is contained in the least significant 4bits of this integer


In [13]:
event.slow_data.SafetyPLC.SPLC_CAM_Status


Out[13]:
59574

In [14]:
from enum import Enum, IntEnum, auto    
class LidStatus(Enum):
    # TODO: check the Enum docu, if this repetition of auto() can be avoided...
    Undefined = auto()
    Closed = auto()
    D2_starting = auto()
    D1_opening = auto()
    D1_opened = auto()
    D2_opening = auto()
    Opened = auto()
    D1_starting = auto()
    D2_closing = auto()
    D2_closed = auto()
    D1_closing = auto()
    OVC_error = auto()
    OVC_error_reseting = auto()
    Timeout_error = auto()
    
    @classmethod
    def from_CAM_Status(cls, status):
        # LidStatus is encoded in the 4 least significant bits of
        # the SafetyPLC.SPLC_CAM_Status
        return cls(status & 0xF)

In [15]:
LidStatus.from_CAM_Status(event.slow_data.SafetyPLC.SPLC_CAM_Status)


Out[15]:
<LidStatus.D2_opening: 6>

So inside a "processor" which wants to skip all events where the Lid is not Opened the code would read like this:


In [16]:
for event in data_stream:
    lid_status = LidStatus.from_CAM_Status(event.slow_data.SafetyPLC.SPLC_CAM_Status)
    if lid_status is not LidStatus.Opened:
        continue
    else:
        # Lid is open, so we can analyze
        pass