o
    <cct                     @   sj  d Z ddlmZ ddlZdejd< ddlZed ddlZddl	Z
ddlmZ ddlZddlZddlZddlmZ ddlmZ dd	lmZ d
Zdd Zde_de_de_dd Zde_dd ddD e_de_dd Zde_dd ddD e_de_G dd dej Z!d d! Z"ddl#Z#ddl$Z$dd"l%m&Z&m'Z' dd#l(T dd$l)m*Z* dd%lm+Z+ G d&d' d'Z,dS )(z0
File to handle linear fitting for Physics 50.

    )formsNz/tmpMPLCONFIGDIRAgg)render)gettext)ValidationError))datazplot data only)constantr	   )linearr
   )	quadraticr   c                 C   s   | d | S )Nr    )xbr   r   /var/www/djphys/igor/fitter.pymyconst"      r   z$y = b$)z$b$)   c                 C   s   ||  | S Nr   )r   mr   r   r   r   myline+   r   r   z$y = mx + b$c                 C      g | ]}d | d qS $r   .0r   r   r   r   
<listcomp>0       r   zm;b;)r   r   c                 C   s   |||   ||  |   S r   r   )r   ar   cr   r   r   myquad4   s   r    z$y = a x^2 + b x + c$c                 C   r   r   r   r   r   r   r   r   9   r   za;b;c)r   r   r   c                   @   sN   e Zd ZejddZejedZej	dddddd	Z
d
efddZdd ZdS )FitFormz0Upload a CSV file with columns x,y,y_uncertainty)	help_text)choices   r   TFz+optional key-value pairs to format the plot)
max_length
min_lengthstriprequiredr"   r   c                 C   s   | d}|d dkrttd| d dd| d| d	kr-ttd
| d ddzt|}W n   Y dS ttddd)z@
        Screen the column heads for appropriate format
        r      r   u   Imbalanced $ in “u   ”dollarscode{}u   Imbalanced braces in “bracesNz3The first row of the CSV file must hold axes labelslabels)countr   _float)selfr   dollar_signsvr   r   r   dollarJ   s"   
