예제 #1
0
def getBestDegree(x, y, fitDomainMin=None, fitDomainMax=None, maxDegree=3):

    # Min Chi-Square Array
    chiSquareArray = []

    # Sort Arrays
    sortIndexes = np.argsort(x)
    x = [x[i] for i in sortIndexes]
    y = [y[i] for i in sortIndexes]

    # Get Fit Domain Limits
    if fitDomainMin == None:
        fitDomainMin = min(x)
    if fitDomainMax == None:
        fitDomainMax = max(x)

    # Filter X and Y Arrays
    xFiltered = []
    yFiltered = []
    for i in range(len(x)):
        if x[i] >= float(fitDomainMin) and x[i] <= float(fitDomainMax):
            xFiltered.append(float(x[i]))
            yFiltered.append(float(y[i]))
    xFiltered = np.array(xFiltered)
    yFiltered = np.array(yFiltered)

    for degree in range(1, maxDegree):

        # Get Polynomial Parameters Array
        polyParams = getPolyParams(degree)
        # Fit
        fit = kmpfit.simplefit(model, [0, 0, 0, 0, 0],
                               xFiltered,
                               yFiltered,
                               parinfo=[{
                                   'fixed': polyParams[0]
                               }, {
                                   'fixed': polyParams[1]
                               }, {
                                   'fixed': polyParams[2]
                               }, {
                                   'fixed': polyParams[3]
                               }, {
                                   'fixed': polyParams[4]
                               }])
        chiSquareArray.append(fit.rchi2_min)

    return chiSquareArray.index(max(chiSquareArray)) + 1
예제 #2
0
                 zorder=1,
                 alpha=0.5)

compendium1 = zeros((len(data), 5), )
compendium1[:, 0] = redshifts
compendium1[:, 1] = d_red
compendium1[:, 2] = csfh
compendium1[:, 3] = ep_csfh
compendium1[:, 4] = em_csfh

p0 = [0.015, 2.9, 2.7, 7.0]
popt, pcov = curve_fit(func, redshifts, csfh, p0=p0, sigma=ep_csfh)
perr = sqrt(diag(pcov))
print(popt, perr)

fobj = kmpfit.simplefit(model, p0, redshifts, csfh, err=ep_csfh)
dfdp = dfdp_m(fobj.params, redshifts)

confprob = 0.68
yjunk, upperband, lowerband = fobj.confidence_band(redshifts, dfdp, confprob,
                                                   model)

## data = loadtxt('md14_UV.txt')
## redshifts1 = 0.5*(data[:,1]+data[:,0])
## d_red = 0.5*(data[:,1]-data[:,0])
## csfh = 10**(data[:,2])
## csfha = csfh
## ep_csfh = 10**(data[:,2]+data[:,3])
## em_csfh = 10**(data[:,2]-data[:,4])

## ax.errorbar(redshifts1, csfh, xerr=d_red, yerr=[csfh-em_csfh,ep_csfh-csfh],
		if 'Title' in Data[DictItem]:
			if Data[DictItem]['Title'] != '':
				plt.title(Data[DictItem]['Title'])

 
		#Plot the data points 
		#========= TO DO: add in an if statement to handle other types of plots ===================
		l = ax.scatter(Data['x'], Data['y'],  s=10, c = Data[DictItem]['PointColour'], marker=str(Data[DictItem]['PointType']), zorder=2)

		if bool(Data['xErr']) and bool(Data['yErr']) and Data[DictItem]['UseErrors'] == True:
			plt.errorbar(Data['x'], Data['y'], xerr = Data['xErr'], yerr = Data['yErr'], ls = 'none')

		#do the fitting and plot it
		if Data[DictItem]['Fit'] == "alpha":			
			if bool(Data[DictItem]['yColErr']): 
				fitting_obj = kmpfit.simplefit(alpha, [ 1, 1 ], Data['x'], Data['y'], err = Data[DictItem]['yColErr']) 
			else:
				fitting_obj = kmpfit.simplefit(alpha, [ 1, 1 ], Data['x'], Data['y'])

			plt.plot(dx, alpha(fitting_obj.params, dx), c = Data[DictItem]['FitColour'])

		elif Data[DictItem]['Fit'] == "line":
			fitting_obj = kmpfit.simplefit(line, [ 1, 1 ], Data['x'], Data['y'])
			plt.plot(dx, line(fitting_obj.params, dx), c = Data[DictItem]['FitColour'])		

		elif Data[DictItem]['Fit'] == "lineErr":
			linear = odr.Model( lineErr )
			mydata = odr.Data( np.asarray(Data['x']), np.asarray(Data['y']), wd = np.asarray(Data['xErr']), we = np.asarray(Data['yErr']) )
			myodr = odr.ODR( mydata, linear, beta0 = [ 1, 1 ] )
			myoutput = myodr.run()
