o
    h}                     @   s   d Z ddlmZ ddlZddlZddlmZmZmZmZm	Z	m
Z
mZmZmZmZ ddlZddlZddlmZmZmZ ddlmZmZ eeZG dd	 d	ZG d
d dZG dd deZdejde	ee e	e! f  fddZ"dS )a   Read SPE files.

This plugin supports reading files saved in the Princeton Instruments
SPE file format.

Parameters
----------
check_filesize : bool
    The number of frames in the file is stored in the file header. However,
    this number may be wrong for certain software. If this is `True`
    (default), derive the number of frames also from the file size and
    raise a warning if the two values do not match.
char_encoding : str
    Deprecated. Exists for backwards compatibility; use ``char_encoding`` of
    ``metadata`` instead.
sdt_meta : bool
    Deprecated. Exists for backwards compatibility; use ``sdt_control`` of
    ``metadata`` instead.

Methods
-------
.. note::
    Check the respective function for a list of supported kwargs and detailed
    documentation.

.. autosummary::
    :toctree:

    SpePlugin.read
    SpePlugin.iter
    SpePlugin.properties
    SpePlugin.metadata

    )datetimeN)
AnyCallableDictIteratorListMappingOptionalSequenceTupleUnion   )RequestIOModeInitializationError)PluginV3ImagePropertiesc                   @   sx  e Zd ZdZdddddddZi d	d
ddeg ddfdddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,i d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUddVdWdXdYddZZd[Zeej	eej
eejeejeejd\Zg d]Zg d^Zd_gZd`S )aSpecaW  SPE file specification data

    Tuples of (offset, datatype, count), where offset is the offset in the SPE
    file and datatype is the datatype as used in `numpy.fromfile`()

    `data_start` is the offset of actual image data.

    `dtypes` translates SPE datatypes (0...4) to numpy ones, e. g. dtypes[0]
    is dtype("<f") (which is np.float32).

    `controllers` maps the `type` metadata to a human readable name

    `readout_modes` maps the `readoutMode` metadata to something human readable
    although this may not be accurate since there is next to no documentation
    to be found.
    )l   <h)*   <H)i  r   )i  z<Q)i  z<i)i  <f)datatypexdimydimxml_footer_offset	NumFramesfile_header_verNumROI)i  r   ROIsi  ))startxr   )endxr   )groupxr   )startyr   )endyr   )groupyr   
   xDimDet)   r   yDimDet)   r   	VChipXdim)   r   	VChipYdim)   r   controller_version)r   r   logic_output)r   r   amp_high_cap_low_noise)   r   mode)   r   exposure_sec)r'   r   date)   z<10Sdetector_temp)$   r   detector_type)(   r   st_diode),   r   
delay_time).   r   shutter_control)2   r   absorb_live)4   r   absorb_mode)6   r   can_do_virtual_chip)8   r   threshold_min_live):   r   threshold_min_val)<   r   threshold_max_live)@   r   threshold_max_val)B   r   
time_local)   <7Stime_utc)   rS   
adc_offset)   r   adc_rate)   r   adc_type)   r   adc_resolution)   r   adc_bit_adjust)   r   gain)   r   comments)   z<80S   	geometric)iX  r   )i  z<16S)i  z<436S)b   r   )d   r   )f   r   )h   r   )i  r   )i  r   )i  r   )i  r   )i  r   )
sw_versionspare_4
XPrePixelsXPostPixels
YPrePixelsYPostPixelsreadout_timer   typeclockspeed_usreadout_modewindow_sizer   i  )r      r      r5   )znew120 (Type II)zold120 (Type I)ST130ST121ST138zDC131 (PentaMax)zST133 (MicroMax/Roper)zST135 (GPIB)VTCCDzST116 (GPIB)zOMA3 (GPIB)OMA4)z
full framezframe transferkineticsrk   N)__name__
__module____qualname____doc__basicnpdtypemetadata
data_startfloat32int32int16uint16uint32dtypescontrollersreadout_modes	no_decode r   r   N/var/www/html/scripts/venv/lib/python3.10/site-packages/imageio/plugins/spe.pyr   A   s    	
 #$%&'()*+,-./012345D





r   c                       s0  e Zd ZdZi ddddddddd	dd
dddddddddddddddddddddddZdd d!d"d#ZG d$d% d%Zi d&eded'd(ed)eded(d*ed+eded,de	d-eded.d/e
d0d1ededd2e	d3eded4d5ed6edd2d7d8 d9edd:d;d8 d<eded=d:ed>edd?d@d8 dAededBd=e
dCdDededd fdEd8dFeded5dBe
d0dGeded,dedHededdIe
dJdKededdedLededId=e
d0ededdeeded=dMe
d0ededdeeded/dNe
d0ededMdOe
d0ededOdPe
d0ededPd.e
d0dQdRededSdTdUd8 idVZedWee	 dXeeef fdYdZZedWee	 d[eeef dXee	ef f fd\d]Zed^e	d_e	dXeed`f f fdadbZedhddedee	f fdfdgZ  ZS )iSDTControlSpeca&  Extract metadata written by the SDT-control software

    Some of it is encoded in the comment strings
    (see :py:meth:`parse_comments`). Also, date and time are encoded in a
    peculiar way (see :py:meth:`get_datetime`). Use :py:meth:`extract_metadata`
    to update the metadata dict.
    u   Jänru   JanFebr   u   Märrv   MarAprr3   Maird   MayJunr)   Jul   Augr5   Sep	   Oktr'   OctNov   Dez   DecstandardTOCCSLr|   	arbitrary)SEQUSETOKINESEARc                
   @   sz   e Zd ZU dZeed< 	 eed< 	 eege	f ed< 	 e