zFitForm.dollarc                 C   s  | j }|d }||d< |j d}|jd d|v rdnd}z	tj||d}W n   ttddd	|j	}t
|D ]\}}|td
tdfvrWttd| dd	q=|j\}	}
|
dk se|
dkrqttdt|
 dd	t|j |d< }|d d D ]}| | q|d |d< |d |d< |jd d df  |d< |jd d df  |d< z|jd d df  |d< W n   d |d< Y | }||d< d S )Nr   filezutf-8r   	,)sepz=Could not load data file; confirm that it is a valid CSV filer+   float64int64z+Column %d has one or more nonnumeric valuescolumnsr)      z+The CSV file must have 2 or 3 columns, not headerxlabelr   ylabelr   yyunc)cleaned_datar8   readdecodeseekpdread_csvr   r2   dtypes	enumeratenpdtypeshapestrlistr>   r7   ilocto_numpy)r4   cdr   file_contentsr;   dfrK   ndtrowscolsheadshr   r   r   clean`   sT   


zFitForm.cleanN)__name__
__module____qualname__r   	FileFieldr   ChoiceFieldfunction_choiceskind	CharFieldoptionsrP   r7   r]   r   r   r   r   r!   =   s    r!   c                 C   s  d\}}}| j dkrt| j| j}| r|j}|d |d |d }}}|d |d }	}
|d }td ttt	d	}|| }|rG|j
|jfng d f\}}t||||||d
}|d }i }|dD ]2}zdd |dD \}}W n   Y qbzt|}W n   zt|}W n   |}Y Y |||< qbz@|jd|	|
|d| t }|dd}|dd}|jj|d||d |d tjt| }|d }|d }W n+ ty } zt|}|d|d | d  |d }W Y d }~n	d }~ww nt }||||d}t!| d|S )N)NNNPOSTr   rC   rD   rA   rB   rd   )r   r	   r
   r   )p0rD   texrf   r:   c                 S   s   g | ]}|  qS r   r'   r   r   r   r   r          zfit.<locals>.<listcomp>=)rA   rB   ri   dpi   
pad_inchesg?png)formatrm   ro   r   r@   r   Herer8   )fitformfigurer@   r   zigor/fitform.htmlr   )"methodr!   rg   FILESis_validrE   dictr   r   r    rh   paramsFitsplitintr3   plotioBytesIOgetfigsavefigrH   urllibparsequotebase64	b64encoderF   	ExceptionrP   	add_errorindexr   )requestrt   r   r@   rs   rT   r   rC   rD   rA   rB   rd   mapperfuncrh   ri   frf   optsfldkr6   valbuffrm   ro   oopserrargsr   r   r   fit   sp   



1r   )	curve_fitOptimizeWarning)*)chi2)rcParamsc                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	de
jfddZed-ddZdd Zdd Zdd Zd.ddZedd Zedd  Zd!d" Zd#d$ Zd%d& Zd/d(d)Zd*d+ Zd,S )0rz   a  
    Base class that performs (non)linear least-squares fits and
    can make carefully formatted plots of the results.

    The function to apply may either be specified by passing in
    appropriate keyword arguments or by subclassing this class and
    providing the requisite functions as methods of the subclass.

    By default, a Fit object immediately attempts to run the fit with
    the information passed to the constructor. If that fails, or if the
    information is insufficient, you can see what the data look like and
    the calculated curve with the passed values for p0 (or the values generated
    by the estimate_p0 function) by calling plot on the resulting object.
    If you want to start the process without attempting a fit, but just
    seeing the plot with the curve generated by values in p0, pass the
    key-value pair adjust=True to the constructor. You can

    These requisite functions/methods are
    - function(x:np.ndarray, *params, **kwargs):
    - tex_f: (optional) a string or callable that returns a string providing
    a representation of the function in LaTeX.
    - estimate_p0(**kwargs): (optional) a function that takes a dictionary
    of keyword arguments, including the instance of this Fit class with the
    name 'self' and returns a vector of initial values for the
    fit parameters. The function may avail itself of data fields in
    the Fit object, including x, y.


    should be subclassed to implement a particular
    (nonlinear) fitting function. This base class provides all of the
    smarts, leaving to the subclass just the essentials particular to
    the chosen function. The subclass should implement the following
    fields and methods:

    - function(self, x:np.ndarray, *params), where self is an instance of a
        subclass of Fit
    - tex_f, a string or @property callable returning a string providing
        a representation of the function in LaTeX. If not defined,
        a crude approximation is generated by introspection of the function.
    - __str__(self), to produce a string representation of the fit
    - __init__(self, x:np.ndarray, y:np.ndarray, **kwargs), constructor
        that must call super().__init__(x, y, p0, tex, **kwargs), where
        p0 is an initial guess for the fitting parameters and
        tex is a list of strings with a LaTeX version of the names
        of the fit parameters

    If the fit is successful, the routine self.after_fit() is called; the
        default routine does nothing, but this would be an opportunity to
        adjust parameters, such as making sure that a parameter that
        enters quadratically has a positive value. In addition, the
        following fields are set:

    - self.valid is set to True
    - self.params is set to the list of optimized fitting parameters

    If yunc holds valid uncertainties, then
    - self.param_uncs is set to the list of parameter uncertainties
    - self.chisq is set
    - self.dof is set to the number of degrees of freedom of the fit
    - self.prob_greater indicates the probability that a greater value
        of chi-squared on repeating the experiment


    Optional keyword inputs:
    - yunc:np.ndarray, an array of uncertainties in the dependent variable
    - xunc:np.ndarray, an array of uncertainties in the independent variable
    - hold:str, a string of the form "01100", where "0" means the variable is
        optimized by the fitting routine and "1" means that it is held at the
        value given in p0
    - tex:[str], a list of strings providing LaTeX code to represent the
        fit parametersc           	   
   K   s  || _ t|| _t|| _t| jt| jksJ d|| _t| ds7t| j dr1| j j| _	n|
d| _	d| _d| _d| _d| _g | _g | _d| _|
d| _t|t| j | _|
d| _d| _d| _d| _d| _d| _d| _d| _d| _zvdD ]C}z|| }W n   t| |d Y q}t|tt frt!t|| }nzt|}W n   d}Y t| || t|t|ksJ q}t| jtj"rt| jtj"rdnd	| _d
|v s| j dkr| #  W dS | $| j | %  W dS  t&y	 } zt'|| _W Y d}~dS d}~ww )a  
        kwargs may include hold="1011", where each 0 corresponds
        to a parameter allowed to vary and 1 to a value held fixed.
        If the function passed has a .tex attribute, it is assumed
        to be a string that can be passed to tex to describe the
        function in the fit annotation. Subclasses may define a
        string variable tex_f for this purpose.

        z,The x and y arrays must have the same lengthfunction_texri   N hold)rD   xuncxyrC   adjust)(functionrM   arrayr   rC   lenrh   hasattrri   r   r   errorr   rD   xerrorsry   
param_uncs	weightingr   dof
tex_labelschisqprob_greateraxdataaxyresidualsaxynormaxxresidualsaxxnormtop_axissetattr
isinstancer3   r|   onesndarrayr}   run_fit	after_fitr   rP   )	r4   r   r   rC   rh   kwargsuncuncseepsr   r   r   __init__)  st   


zFit.__init__c                 G   s   |  |}| j|g|R  S ) )
parametersr   )r4   r   ry   pr   r   r   fhold{  s   
z	Fit.fholdc           	         sp  t | _d}|d7 }|dD ]}t |d q jrZt jts$dt jt jkr0d fddtt|D  _	t j
t j	  _ fd	d
} fdd j	D }n fdd
}z t jtjrn | nt| j
 j| jdd\ _ _W n	 ty   dw tj jv stj jv rd _dS   j _ j j j
g jR    _d jv r
 j j  _t jd  _d jv r j  j  _! j"}t#t$ jdt$| j d } j|  _%t j%d  _ j j  _&dt'( j j  _)t#t* j} jr3t+ jj, _-t. j	D ]\}}||  j-|< q$dS | _-dS )z`Run or re-run the fitting procedure, starting from
        the passed parameter values.
        zFerror;xerrors;yerrors;chisq;prob_greater;norm_yresiduals;reduced_chisqz;params;param_uncsr   Nz6hold must be a string with 1 for fixed, 0 for variablez@The number of digits in hold must match the number of parametersc                    s   g | ]} j | d kr|qS )0)r   r   r4   r   r   r     s    zFit.run_fit.<locals>.<listcomp>c                        j | g|R  S r   )r   r   r   r   r   r   <lambda>      zFit.run_fit.<locals>.<lambda>c                    s   g | ]} j | qS r   )rh   )r   rW   r   r   r   r         c                    r   r   )r   r   r   r   r   r     r   T)rh   sigmaabsolute_sigmazFailed to convergerC   r)   r   r   )/rQ   rh   r{   r   r   r   rP   r   rangevariabler   r   r   rM   r   run_odrr   rC   rD   ry   covarsr   infnanr   r   r   
yresidualsr   norm_yresidualssumr   
xresidualsnorm_xresiduals_slopesqrtpowernorm_residualsreduced_chisqr   cdfr   diagzerossizer   rL   )	r4   rh   fieldsr   r   r   errsrW   pnumr   r   r   r     sp   


		