예제 #4
0
def plot_param(hist, pixel=700, param='mu', error_plot=False):

    plt.figure()
    x = 5 * np.arange(0, hist.data.shape[0], 1)
    mu = np.zeros(x.shape)
    sigma_mu = np.zeros(x.shape)
    x_fit = np.arange(0, 1000, 5)
    #x_fit = x
    y_fit = np.zeros(len(x_fit))
    y_fit_max = np.zeros(len(x_fit))
    y_fit_min = np.zeros(len(x_fit))
    upper_band = np.zeros(len(x_fit))
    lower_band = np.zeros(len(x_fit))
    y_hat = np.zeros(len(x_fit))
    sig_yi = np.zeros(len(x_fit))
    sigma_y = np.zeros(len(x_fit))
    n_sigma = 1

    for j in range(hist.fit_result.shape[2]):

        param_names = [
            '$\mu$', '$\mu_{XT}$', 'gain', 'baseline', '$\sigma_e$',
            '$\sigma_1$', 'amplitude', 'offset'
        ]
        param_units = [
            '[p.e.]', '[p.e.]', '[ADC/p.e.]', '[ADC]', '[ADC]', '[ADC]', '[]',
            '[ADC]'
        ]
        plt.subplot(3, 3, j + 1)

        if error_plot:

            y = hist.fit_result[:, pixel, j, 0]
            y_err = hist.fit_result[:, pixel, j, 1]
            plt.plot(x, y_err / y, label='data', marker='o', linestyle='None')
            plt.ylabel('$\sigma$ / ' + param_names[j])

        else:

            y = hist.fit_result[:, pixel, j, 0] * (hist.fit_result[:, pixel, 2,
                                                                   0] if
                                                   (j == 4 or j == 5) else 1.)
            yerr = hist.fit_result[:, pixel, j,
                                   1] * (hist.fit_result[:, pixel, 2, 0] if
                                         (j == 4 or j == 5) else 1.)

            if j == 0:

                mu = y
                sigma_mu = yerr

                def model(p, x):
                    p0, p1, p2, p3, p4 = p
                    return p0 + p1 * x + p2 * x**2 + p3 * x**3 + p4 * x**4

                def residuals(p, data):

                    x, y = data
                    p0, p1, p2, p3, p4 = p
                    #return (y - model(p, x))/

                # fit with polyfit and compute symmetric CB

                deg = int(4)
                param, covariance = np.polyfit(x,
                                               y,
                                               deg=deg,
                                               w=1. / yerr,
                                               cov=True)
                param_err = np.sqrt(np.diag(covariance))
                xx = np.vstack([x_fit**(deg - i) for i in range(deg + 1)]).T
                yi = np.dot(xx, param)  #
                C_yi = np.dot(xx, np.dot(covariance, xx.T))
                sig_yi = np.sqrt(np.diag(C_yi))
                y_fit = np.polyval(param, x_fit)
                y_fit_max = np.polyval(param + param_err, x_fit)
                y_fit_min = np.polyval(param - param_err, x_fit)

                # fit with kmpfit module and compute CB

                fit = kmpfit.simplefit(model, param, x, y, err=yerr)
                dfdp = [
                    np.ones(len(x_fit)), x_fit, x_fit**2, x_fit**3, x_fit**4
                ]
                #dfdp = [x_fit ** 4, x_fit**3, x_fit**2, x_fit, 1]

                y_hat, upper_band, lower_band = fit.confidence_band(
                    x_fit, dfdp, 0.68, model, abswei=True)

                # compute CB

                print(' covar matrix kmpfit', fit.covar)
                print(' covar matrix polyfit', covariance)

                #fitobj = kmpfit.Fitter(residual=residuals, data=(x, y))
                #fitobj.fit(params0=param)

                #print("\nFit status kmpfit:")
                #print("====================")
                #print("Best-fit parameters:        ", fitobj.params)
                #print("Asymptotic error:           ", fitobj.xerror)
                #print("Error assuming red.chi^2=1: ", fitobj.stderr)
                #print
                #"Chi^2 min:                  ", fitobj.chi2_min
                #print
                #"Reduced Chi^2:              ", fitobj.rchi2_min
                #print
                #"Iterations:                 ", fitobj.niter
                #print
                #"Number of free pars.:       ", fitobj.nfree
                #print
                #"Degrees of freedom:         ", fitobj.dof

                for j in range(len(fit.params)):
                    for k in range(len(fit.params)):

                        sigma_y += dfdp[j] * dfdp[k] * fit.covar[
                            j, k]  #covariance[j,k]#

                sigma_y = np.sqrt(sigma_y * fit.rchi2_min)

                plt.plot(x_fit, y_fit, label='best fit', color='red')
                plt.errorbar(x,
                             y,
                             yerr=yerr,
                             label='data',
                             marker='o',
                             linestyle='None')
                #plt.plot(x_fit, y_fit_max, label='polyfit + 1 $\sigma$')
                #plt.plot(x_fit, y_fit_min, label='polyfit - 1 $\sigma$')
                #plt.plot(x_fit, y_hat, label='kmpfit')
                #plt.fill_between(x_fit, upper_band, lower_band, alpha=0.5, facecolor='blue', label='kmpfit confidence level')
                plt.fill_between(x_fit,
                                 yi + sig_yi,
                                 yi - sig_yi,
                                 alpha=0.5,
                                 facecolor='red',
                                 label='confidence level')
                plt.ylabel(param_names[0] + ' ' + param_units[0])
                print('param ', param, ' ± ', param_err)
                print('kmpfit : ', fit.params, ' ± ', fit.xerror)
                plt.legend(loc='best')

            else:

                plt.errorbar(x,
                             y,
                             yerr=yerr,
                             label='data',
                             marker='o',
                             linestyle='None')
                plt.ylabel(param_names[j] + ' ' + param_units[j])
                plt.legend(loc='best')

    plt.xlabel('DAC')

    plt.figure()
    plt.plot(y_hat, (upper_band - lower_band) / y_hat / 2., label='kmpfit')
    plt.plot(y_fit, sig_yi / y_fit, label='polyfit')
    plt.plot(y_fit, (y_fit_max - y_fit_min) / y_fit / 2.,
             label='polyfit max-min')
    plt.plot(mu, sigma_mu / mu, label='from mpe fits')
    plt.plot(y_fit, 1. / np.sqrt(y_fit), label='Poisson')
    #plt.plot(y_fit, sigma_y / y_fit, label='kpmfit redo')
    plt.xlabel('$\mu$')
    plt.ylabel('${\sigma} / {\mu}$')
    plt.legend(loc='best')

    #plt.figure()
    #plt.errorbar(y_fit, mu, xerr=sig_yi, yerr=sigma_mu)
    #plt.xlabel('incoming light [p.e.]')
    #plt.ylabel('measured light [p.e.]')
    #plt.legend(loc='best')

    plt.figure()
    plt.errorbar(x,
                 mu,
                 yerr=sigma_mu,
                 label='LED calibration',
                 marker='o',
                 linestyle='None',
                 color='k')
    plt.plot(x_fit, y_fit, color='r', label='best fit')
    plt.fill_between(x_fit,
                     y_fit + sig_yi,
                     y_fit - sig_yi,
                     alpha=0.25,
                     facecolor='red',
                     label='1 $\sigma$ confidence level')
    plt.xlabel('DAC')
    plt.ylabel('$\mu$ [p.e.]')
    plt.legend(loc='best')

    plt.figure()
    #plt.plot(x_fit, (upper_band - lower_band) / y_hat / 2., label='kmpfit')
    plt.plot(x_fit, sig_yi / y_fit, label='polyfit')
    #plt.plot(x_fit, (y_fit_max - y_fit_min) / y_fit / 2., label='polyfit max-min')
    #plt.plot(x_fit, sigma_y / y_fit, label='kpmfit redo')
    plt.xlabel('DAC')
    plt.ylabel('${\sigma} / {\mu}$')
    plt.legend(loc='best')
					#===============================================================================
					#============================Start the Fitting==================================
					#===============================================================================

					dx = np.arange(xLowerLimit, xUpperLimit, 0.1)


					# if 'xLowerLimit' in Data[DictItem] and 'xUpperLimit' in Data[DictItem]:
					# 	dx = np.arange(Data[DictItem]['xLowerLimit'], Data[DictItem]['xUpperLimit'] + 500, 0.1)
					# else:
					# 	dx = np.arange(200, 10000, 0.1)

					#do the fitting and plot it		
					if bool(Data[DictItem]['yColErr']): 
						fitting_obj = kmpfit.simplefit(alpha, [ 0, 0 ], Data['x'], Data['y'], err = Data['yErr'])
						# p = np.polyfit(Data['x'], Data['y'], 2, w = Data['yErr'])
					else:
						fitting_obj = kmpfit.simplefit(alpha, [ 0, 0 ], Data['x'], Data['y'])
						# p = np.polyfit(Data['x'], Data['y'], 2)

					# add the fit line
					plt.plot(dx, alpha(fitting_obj.params, dx), c = 'black')

					# # add in a polynomial fit 
					# PolyFit = np.poly1d(p)

					# # show the poly fit
					# x_new = np.linspace(Data['x'][0], Data['x'][-1], 150)
					# y_new = PolyFit(x_new)
					# plt.plot(Data['x'],Data['y'],'o', x_new, y_new, c = 'blue')
