Exemple #1
0
class NGC6633Table(object):
    def __init__(self):
        '''
        Constructor
        '''
        try:
            self._fromfile()
        except:
            self._fromdatabase()
            self._tofile()

    def _fromdatabase(self):
        """
        import the table from a database
        """
        from datasource import DataSource
        from astropy.coordinates import SkyCoord  # @UnresolvedImport
        from astropy import units as u
        self.wifsip = DataSource(database=config.dbname, user=config.dbuser, host=config.dbhost)
        self.stars = []
        columns = self.wifsip.columns('ngc6633')
        
        params = {'columns': ', '.join(columns),
                  'key': columns[0]} 
        query = "SELECT %(columns)s FROM ngc6633 ORDER BY %(key)s;" % params 
        self._stars = self.wifsip.query(query)
        
        columns = self.wifsip.columns('ngc6633')
        data_types = self.wifsip.data_types('ngc6633')
        
        arraydata = []
        c = columns.index('coord')
        for star in self._stars:
            starlist = list(star)
            coord = star[c]
            ra, dec = coord.strip('()').split(',')
            
            newcoord = SkyCoord(ra=float(ra)*u.deg, dec=float(dec)*u.deg)
            starlist[c] = newcoord
            arraydata.append(tuple(starlist))
        
        dtype = zip(columns, data_types)
        #print dtype
        self.stars = np.array(arraydata, dtype = dtype)
        
    def _fromfile(self, filename=None):
        """
        unpickle the data from a file
        """
        import pickle
        
        if filename is None:
            filename = config.datapath+'/stars.pickle'
        with open(filename,'rb') as picklefile:
            self.stars = pickle.load(picklefile)
    
    def _tofile(self, filename=None):
        """
        pickle the data to a file
        """
        import pickle
        
        if filename is None:
            filename = config.datapath+'/stars.pickle'
        with open(filename, 'wb') as picklefile:
            pickle.dump(self.stars, picklefile)
Exemple #2
0
class Analysis(object):
    def __init__(self):
        '''
        Constructor
        '''
        from datasource import DataSource

        self.wifsip = DataSource(database=config.dbname,
                                 user=config.dbuser,
                                 host=config.dbhost)
        self.stars = []
        query = "SELECT starid, bv ,vmag ,vmag_err from ngc6633;"
        self._stars = self.wifsip.query(query)

        columns = self.wifsip.columns('ngc6633')
        data_types = self.wifsip.data_types('ngc6633')

        for c, d in zip(columns, data_types):
            print c, d
        arraydata = []
        for star in self._stars:
            arraydata.append(tuple(star))
        columns = ['starid', 'bv', 'vmag', 'vmag_err']
        data_types = ['S25', np.float16, np.float16, np.float16]
        self.stars = np.array(arraydata, dtype=zip(columns, data_types))