zFit.run_fitc                 C   s   dS )z9Override to perform any post-fit alteration of parametersNr   r   r   r   r   r     s   zFit.after_fitc              	      s   t | j| jdt| jd dt| jd d} fdd}t|}t||| j	}|
  || _|j}|jdkrJ|j| _|j| _|j| _|j| _dS dS )z>Run an orthogonal distance regression to handle errors along x      ?r)   )wdwec                    s    |g| R  S r   r   )betar   r   r   r   f_odr  s    zFit.run_odr.<locals>.f_odrr   N)Datar   rC   rM   r   r   rD   ModelODRrh   runodroutputinfor   ry   cov_betar   epsr   deltar   )r4   r   r   r   modelr   r   r   r   r   r     s$   
zFit.run_odrc                 C   s:   | j r| j}t| jD ]
\}}|| ||< qt|S |S )z?Handle the subset of parameters that are being allowed to vary.)r   rh   rL   r   rM   r   )r4   parr   rW   r   r   r   r   r     s   
zFit.parameterstc                 C   s<   | j dkrg S | jr| j |g| jR  S | j |g| jR  S )z=Evaluate the fitting function using current parameter values.N)r   validry   rh   )r4   r   r   r   r   __call__  s
   
zFit.__call__ư>c                 C   s(   | | j | | | j |  }|d|  S )z>Return a numerical approximation  to the slope at each data ptr)   )r   )r4   dxdyr   r   r   r   
  s   z
Fit._slopec              	   C   sH  | j j}t| j }|jdd  }|g}t| jtj}| j	rt
t| jD ]D}||| dd| j| d |ri|d  d| j| d7  < | j| dkri|d  d	t| j| | j|  d
 dd7  < q%|r|d| j d| jd |d  d	| jdd7  < |d  dd
