Metadata-Version: 2.1
Name: nds2utils
Version: 0.0.2
Summary: nds2 utilities for reading LIGO data quickly and easily
Home-page: https://git.ligo.org/craig-cahillane/nds2utils
Author: Craig Cahillane
Author-email: ccahilla@caltech.edu
License: UNKNOWN
Description: # nds2utils
        
        nds2utils is a user interface for the python nds2 client.  
        nds2 error messages and data structures can be hard to parse. 
        nds2utils provides helper functions, defaults, warnings, and error messages for users trying to get ligo data with python. 
        
        # Installation
        
        If you don't already have numpy , scipy, nds2-client, and python-nds2-client, this library requires them.
        You can either conda install or pip install
        ```
        conda install numpy scipy nds2-client python-nds2-client
        ```
        ```
        pip install numpy scipy nds2-client python-nds2-client
        ```
        Tested versions at the time of this publishing:
        python              3.7.3
        numpy               1.17.0 
        scipy               1.3.1
        nds2-client         0.16.3
        python-nds2-client  0.16.4
        
        You can install nds2utils using `pip` at https://pypi.org/project/nds2utils/ 
        ```
        pip install nds2utils
        ```
        
        # Quick Start
        
        # Slow Start
        
        Open an ipython terminal, and import the dataUtils library by running
        ```python
        import nds2utils
        from nds2utils.dataUtils import *
        ```
        
        You can't remember the exact name for the calibrated DARM channel you want, so you run
        ```python
        find_channels('H1:CAL*')
        ```
        
        You see the channel you want in the output, `H1:CAL-DELTAL_EXTERNAL_DQ`.
        
        You want to look at the DARM and intensity noise witness channel amplitude spectral density and transfer function at the time there was excess intensity noise at LIGO Hanford.  
        You happen to know the gps times you want to look at.  
        You rerun `find_channels('H1:PSL-ISS_SECONDLOOP*DQ')` and find the out of loop intensity noise witness channel, `H1:PSL-ISS_SECONDLOOP_RIN_OUTER_OUT_DQ`: 
        ```python
        channels = np.array(['H1:CAL-DELTAL_EXTERNAL_DQ', 'H1:PSL-ISS_SECONDLOOP_RIN_OUTER_OUT_DQ'])
        gps_start = 1256805122
        duration = 100 # seconds
        gps_stop = gps_start + duration
        binwidth = 1  # Hz, frequency bin spacing for the ASDs and TFs.
        overlap = 0.5 # fraction between 0 and 1.  overlap ratio for the data window. 
        
        # Get time-series of data and sampling frequency,
        # and calculate PSDs, ASDs, CSDs, and TFs between all channels
        # stored in a dictionary with channel names as keys, and dictionaries for values.
        dataDict = getCSDs(channels, gps_start, gps_stop, binwidth, overlap)  
        ```
        
        `dataDict` is a dictionary of dictionaries.
        The top level dictionary uses channel names as keys, and returns values which are dictionaries containing the data relevant to the channel key.
        You define a second-level dictionary, `darmDict`, to look only at the darm dictionary:
        ```python
        print(darmDict.keys())
        
        darmDict = dataDict['H1:CAL-DELTAL_EXTERNAL_DQ']
        
        print(darmDict.keys())
        ```
        
        `darmDict` contains the following keys:
        
        Raw data keys:
        - `'data'`     = the raw data from the channel
        - `'fs'`       = sampling frequency of the data
        - `'gpsStart'` = gps time representing the first data point acquired
        - `'duration'` = time length of data acquired
        
        PSD data keys:
        - `'averages'` = int.   number of averages for the power spectral density calculation
        - `'binwidth'` = float. Hz, frequency bin spacing for the ASDs and TFs
        - `'overlap'`  = float. fraction between 0 and 1.  overlap ratio for the data window.
        - `'fftLen'`   = float. length in seconds for the FFTs. Used in scipy.welch() PSD calculation.
        - `'nperseg'`  = int.   number of samples per FFT segment.
        - `'ff'`       = array. frequency vector for this channels ASDs and PSDs
        - `'PSD'`      = array. power spectral density in units^2/Hz
        - `'ASD'`      = array. amplitude spectral density in units/rtHz
        - `'df'`       = float. Hz. delta frequency vector, should be the same as binwidth. 
        
        CSD and TF data keys: (names of all other channels, in this case, `'ISS_SECONDLOOP_RIN_OUTER_OUT_DQ'`:
        - `'H1:PSL-ISS_SECONDLOOP_RIN_OUTER_OUT_DQ'` = dictionary containing CSD, TF, and coherence info.
        
        We make another definition of the third level dictionary to get CSD and TF info:
        ```python
        iss2darmDict = dataDict['H1:CAL-DELTAL_EXTERNAL_DQ']['H1:PSL-ISS_SECONDLOOP_RIN_OUTER_OUT_DQ']
        print(iss2darmDict.keys())
        ```
        `iss2darmDict` contains the following keys:
        - `'ff'`       = array. frequency vector for these two channels CSDs, TFs, and coherences 
        - `'CSD'`      = array. cross spectral density in units $`\mathrm{unit_a} * \mathrm{unit_b}/\mathrm{Hz}`$
        - `'TF'`       = array. transfer function in $`\mathrm{unit_b} / \mathrm{unit_b}`$
        - `'coh'`      = array. power coherence, unitless $` \gamma^2 = |\mathrm{CSD}_{AB}|^2 / (\mathrm{PSD}_A * \mathrm{PSD}_B) `$
        
        The convention for the cross spectral density: The first channel is the complex conjugated one. 
        
        - `dataDict[chanB][chanA]['CSD']` = $`\mathrm{CSD}_{AB}`$ = $`\langle{b^*}\rvert{a}\rangle`$
        
        The convention for the transfer function: chanB is the first channel in the dataDict, chanA is the second:
         
        - `dataDict[chanB][chanA]['TF']` = H(f) = $`\frac{\mathrm{CSD}_{AB}}{\mathrm{PSD}_{A}}`$ = $`\frac{\langle{a^*}\rvert{b}\rangle}{\langle{a^2}\rangle}`$ 
        
        The convention for the coherence: coherence is the power coherence:
         
        - `dataDict[chanB][chanA]['coh']` = $`\gamma^2 = \frac{|\langle{a^*}\rvert{b}\rangle|^2}{\langle{a^2}\rangle \langle{b^2}\rangle}`$
        
        # Features
        
        Quick and easy data acquisition using nds2. `acquireData()`
        Acquisition of data in real-time `stitchRealTimeData()`
        Automatic computation of power spectral densities, cross spectral densities, transfer functions, and coherence. 'getPSDs(), getCSDs()'
        Quick plotting of your data using plotUtils
        
        Coming soon: Examples. Tons of examples.  If in doubt right now, look in the docstrings, some already have nice examples. 
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
