³ò
u\Kc        	   @   sS  d  Z  d d k Z d d k Z d d k Z d d k Z d d k Z e i Z d e f d „  ƒ  YZ	 d e
 f d „  ƒ  YZ d e f d „  ƒ  YZ e d	 d d „ Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e
 f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s  
nmrfit.py

Fit NMR spectra

SpectrumModel - base class for all fit models
FilteredStep - models a spectrum of a step function passed through
a high-pass filter

FitError - exception, raised when a fit diverges

12 September 2008, Lev, based on Michael's stunning code
iÿÿÿÿNt   FitErrorc           B   s#   e  Z d  Z d d „ Z d „  Z RS(   sm   
    This exception is raised when a fit diverged
    'self.fit', if not None, points to the fit results
    c         C   s   | |  _  d  S(   N(   t   fit(   t   selfR   (    (    s   c:\py\lib\nmrfit.pyt   __init__)   s    c         C   s   d S(   Ns	   Fit Error(    (   R   (    (    s   c:\py\lib\nmrfit.pyt   __repr__,   s    N(   t   __name__t
   __module__t   __doc__t   NoneR   R   (    (    (    s   c:\py\lib\nmrfit.pyR    $   s   t   SpectrumModelc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s8   
    A base class for models used to fit spetra    
    c         C   s9   t  | t i ƒ o | i } n t i | |  i | ƒ ƒ S(   s¾   
        Construct an nmr.Spectrum representation of the fit at at given
        frequencies. 'f' is expected to be either an array of frequencies
        or an nmr.Spectrum object.
        (   t
   isinstancet   nmrt   Spectrumt   ft	   calculate(   R   R   (    (    s   c:\py\lib\nmrfit.pyt   model3   s    c         C   s   | |  i  | ƒ S(   sj   
        Return a difference between an NMR.Spectrum object 'spectrum' and
        the fit model.
        (   R   (   R   t   spectrum(    (    s   c:\py\lib\nmrfit.pyt   subtract=   s    c         C   s   t  i t | ƒ ƒ S(   s§   
        This function is to be overriden in child classes. It returns an array
        of frequency domain complex amplitudes for given array of frequencies.
        (   t   numpyt   zerost   len(   R   R   (    (    s   c:\py\lib\nmrfit.pyR   D   s    (   R   R   R   R   R   R   (    (    (    s   c:\py\lib\nmrfit.pyR	   .   s   	
	t   FilteredStepc           B   sM   e  Z d  Z d „  Z d „  Z e d d „ ƒ Z e e d „ ƒ Z	 d „  Z
 RS(   s  
    This model describes a step function going through a high-pass filter.
    The model is:
    
    w(f) = B/(f1 + i*f)
    
    where B is the step amplitude, f1 is the filter -3dB frequency
    and i is the imaginary unit. The fit assumes B to be real.
    c         C   s   | |  _  | |  _ | |  _ d  S(   N(   t   Bt   f1t   fit_f1(   R   R   R   R   (    (    s   c:\py\lib\nmrfit.pyR   V   s    		c         C   s   |  i  |  i d | S(   Ny              ð?(   R   R   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   [   s    c         C   s~   | d j o1 t i |  i |  i ƒ  |  i ƒ  ƒ } t } n t } t i | |  i ƒ  |  i |  i ƒ  ƒ } t | | | ƒ S(   sŠ   
        Fit a spectrum to a FilteredStep. If filter cutoff frequency 'f1' is
        not specified, it is inferred from the fit.
        N(	   R   R   t   meanR   t   ret   imt   Truet   FalseR   (   R   R   R   R   (    (    s   c:\py\lib\nmrfit.pyR   ]   s    '
*c         C   s3   t  i |  i d d d d ƒ d | o d n d ƒS(   sk   
        Take care of transient in the ULT Run 20 Lowfield NMR due to a filtered
        FLL reset
        t   fminiô  t   fmaxg     jø@R   iÐ  i¤  (   R   R   t   frange(   R   t   usePXI(    (    s   c:\py\lib\nmrfit.pyt
   fitRun20LFm   s    c         C   s   d |  i  |  i f S(   Ns   FilteredStep(f1=%g, B=%g)(   R   R   (   R   (    (    s   c:\py\lib\nmrfit.pyR   u   s    N(   R   R   R   R   R   t   staticmethodR   R   R   R"   R   (    (    (    s   c:\py\lib\nmrfit.pyR   K   s   			giUMuÿ>i   i   c         C   sO   |  i  | ƒ i d | ƒ i d ƒ i d | ƒ } t i | | ƒ } | i | ƒ S(   sµ   
    Take care of mismatch between the start and the end of the data 
    and subtract eddy current transient in the ULT Run 20 Lowfield NMR
    
    Return a modified spectrum
    i    i   t   Npad(   t   periodt   ranget   subtract_linearbgt   fftR   R"   R   (   t   traceR!   t   truncateR$   R   t	   transient(    (    s   c:\py\lib\nmrfit.pyt   distilRun20LFw   s    0t
   Lorentzianc           B   s‰   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z d „  Z RS(   sµ  
    This model describes a phase-rich Lorentzian:
    
    w(f) = 1/2 * A * T2 * exp(i*phi) / (1 + 2*pi*i*(f-f0)*T2)

    f0 - resonance frequency
    A - amplitude
    T2 - relaxation time
    phi - phase
    
    w(f) is a Fourier Transform of:
    
    u(t) = A * cos(2*pi*f0 * t + phase) * exp(-t / T2) for t >= 0, 0 for t < 0
    
    Parameters derived from f0, A, T2 and phi are available as phase_deg(), linewidth() and Q()
    c         C   sR   | d j  o | } | t  7} n | |  _ | |  _ | |  _ | d t  |  _ d  S(   Ni    i   (   t   pit   f0t   At   T2t   phi(   R   R/   R0   R1   R2   (    (    s   c:\py\lib\nmrfit.pyR   •   s    			c         C   s%   t  i |  i |  i |  i |  i | ƒ S(   N(   R-   t   lR/   R0   R1   R2   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   Ÿ   s    c         C   s5   d | | t  i d | ƒ d d t | |  | S(   sä   
        For a frequency or an array of frequencies 'f' return a lorentzian
        defined by:
            f0  - resonance frequency
            A   - amplitude
            T2  - relaxation time
            phi - phase
        g      à?y              ð?i   y               @(   R   t   expR.   (   R/   R0   R1   R2   R   (    (    s   c:\py\lib\nmrfit.pyR3   ¡   s    
c      	   C   s³   |  i  ƒ  \ } } t i | ƒ d t } |  i ƒ  t | ƒ d d } |  i | t | ƒ j d } d d t t | | ƒ } d t | ƒ | } t d | d | d | d | ƒ S(   sF   
        Make an initial guess for Lorentzian fit parameters.
        i   i    i   R/   R0   R1   R2   (   t   findpeakt   flibt   phaseR.   t   absR   t   minR-   (   R   R/   t   peakR2   t   Kt   f_halfR1   R0   (    (    s   c:\py\lib\nmrfit.pyt   guess­   s    c         C   s5   |  \ } } } } t  | t i | | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   R-   R3   (   t   paramR   t   wR/   R0   R1   R2   (    (    s   c:\py\lib\nmrfit.pyt	   residualsÂ   s    c      
   C   sÍ   t  i |  ƒ } t i i t  i | i | i | i | i	 g d |  i
 |  i f d d d t d ƒ ƒ} t  d | d d d | d d	 d
 | d d d | d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d  S(   Nt   argst   xtolgê-™—q=t   maxfevg     jø@R/   i    R0   i   R1   i   R2   i   (   R-   R=   t   scipyt   optimizet   leastsqR@   R/   R0   R1   R2   R   R?   t   intR    (   R   t   gt   resR   (    (    s   c:\py\lib\nmrfit.pyR   Ê   s    TAc         C   s   |  i  d t S(   s   phase in degreesi´   (   R2   R.   (   R   (    (    s   c:\py\lib\nmrfit.pyt	   phase_degÔ   s    c         C   s   t  |  i |  i S(   s   quality factor of resonance(   R.   R/   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyt   QÕ   s    c         C   s   d t  |  i S(   t	   linewidthi   (   R.   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRL   Ö   s    c         C   s#   d |  i  |  i |  i |  i ƒ  f S(   Ns:   Lorentzian(f0 = %.2f, A = %g, T2 = %g, phase = %g degrees)(   R/   R0   R1   RJ   (   R   (    (    s   c:\py\lib\nmrfit.pyR   ×   s    c         C   s    t  |  i d |  i |  i d ƒ S(   s³   
        Return a normalised Lorentzian with a peak height of 1 and zero phase.
        This is to adjust phases of signals aquired with
        tuned sensors/amplifiers.
        i   i    (   R-   R/   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyt	   normaliseÙ   s    (   R   R   R   R   R   R#   R3   R=   R@   R   RJ   RK   RL   R   RM   (    (    (    s   c:\py\lib\nmrfit.pyR-   ƒ   s   	
	
				t   ProperLorentzianc           B   s€   e  Z d  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z RS(   s  
    This model describes a phase-rich Lorentzian with a peak at negative frequencies:
    
    w(f) = 1/2 * A * T2 * exp(i*phi) / (1 + 2*pi*i*(f-f0)*T2) + 1/2 * A * T2 * exp(-i*phi) / (1 + 2*pi*i*(f+f0)*T2)

    f0 - resonance frequency
    A - amplitude
    T2 - relaxation time
    phi - phase
    
    w(f) is a Fourier Transform of:
    
    u(t) = A * cos(2*pi*f0 * t + phase) * exp(-t / T2) for t >= 0, 0 for t < 0
    
    Parameters derived from f0, A, T2 and phi are available as phase_deg(), linewidth() and Q()
    c         C   s%   t  i |  i |  i |  i |  i | ƒ S(   N(   RN   R3   R/   R0   R1   R2   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   ó   s    c         C   sj   d | | t  i d | ƒ d d t | |  | d | | t  i d | ƒ d d t | |  | S(   sä   
        For a frequency or an array of frequencies 'f' return a lorentzian
        defined by:
            f0  - resonance frequency
            A   - amplitude
            T2  - relaxation time
            phi - phase
        g      à?y              ð?i   y               @y              ð¿(   R   R4   R.   (   R/   R0   R1   R2   R   (    (    s   c:\py\lib\nmrfit.pyR3   õ   s    
4c      	   C   s³   |  i  ƒ  \ } } t i | ƒ d t } |  i ƒ  t | ƒ d d } |  i | t | ƒ j d } d d t t | | ƒ } d t | ƒ | } t d | d | d | d | ƒ S(   sF   
        Make an initial guess for Lorentzian fit parameters.
        i   i    i   R/   R0   R1   R2   (   R5   R6   R7   R.   R8   R   R9   RN   (   R   R/   R:   R2   R;   R<   R1   R0   (    (    s   c:\py\lib\nmrfit.pyR=     s    c         C   s5   |  \ } } } } t  | t i | | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   RN   R3   (   R>   R   R?   R/   R0   R1   R2   (    (    s   c:\py\lib\nmrfit.pyR@     s    c      
   C   sÍ   t  i |  ƒ } t i i t  i | i | i | i | i	 g d |  i
 |  i f d d d t d ƒ ƒ} t  d | d d d | d d	 d
 | d d d | d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d  S(   NRA   RB   gê-™—q=RC   g     jø@R/   i    R0   i   R1   i   R2   i   (   RN   R=   RD   RE   RF   R@   R/   R0   R1   R2   R   R?   RG   R    (   R   RH   RI   R   (    (    s   c:\py\lib\nmrfit.pyR     s    TAc         C   s   |  i  d t S(   s   phase in degreesi´   (   R2   R.   (   R   (    (    s   c:\py\lib\nmrfit.pyRJ   )  s    c         C   s   t  |  i |  i S(   s   quality factor of resonance(   R.   R/   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRK   *  s    c         C   s   d t  |  i S(   RL   i   (   R.   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRL   +  s    c         C   s#   d |  i  |  i |  i |  i ƒ  f S(   Ns:   Lorentzian(f0 = %.2f, A = %g, T2 = %g, phase = %g degrees)(   R/   R0   R1   RJ   (   R   (    (    s   c:\py\lib\nmrfit.pyR   ,  s    c         C   s    t  |  i d |  i |  i d ƒ S(   s³   
        Return a normalised Lorentzian with a peak height of 1 and zero phase.
        This is to adjust phases of signals aquired with
        tuned sensors/amplifiers.
        i   i    (   RN   R/   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRM   .  s    (   R   R   R   R   R#   R3   R=   R@   R   RJ   RK   RL   R   RM   (    (    (    s   c:\py\lib\nmrfit.pyRN   á   s   	
				t   PhaselessLorentzianc           B   sw   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 d „  Z
 d „  Z d	 „  Z RS(
   s  
    This model describes a phase-poor Lorentzian:
    
    |w(f)| = 1/2 * A * T2 / (1 + 2*pi*i*(f-f0)*T2)

    f0 - resonance frequency
    A - amplitude
    T2 - relaxation time
        
    Parameters derived from f0, A, T2 are available as linewidth() and Q()
    c         C   s7   | d j  o | } n | |  _  | |  _ | |  _ d  S(   Ni    (   R/   R0   R1   (   R   R/   R0   R1   (    (    s   c:\py\lib\nmrfit.pyR   D  s
    		c         C   s   t  i |  i |  i |  i | ƒ S(   N(   RO   R3   R/   R0   R1   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   L  s    c         C   s-   d | | t  i d d t | |  | ƒ S(   sÌ   
        For a frequency or an array of frequencies 'f' return a lorentzian
        defined by:
            f0  - resonance frequency
            A   - amplitude
            T2  - relaxation time
        g      à?i   y               @(   R   R8   R.   (   R/   R0   R1   R   (    (    s   c:\py\lib\nmrfit.pyR3   N  s    	c         C   s–   |  i  ƒ  \ } } |  i ƒ  t | ƒ d d } |  i | t | ƒ j d } d d t t | | ƒ } d t | ƒ | } t d | d | d | ƒ S(   sF   
        Make an initial guess for Lorentzian fit parameters.
        i   i    i   R/   R0   R1   (   R5   R8   R   R9   R.   RO   (   R   R/   R:   R;   R<   R1   R0   (    (    s   c:\py\lib\nmrfit.pyR=   Y  s    c         C   s/   |  \ } } } t  | t i | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   RO   R3   (   R>   R   R?   R/   R0   R1   (    (    s   c:\py\lib\nmrfit.pyR@   k  s    c      
   C   s¿   t  i |  ƒ } t i i t  i | i | i | i g d |  i	 t
 |  i ƒ f d d d t d ƒ ƒ} t  d | d d d | d d	 d
 | d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d  S(   NRA   RB   gê-™—q=RC   g     jø@R/   i    R0   i   R1   i   (   RO   R=   RD   RE   RF   R@   R/   R0   R1   R   R8   R?   RG   R    (   R   RH   RI   R   (    (    s   c:\py\lib\nmrfit.pyR   s  s    T3c         C   s   t  |  i |  i S(   s   quality factor of resonance(   R.   R/   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRK   }  s    c         C   s   d t  |  i S(   RL   i   (   R.   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyRL   ~  s    c         C   s   d |  i  |  i |  i f S(   Ns/   PhaselessLorentzian(f0 = %.2f, A = %g, T2 = %g)(   R/   R0   R1   (   R   (    (    s   c:\py\lib\nmrfit.pyR     s    (   R   R   R   R   R   R#   R3   R=   R@   R   RK   RL   R   (    (    (    s   c:\py\lib\nmrfit.pyRO   7  s   		
		t   Burstc           B   sn   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 d „  Z
 d „  Z RS(	   sp  
    This model describes a burst of sinewave:

    w(f) = A * exp(i*phi) / 2 * (1 - exp(-2i*pi*(f-f0)*T)) / (2i*pi*(f-f0))
    w(f0) = A * exp(i*phi) * T / 2

    f0 - resonance frequency
    A - amplitude
    T - burst length
    phi - phase
    
    w(f) is a Fourier Transform of:
    
    u(t) = A * cos(2*pi*f0 * t + phase) for 0 <= t <= T, 0 otherwise.    
    c         C   s0   | |  _  | |  _ | |  _ | d t |  _ d  S(   Ni   (   R/   R0   t   TR.   R2   (   R   R/   R0   RQ   R2   (    (    s   c:\py\lib\nmrfit.pyR   ’  s    			c         C   s%   t  i |  i |  i |  i |  i | ƒ S(   N(   RP   t   bR/   R0   RQ   R2   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   ˜  s    c         C   sy   d | t  i d | ƒ d t  i d t | |  | ƒ d t | |  } d | t  i d | ƒ | | | |  j <| S(   sÛ   
        For a frequency or an array of frequencies 'f' return a lorentzian
        defined by:
            f0  - resonance frequency
            A   - amplitude
            T   - length
            phi - phase
        g      à?y              ð?i   y               Ày               @(   R   R4   R.   (   R/   R0   RQ   R2   R   t   s(    (    s   c:\py\lib\nmrfit.pyRR   š  s    
L)c      	   C   s\   |  i  ƒ  \ } } t i | ƒ d t } d t | ƒ | } t d | d | d | d | ƒ S(   sF   
        Make an initial guess for Lorentzian fit parameters.
        i   R/   R0   RQ   R2   (   R5   R6   R7   R.   R8   RP   (   R   RQ   R/   R:   R2   R0   (    (    s   c:\py\lib\nmrfit.pyR=   ¨  s    c         C   s2   |  \ } } } t  | t i | | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   RP   RR   (   R>   R   R?   RQ   R/   R0   R2   (    (    s   c:\py\lib\nmrfit.pyR@   ·  s    c      
   C   sÅ   t  i |  | ƒ } t i i t  i | i | i | i g d |  i	 |  i
 | f d d d t d ƒ ƒ} t  d | d d d | d d	 d
 | d | d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d  S(   NRA   RB   gê-™—q=RC   g     jø@R/   i    R0   i   RQ   R2   i   (   RP   R=   RD   RE   RF   R@   R/   R0   R2   R   R?   RG   R    (   R   RQ   RH   RI   R   (    (    s   c:\py\lib\nmrfit.pyR   ¿  s    Q9c         C   s   |  i  d t S(   s   phase in degreesi´   (   R2   R.   (   R   (    (    s   c:\py\lib\nmrfit.pyRJ   É  s    c         C   s#   d |  i  |  i |  i |  i ƒ  f S(   Ns4   Burst(f0 = %.2f, A = %g, T = %g, phase = %g degrees)(   R/   R0   RQ   RJ   (   R   (    (    s   c:\py\lib\nmrfit.pyR   Ê  s    (   R   R   R   R   R   R#   RR   R=   R@   R   RJ   R   (    (    (    s   c:\py\lib\nmrfit.pyRP     s   		
	t   DoubleLorentzianc           B   sV   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z	 RS(   sÅ   
    This model describes a pair of phase-rich Lorentzians

    a.f0,  b.f0  - resonance frequency
    a.A,   b.A   - amplitude
    a.T2,  b.T2  - relaxation time
    a.phi, b.phi - phase
    
    c         C   s   | |  _  | |  _ d  S(   N(   t   aRR   (   R   RU   RR   (    (    s   c:\py\lib\nmrfit.pyR   ×  s    	c         C   s    |  i  i | ƒ |  i i | ƒ S(   N(   RU   R   RR   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR   Û  s    c         C   sZ   |  \ } } } } } } }	 }
 t  | t i | | | | | ƒ t i | | |	 |
 | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   R-   R3   (   R>   R   R?   t   f0at   Aat   T2at   phiat   f0bt   Abt   T2bt   phib(    (    s   c:\py\lib\nmrfit.pyR@   Ý  s    c      
   C   s„  t  | t ƒ p t i |  i | Œ  ƒ } n t  | t ƒ p t i |  i | Œ  ƒ } n | i | i | i | i | i | i | i | i g } t i	 i
 t i | d |  i |  i f d d d t d ƒ ƒ} t d | d d d | d d	 d
 | d d d | d d ƒ } t d | d d d | d d d
 | d d d | d d ƒ } t | | ƒ } | d	 d	 j o | Sn t | ƒ ‚ d S(   s6  
        fit a double lorentzian to the 'spectrum'.
        'guess_a' and 'guess_b' are either initial guesses
        for the lorentzians (objects of 'LorentzianFit' type)
        or tuples containing the frequency ranges to run
        the single Lorentzian fits on in order to obtain these guesses.
        RA   RB   gê-™—q=RC   g     jø@R/   i    R0   i   R1   i   R2   i   i   i   i   i   N(   R
   R-   R   R    R/   R0   R1   R2   RD   RE   RF   RT   R@   R   R?   RG   R    (   R   t   guess_at   guess_bR=   RI   RU   RR   R   (    (    s   c:\py\lib\nmrfit.pyR   å  s    	6<AAc         C   s+   t  i |  |  i ƒ  | g | |  i ƒ  g ƒ S(   s×   
        fit a double lorentzian to the 'spectrum'.
        Initial guesses are obtained by fitting
        single Lorentzians on parts of the spectrum below (a) and above (b)
        the frequency 'f_cut'.
        (   RT   R   R   R   (   R   t   f_cut(    (    s   c:\py\lib\nmrfit.pyt   cut_and_fitþ  s    c         C   s   d |  i  |  i f S(   Ns   %s, %s(   RU   RR   (   R   (    (    s   c:\py\lib\nmrfit.pyR     s    (
   R   R   R   R   R   R#   R@   R   Ra   R   (    (    (    s   c:\py\lib\nmrfit.pyRT   Ì  s   			
t   NoisePowerLorentzianc           B   sk   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e e d „ ƒ Z e d „  ƒ Z	 e e d „ ƒ Z
 d „  Z RS(   sú   
    This model describes a Lorentzian peak in the noise power:
    
    S(f) = Sp / (1 + {2*Q*(1 - f/f0)}^2) + S0 

    Sp - peak noise level
    f0 - resonance frequency
    Q - quality factor of the resonance
    S0 - offresonance noise level
    c         C   sL   t  i | ƒ i ƒ  |  _ t  i | ƒ i ƒ  |  _ t | ƒ |  _ | |  _ d  S(   N(   R   t   realR   t   SpR/   R8   RK   t   S0(   R   Rd   R/   RK   Re   (    (    s   c:\py\lib\nmrfit.pyR     s    c         C   s%   t  i |  i |  i |  i |  i | ƒ S(   N(   Rb   t   plRd   R/   RK   Re   (   R   R   (    (    s   c:\py\lib\nmrfit.pyR     s    c         C   s$   |  d d | d | | d | S(   s  
        For a frequency or an array of frequencies 'f' return a power lorentzian
        defined by:
            Sp - peak noise level
            f0 - resonance frequency
            Q - quality factor of the resonance
            S0 - offresonance noise level
        i   i   (    (   Rd   R/   RK   Re   R   (    (    s   c:\py\lib\nmrfit.pyRf     s    
c      	   C   s»   | o1 t  i |  i d |  i d f ƒ } |  | }  n d } |  i ƒ  \ } } t |  i | d ƒ } |  i | t | ƒ j d } d | t | | ƒ } t d | d | d | d | ƒ S(	   sR   
        Make an initial guess for noise power Lorentzian fit parameters.
        i    iÿÿÿÿg        i   R/   RK   Rd   Re   (   R   R   R?   R5   R8   R   R9   Rb   (   R   t   allowOffLevelRe   R/   Rd   R;   R<   RK   (    (    s   c:\py\lib\nmrfit.pyR=   +  s    #c         C   sa   t  |  ƒ d j o |  \ } } } d } n |  \ } } } } t | t i | | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        i   g        (   R   R8   Rb   Rf   (   R>   R   R?   Rd   R/   RK   Re   (    (    s   c:\py\lib\nmrfit.pyR@   >  s
    
c      
   C   s:  t  i |  | ƒ } | o | i | i | i | i g n | i | i | i g } t i i t  i	 | d |  i
 |  i f d d d t d ƒ ƒ} | oE t  d | d d d | d d	 d
 | d d d | d d ƒ } n: t  d | d d d | d d	 d
 | d d d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d S(   sš   
        Fit a (noise) power Lorentzian to the data.
        
        allowOffLevel (True/False) determines if off-resonance spectrum is non-zero
        RA   RB   gê-™—q=RC   g     jø@Rd   i    R/   i   RK   i   Re   i   g        N(   Rb   R=   Rd   R/   RK   Re   RD   RE   RF   R@   R   R?   RG   R    (   R   Rg   RH   RI   R3   (    (    s   c:\py\lib\nmrfit.pyR   J  s    ><E9c         C   s    d |  i  |  i |  i |  i f S(   Ns9   NoisePowerLorentzian(Sp = %g, f0 = %.2f, Q = %g, S0 = %g)(   Rd   R/   RK   Re   (   R   (    (    s   c:\py\lib\nmrfit.pyR   ]  s    (   R   R   R   R   R   R#   Rf   R   R=   R@   R   R   (    (    (    s   c:\py\lib\nmrfit.pyRb     s   
		t
   TraceModelc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sA   
    A base class for models used to fit time domain signals
    c         C   s<   t  | t i ƒ o | i ƒ  } n t i | |  i | ƒ ƒ S(   s»   
        Construct an nmr.Trace representation of the fit at at given
        frequencies. 't' is expected to be either an array of sampling times
        or an nmr.Trace object.
        (   R
   R   t   Tracet   tR   (   R   Rj   (    (    s   c:\py\lib\nmrfit.pyR   d  s    c         C   s   | |  i  | ƒ S(   sƒ   
        Return a difference between an NMR.Trace object 'trace' and
        the fit model. Subtrace the fit FROM the data
        (   R   (   R   R)   (    (    s   c:\py\lib\nmrfit.pyR   n  s    c         C   s   t  i t t ƒ ƒ S(   s†   
        This function is to be overriden in child classes. It returns an array
        of signal samples at given times 't'.
        (   R   R   R   R   (   R   Rj   (    (    s   c:\py\lib\nmrfit.pyR   u  s    (   R   R   R   R   R   R   (    (    (    s   c:\py\lib\nmrfit.pyRh   _  s   	
	t
   CosineWavec           B   sz   e  Z d  Z d „  Z e d „  ƒ Z d „  Z e d	 d	 d „ ƒ Z e d	 d	 d „ ƒ Z	 e d „  ƒ Z
 d „  Z d „  Z RS(
   s”   
    A cosine wave fit in time domain

    A - amplitude,
    f0 - frequency,
    phi - initial phase
    
    S(t) = A * cos(2*pi*f0*t + phi)

    c         C   s'   | |  _  | |  _ | d t |  _ d  S(   Ni   (   R/   R0   R.   R2   (   R   R/   R0   R2   (    (    s   c:\py\lib\nmrfit.pyR   ˆ  s    		c         C   s!   | t  i d t |  | | ƒ S(   Ni   (   R   t   cosR.   (   R/   R0   R2   Rj   (    (    s   c:\py\lib\nmrfit.pyR?     s    c         C   s   t  i |  i |  i |  i | ƒ S(   N(   Rk   R?   R/   R0   R2   (   R   Rj   (    (    s   c:\py\lib\nmrfit.pyR     s    c         C   sS   |  i  ƒ  i | | ƒ } t | i ƒ  t | i ƒ  ƒ |  i ƒ  t i | i ƒ  ƒ ƒ S(   sw   
        Make a guess. Optional arguments fmin and fmax restrict the frequency
        range for the sinewave.
        (	   R(   R    Rk   t   peakfR8   R:   t   timespanR6   R7   (   R)   R   R   R?   (    (    s   c:\py\lib\nmrfit.pyR=   ’  s    c      
   C   sÂ   t  i |  | | ƒ } t i i t  i | i | i | i g d |  i	 ƒ  |  i
 f d d d t d ƒ ƒ} t  d | d d d | d d	 d
 | d d ƒ } | d	 d	 j o | Sn t | ƒ ‚ d S(   s4   
        Fit a cosine wave through a trace.
        RA   RB   gê-™—q=RC   g     jø@R/   i    R0   i   R2   i   N(   Rk   R=   RD   RE   RF   R@   R/   R0   R2   Rj   RS   RG   R    (   R)   R   R   RH   RI   R   (    (    s   c:\py\lib\nmrfit.pyR   ›  s    Q3c         C   s/   |  \ } } } t  | t i | | | | ƒ ƒ S(   s1   
        Calculate residuals for the fit
        (   R8   Rk   R?   (   R>   R   R?   R/   R0   R2   (    (    s   c:\py\lib\nmrfit.pyR@   ¨  s    c         C   s   |  i  d t S(   s   phase in degreesi´   (   R2   R.   (   R   (    (    s   c:\py\lib\nmrfit.pyRJ   °  s    c         C   s   d |  i  |  i |  i ƒ  f S(   Ns1   CosineWave(f0 = %.2f, A = %g, phase = %g degrees)(   R/   R0   RJ   (   R   (    (    s   c:\py\lib\nmrfit.pyR   ±  s    N(   R   R   R   R   R#   R?   R   R   R=   R   R@   RJ   R   (    (    (    s   c:\py\lib\nmrfit.pyRk   }  s   
			i   (   R   R6   R   R   t   matht   scipy.optimizeRD   R.   t	   ExceptionR    t   objectR	   R   R   R,   R-   RN   RO   RP   RT   Rb   Rh   Rk   (    (    (    s   c:\py\lib\nmrfit.pys   <module>   s$   	
,^VJK?T