def line_fit(p, x, y, y_error, x_error=False, iterations=10000): """ Linear Fit to data, taking either errors in y or both in x and y into account. Parameters ---------- p : list Containg slope (m) and y-axis intersection (b) p=[m, b]. Same as in :func:`line` and :func:`antiline`. x : float or list x measurements. Data. y : float or list y measurements. Data. y_error : float or list The y measurment errors. x_error : float or list The x measurment errors. If unset only errors in y are taken into account. """ p1, cov, info, mesg, success = least(linear_error_function, p, args=(x, y, y_error, x_error), maxfev=int(iterations), full_output=1) dof = len(x) - len(p) - 1 # degrees of Freedom chisq = sum(info['fvec'] * info['fvec']) / dof Error = std(info['fvec']) return p1, chisq, Error
def _grid_fit(data, beta, nu_or_lambda='nu', fit_beta=False, rawChiSq=False, kappa='Kruegel'): r""" Different approach to find the best fitting SED using certain ranges of temperatures and masses to avoid unreasonably high values. Not sure about the functionality and the code is badly written with the temperature and mass ranges hard coded. Thats why its not public. Once approved it may be made public again. Parameters ---------- data : array Same format as in grey_body_fit. beta : The beta value. If fit_beta=True this is varied in the fits. kappa : As in :func:`greybody`. Other Parameters ---------------- fit_beta: True or False Steers if beta is fittet or not. rawChisq: True or False Returns chi square without normalisation, or not. """ def _err(p, x, y, y_error, nu_or_lambda): """ The function to be minimized by scipy.optimize.leastsq. It returns the difference between the measured fluxes, y, and the calculated fluxes for the parameters p of the SED at the given frequency x. Parameters ---------- p : list same start start_parameter as in grey_body_fit x and y : The two rows, data[0] and data[1] of the data variable from grey_body_fit. y_error : The absolute error on the flux measurement. Other Parameters ---------------- nu_or_lambda : string Specify whether x is a frequency :math:`\nu` ``'nu'`` or a wavelenght :math:`\lambda` ``'lambda'``; default is ``'nu'``.:: **Don't** use ``'lambda'`` as this part of the :py:func:`grey_body` is not up-to-date. Notes ----- This function caluclates the residuals that are minimized by :func:`leastsq`, thus it calculates: .. math:: (model-measurement)/\sigma Note the :math:`\chi^2` is defined as: .. math:: \chi^2 = \frac{1}{N} \sum{(model-measurement)/\sigma} :warning:`Formula has to be checked.` This functions is different from the _err functions in grey_body_fit because the start parameters are handles differently. """ if not fit_beta: pMulti = [T, p, beta] print pMulti if fit_beta: pMulti = [Temps, p] print pMulti return (((multi_component_grey_body(pMulti, x, nu_or_lambda, kappa)[0]) - y) / y_error) beta = [beta] T1 = arange(5, 70, 1) T2 = arange(20, 100, 1) chisqList = {} chisqList1 = [] for i in T1: for j in T2: T = [i, j] N = [1e2, 1] if not fit_beta: p = N if fit_beta: p = N + beta p2, cov, info, mesg, success = least(_err, p, args=(data[0], data[1], data[2], nu_or_lambda), maxfev=int(1e9), full_output=1) dof = len(data[0]) - len(p) - 1 # Degrees of Freedom chisq = sum(info['fvec'] * info['fvec']) / dof # see above rawchisq = sum(info['fvec'] * info['fvec']) chisqList[chisq] = [[i, j], p2] chisqList1 += [chisq] chisq = sorted(chisqList)[0] T, p2 = chisqList[sorted(chisqList)[0]] if not fit_beta: numberOfComponents = len(p) p2 = [T, p2, beta] if fit_beta: numberOfComponents = (len(p) - 1) p2 = [Temps, list(p2[0:numberOfComponents]), [p2[len(p) - 1]]] if not rawChiSq: return p2, chisq if rawChiSq: return p2, rawchisq return sorted(chisq)[0]
def grey_body_fit(data, start_parameter, nu_or_lambda='nu', fit_beta=False, fix_temperature=False, rawChiSq=None, kappa='Kruegel', residuals=False, iterations=1e9): r""" This function fits a multi component grey body model to an observed SED for the optical thin case. Parameters ---------- data : array The obseved data. Array of shape(3, x) first row has to be the X values (Frequency in [GHz]) of the measurements, second row the Y values (Flux [Jy]), and the third row the Z values the errors on the fluxes i.e.: data = array([[X1, X2, X3, ...], [Y1, Y2, Y3,...], [Z1, Z2, Z3, ...]]) start_parameter : array Array of a first guess of the parameters of the grey_body components. The number of components is arbitrary. start_parameter = [[T1, T2, T3,...], [N1, N2, N3, ...], beta] fit_beta : True or False If True Beta is allowed to vary. Default is False. fix_temperature : True or False If True the Temperature is fixed allowed to vary. rawChiSq : if None the function gives the reduced chisq Value. If True the function gives chisq without dividing it by the dof Returns ------- p2 : list The final grey_body parameters that reduce the least squares for the given dataset. chisq/rawChiSq : chisq is reduced chisq with degrees of freedom: dof= #dataPoints-#freeFitParameters-1 Other Parameters ---------------- nu_or_lambda : string Specify whether x is a frequency :math:`\nu` ``'nu'`` or a wavelenght :math:`\lambda` ``'lambda'``; default is ``'nu'``.:: **Don't** use ``'lambda'`` as this part of the :py:func:`grey_body` is not up-to-date. See Also -------- scipy.optimize.leastsq: This function is used to perform the least squares fit. multi_component_grey_body, grey_body, black_body: Defining the function to be fittet to the data. Notes ----- A one component fit has four free parameters if beta is allowed to vary or three if beta is fixed (one more than parameters to fit). Each additional component adds two more free paramters to fit. Assure that: number of data points > number of free parameters. """ # Distinguish between the different options and build the parameter list # needed by optimize.leastsq() if not fit_beta: if not fix_temperature: p = start_parameter[0] + start_parameter[1] beta = start_parameter[2] if fix_temperature: p = start_parameter[1] Temps = start_parameter[0] beta = start_parameter[2] if fit_beta: if not fix_temperature: p = start_parameter[0] + start_parameter[1] + start_parameter[2] if fix_temperature: p = start_parameter[1] + start_parameter[2] Temps = start_parameter[0] def _err(p, x, y, y_error, nu_or_lambda): """ The function to be minimized by scipy.optimize.leastsq. It returns the difference between the measured fluxes, y, and the calculated fluxes for the parameters p of the SED at the given frequency x. Parameters ---------- p : list same start start_parameter as in grey_body_fit x and y : The two rows, data[0] and data[1] of the data variable from grey_body_fit. y_error : The absolute error on the flux measurement. Other Parameters ---------------- nu_or_lambda : string Specify whether x is a frequency :math:`\nu` ``'nu'`` or a wavelenght :math:`\lambda` ``'lambda'``; default is ``'nu'``.:: **Don't** use ``'lambda'`` as this part of the :py:func:`grey_body` is not up-to-date. Notes ----- This function caluclates the residuals that are minimized by :func:`leastsq`, thus it calculates: .. math:: (model-measurement)/\sigma Note the :math:`\chi^2` is defined as: .. math:: \chi^2 = \frac{1}{N} \sum{(model-measurement)/\sigma} :warning:`Formula has to be checked.` """ if not fit_beta: if not fix_temperature: numberOfComponents = (len(p)) / 2 pMulti = [list(p[0:numberOfComponents]), list(p[numberOfComponents:numberOfComponents * 2])] pMulti += [beta] if fix_temperature: pMulti = [Temps, p, beta] if fit_beta: if not fix_temperature: numberOfComponents = (len(p) - 1) / 2 pMulti = [list(p[0:numberOfComponents]), list(p[numberOfComponents:numberOfComponents * 2]), p[len(p) - 1]] if fix_temperature: numberOfComponents = len(p) - 1 pMulti = [Temps, list(p[0:numberOfComponents]), p[len(p) - 1]] return (((multi_component_grey_body(pMulti, x, nu_or_lambda, kappa=kappa)[0]) - y) / y_error) # The actual fit # maxfev : Number of integrations # full_output: Additional informations # args: X and Y data p2, cov, info, mesg, success = least(_err, p, args=(data[0], data[1], data[2], nu_or_lambda), maxfev=int(iterations), full_output=1) # return of the optimized parameters dof = len(data[0]) - len(p) - 1 # degrees of Freedom chisq = sum(info['fvec'] * info['fvec']) / dof # see above rawchisq = sum(info['fvec'] * info['fvec']) if not fit_beta: if not fix_temperature: numberOfComponents = (len(p)) / 2 p2 = [list(p2[0:numberOfComponents]), list(p2[numberOfComponents:numberOfComponents * 2]), beta] if fix_temperature: numberOfComponents = len(p) p2 = [Temps, p2, beta] if fit_beta: if not fix_temperature: numberOfComponents = (len(p) - 1) / 2 p2 = [list(p2[0:numberOfComponents]), list(p2[numberOfComponents:numberOfComponents * 2]), [p2[len(p) - 1]]] if fix_temperature: numberOfComponents = (len(p) - 1) p2 = [Temps, list(p2[0:numberOfComponents]), [p2[len(p) - 1]]] if residuals: return p2, chisq, info['fvec'] if rawChiSq == None: return p2, chisq if rawChiSq: return p2, rawchisq