예제 #6
0
    a, b = p
    y = a + b * x
    return y


# Artificial data
N = 50  # Number of data points
mean = 0.0
sigma = 0.6  # Characteristics of the noise we add
x = numpy.linspace(2, 10, N)
paramsreal = [1.0, 1.0]
noise = numpy.random.normal(mean, sigma, N)
y = model(paramsreal, x) + noise
err = numpy.random.normal(mean, sigma, N)

# Simple interface
p0 = (0, 0)
xl = list(range(10))
yl = [k * 0.5 for k in xl]
fitobj = kmpfit.simplefit(model, p0, xl, yl)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.stderr)

fitobj = kmpfit.simplefit(model, p0, x, y, err=err, xtol=1e-8)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.xerror)

fitobj = kmpfit.simplefit(model, p0, x, y, maxiter=100)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.stderr)
   a, b = p
   y = a + b*x
   return y


# Artificial data
N = 50                             # Number of data points
mean = 0.0; sigma = 0.6            # Characteristics of the noise we add
x = numpy.linspace(2, 10, N)
paramsreal = [1.0, 1.0]
noise = numpy.random.normal(mean, sigma, N)
y = model(paramsreal, x) + noise
err = numpy.random.normal(mean, sigma, N)


# Simple interface
p0 = (0,0)
xl = list(range(10))
yl = [k*0.5 for k in xl]
fitobj = kmpfit.simplefit(model, p0, xl, yl)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.stderr)