| j dd7  < n|| j d|S )Nr   >16sz = z^8.4gu    ± .2gr   z (d   z%)zN_dof = z
, chisq = .3g)z, P> = %
)r   r^   inspectgetfullargspecr   r   rD   rM   r   r   r   r   ry   appenderrorsr   absr   r   r   r   r   join)r4   namer   argnameslineshas_uncrW   r   r   r   __str__  s2   "$ 
zFit.__str__c                 C   sn   d|vr|S t d|}|r/|dd }|ddkr |d7 }|tt|dd 7 }|S td	|  |S )
zI
        Render a string representation of a value in TeX format
        ez#([-+0-9.]*)\s?e\s?([+-])\s?([0-9]*)r   z \times 10^{r)   -r?   r.   z	Ack! for )researchgrouprP   r|   print)r4   r   r   sr   r   r   texval)  s   z
Fit.texvalc              
   C   s,  |dkrt |ddfS zp|dkr|dksJ ttt|}tt|}d| | }| | }t||}t||}|t| }	dt | d }
| |
|}| |d}|	dkra|	d}n|	d	krnd
|	 dd }n	td|	  d }||fW S  ty } z|d|dfW  Y d}~S d}~ww )zQ
        Produce a LaTeX representation of the value and its uncertainty
        g        r   r)   z{:0.zf}r   r   z.2fgMbP?r   .1fz\%g    .Az	\;\rm ppmr   N)	rP   r|   rM   log10r  roundr  rq   r   )r4   r   r   xdigitsdxdigitsdigits
round_spotxrounddxroundratiofmtmainr   relr   r   r   r   tex_val_unc9  s0   




zFit.tex_val_uncTc                 C   s
  t | dr| jr| jn| jj}| jr| j}nt| j}|jdd }|g}t| j	t
j}|rL| jrLd| | jd d| j  dd| j d	 d
 g}| jr|ra|dd |d |d tt| jD ]Z}|r|d||  d  |ddd | | j| | j| D  qh||| dd | | j| | j| \}	}
}|dkr|	 d}nd|	|
|}|d  |7  < qh|r|r|d ||d d |d  d  |d n||d  ||d  n|r|d n|| j d|}|S )z\Generate an annotation showing the fit function
        and the fitting parameters.
        r   r   Nz$\chi_\nu^2 = r   z\;\; \mathrm{for}\;\; \nu = %d$z$P_> = r   r  z\%$r   z'\begin{tabular}{lcc}\multicolumn{3}{c}{z}\\[0.05in]z/\textbf{Param} & \textbf{Value} & \textbf{Unc.}z\\ z & c                 S   r   r   r   r   r   r   r   r     s    
z"Fit.legend_tex.<locals>.<listcomp>r   z = $r   z	$ (fixed)z{0} \pm {1}\; ({2})$r   z\\[0.05in]\multicolumn{3}{c}{z \qquad r.   z\end{tabular}r  )r   r   r   r^   r   r  r  r   r   rD   rM   r   r   r  r   r   r   insertr  r   r   ry   r	  r$  r   rq   r   )r4   	use_tabler
  r  r   r  r  statsrW   r6   urvalsresr   r   r   