def ed< 	 edfdededeege	f dee fddZdS )	zSDTControlSpec.CommentDescz>Describe how to extract a metadata entry from a comment stringnslicecvtNscalec                 C   s   || _ || _|| _|| _d S N)r   r   r   r   )selfr   r   r   r   r   r   r   __init__   s   
z#SDTControlSpec.CommentDesc.__init__)r}   r~   r   r   int__annotations__r   r   strr   r   floatr	   r   r   r   r   r   CommentDesc   s*   
 r   sdt_major_versionrP   D   sdt_minor_versionF   sdt_controller_namer   exposure_timerN   I   gư>
color_coder-   detection_channels   r/   background_subtractionc                 C      | dkS )NBr   xr   r   r   <lambda>      zSDTControlSpec.<lambda>	em_active    c                 C   r   )NEr   r   r   r   r   r   	  r   em_gain   modulation_active!   c                 C   r   )NAr   r   r   r   r   r     r   
pixel_size   g?sequence_typec                    s
    j |  S r   )sequence_typesr   	__class__r   r   r        
 gridn_macrodelay_macro   gMbP?n_mini
delay_mini%   O   r@   7   )n_microdelay_micro	n_subpicsdelay_shutterdelay_prebleachbleach_timerecovery_timebleach_piezo_active"   #   c                 C   r   )Nzr   r   r   r   r   r     r   ))rd   r   )rd   ru   rb   returnc                 C   sX   | d dd dkrdS zt | d dd t | d dd fW S  ty+   Y dS w )a-  Get the version of SDT-control metadata encoded in the comments

        Parameters
        ----------
        comments
            List of SPE file comments, typically ``metadata["comments"]``.

        Returns
        -------
        Major and minor version. ``-1, -1`` if detection failed.
        r3   r   L   COMVER)r   N   P   )r   
ValueError)rb   r   r   r   get_comment_version"  s   *z"SDTControlSpec.get_comment_versionversionc                    s6  i }t |d d D ]\}z j|d |f }W n	 ty    Y q
w | D ]@\}}z|| |j |j }|jdur?||j9 }|||< W q% tye } zt	
d| d|  d||< W Y d}~q%d}~ww q
| jvrdtdd  j}	t	
d	|d  d
|d dd|	 d | d | d  }
|
 |d< |S )aC  Extract SDT-control metadata from comments

        Parameters
        ----------
        comments
            List of SPE file comments, typically ``metadata["comments"]``.
        version
            Major and minor version of SDT-control metadata format

        Returns
        -------
        Dict of metadata
        ru   r   Nz-Failed to decode SDT-control metadata field `z`: z, c                 S   s   | d  d| d dS )Nr   .ru   02r   r   r   r   r   r   ^      z/SDTControlSpec.parse_comments.<locals>.<lambda>z)Unsupported SDT-control metadata version r   r   z. Only versions z@ are supported. Some or all SDT-control metadata may be missing.r   comment)rangecomment_fieldsKeyErroritemsr   r   r   r   	Exceptionwarningswarnjoinmapstrip)rb   r   sdt_mdminorcmtnamespecvesupported_verr   r   r   r   parse_comments6  sB   