fitobj = kmpfit.simplefit(model, p0, x, y, err=err, xtol=1e-8)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.xerror)

fitobj = kmpfit.simplefit(model, p0, x, y, maxiter=100)
print("Best fit parameters:", fitobj.params)
print("Parameter errors:  :", fitobj.stderr)
예제 #8
0
def getCurveFit(x,
                y,
                fitDomainMin=None,
                fitDomainMax=None,
                polyParams=[0, 0, 0, 0, 1]):

    # Sort Arrays
    sortIndexes = np.argsort(x)
    x = [x[i] for i in sortIndexes]
    y = [y[i] for i in sortIndexes]

    # Get Fit Domain Limits
    if fitDomainMin == None:
        fitDomainMin = min(x)
    if fitDomainMax == None:
        fitDomainMax = max(x)

    # Filter X and Y Arrays
    xFiltered = []
    yFiltered = []
    for i in range(len(x)):
        if x[i] >= float(fitDomainMin) and x[i] <= float(fitDomainMax):
            xFiltered.append(float(x[i]))
            yFiltered.append(float(y[i]))
    xFiltered = np.array(xFiltered)
    yFiltered = np.array(yFiltered)

    # Fit
    fit = kmpfit.simplefit(model, [0, 0, 0, 0, 0],
                           xFiltered,
                           yFiltered,
                           parinfo=[{
                               'fixed': polyParams[0]
                           }, {
                               'fixed': polyParams[1]
                           }, {
                               'fixed': polyParams[2]
                           }, {
                               'fixed': polyParams[3]
                           }, {
                               'fixed': polyParams[4]
                           }])
    a, b, c, d, e = fit.params

    # Get Error Bands
    dfdp = [0, xFiltered, xFiltered**2, xFiltered**3, xFiltered**4]
    yFit, dyFitUpper, dyFitLower = fit.confidence_band(xFiltered, dfdp, 0.95,
                                                       model)

    samplingIndexes = [int(x) for x in np.linspace(0, len(xFiltered) - 1, 100)]
    if isinstance(xFiltered[0], (int, np.int64)):
        xFiltered = [int(x) for x in xFiltered]
    if isinstance(yFiltered[0], (int, np.int64)):
        yFiltered = [int(x) for x in yFiltered]

    xFilteredSample = [xFiltered[i] for i in samplingIndexes]
    yFilteredSample = [yFit[i] for i in samplingIndexes]
    dyFitLowerSample = [dyFitLower[i] for i in samplingIndexes]
    dyFitUpperSample = [dyFitUpper[i] for i in samplingIndexes]

    return [{
        'x': xFilteredSample[i],
        'y': yFilteredSample[i],
        'errorLower': dyFitLowerSample[i],
        'errorUpper': dyFitUpperSample[i]
    } for i in range(len(samplingIndexes))]