legend_tex[  sz   





zFit.legend_texc                 C   s   | j du o	t| dS )zDid the fit exit successfully?Nr   )r   r   r   r   r   r   r     s   z	Fit.validc                 C   s*   | j r
t| jtjsdS t| j| j S )zK
        By what factor errors need to grow to yield chisq/DoF = 1
        N)r   r   r   rM   r   r   r   r   r   r   r   r   error_scale  s   zFit.error_scalec              	   K   s  d\}}| dd}d}g }| jr0| dd| jv o|}|r#|d | dd	}|r0|d
 |d || _| jd9i | | j| | dd}| dd}| dt	| j
}	| dt| j
}
| dt	| j}| dt| j}| d| d}}| dd}|r| jjddd t|tjstdtt|	t|
|}nt|tjst|	|
|}|s| |}|r| jjddd t|t|kr| j|| | dt| j
dk rdnd}| jr| jj| j
| j| j| jdd |d! n| jj| j
| jd |d" d#|v r| j|d#  d$|v r$| j|d$  |r|r2| jjddd | jj|	|
gd%d%gd&d d' | jd(kr[| d(}| jj| j
| j |dd)d* d+}nd,}| jj| j
| j | jd-d|d. | jd/ d0| jv r|r| j!jddd | j!jd%d%g||gd&d d' | j!j| j"| j|d)dd1 | j!j| j"| j| jdd-|d2 | j!d/ |r|r| j#jddd | j#j|	|
gd%d%gd&d d' | d}| j#j| j
| j$d)d|d3 | j#d4 d0| jv r| j%}|jd%d%g||gd&d d' | d0}|j| j&| jd)d|d3 |d4 	 | j(}|)|j* z| j+}|,| |j-d5d6d7 W n   Y | d| df}|d% d8ksK|d+ d8krQ| jj.|  | d| df}|d% d8ksi|d+ d8krq| jj/|  d8S d8S ):ap  
        Generate a plot showing the data, fit, residuals, and
        normalized residuals.

        Optional kwargs:

        - residuals (boolean)
        - normalized_residuals (boolean)
        - title (str)
        - xlabel (str)
        - ylabel (str)
        - figsize (width, height)
        - msize (marker size, in pts)
        - logx (boolean)
        - logy (boolean)
        - xmin (float)
        - xmax (float)
        - ymin (float)
        - ymax (float)
        - xfit (array of positions at which to compute the fitted curve)
        - yfit (array of precomputed fit values). If yfit is not supplied,
          the fitted curve will be evaluated at xfit values.
        - npoints (int) defaults to 200 and specifies the number of points
          to use in computing the fitted curve
        - legend (xfrac, yfrac) specifies the anchor position of the
          annotation, expressed as a fraction of the width and height of the
          plot area. Defaults to (0.1, 0.1). Alternatively, can be a suitable
          combination of north, east, south, and west for position outside
          the plot area.
        )FFtitler   Fnormalized_residualsrC   r   	residualsTr   r   logxlogyxminxmaxyminymaxxfityfitnpoints   logclip)nonposx
   )nonposymsize         o      ?)yerrxerrr!  alpha
markersize)rH  r  rA   rB   r   zk-)rH  r      )r   markerr  r   r?   None)rF  lsrK  mszRes.r   )r   r  rK  )rG  rK  rM  rN  )r  rK  r   zN.R.gQ?g{Gz?)hspacewspaceNr   )0r   r   r   r  
axes_order
make_gspecr   	set_titlerM   minr   maxrC   r   
set_xscaler   r   r   linspacer  r   
set_yscaler   r}   errorbarrD   r   scatter
set_xlabel
set_ylabelr   norm_res_colorsr   r   r   r   r   r   r   fit_resultsr   align_ylabelsaxesgstight_layoutupdateset_xlimset_ylim)r4   r   r   normalized_yresidualsr.  NORMrQ  r1  r2  r3  r4  r5  r6  r7  r8  r9  r@  colorsrN  axr   ra  xlimylimr   r   r   r}     s  











zFit.plotc                 K   sZ  | dd}| dtd }td }| dd}dtd	< d
td< dtd< dtd< dtd< dtd< dtd< dtd< | j}|\}}tdgdgddddd}	| js^tj|	d\| _| _| j| _	dS | 
|}
dt| j }|| d d }d|
v r||
dd}
t|
|||ddd d!ddd"
| _| j}td#d$d d d%}d&}t|tr||d'< t|d(krg d)|	d*< nt|d+krdd,g|	d*< tjt|d||	d-\| _| _d.D ]}||v rt| || j||  q| jd/ | _	| jj|
fi | t|trd0d1 | d2D }|d/ |d3< t|dkrdn|d |d4< |d3 d5v rdtj||| d6 fd7| _d}|d3 d8kr=|d/d9 |
|7 }
n	|d9 ||
 }
t|d(krgdd,|d | g|	d*< d:| jv rfd+}d,dg|	d;< n,t|d,krddd,|d< | g|	d*< d:| jv rd(}g d=|	d;< n
d,|d> | g|	d*< |d3 d8krt|	d* d|	d*< | jjdP|t|d?|	}|| _|j d@dA |dB}| j!||d/f | _t"|D ]7\}}|dCv rڐq| jj!||d/f | jdD}tj#|$ dEdF tj%d/d/dG t| || |d/kr|| _	q|dkrEt&dd+gdHdIgD ]/\}}||kr  n%| jj!|||f | jdJ}tj#|' dEdF tj%d/d/dG t| || q| j!||d9d/f | _(| j()dK | j(j|
fi | ntj|d/ dL |d fd7| _dM}|d3 dNkr||gn||g|	d;< t|d+krdd,g|	d*< nt|d(krg d)|	d*< | jjdPd+t|d?|	}|d3 dOkrd/nd}| j!|dd|f | _(| j(j|
fi | | j(*  |dB}| j!||d| f | _t"|D ]2\}}|dCv rq| jj!||d| f | jdD}t| || tj#|$ dEdF |d/kr|| _	q|d/ }t+| |}|| _	dS )Qz
        Figure out how to layout the axes of the plot.
        Relevant issues:
          - do we have residuals and normalized residuals in y
          - in x?
          - is the legend outside the plot area?
        legendsouthfigsizezfigure.figsizez	font.sizetableTserifzfont.familyg      (@ztext.usetexz	xtick.topinzxtick.directionzytick.rightzytick.directionzsavefig.transparentr   g?g      ?g333333?)width_ratiosheight_ratiosrO  rP  leftright)gridspec_kwNg      @g      ?H   tabularr  r   皙?centermiddle)
