U
    ?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eje	ee e	e! f  d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                0   @   s  e Zd ZdZdddddddZd	d
eddddddg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/d0d1d2d3d4d5d6d7d8dd9d:d;d<dd=/Zd>Zeej	eej
eejeejeejd?Zd@dAdBdCdDdEdFdGdHdIdJdKgZdLdMdNgZdOgZdPS )Q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)i  r   i  )startxr   )endxr   )groupxr   )startyr   )endyr   )groupyr   
   )   r   )   r   )   r   )   r   )r   r   )r   r   )   r   )   r   )r%   r   )   z<10S)$   r   )(   r   ),   r   ).   r   )2   r   )4   r   )6   r   )8   r   ):   r   )<   r   )@   r   )B   r   )   <7S)   r:   )   r   )   r   )   r   )   r   )   r   )   r   )   z<80S   )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   )/NumROIROIsxDimDetyDimDet	VChipXdim	VChipYdimZcontroller_versionZlogic_outputZamp_high_cap_low_noisemodeexposure_secdateZdetector_tempZdetector_typeZst_diodeZ
delay_timeZshutter_controlabsorb_liveZabsorb_modecan_do_virtual_chipthreshold_min_liveZthreshold_min_valthreshold_max_liveZthreshold_max_val
time_localtime_utcZ
adc_offsetZadc_rateZadc_typeZadc_resolutionZadc_bit_adjustZgaincomments	geometricZ
sw_versionspare_4
XPrePixelsXPostPixels
YPrePixelsYPostPixelsZreadout_timer   typeZclockspeed_usreadout_modeZwindow_sizer   i  )r      r      r+   znew120 (Type II)zold120 (Type I)ZST130ZST121ZST138zDC131 (PentaMax)zST133 (MicroMax/Roper)zST135 (GPIB)ZVTCCDzST116 (GPIB)zOMA3 (GPIB)ZOMA4z
full framezframe transferkineticsrY   N)__name__
__module____qualname____doc__basicnpdtypemetadata
data_startZfloat32Zint32Zint16Zuint16Zuint32dtypescontrollersreadout_modes	no_decode rp   rp   E/var/www/html/venv/lib/python3.8/site-packages/imageio/plugins/spe.pyr   A   s   
D




	
r   c                       s  e Zd ZdZ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ededdeededdeededde	ededde
dededde	ededdeeddd d! edd"d#d! eded$d"eedd%d&d! eded'd$e
d(ededd fd)d!ededd'e
dededdeededd*e
d+ededdeeded*d$e
dededdeeded$d,e
dededde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
dd0d1eded2d3d4d! id5Zeee	 eeef d6d7d8Zeee	 eeef ee	ef d9 fd:d;Zee	e	eed<f d= fd>d?ZedDee	dA fdBdCZ  ZS )E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.
    r`   r   ra   r*   rC   r&      r+   	   r%         )u   JänJanFebu   MärMarAprZMaiMayJunJulAugSepZOktOctNovZDezDecstandardZTOCCSLrb   	arbitrary)ZSEQUZSETOZKINEZSEARc                   @   sl   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eeeege	f ee ddd	ZdS )
zSDTControlSpec.CommentDescz>Describe how to extract a metadata entry from a comment stringnslicecvtNscaler   r   r   r   c                 C   s   || _ || _|| _|| _d S Nr   )selfr   r   r   r   rp   rp   rq   __init__   s    z#SDTControlSpec.CommentDesc.__init__)rc   rd   re   rf   int__annotations__r   r   strr   r   floatr	   r   rp   rp   rp   rq   CommentDesc   s   
r   r8   D   F   r   r7   I   gư>r(      r)   c                 C   s   | dkS )NBrp   xrp   rp   rq   <lambda>      zSDTControlSpec.<lambda>    c                 C   s   | dkS )NErp   r   rp   rp   rq   r   	  r      !   c                 C   s   | dkS )NArp   r   rp   rp   rq   r     r      g?c                    s
    j |  S r   )sequence_typesr   	__class__rp   rq   r     r      gMbP?%   O   r0   7   )Zsdt_major_versionZsdt_minor_versionZsdt_controller_nameZexposure_timeZ
color_codeZdetection_channelsZbackground_subtractionZ	em_activeZem_gainZmodulation_activeZ
pixel_sizeZsequence_typegridZn_macroZdelay_macroZn_miniZ
delay_miniZn_microZdelay_microZ	n_subpicsZdelay_shutterZdelay_prebleachZbleach_timeZrecovery_timeZbleach_piezo_active"   #   c                 C   s   | dkS )Nzrp   r   rp   rp   rq   r     r   ))rC   r   )rC   r`   )rW   returnc                 C   s^   | d dd dkrdS z*t | d dd t | d dd fW S  tk
rX   Y dS X dS )	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.
        r*   r   L   ZCOMVER)r   N   P   N)r   