예제 #9
0
def fit_monthly(alldarks, orbit, verbose=False, kappasigma=False, debug_pixnr=None, short=False, give_errors=False, **kwargs):
    """
    fit dark model to two neighbouring monthly calibration orbits

    Parameters
    ----------

    alldarks : AllDarks object
        used to get underlying dark states from sdmf database in an easy and unambiguous way
    orbit : int
        absolute orbit number
    verbose : bool, optional
        if True, provide verbose output
    give_errors: bool, optional
        if True, return errors of fit parameters
    kappasigma : bool, optional
        if True, use kappasigma filter 
    """

    # minimum nr of degrees of freedom
    min_degrees = 8

    orbit_range = orbit-2, orbit+1.99
    if verbose:
        print(orbit_range)

    n_exec, all_state_phases, pet, coadd, all_readouts, all_sigmas, ephases = alldarks.get_range(orbit_range)

    idxje = pet > .5
    if np.sum(idxje) == 0:
        print("warn: no 1.0s pet")

    #
    # fit it
    #

    x = ephases-orbit, pet #, coadd
    if verbose:
        print(pet.shape)
        print(pet)
        print(coadd)
    
    # small pets should not be taken very seriously, unless specified or the rest is saturated..
    if not short:
        idx = pet < .49
        if np.sum(idx) > 0:
            idx = np.where(idx)[0]
            all_sigmas[idx,:] *= 50

    aoinfo = dict(fixed=False, limits=[0,10000])
    dcinfo = dict(fixed=False, limits=[-10000.,+500000.])
    amp1info = dict(fixed=False, limits=[-200,+200])
    trendinfo = dict(fixed=False, limits=[-100,+100])
    amp2info = dict(fixed=False, limits=[-.4,+.4])
    phase1info = dict(fixed=False, limits=[-3.,+3.])
    phase2info = dict(fixed=False, limits=[-3.,+3.])
    parinfo = [aoinfo,dcinfo,amp1info,trendinfo,phase1info,amp2info,phase2info]

    # prepare initial parameters
    ao0 = 3000
    dc0 = 4000
    amp1_0 = 0
    trend0 = 0
    amp2_0 = 0.1
    phase_offset1 = 0
    phase_offset2 = 0
    p0 = np.array([ao0, dc0, amp1_0, trend0, phase_offset1, amp2_0, phase_offset2])

    # ..and fit
    n_done = 0
    statuses = np.zeros(n_pix)
    res_phases = np.zeros(n_pix)
    res_phases2 = np.zeros(n_pix)
    err_phase1 = np.zeros(n_pix)
    err_phase2 = np.zeros(n_pix)
    for pixnr in range(n_pix):
        pix_readouts = all_readouts[:,pixnr]
        pix_sigmas = all_sigmas[:,pixnr]
        idx_fin = np.isfinite(pix_readouts) & (pix_sigmas > 0)
        if np.sum(idx_fin) > min_degrees:
            pix_readouts = pix_readouts[idx_fin]
            pix_sigmas = pix_sigmas[idx_fin]
            x = (ephases-orbit)[idx_fin], pet[idx_fin]
            n = pix_readouts.size

            # pass a
            fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
            residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
            dev_residual = np.std(residual)
            avg_residual = np.mean(residual)

            if kappasigma:
                # pass b : coarse kappa sigma filter 
                idx = (residual-avg_residual)**2 > 10.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 500
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
                residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
                dev_residual = np.std(residual)
                avg_residual = np.mean(residual)

                # pass c : finer kappa sigma filter 
                idx = (residual-avg_residual)**2 > 5.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 500
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)

            n_done += 1
        else:
            continue
        if verbose:
            print(pixnr, dev_residual, fitobj.params[4] % 1, fitobj.message)
        statuses[pixnr] = fitobj.status
        res_phases[pixnr] = fitobj.params[4]
        res_phases2[pixnr] = fitobj.params[6]
        err_phase1[pixnr] = fitobj.xerror[4]
        err_phase2[pixnr] = fitobj.xerror[6]
        if (fitobj.status <= 0):
           raise FitFailedError('Error message = '+fitobj.message)

    # center the negative phase shift
    idx_neg = res_phases > 0.5
    res_phases[idx_neg] -= 0.5
    idx_neg = res_phases2 > 0.5
    res_phases2[idx_neg] -= 0.5
    # compute channel phase shift
    channel_phase1 = np.median(res_phases) % 1
    channel_phase2 = np.median(res_phases2) % 1
    np.sort(res_phases)

    if verbose:
        print('channel median phase =', channel_phase1, channel_phase2)
    phase1info = dict(fixed=True, limits=[-3.,+3.])
    phase2info = dict(fixed=True, limits=[-3.,+3.])
    parinfo = [aoinfo,dcinfo,amp1info,trendinfo,phase1info,amp2info,phase2info]  
    p0[4] = channel_phase1
    p0[6] = channel_phase2

    #
    # pass 2 - fix phase shift
    #

    aos = np.zeros(n_pix)
    lcs = np.zeros(n_pix)
    amps = np.zeros(n_pix)
    amps2 = np.zeros(n_pix)
    trends = np.zeros(n_pix)
    err_aos = np.zeros(n_pix)
    err_lcs = np.zeros(n_pix)
    err_amps = np.zeros(n_pix)
    err_amps2 = np.zeros(n_pix)
    err_trends = np.zeros(n_pix)
    statuses = np.zeros(n_pix)
    for pixnr in range(n_pix):
        pix_readouts = all_readouts[:,pixnr]
        pix_sigmas = all_sigmas[:,pixnr]
        idx_fin = np.isfinite(pix_readouts) & (pix_sigmas > 0)
        if np.sum(idx_fin) > min_degrees:
            pix_readouts = pix_readouts[idx_fin]
            pix_sigmas = pix_sigmas[idx_fin]
            x = (ephases-orbit)[idx_fin], pet[idx_fin]
            n = pix_readouts.size

            # pass a
            fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
            residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
            dev_residual = np.std(residual)
            avg_residual = np.mean(residual)

            if kappasigma:
                # pass b : coarse kappa sigma filter 
                idx = (residual-avg_residual)**2 > 10.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 500
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
                residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
                dev_residual = np.std(residual)
                avg_residual = np.mean(residual)

                # pass c : finer kappa sigma filter 
                idx = (residual-avg_residual)**2 > 5.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 500
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)

            n_done += 1
        else:
            continue
        if verbose:
            print(pixnr, fitobj.message)
        statuses[pixnr] = fitobj.status
        aos[pixnr] = fitobj.params[0]
        lcs[pixnr] = fitobj.params[1]
        amps[pixnr] = fitobj.params[2]
        trends[pixnr] = fitobj.params[3]
        amps2[pixnr] = fitobj.params[5]
        if (fitobj.status <= 0):
           print('Error message = ', fitobj.message)
           quit()
        err_aos[pixnr] = fitobj.xerror[0]
        err_lcs[pixnr] = fitobj.xerror[1]
        err_amps[pixnr] = fitobj.xerror[2]
        err_trends[pixnr] = fitobj.xerror[3]
        err_amps2[pixnr] = fitobj.xerror[5]

    channel_amp2 = np.median(amps2[np.where(statuses > 0)])

    if debug_pixnr is not None:
        import matplotlib.pyplot as plt
        plt.ticklabel_format(useOffset=False)

        # compute errors
        n_bins = 100
        x_bins = np.linspace(orbit_range[0], orbit_range[1], num=n_bins) - orbit
        err_ds = np.empty([n_bins], dtype=np.float64)
        for i in range(n_bins):
            phi = x_bins[i]
            err_ds[i] = err_lcs[debug_pixnr]**2 \
                      + err_amps[debug_pixnr]**2 * (cos(2*pi*(res_phases[debug_pixnr]+phi)) + amps2[debug_pixnr]*(cos(4*pi*(res_phases2[debug_pixnr]+phi))))**2 \
                      + err_phase1[debug_pixnr]**2 * (2*pi*amps[debug_pixnr]*sin(2*pi*(res_phases[debug_pixnr]+phi)))**2 \
                      + err_amps2[debug_pixnr]**2 * (amps[debug_pixnr]*cos(4*pi*(res_phases2[debug_pixnr]+phi)))**2 \
                      + err_phase2[debug_pixnr]**2 * (4*pi*amps[debug_pixnr]*amps2[debug_pixnr]*sin(4*pi*(res_phases2[debug_pixnr]+phi)))**2 \
                      + err_trends[debug_pixnr]**2 * phi**2
        err_ds = np.sqrt(err_ds)

        plt.cla()
        plt.suptitle("vardark of pixel "+str(debug_pixnr));
        p = aos[debug_pixnr], lcs[debug_pixnr], amps[debug_pixnr], trends[debug_pixnr], channel_phase1, amps2[debug_pixnr], channel_phase2
        plt.errorbar(ephases-orbit, all_readouts[:,debug_pixnr], yerr=all_sigmas[:,debug_pixnr], fmt='bo', label="data")
        x = x_bins, np.array((0.5-petcorr) + np.zeros(n_bins))
        model = scia_dark_fun2(p,x)
        plt.plot(x_bins, model, 'g-', label="model", lw=2)
        plt.plot(x_bins, model+err_ds, 'g-', label="model hi")
        plt.plot(x_bins, model-err_ds, 'g-', label="model lo")
        x = x_bins, np.array((1.0-petcorr) + np.zeros(n_bins))
        model = scia_dark_fun2(p,x)
        plt.plot(x_bins, model, 'g-', label="model", lw=2)
        plt.plot(x_bins, model+err_ds, 'g-', label="model hi")
        plt.plot(x_bins, model-err_ds, 'g-', label="model lo")
        x = x_bins, np.array((0.125-petcorr) + np.zeros(n_bins))
        model = scia_dark_fun2(p,x)
        plt.plot(x_bins, model, 'g-', label="model", lw=2)
        plt.plot(x_bins, model+err_ds, 'g-', label="model hi")
        plt.plot(x_bins, model-err_ds, 'g-', label="model lo")
        plt.show()

    if give_errors:
        errors = {"aos":err_aos, 
                  "off":err_lcs, 
                  "amps":err_amps, 
                  "amps2":err_amps2, 
                  "phase1":err_phase1, 
                  "phase2":err_phase2, 
                  "trends":err_trends}
        return channel_phase1, channel_phase2, aos, lcs, amps, channel_amp2, trends, errors
    else:
        return channel_phase1, channel_phase2, aos, lcs, amps, channel_amp2, trends