text	num_lines
msg_heightpositionr   rC   havaprimary	secondary)rE  rE  zaxes fraction)r   xycoordsr  r  z 
 
r   r?   )r   r      rs  r)   r  )nrowssharexrn  rv  )r   r   r   r   c                 S   s   g | ]}| d qS )z"'rj   r   r   r   r   r     r   z"Fit.make_gspec.<locals>.<listcomp>r   r  r  )northrm  g      ?)rn  r  axlegendr   rr     )r  r   r   g      @)ncolsr  g{Gz?)rO  r   )r   r  )r  F)visible)rP  rO  r   r   )shareyoffg      @rC  eastwestr   ),r   r   rQ  rx   r   pltsubplotsr   r   r   r,  r   ry   replace_legendr   tupler`  r   r   annotaterP   lowerr{   rt   r%  r  r   rM   rolladd_gridspecra  rc  add_subplotrL   setpget_xticklabelssubplots_adjustzipget_yticklabelsr  axisset_axis_offgetattr)r4   r   rl  rn  fontsizer&  rQ  widthheightgspecmsgr}  r~  legr   legend_paddingri  r   r  ra  ndatarW   whichr   legwidthcoldindextopperr   r   r   rR    s^  	

















zFit.make_gspecc                 K   s  | dd}|  }t|d}t|trw| d }|d }	t|dkr+|d nd}
|d }| \}}|	dkrk|| }|| d|| ddf}|j	|d	 d
\}}}|
dkr`d\}}n|
dkrid\}}nd}|j
|||||d dS |\}}|\}}d|d  | |d |  }d|d  | |d |  }|d dk rdn	|d dkrdnd}|d dk rdn	|d dkrdnd}|jd }|j
|||||d dS )r   rl  )ry  ry  r  r   r   Nr?   rm  )rect)rE  r   bottomr  )r   rt  r  )r   ru  rz  )horizontalalignmentverticalalignmentg333333?rt  ffffff?ru  r  topr   )r   r,  r   r{   r   rP   r  get_size_inchesset_figheightrb  r|  r`  )r4   r   xboundsyboundsr   rl  r  r}  r   r  r  legend_heightr  r  
new_heightr  xposyposvalignhalignr3  r4  r5  r6  ri  r   r   r   r^  m  s^   







zFit.fit_resultsrC   c                 C   sF   |dkr| j }n|dkr| j}n| j}tjt|tjd}| |S )z>
        return a color map for the desired residuals
        rC   r   )rN   )r   r   r   rM   asarrayr  uint16_res_colors)r4   rd   norm_ressigmasr   r   r   r]    s   
zFit.norm_res_colorsc                    sN   d||dk< d}ddd|fddd|fddd|fddd|fg  fdd	|D S )
Nr?   g      ?r   r  g?r   r   c                    s   g | ]} | qS r   r   r   colormapr   r   r     rk   z#Fit._res_colors.<locals>.<listcomp>r   )r4   r  rH  r   r  r   r    s   



zFit._res_colorsN)r   )T)rC   )r^   r_   r`   __doc__r   r   r   r   r   r   rM   r   r   propertyr   r  r  r$  r,  r   r-  r}   rR  r^  r]  r  r   r   r   r   rz      s4    HRZ	
"N

 Q g
Arz   )-r  djangor   osenviron
matplotlibusenumpyrM   pandasrI   matplotlib.pyplotpyplotr  r~   r   r   django.shortcutsr   django.utils.translationr   r2   django.formsr   rc   r   ri   ry   rh   r   r{   r    Formr!   r   r  r  scipy.optimizer   r   	scipy.odrscipy.statsr   r   rz   r   r   r   r   <module>   sJ   

UF