def test_axis(self): """Test sigma calculation when axis is not None""" self.mean, self.sigma = sigmaclip.calcsigma(self.data2d, self.errors2d, errors_as_weight=True) self.assertAlmostEqual(self.mean, 2.75) self.assertAlmostEqual(self.sigma, 1.898753053) self.mean, self.sigma = sigmaclip.calcsigma(self.data2d, self.errors2d, axis=0, errors_as_weight=True) self.assertEqual((abs(self.mean - numpy.array([2.0, 3.0])) < 1e-7).all(), True) self.assertEqual((abs(self.sigma - numpy.array([2.0, 2.0])) < 1e-7).all(), True) self.mean, self.sigma = sigmaclip.calcsigma(self.data2d, self.errors2d, axis=1, errors_as_weight=True) self.assertEqual((abs(self.mean - numpy.array([0.75, 2.75, 4.75])) < 1e-7).all(), True) self.assertEqual((abs(self.sigma - numpy.array( [0.70710678, 0.70710678, 0.70710678])) < 1e-7).all(), True) self.mean, self.sigma = sigmaclip.calcsigma(self.data3d, self.errors3d, axis=None, errors_as_weight=True) self.assertAlmostEqual(self.mean, 11.75) self.assertAlmostEqual(self.sigma, 7.10517533095) self.mean, self.sigma = sigmaclip.calcsigma(self.data3d, self.errors3d, axis=0, errors_as_weight=True) mean = numpy.array([[6., 7., 8., 9.], [10., 11., 12., 13.], [14., 15., 16., 17.]]) sigma = numpy.array([[8.48528137, 8.48528137, 8.48528137, 8.48528137], [8.48528137, 8.48528137, 8.48528137, 8.48528137], [8.48528137, 8.48528137, 8.48528137, 8.48528137]]) self.assertEqual((abs(self.mean - mean) < 1e-7).all(), True) self.assertEqual((abs(self.sigma - sigma) < 1e-7).all(), True) self.mean, self.sigma = sigmaclip.calcsigma(self.data3d, self.errors3d, axis=1, errors_as_weight=True) mean = numpy.array([[4., 5., 6., 7.], [16., 17., 18., 19.]]) sigma = numpy.array([[4., 4., 4., 4.], [4., 4., 4., 4.]]) self.assertEqual((abs(self.mean - mean) < 1e-7).all(), True) self.assertEqual((abs(self.sigma - sigma) < 1e-7).all(), True) self.mean, self.sigma = sigmaclip.calcsigma(self.data3d, self.errors3d, axis=2, errors_as_weight=True) mean = numpy.array([[1.75, 5.75, 9.75], [13.75, 17.75, 21.75]]) sigma = numpy.array([[1.31425748, 1.31425748, 1.31425748], [1.31425748, 1.31425748, 1.31425748]]) self.assertEqual((abs(self.mean - mean) < 1e-7).all(), True) self.assertEqual((abs(self.sigma - sigma) < 1e-7).all(), True)
def calc_background(self, niter=-50, kappa=(5, 5)): """ Estimate background flux Kwargs: niter (int): number of iterations. Passed on to sigmaclip() kappa (2-tuple of floats): lower and upper kappa values. Passed on to sigmaclip() Returns: (dict): mean, sigma, indices where light curve is at background level (True) and where not (False). Uses sigmaclipping to estimate a background. This only works well when there are enough background points. Also estimates the first point in time where the light curve deviates from the background (T_zero), and the current duration where the light curve is above the background. """ logger = logging.getLogger('tkp') indices = numpy.ones(self.fluxes.shape, dtype=numpy.bool) nniter = -niter if niter < 0 else niter for i in range(nniter): value = numpy.median(self.fluxes[indices]) # Get the sigma from the measured flux errors, instead of # deriving it from the spread in values sigma = numpy.mean(self.errors[indices]) # Throw away all data that are kappa*sigma above the current # background value newindices = numpy.logical_and( self.fluxes < value + kappa[1] * sigma, indices) if niter < 0: if (newindices == indices).all(): # no change anymore break indices = newindices # Now check if there are still data below the background # Above, we have assumed most transients rise above the # background, so we filter out increases in flux, not decreases # We do that here now # We can't do it at the same time as filtering the increase, # because that may filter too much at one for i in range(nniter): value = numpy.median(self.fluxes[indices]) # Get the sigma from the measured flux errors, instead of # deriving it from the spread in values sigma = numpy.mean(self.errors[indices]) # Throw away all data that are kappa*sigma above the current # background value newindices = numpy.logical_and( self.fluxes > value - kappa[0] * sigma, indices) if niter < 0: if (newindices == indices).all(): # no change anymore break indices = newindices if len(numpy.where(indices)[0]) > 1: value, sigma = calcsigma(self.fluxes[indices], self.errors[indices]) # Now that we have the proper background, recalculate the indices indices = (self.fluxes > value - sigma*kappa[0]) & (self.fluxes < value + sigma*kappa[1]) self.background['mean'] = value self.background['sigma'] = sigma self.background['indices'] = indices return self.background
def test_weighted(self): """Calculate weighted mean and sample standard deviation""" self.mean, self.sigma = sigmaclip.calcsigma(data=self.data, errors=self.errors, mean=None) self.assertAlmostEqual(self.mean, 22.3759213759) self.assertAlmostEqual(self.sigma, 1.15495684937)
def test_unweighted(self): """Calculate unweighted mean and sample standard deviation""" self.mean, self.sigma = sigmaclip.calcsigma(data=self.data, errors=None, mean=None) self.assertAlmostEqual(self.mean, 23.5714285714) self.assertAlmostEqual(self.sigma, 3.40867241299)