예제 #10
0
def fit_eclipse_orbit(alldarks, orbit, aos, lcs, amps, amp2, channel_phaseshift, channel_phaseshift2, 
                      give_errors=False, verbose=False, short=False, kappasigma=False, **kwargs):
    """
    fit dark model to an orbits with normal (eclipse) dark states
    use parameters computed from nearest calibration orbits

    Parameters
    ----------

    alldarks : AllDarks object
        used to get underlying dark states from sdmf database in an easy and unambiguous way
    orbit : int
        absolute orbit number
    aos : numpy array, 1024 floats 
        analog offset per pixel for this orbit
    lcs : numpy array, 1024 floats 
        dark current (constant part) per pixel for this orbit
    amps : numpy array, 1024 floats 
        orbital variation amplitude per pixel for this orbit
    channel_amp2 : float
        amplitude of first harmonic of orbital variation (channel mean)
    channel_phaseshift : float
        phase shift of orbital variation (channel mean)
    channel_phaseshift2 : float
        phase shift of first harmonic orbital variation (channel mean)
    give_errors : bool, optional
        if set, return also fit uncertainty
    verbose : bool, optional
        if set, provide verbose output
    kappasigma : bool, optional
        if set, use kappasigma filter 
    """

    # minimum nr of degrees of freedom
    min_degrees = 3

    #
    # get all dark data
    # 

    orbit_range = orbit-1, orbit+0.99
    n_exec, all_state_phases, pet, coadd, all_readouts, all_sigmas, ephases = alldarks.get_range(orbit_range)

    if ephases.size < min_degrees:
        raise NotEnoughDataError("Not enough datapoints for fit: "+str(ephases.size))

    #
    # initialize data points (coadd is always 1 as we only do ch8 nadir)
    #

    x = ephases-orbit, pet #, coadd

    # small pets should not be taken veryseriously, unless specified or the rest is saturated..
    if not short:
        idx = pet < .49
        if np.sum(idx) > 0:
            idx = np.where(idx)[0]
            all_sigmas[idx,:] *= 50

    #
    # setup attributes of fit parameters
    #

    # note the limits are just slightly wider than in the monthly fit. we do this to get rid of float32->float64 conversion errors!
    aoinfo = dict(fixed=True, limits=[-0.1,10000.1])
    dcinfo = dict(fixed=False, limits=[-10000.1,+500000.1])
    amp1info = dict(fixed=True, limits=[-200.1,+200.1])
    trendinfo = dict(fixed=False, limits=[-100.1,+100.1])
    amp2info = dict(fixed=True, limits=[-.41,+.41])
    phase1info = dict(fixed=True, limits=[-3.01,+3.01])
    phase2info = dict(fixed=True, limits=[-3.01,+3.01])
    parinfo = [aoinfo,dcinfo,amp1info,trendinfo,phase1info,amp2info,phase2info] 

    #
    # setup result data arrays
    #

    n_done = 0
    statuses = np.zeros(n_pix)
    res_trends = np.empty(n_pix)
    res_lcs = np.empty(n_pix)
    res_trends[:] = np.nan
    res_lcs[:] = np.nan
    err_trends = np.empty(n_pix)
    err_lcs = np.empty(n_pix)
    err_trends[:] = np.nan
    err_lcs[:] = np.nan
    uncertainty = np.empty(n_pix)
    uncertainty[:] = np.nan

    #
    # ..and fit
    #

    for pixnr in range(n_pix):
        # prepare initial parameters.. 
        p0 = np.array([aos[pixnr], lcs[pixnr], amps[pixnr], 0, channel_phaseshift, amp2, channel_phaseshift2]) 
        pix_readouts = all_readouts[:,pixnr]
        pix_sigmas = all_sigmas[:,pixnr]
        idx_fin = np.isfinite(pix_readouts) & (pix_sigmas > 0) & np.isfinite(pix_sigmas)
        if np.sum(idx_fin) > min_degrees:
            pix_readouts = pix_readouts[idx_fin]
            pix_sigmas = pix_sigmas[idx_fin]
            x = (ephases-orbit)[idx_fin], pet[idx_fin]
            n = pix_readouts.size

            fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
            residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
            dev_residual = np.std(residual)
            avg_residual = np.mean(residual)

            if kappasigma:
                # pass b : coarse kappa sigma filter 
                idx = (residual-avg_residual)**2 > 10.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 50
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)
                residual = scia_dark_fun2(fitobj.params, x) - pix_readouts
                dev_residual = np.std(residual)
                avg_residual = np.mean(residual)

                # pass c : finer kappa sigma filter 
                idx = (residual-avg_residual)**2 > 5.*dev_residual
                if np.sum(idx) > 0:
                    pix_sigmas[idx] *= 50
                fitobj = kmpfit.simplefit(scia_dark_fun2, p0, x, pix_readouts, err=pix_sigmas, ftol=1e-10, parinfo=parinfo)

            n_done += 1
        else:
            continue
        if verbose:
            print(pixnr, fitobj.message)
            print(p0, x, pix_readouts, pix_sigmas)
        if (fitobj.status <= 0):
            raise FitFailedError(fitobj.message)
        statuses[pixnr] = fitobj.status
        res_lcs[pixnr] = fitobj.params[1]
        err_lcs[pixnr] = fitobj.xerror[1]
        res_trends[pixnr] = fitobj.params[3]
        err_trends[pixnr] = fitobj.xerror[3]
        uncertainty[pixnr] = np.std(scia_dark_fun2(fitobj.params, x) - pix_readouts)

    if give_errors:
        return x, res_lcs, res_trends, err_lcs, err_trends, all_readouts, all_sigmas, uncertainty
    else:
        return x, res_lcs, res_trends, all_readouts, all_sigmas