#        self.age = 10**8.557/1e6 # in Myr from Webda
#        self.ebv = 0.031 # from Webda
#        self.dm = 9.53 # from Webda

    def getstars(self):
        """
        build up a list of stars, where we do not have periods yet
        """
        query = "SELECT starid, vmag, bv" \
        " FROM ngc6633 " \
        " WHERE vmag<18 " \
        " AND vmag < 10 + bv*5.4 " \
        " AND vmag > 7.5 + bv*5.4" \
       # " AND bv>0.4 " \
        " AND NOT good IS NULL" \
        " ORDER BY vmag LIMIT 100;"

        result = self.wifsip.query(query)
        print '... %d stars found' % len(result)
        self.stars = [s[0] for s in result]
        self.vmag = [s[1] for s in result]
        self.bv = [s[2] for s in result]

    def setperiod(self, starid, period, theta=1.0):
        self.starid = starid
        params = {'starid': starid, 'period': period, 'theta': theta}
        if np.isfinite(period):
            query = """UPDATE ngc6633 SET period = %(period)f, theta = %(theta)f WHERE starid='%(starid)s';""" % params
        else:
            query = """UPDATE ngc6633 SET period = NULL, theta=NULL WHERE starid='%(starid)s';""" % params
        self.wifsip.execute(query)

    def setamp(self, starid, amplitude):
        self.starid = starid
        params = {'starid': starid, 'amp': amplitude}
        if np.isfinite(amplitude):
            query = """UPDATE ngc6633 SET amp = %(amp)f WHERE starid='%(starid)s';""" % params
        else:
            query = """UPDATE ngc6633 SET amp = NULL WHERE starid='%(starid)s';""" % params
        self.wifsip.execute(query)

    def setbad(self, starid):
        self.starid = starid
        query = """UPDATE ngc6633 SET good = False WHERE starid='%s';""" % starid
        self.wifsip.execute(query)

    #def __setattr__(self, name, value):
    #    params = {'starid': self.starid, 'name': name, 'value': str(value)}
    #
    #    query = """UPDATE ngc6633 SET %(name)s = %(value)s WHERE starid='%(starid)s';""" % params
    #    self.wifsip.execute(query)

    #def __getattribute__(self, name):
    #    params = {'starid': self.starid, 'name': name}
    #    query = "SELECT %(name)s from ngc6633 WHERE starid='%(starid)s';" % params
    #    result = self.wifsip.query(query)
    #    return result[0]

    def plot_lightcurve(self):
        """
        plot the lightcurve for a given star
        """
        mean = np.mean(self.mag)
        plt.hlines(mean, min(self.hjd), max(self.hjd), linestyle='--')
        plt.xlim(min(self.hjd), max(self.hjd))
        plt.grid()
        plt.errorbar(self.hjd, self.mag, yerr=self.err * 0.5, fmt='o')
        ylim = plt.ylim()
        plt.ylim(ylim[1], ylim[0])

    def plot_clean(self, periods, amplitudes):
        plt.plot(periods, amplitudes, 'k')
        i = np.argmax(amplitudes)
        period = periods[i]
        plt.axvline(x=period, color='red', alpha=0.5)
        plt.axhline(np.mean(amplitudes), color='b', ls='--')
        plt.axhline(5. * np.mean(amplitudes), color='g', ls='--')
        plt.xlim(min(periods), max(periods))
        plt.minorticks_on()

    def plot_pdm(self, periods, thetas):
        #plt.plot(periods, thetas, 'k')

        from scipy import signal
        kernel = signal.gaussian(101, 2)
        n = len(thetas) / 2
        padded_thetas = np.lib.pad(thetas,
                                   n,
                                   mode='constant',
                                   constant_values=(1.0, 1.0))
        smoothed = signal.fftconvolve(padded_thetas, kernel,
                                      mode='same')[n:-n] / 5
        plt.plot(periods, smoothed, 'k')
        i = np.argmin(smoothed)
        period = periods[i]
        plt.axvline(x=period, color='red', alpha=0.5)
        plt.axhline(0.8, color='b', ls='--')

        plt.xlim(min(periods), max(periods))
        plt.ylim(0.0, 1.0)
        plt.minorticks_on()

    def plot_phase(self, period):
        from functions import phase
        tp, yp = phase(self.hjd, self.mag, period)

        s1 = np.sin(2 * np.pi * tp / period)
        c1 = np.cos(2 * np.pi * tp / period)
        s2 = np.sin(4 * np.pi * tp / period)
        c2 = np.cos(4 * np.pi * tp / period)

        A = np.column_stack((np.ones(tp.size), s1, c1, s2, c2))
        c, _, _, _ = np.linalg.lstsq(A, yp)

        tp1 = np.linspace(0.0, 2 * period, 100)
        s1 = np.sin(2 * np.pi * tp1 / period)
        c1 = np.cos(2 * np.pi * tp1 / period)
        s2 = np.sin(4 * np.pi * tp1 / period)
        c2 = np.cos(4 * np.pi * tp1 / period)

        plt.scatter(tp, yp, edgecolor='none', alpha=0.75)
        plt.scatter(tp + period, yp, edgecolor='none', alpha=0.75)
        plt.plot(tp1,
                 c[1] * s1 + c[2] * c1 + c[3] * s2 + c[4] * c2,
                 'k',
                 linestyle='--',
                 linewidth=2)
        plt.xlim(0.0, 2 * period)
        plt.ylim(max(yp - np.mean(yp)), min(yp - np.mean(yp)))
        plt.xlabel('P = %.4f' % period)

    def analysis(self, show=False):
        """perform a PDM analysis on each lightcurve"""
        from matplotlib import rcParams
        print 'Analysis'

        fig_width = 18.3 / 2.54  # width in inches, was 7.48in
        fig_height = 23.3 / 2.54  # height in inches, was 25.5
        fig_size = [fig_width, fig_height]
        #set plot attributes
        params = {
            'backend': 'Agg',
            'axes.labelsize': 12,
            'axes.titlesize': 12,
            'font.size': 12,
            'xtick.labelsize': 12,
            'ytick.labelsize': 12,
            'figure.figsize': fig_size,
            'savefig.dpi': 300,
            'font.family': 'sans-serif',
            'axes.linewidth': 0.5,
            'xtick.major.size': 2,
            'ytick.major.size': 2,
        }
        rcParams.update(params)

        minperiod = 1.3
        maxperiod = 15

        for starid, vmag, bv in zip(self.stars, self.vmag, self.bv):
            print '%-24s ' % starid,
            try:
                lc = LightCurve(starid)

            except IOError:
                logger.error("Can't load lightcurve %s" % starid)
                print 'no lightcurve'
                self.setbad(starid)
                continue

            if len(lc) < 50:
                logger.warn("%s: not enough datapoints" % starid)
                print 'not enough datapoints'
                continue
            # perform a 3sigma clipping
            i = np.where(lc.hjd > 2456762)[0]
            lc.mag = lc.mag[i]
            lc.hjd = lc.hjd[i]
            lc.normalize()
            lc.clip()
            lc.detrend()
            lc.sigma_clip()
            lc.normalize()

            self.hjd = lc.hjd
            self.mag = lc.mag
            self.err = lc.err

            clean_periods, clean_amplitudes = lc.clean(minperiod, maxperiod)
            pdm_periods, pdm_thetas = lc.pdm(minperiod, maxperiod)
            #period = clean_periods[np.argmax(clean_amplitudes)]

            from scipy import interpolate

            i = np.argsort(clean_periods)
            c_periods = clean_periods[i]
            c_amps = clean_amplitudes[i]
            c_periods = np.insert(c_periods, 0, 0.0)
            c_amps = np.insert(c_amps, 0, 0.0)
            c_periods = np.insert(c_periods, -1, maxperiod)
            c_amps = np.insert(c_amps, -1, 0.0)
            c_int = interpolate.interp1d(c_periods, c_amps)

            # use interpolation function returned by `interp1d`
            sum_amp = c_int(pdm_periods) * (1. - pdm_thetas)
            sum_amp /= max(sum_amp)
            i = np.argmax(sum_amp)
            period = pdm_periods[i]
            theta = pdm_thetas[i]

            import functions as fx

            ci = np.argmax(c_amps)
            try:
                pgf_amp, pgf_mean, pgf_sigma = fx.gauss_fit(
                    pdm_periods, 1. - pdm_thetas, pdm_thetas[i], period, 1.0)
            except:
                pgf_sigma = 0.0
            try:
                cgf_amp, cgf_mean, cgf_sigma = fx.gauss_fit(
                    c_periods, c_amps, c_amps[ci], c_periods[ci], 1.0)
            except:
                cfg_sigma = 0.0

            sigma_limit = 5.3
            theta_limit = 0.8
            try:
                ci = np.argmax(c_amps)

                params = {
                    'period': period,
                    'period_err': pgf_sigma,
                    'clean_period': c_periods[ci],
                    'clean_amp': c_amps[ci],
                    'clean_sigma': cgf_sigma,
                    'theta': theta,
                    'freq': period,
                }

                keys = ', '.join(params.keys())
                values = ', '.join([str(v) for v in params.values()])

                query = """UPDATE ngc6633 SET (%s) = (%s) WHERE starid='%s';""" % (
                    keys, values, starid)
                self.wifsip.execute(query)
            except:
                print 'Cannot store params for starid %s' % starid

            mamp = np.mean(clean_amplitudes)
            if max(clean_amplitudes
                   ) > sigma_limit * mamp and pdm_thetas[i] < theta_limit:
                print "%.2f %.1f" % (period, max(clean_amplitudes) / mamp)
                self.setperiod(starid, period)
            else:
                print '< %.1f sigmas or  theta %.2f > %.2f' % (
                    sigma_limit, pdm_thetas[i], theta_limit)
                self.setperiod(starid, np.nan)
                continue

            amp, _ = lc.phased(period)
            self.setamp(starid, amp)

            star = {'tab': 0, 'bv': bv}

            plt.subplot(
                411)  ##################################################
            plt.title('%s (%d) V = %.2f B-V=%.2f' %
                      (starid, star['tab'], vmag, bv))
            self.plot_lightcurve()

            plt.subplot(
                412)  ##################################################
            self.plot_clean(clean_periods, clean_amplitudes)

            plt.subplot(
                413)  ##################################################
            plt.plot(pdm_periods, sum_amp, 'g')
            plt.axvline(period, color='b')
            self.plot_pdm(pdm_periods, pdm_thetas)

            plt.subplot(
                414)  ##################################################
            self.plot_phase(period)

            #             plt.scatter(tp, yp-np.mean(yp), edgecolor='none', alpha=0.75)
            #             plt.plot(tp1,c[1]*s1+c[2]*c1+c[3]*s2+c[4]*c2, 'k',
            #                      linestyle='--', linewidth=2)
            #             plt.xlim(0.0,period)
            #             plt.ylim(max(yp-np.mean(yp)),min(yp-np.mean(yp)))
            #             plt.xlabel('P = %.4f' % period)
            #             plt.grid()
            #             #plt.show()
            #             period_err = 0.0
            #             comment = 'P=%6.3f+-%.3f a=%.3f+-%.4f %.2f' % \
            #             (period, period_err, amp, amp_err, theta)
            #             plt.savefig(config.plotpath+'%s(%d).pdf' % (starid,star['tab']))
            #             plt.close()
            #
            #             logger.info( comment)
            #             print comment
            if show: plt.show()
            else:
                plt.savefig(config.plotpath + '%s(%d).pdf' %
                            (starid, star['tab']))
            plt.close()