class Calibrate(object): ''' classdocs ''' def __init__(self, obj='', filtercol='V'): ''' Constructor: Initialize database set filtercolor ''' from datasource import DataSource self.wifsip = DataSource(database='wifsip', host='pina', user='******') self.obj = obj if filtercol in ('B', 'V', 'R', 'I'): self.filtercol = filtercol else: raise (ValueError) logging.basicConfig(filename=config.projectpath + 'calibration.log', format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO) logging.info('Object: %s', self.obj) logging.info('Setting filtercolor=%s', self.filtercol) def getframes(self, refframe): logging.info('getframes ...') query = "SELECT object FROM frames WHERE objid='%s';" % refframe obj = self.wifsip.query(query)[0][0] print(refframe, '-->', obj) logging.info('%s --> %s' % (refframe, obj)) query = """SELECT objid FROM frames WHERE object LIKE '%s' AND filter like '%s';""" % (obj, self.filtercol) result = self.wifsip.query(query) self.frames = [r[0] for r in result] logging.info('%d frames' % len(self.frames)) def getrefframes(self): ''' choose the frames with the highest number of matched stars for each field and filter ''' logging.info('getrefframes ...') query = """SELECT object,max(matched) FROM frames WHERE object LIKE '%s' AND filter = '%s' GROUP BY object ORDER BY object;""" % (self.obj, self.filtercol) result = self.wifsip.query(query) logging.info('%d frames' % len(result)) for r in result: print(r[0], '\t', r[1]) maxmatched = [{'object': r[0], 'matched': r[1]} for r in result] self.ref = [] for m in maxmatched: query = """SELECT objid FROM frames WHERE object LIKE '%s' AND filter like '%s' AND matched = %d;""" % \ (m['object'], self.filtercol, m['matched']) self.ref.append(self.wifsip.query(query)[0][0]) logging.info('%d frames' % len(self.ref)) def corrframes(self, refframe=''): logging.info('create view phot1') try: self.wifsip.execute('DROP VIEW phot1;') except psycopg2.ProgrammingError: logging.info('drop view phot1 failed') query = """CREATE VIEW phot1 AS SELECT * FROM phot WHERE objid='%s' AND phot.mag_auto>12 and phot.mag_auto<16 AND flags=0 ORDER BY phot.mag_auto;""" % (refframe) self.wifsip.execute(query) for frame in self.frames: query = """SELECT phot.mag_auto, phot1.mag_auto FROM phot, phot1 WHERE phot.objid='%s' AND circle(phot.coord,0) <@ circle(phot1.coord,0.15/3600.); """ % frame result = self.wifsip.query(query) if len(result) == 0: logging.warn('no data for frame %s' % frame) omag = np.array([r[0] for r in result]) cmag = np.array([r[1] for r in result]) mstd = np.std(omag - cmag) corr = np.mean(omag - cmag) s = '%s %6.3f %.3f %3d' % (frame, corr, mstd, len(omag)) logging.info(s) if len(omag) < 100 or mstd > 0.015: corr = np.nan # print '#' else: print(s) self.updateframe(frame, corr) logging.info('drop view phot1') self.wifsip.dropview('phot1') def updateframe(self, frame, corr): if np.isnan(corr): query = """UPDATE frames SET corr = NULL WHERE objid = '%s';""" % frame else: query = """UPDATE frames SET corr = %f WHERE objid = '%s';""" % (corr, frame) self.wifsip.execute(query) def resetframes(self): logging.info('reset frames') query = """UPDATE frames SET corr=NULL WHERE object LIKE '%s' AND filter like '%s';""" % (self.obj, self.filtercol) self.wifsip.execute(query)
class Photometry(object): ''' classdocs ''' def __init__(self, filtercol='V'): ''' Constructor ''' from datasource import DataSource self.wifsip = DataSource(database='wifsip', host='pina', user='******') if filtercol in ('B', 'V'): self.filtercol = filtercol else: raise (ValueError) self.frames = [] print 'filter %s' % self.filtercol def createtable(self): ''' create table for the photometry ''' if not raw_input('press Y to erase m48stars') == 'Y': return query = """ DROP TABLE IF EXISTS m48stars; CREATE TABLE m48stars( starid varchar(25), bv real, vmag real default 0, vmag_err real, bmag real default 0, bmag_err real, period real, period_err real, theta real, amp real, amp_err real, nv integer default 0, nb integer default 0, ra double precision, dec double precision, coord point, PRIMARY KEY (starid)); GRANT SELECT ON m48stars TO public; CREATE INDEX idx_m48stars_coords ON m48stars USING GIST (circle(coord,1.0/3600.)); """ self.wifsip.execute(query) print "table 'm48stars' created" def cleartable(self): if not raw_input('press Y to clear m48stars') == 'Y': return query = """ UPDATE m48stars SET vmag = 0, vmag_err = NULL, bmag = 0, bmag_err =NULL, nv = 0, nb = 0, bv = NULL; """ self.wifsip.execute(query) print "table 'm48stars' cleared" def getframes(self): for field in ['C', 'NW', 'NE', 'SW', 'SE']: query = """SELECT object, objid, abs(corr) FROM frames WHERE object LIKE 'M 48 BVI %s' AND filter LIKE '%s' AND NOT corr IS NULL ORDER BY abs(corr) limit 5;""" % (field, self.filtercol) result = self.wifsip.query(query) if len(result) == 0: print 'no frames found!' for r in result: print '%s\t%s\t%.3f: ' % r objid = r[1] self.filltable(objid) self.frames.append(objid) self.wifsip.dropview('phot1') self.update_magnitudes() #print '\n'.join(self.frames) def filltable(self, objid): #get the stars from the phot table ... query = """ SELECT phot.objid ||'#'|| star, mag_auto-corr, alphawin_j2000 , deltawin_j2000 FROM phot,frames WHERE frames.objid='%s' AND phot.objid=frames.objid AND flags<8;""" % (objid) result = self.wifsip.query(query) #... and inject them into the m48stars stars = len(result) if stars > 400: print '%5d stars: ' % stars, oldstars = 0 newstars = 0 for r in result: ostars = self.addstar(r[0], r[1], r[2], r[3]) if ostars == 0: newstars += 1 else: oldstars += 1 print '%5d old , %5d new' % (oldstars, newstars) self.wifsip.commit() else: print 'not enough stars (%d)' % stars #value = '%s\t%f\t%f\t%f' % r #print value def addstar(self, starid, mag, ra, dec): # identify by coordinates, if the star is already in table query = """SELECT starid FROM m48stars WHERE circle(point(%f,%f),0)<@circle(coord,1.0/3600.) ORDER BY point(%f,%f)<->coord LIMIT 1;""" % (ra, dec, ra, dec) result = self.wifsip.query(query) oldstar = 0 # if not: append new star if len(result) == 0: oldstar = 0 if self.filtercol == 'B': query = """INSERT INTO m48stars (starid, bmag, nb, ra, dec, coord) VALUES ('%s', %f, 1, %f, %f, point(%f,%f))""" % ( starid, mag, ra, dec, ra, dec) elif self.filtercol == 'V': query = """INSERT INTO m48stars (starid, vmag, nv, ra, dec, coord) VALUES ('%s', %f, 1, %f, %f, point(%f,%f))""" % ( starid, mag, ra, dec, ra, dec) # if star exists: add up magnitudes, increase counter else: oldstar = 1 oldid = result[0][0] if self.filtercol == 'B': query = """UPDATE m48stars SET bmag = bmag + %f, nb = nb + 1 WHERE starid = '%s'; """ % (mag, oldid) elif self.filtercol == 'V': query = """UPDATE m48stars SET vmag = vmag + %f, nv = nv + 1 WHERE starid = '%s'; """ % (mag, oldid) self.wifsip.execute(query) return oldstar def update_magnitudes(self): if self.filtercol == 'B': query = """UPDATE m48stars SET bmag=bmag/nb WHERE nb>1; UPDATE m48stars SET bmag=NULL WHERE nb=0;""" elif self.filtercol == 'V': query = """ UPDATE m48stars SET vmag=vmag/nv WHERE nv>1; UPDATE m48stars SET vmag=NULL WHERE nv=0;""" self.wifsip.execute(query) def update_sigmas(self): import numpy as np if self.filtercol == 'V': field = 'vmag' elif self.filtercol == 'B': field = 'bmag' query = """SELECT starid, coord FROM m48stars WHERE (NOT bv IS NULL) AND (%s_err IS NULL);""" % (field) starlist = self.wifsip.query(query) for star in starlist: print '%5d ' % starlist.index(star), print '%-24s: %-25s' % star, query = """SELECT phot.objid, mag_auto-corr FROM phot, frames WHERE object like 'M 48 BVI %%' AND phot.objid=frames.objid AND filter='%s' AND flags<8 AND point%s <@ circle(phot.coord,1./3600.) ORDER BY abs(corr) LIMIT 5;""" % (self.filtercol, star[1]) result = self.wifsip.query(query) mags = np.array([r[1] for r in result]) try: err = np.std(mags) print mags, print '%.3f %.4f' % (np.mean(mags), err) if np.isfinite(err): query = "UPDATE m48stars SET %s_err=%f WHERE starid='%s';" % ( field, err, star[0]) self.wifsip.execute(query) except TypeError: print 'no data' def update_bv(self): query = "UPDATE m48stars SET bv = bmag-vmag;" self.wifsip.execute(query)
class Photometry(object): ''' Photometry class has the following tasks: * create the db table * optionally clear the values for recalculation * build up a list of stars * collect B and V magnitudes for each star ''' def __init__(self, objname=None, filtercol='V', dbname=None): ''' Constructor ''' self.wifsip = DataSource(database='wifsip', host='pina', user='******') print(objname) if objname is None: # 'M48 BVI' raise (ValueError, 'objname not set') else: self.objname = objname if filtercol in ('B', 'V', 'R', 'I', 'u', 'v', 'b', 'y', 'hbn', 'hbw'): self.filtercol = filtercol else: raise (ValueError, 'unknown filter color') self.frames = [] if dbname is None: # 'M48stars' raise (ValueError, 'tablename not set') else: self.dbname = dbname print('filter %s' % self.filtercol) def createtable(self): ''' create table for the photometry ''' if not input('press Y to erase ' + self.dbname) == 'Y': return query = """ DROP TABLE IF EXISTS %(dbname)s; CREATE TABLE %(dbname)s( starid varchar(25), bv real, vmag real default 0, vmag_err real, bmag real default 0, bmag_err real, period real, period_err real, amp real, amp_err real, nv integer default 0, nb integer default 0, ra double precision, dec double precision, coord point, PRIMARY KEY (starid)); GRANT SELECT ON %(dbname)s TO public; CREATE INDEX idx_%(dbname)s_coords ON %(dbname)s USING GIST (circle(coord,1.0/3600.)); """ % { 'dbname': self.dbname } self.wifsip.execute(query) print("table '%s' created" % self.dbname) def cleartable(self): """ clears photometric values from the table for recalculation """ if not input('press Y to clear ' + self.dbname) == 'Y': return query = """ UPDATE %s SET vmag = 0, vmag_err = NULL, bmag = 0, bmag_err = NULL, nv = 0, nb = 0, bv = NULL; """ % self.dbname self.wifsip.execute(query) print("table '%s' cleared" % self.dbname) def getframes(self, fields=['C', 'NW', 'NE', 'SW', 'SE']): for field in fields: if len(field) > 0: objname = self.objname + ' ' + field else: objname = self.objname query = """SELECT object, objid, abs(corr) FROM frames WHERE object LIKE '%s' AND filter LIKE '%s' AND NOT corr IS NULL ORDER BY abs(corr) limit 5;""" % (objname, self.filtercol) result = self.wifsip.query(query) if len(result) == 0: print('no frames found!') for r in result: print('%s\t%s\t%.3f: ' % r) objid = r[1] self.filltable(objid) self.frames.append(objid) self.wifsip.dropview('phot1') self.update_magnitudes() # print '\n'.join(self.frames) def filltable(self, objid): # get the stars from the phot table ... query = """ SELECT phot.objid ||'#'|| star, mag_auto-corr, alphawin_j2000 , deltawin_j2000 FROM phot,frames WHERE frames.objid='%s' AND phot.objid=frames.objid AND flags<8;""" % (objid) result = self.wifsip.query(query) # ... and inject them into the m48stars stars = len(result) if stars > 400: print('%5d stars: ' % stars, end=' ') oldstars = 0 newstars = 0 for r in result: ostars = self.addstar(r[0], r[1], r[2], r[3]) if ostars == 0: newstars += 1 else: oldstars += 1 print('%5d old , %5d new' % (oldstars, newstars)) self.wifsip.commit() else: print('not enough stars (%d)' % stars) def addstar(self, starid, mag, ra, dec): # identify by coordinates, if the star is already in table query = """SELECT starid FROM %(dbname)s WHERE circle(point(%(ra)f,%(dec)f),0)<@circle(coord,1.0/3600.) ORDER BY point(%(ra)f,%(dec)f)<->coord LIMIT 1;""" % { 'dbname': self.dbname, 'ra': ra, 'dec': dec } result = self.wifsip.query(query) oldstar = 0 # if not: append new star if self.filtercol == 'B': mname, nname = ('bmag', 'nb') elif self.filtercol == 'V': mname, nname = ('vmag', 'nv') if len(result) == 0: oldstar = 0 query = """INSERT INTO %s (starid, %s, %s, ra, dec, coord) VALUES ('%s', %f, 1, %f, %f, point(%f,%f))""" % \ (self.dbname, mname, nname, starid, mag, ra, dec, ra, dec) # if star exists: add up magnitudes, increase counter else: oldstar = 1 oldid = result[0][0] query = """UPDATE %(dbname)s SET %(mname)s = %(mname)s + %(mag)f, %(nname)s = %(nname)s + 1 WHERE starid = '%(oldid)s'; """ % { 'dbname': self.dbname, 'mname': mname, 'nname': nname, 'mag': mag, 'oldid': oldid } self.wifsip.execute(query) return oldstar def update_magnitudes(self): if self.filtercol == 'B': magfield, nfield = 'bmag', 'nb' elif self.filtercol == 'V': magfield, nfield = 'vmag', 'nv' query = """UPDATE %(dbname)s SET %(magfield)s=%(magfield)s/%(nfield)s WHERE %(nfield)s>1; UPDATE %(dbname)s SET %(magfield)s=NULL WHERE %(nfield)s=0;""" % \ {'dbname': self.dbname, 'magfield': magfield, 'nfield': nfield} self.wifsip.execute(query) def update_sigmas(self): """ update the photometric erros after the magnitude has been calculated """ import numpy as np if self.filtercol == 'V': field = 'vmag' elif self.filtercol == 'B': field = 'bmag' query = """SELECT starid, coord FROM %s WHERE (NOT bv IS NULL) AND (%s_err IS NULL);""" % (self.dbname, field) starlist = self.wifsip.query(query) for star in starlist: print('%5d ' % starlist.index(star), end=' ') print('%-24s: %-25s' % star, end=' ') query = """SELECT phot.objid, mag_auto-corr FROM phot, frames WHERE object like '%s %%' AND phot.objid=frames.objid AND filter='%s' AND flags<8 AND point%s <@ circle(phot.coord,1./3600.) ORDER BY abs(corr) LIMIT 5;""" % (self.objname, self.filtercol, star[1]) result = self.wifsip.query(query) mags = np.array([r[1] for r in result]) try: err = np.std(mags) print(mags, end=' ') print('%.3f %.4f' % (np.mean(mags), err)) if np.isfinite(err): query = "UPDATE %s SET %s_err=%f WHERE starid='%s';" % \ (self.dbname, field, err, star[0]) self.wifsip.execute(query) except TypeError: print('no data') def update_bv(self): """ just calculate the B-V """ query = "UPDATE %s SET bv = bmag-vmag;" % self.dbname self.wifsip.execute(query)