예제 #11
0
def extract_gain_info(data_set, ccd, node):

    """
    create pha count profile from given data sets and fit model parameters
    input: data_set         --- a list of extracted fits data
           ccd              --- ccd #
           node             --- node #
    output: d_list : [al_cent, mn_cent, ti_cent, b, a, be, ae]
                    al_cent --- center of al line
                    mn_cent --- center of mn line
                    ti_cent --- center of ti line
                    b       --- slope of the fitted line
                    a       --- intercept of the fitted line
                    be      --- the error of the slope
                    ae      --- the error of the intercept
    """

#
#--- create a histgram data for specified CCD / Node combination
#
    hist = extract_hist_data(data_set, ccd, node)
#
#--- if the hist data is empty, just add an empty list for house keeping
#
    if hist == 'na':
        return []
#
#--- Mn K alpha
#
    y      = hist[1200:2500]

    ymax   = max(y)
    xpos   = y.index(ymax) + 1200
    hwidth = 200
#
#--- if the count rate is too low, we cannot fit the data; so limit data larger than 20 counts
#
    start  = xpos - hwidth
    stop   = xpos + hwidth
    ybin   = hist[start:stop]
    chk    = 0
    for ent in ybin:
        chk += int(ent)

    if chk < 20:
        return []

    [mn_amp, mn_cent, mn_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)