zSDTControlSpec.parse_commentsr7   timeNc              
      s   z1 j | dd  }tt| dd |t| dd t|dd t|dd t|dd W S  tyM } ztd| d W Y d	}~d	S d	}~ww )
ai  Turn date and time saved by SDT-control into proper datetime object

        Parameters
        ----------
        date
            SPE file date, typically ``metadata["date"]``.
        time
            SPE file date, typically ``metadata["time_local"]``.

        Returns
        -------
        File's datetime if parsing was succsessful, else None.
        r   rd   r   r   r3   r)   z1Failed to decode date from SDT-control metadata: r   N)monthsr   r   r   loggerinfo)r7   r  monthr	  r   r   r   get_datetimei  s    zSDTControlSpec.get_datetimelatin1metachar_encodingc                    s     | d }tdd |D rtd dS  | d |}| d | |  | d | d }|rC|| d< | d | d | d	 }z||| d
< | d	 W n t	yc   t
d Y nw | d | d dS )ar  Extract SDT-control metadata from SPE metadata

        SDT-control stores some metadata in comments and other fields.
        Extract them and remove unused entries.

        Parameters
        ----------
        meta
            SPE file metadata. Modified in place.
        char_encoding
            Character encoding used to decode strings in the metadata.
        rb   c                 s   s    | ]}|d k V  qdS )r   Nr   .0cr   r   r   	<genexpr>  s    z2SDTControlSpec.extract_metadata.<locals>.<genexpr>zSDT-control comments not found.Nr7   rQ   r   rk   modulation_scriptzHFailed to decode SDT-control laser modulation script. Bad char_encoding?rT   r6   )r   anyr  debugr  popupdater  decodeUnicodeDecodeErrorr   r   )r  r  comversdt_metadtsp4r   r   r   extract_metadata  s.   





zSDTControlSpec.extract_metadata)r  )r}   r~   r   r   r  r   r   r   r   r   r   r   staticmethodr
   r   r   r   r   r  r   r   r  r   r$  __classcell__r   r   r   r   r      s    	
	
" 

2$"r   c                       s  e Zd Z			ddededee dee ddf
 fdd	Zd
ddede	j
fddZdee	j
 fddZ	
			d dededededeeef f
ddZdededeeef fddZdeeef fddZd!dedefddZdeeef dedeeef fddZ  ZS )"	SpePluginTNrequestcheck_filesizer  r!  r   c              	      sl  t  | |jjtjkrtd|durtdt	 || _
|dur(tdt	 || _| j | _zy| tjd}|d | _tj|d  | _|d |d	 f| _|d
 | _|r|d dkra|d }n| jdtj | j }|tj }|| jd | jd  | jj  }|| jkrtd| jj d| j d| d t|| j| _| jtj W dS  ty   tdw )a  Instantiate a new SPE file plugin object

        Parameters
        ----------
        request : Request
            A request object representing the resource to be operated on.
        check_filesize : bool
            If True, compute the number of frames from the filesize, compare it
            to the frame count in the file header, and raise a warning if the
            counts don't match. (Certain software may create files with
        char_encoding : str
            Deprecated. Exists for backwards compatibility; use ``char_encoding`` of
            ``metadata`` instead.
        sdt_meta : bool
            Deprecated. Exists for backwards compatibility; use ``sdt_control`` of
            ``metadata`` instead.

        zcannot write SPE filesNz{Passing `char_encoding` to the constructor is deprecated. Use `char_encoding` parameter of the `metadata()` method instead.ztPassing `sdt_meta` to the constructor is deprecated. Use `sdt_control` parameter of the `metadata()` method instead.r  r   r   r   r   r   rv   r   r   ru   zThe file header of z claims there are z  frames, but there are actually z frames.z)SPE plugin cannot read the provided file.) superr   r4   io_moder   writer   r   r   DeprecationWarning_char_encoding	_sdt_metar(  get_file_file_parse_headerr   r   _file_header_verr   _dtype_shape_lenseekosSEEK_ENDtellr   itemsizefilenameminr   )r   r(  r)  r  r!  r  data_endliner   r   r   r     sT   




 