ValueError)rW   rp   rp   rq   get_comment_version"  s    *z"SDTControlSpec.get_comment_version)rW   versionr   c                    s>  i }t |d d D ]}z j|d |f }W n tk
rF   Y qY nX | D ]\}}z6|| |j |j }|jdk	r||j9 }|||< W qP tk
r } z"t	
d| d|  d||< W 5 d}~X Y qPX qPq| jkrd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
        r`   r   Nz-Failed to decode SDT-control metadata field `z`: z, c                 S   s   | d  d| d dS )Nr   .r`   02rp   r   rp   rp   rq   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)rW   r   Zsdt_mdminorZcmtnamespecveZsupported_verr   r   rp   rq   parse_comments6  s6    


 zSDTControlSpec.parse_commentsN)rP   timer   c              
      s   zb j | dd  }tt| dd |t| dd t|dd t|dd t|dd W S  tk
r } ztd| d W 5 d	}~X Y nX d	S )
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   rC   rt   r   r*   r&   z1Failed to decode date from SDT-control metadata: r   N)monthsr   r   r   loggerinfo)rP   r   monthr   r   rp   rq   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 }|r|| d< | d | d | d	 }z||| d
< | d	 W n t	k
r   t
d Y nX | 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.
        rW   c                 s   s   | ]}|d k V  qdS )r   Nrp   .0crp   rp   rq   	<genexpr>  s     z2SDTControlSpec.extract_metadata.<locals>.<genexpr>zSDT-control comments not found.NrP   rU   r   rY   Zmodulation_scriptzHFailed to decode SDT-control laser modulation script. Bad char_encoding?rV   rO   )r   anyr   debugr   popupdater   decodeUnicodeDecodeErrorr   r   )r   r   Zcomversdt_metadtZsp4r   rp   rq   extract_metadata  s,    






zSDTControlSpec.extract_metadata)r   )rc   rd   re   rf   r   r   r   r   r   r   r   r   staticmethodr
   r   r   r   r   r   r   r   r   r   r   __classcell__rp   rp   r   rq   rr      s   
  
 " 

2 rr   c                       s   e Zd Zdeeee ee dd fddZddee	j
dd	d
Zee	j
 dddZdeeeeeeef dddZeeeeef dddZeeef dddZdeedddZeeef eeeef dddZ  ZS )	SpePluginTN)requestcheck_filesizer   r   r   c              	      sz  t  | |jjtjkr"td|dk	r6tdt	 || _
|dk	rPtdt	 || _| j | _z| tjd}|d | _tj|d  | _|d |d	 f| _|d
 | _|rF|d dkr|d }n| jdtj | j }|tj }|| jd | jd  | jj  }|| jkrFtd| jj d| j d| d t|| j| _| jtj W n tk