#
#--- AL K alpha
#
    ymax   = 0.5  * mn_amp
    xpos   = 0.25 * mn_cent
    hwidth = 50

    [al_amp, al_cent, al_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)
#
#--- Ti K alpha
#
    ymax   = 0.5   * mn_amp
    xpos   = 0.765 * mn_cent
    hwidth = 100

    [ti_amp, ti_cent, ti_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)

#
#--- fit a straight line
#
    pos      = [al_cent, ti_cent, mn_cent]
    p0       = [0, 1]
    fitobj   = kmpfit.simplefit(lmodel, p0, ev, pos)
    [a, b]   = fitobj.params
    [ae,be]  = fitobj.stderr

    d_list   = [al_cent, mn_cent, ti_cent, b, a, be, ae]

    return d_list        
예제 #12
0
def extract_gain_info(data_set, ccd, node):
    """
    create pha count profile from given data sets and fit model parameters
    input: data_set         --- a list of extracted fits data
           ccd              --- ccd #
           node             --- node #
    output: d_list : [al_cent, mn_cent, ti_cent, b, a, be, ae]
                    al_cent --- center of al line
                    mn_cent --- center of mn line
                    ti_cent --- center of ti line
                    b       --- slope of the fitted line
                    a       --- intercept of the fitted line
                    be      --- the error of the slope
                    ae      --- the error of the intercept
    """

    #
    #--- create a histgram data for specified CCD / Node combination
    #
    hist = extract_hist_data(data_set, ccd, node)
    #
    #--- if the hist data is empty, just add an empty list for house keeping
    #
    if hist == 'na':
        return []
#
#--- Mn K alpha
#
    y = hist[1200:2500]

    ymax = max(y)
    xpos = y.index(ymax) + 1200
    hwidth = 200
    #
    #--- if the count rate is too low, we cannot fit the data; so limit data larger than 20 counts
    #
    start = xpos - hwidth
    stop = xpos + hwidth
    ybin = hist[start:stop]
    chk = 0
    for ent in ybin:
        chk += int(ent)

    if chk < 20:
        return []

    [mn_amp, mn_cent, mn_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)
    #
    #--- AL K alpha
    #
    ymax = 0.5 * mn_amp
    xpos = 0.25 * mn_cent
    hwidth = 50

    [al_amp, al_cent, al_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)
    #
    #--- Ti K alpha
    #
    ymax = 0.5 * mn_amp
    xpos = 0.765 * mn_cent
    hwidth = 100

    [ti_amp, ti_cent, ti_width, floor] = fit_pmodel(hist, ymax, xpos, hwidth)

    #
    #--- fit a straight line
    #
    pos = [al_cent, ti_cent, mn_cent]
    p0 = [0, 1]
    fitobj = kmpfit.simplefit(lmodel, p0, ev, pos)
    [a, b] = fitobj.params
    [ae, be] = fitobj.stderr

    d_list = [al_cent, mn_cent, ti_cent, b, a, be, ae]

    return d_list