zSpePlugin.__init__.indexrA  c                C   s   |t u rtj}| jd | jd  | j }| jg| jR }n=|dk r)td| d|| jkr:td| d| j dtj|| jd  | jd  | jj  }| jd | jd  }| j}| j	| t
j| j| j|d}||S )a<  Read a frame or all frames from the file

        Parameters
        ----------
        index : int
            Select the index-th frame from the file. If index is `...`,
            select all frames and stack them along a new axis.

        Returns
        -------
        A Numpy array of pixel values.

        r   ru   zIndex `z` is smaller than 0.z5` exceeds the number of frames stored in this file (`z`).r   count)Ellipsisr   r   r5  r6  
IndexErrorr4  r;  r1  r7  r   fromfilereshape)r   rA  read_offsetrC  	out_shapedatar   r   r   read  s&   

zSpePlugin.readc                    s    fddt  jD S )zrIterate over the frames in the file

        Yields
        ------
        A Numpy array of pixel values.
        c                 3   s    | ]	} j |d V  qdS )r@  N)rK  )r  ir   r   r   r  1  s    z!SpePlugin.iter.<locals>.<genexpr>)r   r6  rM  r   rM  r   iter)  s   zSpePlugin.iterr  exclude_appliedsdt_controlc                 C   s>   | j dk r| jdur| j}| jdur| j}| ||S |  S )ua  SPE specific metadata.

        Parameters
        ----------
        index : int
            Ignored as SPE files only store global metadata.
        exclude_applied : bool
            Ignored. Exists for API compatibility.
        char_encoding : str
            The encoding to use when parsing strings.
        sdt_control : bool
            If `True`, decode special metadata written by the
            SDT-control software if present.

        Returns
        -------
        metadata : dict
            Key-value pairs of metadata.

        Notes
        -----
        SPE v3 stores metadata as XML, whereas SPE v2 uses a binary format.

        .. rubric:: Supported SPE v2 Metadata fields

        ROIs : list of dict
            Regions of interest used for recording images. Each dict has the
            "top_left" key containing x and y coordinates of the top left corner,
            the "bottom_right" key with x and y coordinates of the bottom right
            corner, and the "bin" key with number of binned pixels in x and y
            directions.
        comments : list of str
            The SPE format allows for 5 comment strings of 80 characters each.
        controller_version : int
            Hardware version
        logic_output : int
            Definition of output BNC
        amp_hi_cap_low_noise : int
            Amp switching mode
        mode : int
            Timing mode
        exp_sec : float
            Alternative exposure in seconds
        date : str
            Date string
        detector_temp : float
            Detector temperature
        detector_type : int
            CCD / diode array type
        st_diode : int
            Trigger diode
        delay_time : float
            Used with async mode
        shutter_control : int
            Normal, disabled open, or disabled closed
        absorb_live : bool
            on / off
        absorb_mode : int
            Reference strip or file
        can_do_virtual_chip : bool
            True or False whether chip can do virtual chip
        threshold_min_live : bool
            on / off
        threshold_min_val : float
            Threshold minimum value
        threshold_max_live : bool
            on / off
        threshold_max_val : float
            Threshold maximum value
        time_local : str
            Experiment local time
        time_utc : str
            Experiment UTC time
        adc_offset : int
            ADC offset
        adc_rate : int
            ADC rate
        adc_type : int
            ADC type
        adc_resolution : int
            ADC resolution
        adc_bit_adjust : int
            ADC bit adjust
        gain : int
            gain
        sw_version : str
            Version of software which created this file
        spare_4 : bytes
            Reserved space
        readout_time : float
            Experiment readout time
        type : str
            Controller type
        clockspeed_us : float
            Vertical clock speed in microseconds
        readout_mode : ["full frame", "frame transfer", "kinetics", ""]
            Readout mode. Empty string means that this was not set by the
            Software.
        window_size : int
            Window size for Kinetics mode
        file_header_ver : float
            File header version
        chip_size : [int, int]
            x and y dimensions of the camera chip
        virt_chip_size : [int, int]
            Virtual chip x and y dimensions
        pre_pixels : [int, int]
            Pre pixels in x and y dimensions
        post_pixels : [int, int],
            Post pixels in x and y dimensions
        geometric : list of {"rotate", "reverse", "flip"}
            Geometric operations
        sdt_major_version : int
            (only for files created by SDT-control)
            Major version of SDT-control software
        sdt_minor_version : int
            (only for files created by SDT-control)
            Minor version of SDT-control software
        sdt_controller_name : str
            (only for files created by SDT-control)
            Controller name
        exposure_time : float
            (only for files created by SDT-control)
            Exposure time in seconds
        color_code : str
            (only for files created by SDT-control)
            Color channels used
        detection_channels : int
            (only for files created by SDT-control)
            Number of channels
        background_subtraction : bool
            (only for files created by SDT-control)
            Whether background subtraction war turned on
        em_active : bool
            (only for files created by SDT-control)
            Whether EM was turned on
        em_gain : int
            (only for files created by SDT-control)
            EM gain
        modulation_active : bool
            (only for files created by SDT-control)
            Whether laser modulation (“attenuate”) was turned on
        pixel_size : float
            (only for files created by SDT-control)
            Camera pixel size
        sequence_type : str
            (only for files created by SDT-control)
            Type of sequnce (standard, TOCCSL, arbitrary, …)
        grid : float
            (only for files created by SDT-control)
            Sequence time unit (“grid size”) in seconds
        n_macro : int
            (only for files created by SDT-control)
            Number of macro loops
        delay_macro : float
            (only for files created by SDT-control)
            Time between macro loops in seconds
        n_mini : int
            (only for files created by SDT-control)
            Number of mini loops
        delay_mini : float
            (only for files created by SDT-control)
            Time between mini loops in seconds
        n_micro : int (only for files created by SDT-control)
            Number of micro loops
        delay_micro : float (only for files created by SDT-control)
            Time between micro loops in seconds
        n_subpics : int
            (only for files created by SDT-control)
            Number of sub-pictures
        delay_shutter : float
            (only for files created by SDT-control)
            Camera shutter delay in seconds
        delay_prebleach : float
            (only for files created by SDT-control)
            Pre-bleach delay in seconds
        bleach_time : float
            (only for files created by SDT-control)
            Bleaching time in seconds
        recovery_time : float
            (only for files created by SDT-control)
            Recovery time in seconds
        comment : str
            (only for files created by SDT-control)
            User-entered comment. This replaces the "comments" field.
        datetime : datetime.datetime
            (only for files created by SDT-control)
            Combines the "date" and "time_local" keys. The latter two plus
            "time_utc" are removed.
        modulation_script : str
            (only for files created by SDT-control)
            Laser modulation script. Replaces the "spare_4" key.
        bleach_piezo_active : bool
            (only for files created by SDT-control)
            Whether piezo for bleaching was enabled
        rv   N)r3  r.  r/  _metadata_pre_v3_metadata_post_v3)r   rA  rO  r  rP  r   r   r   r   3  s    
M

zSpePlugin.metadatac           	         s  |  tj|  dd}|dk rdn|}t d d|  d<  fdddD  d<  fd	dd
D  d<  fdddD  d<  fdddD  d< dd  d D  d< g } dd}|d@ ri|d |d@ rr|d |d@ r{|d | d<  d }d|  krttjkrn n
tj|d   d< nd d<  d }d|  krttjkrn n
tj|d   d< nd d< dD ]
}t	 |  |< q|rt
 |  S )aZ  Extract metadata from SPE v2 files

        Parameters
        ----------
        char_encoding
            String character encoding
        sdt_control
            If `True`, try to decode special metadata written by the
            SDT-control software.

        Returns
        -------
        dict mapping metadata names to values.

        r   Nru   r    c                       g | ]}  |d qS r   r  r  kmr   r   
<listcomp>  r   z.SpePlugin._metadata_pre_v3.<locals>.<listcomp>)r(   r*   	chip_sizec                    rS  r   rT  rU  rW  r   r   rY     r   )r,   r.   virt_chip_sizec                    rS  r   rT  rU  rW  r   r   rY  !  r   )rl   rn   
pre_pixelsc                    rS  r   rT  rU  rW  r   r   rY  "  r   )rm   ro   post_pixelsc                 S   s   g | ]}t |qS r   )r   r  r   r   r   rY  %  s    rb   re   r   rotater   reverser3   fliprq   rs   )rC   rG   rI   rM   )r2  r   r   r  roi_array_to_dictappendlenr   r   boolr   r$  )	r   r  rP  nrgftrrV  r   rW  r   rQ    s>   


zSpePlugin._metadata_pre_v3c                 C   s0   |  tjd}| j|d  | j }d|iS )zExtract XML metadata from SPE v3 files

        Returns
        -------
        dict with key `"__xml"`, whose value is the XML metadata
        r  r   __xml)r2  r   r   r1  r7  rK  )r   r  xmlr   r   r   rR  M  s   
zSpePlugin._metadata_post_v3c                 C   s:   |t u rt| jg| jR | j| jddS t| j| jddS )a  Standardized ndimage metadata.

        Parameters
        ----------
        index : int
            If the index is an integer, select the index-th frame and return
            its properties. If index is an Ellipsis (...), return the
            properties of all frames in the file stacked along a new batch
            dimension.

        Returns
        -------
        properties : ImageProperties
            A dataclass filled with standardized image metadata.
        T)shaper   n_imagesis_batchF)rl  r   rn  )rD  r   r6  r5  r4  )r   rA  r   r   r   
propertiesZ  s   zSpePlugin.propertiesr  c           	   	      s   i }t  fdd}| D ]`\}}| j|d  t|dk r#dn|d }t j| j|d |d}|jjdkrV|t	j
vrVz||}W n tyU   td	| d
 Y nw z| }W n tyj   t |}Y nw |||< q|S )a  Get information from SPE file header

        Parameters
        ----------
        spec
            Maps header entry name to its location, data type description and
            optionally number of entries. See :py:attr:`Spec.basic` and
            :py:attr:`Spec.metadata`.
        char_encoding
            String character encoding

        Returns
        -------
        Dict mapping header entry name to its value
        c                    s
   |   S r   )r  r   r  r   r   r     r   z)SpePlugin._parse_header.<locals>.<lambda>r   rv   ru   r   rB  SzFailed to decode "z3" metadata string. Check `char_encoding` parameter.)r   	vectorizer   r1  r7  rc  rF  r   kindr   r   r   r   r   itemr   squeeze)	r   r  r  retr  r  spcntr  r   rp  r   r2  t  s*   

zSpePlugin._parse_header)TNN).Tr  T).)r}   r~   r   r   rd  r	   r   r   r   r   ndarrayrK  r   rN  r   r   r   rQ  rR  r   ro  r   r   r2  r&  r   r   r   r   r'    sV    P%

 UF

r'  ar   c           	      C   sd   g }| g d } | D ]%\}}}}}}t |t |gt |t |gt |t |gd}|| q
|S )a\  Convert the `ROIs` structured arrays to :py:class:`dict`

    Parameters
    ----------
    a
        Structured array containing ROI data

    Returns
    -------
    One dict per ROI. Keys are "top_left", "bottom_right", and "bin",
    values are tuples whose first element is the x axis value and the
    second element is the y axis value.
    )r!   r$   r"   r%   r#   r&   )top_leftbottom_rightbin)r   rb  )	rz  	dict_listsxsyexeygxgyroi_dictr   r   r   ra    s   ra  )#r   r   loggingr8  typingr   r   r   r   r   r   r	   r
   r   r   r   numpyr   core.requestr   r   r   core.v3_plugin_apir   r   	getLoggerr}   r  r   r   r'  ry  r   r   ra  r   r   r   r   <module>   s&   #0
  r   (s