rt   tdY nX dS )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   ra   r   r   r`   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   rN   Zio_moder   writer   r   r   DeprecationWarning_char_encoding	_sdt_metar   Zget_file_file_parse_headerr   rg   _file_header_verrl   _dtype_shape_lenseekosSEEK_ENDtellrk   itemsizefilenameminr   )r   r   r   r   r   r   Zdata_endliner   rp   rq   r     sJ    




 zSpePlugin.__init__.index)r   r   c                C   s   |t kr8tj}| jd | jd  | j }| jf| j}n~|dk rRtd| dnd|| jkrvtd| d| j dn@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   r`   zIndex `z` is smaller than 0.z5` exceeds the number of frames stored in this file (`z`).ri   count)Ellipsisr   rk   r   r   
IndexErrorr   r   r   r   rh   fromfileZreshape)r   r   read_offsetr   Z	out_shapedatarp   rp   rq   read  s&    
zSpePlugin.read)r   c                    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)r   )r   ir   rp   rq   r   1  s     z!SpePlugin.iter.<locals>.<genexpr>)r   r   r   rp   r   rq   iter)  s    zSpePlugin.iterr   )r   exclude_appliedr   sdt_controlr   c                 C   s>   | j dk r6| jdk	r| j}| jdk	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
        ra   N)r   r   r   _metadata_pre_v3_metadata_post_v3)r   r   r  r   r  rp   rp   rq   rj   3  s     M


zSpePlugin.metadata)r   r  r   c           	         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@ r|d |d@ r|d |d@ r|d | d<  d }d|  kr$ttjkr<n ntj|d   d< nd d<  d }d|  krjt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.

        rH   Nr`   rI   c                    s   g | ]}  |d qS r   r   r   kmrp   rq   
<listcomp>  s     z.SpePlugin._metadata_pre_v3.<locals>.<listcomp>)rJ   rK   Z	chip_sizec                    s   g | ]}  |d qS r   r  r  r	  rp   rq   r     s     )rL   rM   Zvirt_chip_sizec                    s   g | ]}  |d qS r   r  r  r	  rp   rq   r  !  s     )rZ   r\   Z
pre_pixelsc                    s   g | ]}  |d qS r   r  r  r	  rp   rq   r  "  s     )r[   r]   Zpost_pixelsc                 S   s   g | ]}t |qS rp   )r   r   rp   rp   rq   r  %  s     rW   rX   r   rotater   reverser*   flipr^   r_   )rQ   rR   rS   rT   )r   r   rj   r   roi_array_to_dictappendlenrm   rn   boolrr   r   )	r   r   r  nrgftrr  rp   r	  rq   r    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   Z__xml)r   r   rg   r   r   r   )r   r   xmlrp   rp   rq   r  M  s    
zSpePlugin._metadata_post_v3c                 C   s8   |t kr&t| jf| j| 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)shaperi   Zn_imagesis_batchF)r  ri   r  )r   r   r   r   r   )r   r   rp   rp   rq   
propertiesZ  s    zSpePlugin.properties)r   r   r   c           	   	      s   i }t  fdd}| D ]\}}| j|d  t|dk rFdn|d }t j| j|d |d}|jjdkr|t	j
krz||}W n& tk
r   td	| d
 Y nX z| }W n tk
r   t |}Y nX |||< 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   rp   rq   r     r   z)SpePlugin._parse_header.<locals>.<lambda>r   ra   r`   r   r   SzFailed to decode "z3" metadata string. Check `char_encoding` parameter.)rh   Z	vectorizer   r   r   r  r   ri   kindr   ro   r   r   r   itemr   Zsqueeze)	r   r   r   retr   r   spZcntr   rp   r  rq   r   t  s&    


zSpePlugin._parse_header)TNN).Tr   T).)rc   rd   re   r   r  r	   r   r   r   rh   ndarrayr   r   r  r   r   rj   r  r  r   r  r   r   r   r   rp   rp   r   rq   r     s>      P%    
 UF
 
r   )ar   c           	      C   sl   g }| ddddddg } | D ]J\}}}}}}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   r  )	r#  Z	dict_listsxZsyexZeyZgxgyZroi_dictrp   rp   rq   r    s    r  )#rf   r   loggingr   typingr   r   r   r   r   r   r	   r
   r   r   r   numpyrh   Zcore.requestr   r   r   Zcore.v3_plugin_apir   r   	getLoggerrc   r   r   rr   r   r"  r   r   r  rp   rp   rp   rq   <module>   s$   #0
  r   s