IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 12, 2014, 4:10:18 PM (12 years ago)
Author:
eugene
Message:

merge changes from branches/eam_branches/ipp-20140717

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippToPsps/jython/stackbatch.py

    r37106 r37246  
    1 q#!/usr/bin/env jython
     1#!/usr/bin/env jython
    22
    33import os.path
    44import glob
    55import sys
    6 
     6import math
    77
    88import stilts
     
    1717from ipptopspsdb import IppToPspsDb
    1818from scratchdb import ScratchDb
     19from sqlUtility import sqlUtility
    1920
    2021import logging.config
     
    3940                 scratchDb,
    4041                 skyID,
    41                  batchID,
    42                  useFullTables):
     42                 batchID):
    4343
    4444       super(StackBatch, self).__init__(
     
    5252               batchID,
    5353               "ST",
    54                "",
    55                #gpc1Db.getStackStageCmf(skychunk.dvoLabel, stackID),
    56                useFullTables)
    57 
    58        # self.printline = 0
    59        # # self.testprint()
    60 #       self.logger.infoPair("did I get", "here");
     54               None)
     55
    6156       self.stackType = "DEEP_STACK" # TODO
    62        ## = stuff I commented out for pv2 stacks
     57       self.stackTypeID = self.getStackTypeID()
    6358       
    64        #heather tasks
    65 
    66        # get a list of stackIDs
    67        self.logger.infoPair ("getting stackID for: ","g.00000")
    68        gstackID = gpc1Db.getStackIDFromSkyIDAndFilter( skychunk.dvoLabel, skyID, "g.00000")
    69        self.logger.infoPair ("getting stackID for: ","r.00000")
    70        rstackID = gpc1Db.getStackIDFromSkyIDAndFilter( skychunk.dvoLabel, skyID, "r.00000")
    71        self.logger.infoPair ("getting stackID for: ","i.00000")
    72        istackID = gpc1Db.getStackIDFromSkyIDAndFilter( skychunk.dvoLabel, skyID, "i.00000")
    73        self.logger.infoPair ("getting stackID for: ","z.00000")
    74        zstackID = gpc1Db.getStackIDFromSkyIDAndFilter( skychunk.dvoLabel, skyID, "z.00000")
    75        self.logger.infoPair ("getting stackID for: ","y.00000")
    76        ystackID = gpc1Db.getStackIDFromSkyIDAndFilter( skychunk.dvoLabel, skyID, "y.00000")
    77  #      self.logger.infoPair("g stackID ",gstackID)       
    78  #      self.logger.infoPair("r stackID ",rstackID)
    79  #      self.logger.infoPair("i stackID ",istackID)
    80  #      self.logger.infoPair("z stackID ",zstackID)
    81  #      self.logger.infoPair("y stackID ",ystackID)
    82  #      raise
    83        # from each stackget fits name from getStackStageCmf
    84        if gstackID > 0:
    85            self.logger.infoPair ("finding fits file for: ","g.00000")
    86            gfits = gpc1Db.getStackStageCmf(skychunk.dvoLabel, gstackID)
    87            self.gfits = gfits
    88        if rstackID > 0:   
    89            self.logger.infoPair ("finding fits file for: ","r.00000")
    90            rfits = gpc1Db.getStackStageCmf(skychunk.dvoLabel, rstackID)
    91            self.rfits = rfits
    92        if istackID > 0:   
    93            self.logger.infoPair ("finding fits file for: ","i.00000")
    94            ifits = gpc1Db.getStackStageCmf(skychunk.dvoLabel, istackID)
    95            self.ifits = ifits
    96        if zstackID > 0:   
    97            self.logger.infoPair ("finding fits file for: ","z.00000")
    98            zfits = gpc1Db.getStackStageCmf(skychunk.dvoLabel, zstackID)
    99            self.zfits = zfits
    100        if ystackID > 0:   
    101            self.logger.infoPair ("finding fits file for: ","y.00000")
    102            yfits = gpc1Db.getStackStageCmf(skychunk.dvoLabel, ystackID)
    103            self.yfits = yfits
    104 
    105        #from each of those get self.gheader, self.rheader, etc.
    106        if gstackID > 0:   
    107            if gfits:
    108                gheader = gfits.getPrimaryHeader()
    109                if not gheader:
    110                    self.logger.errorPair("could not read FITS PHU for ",gstackID)
    111                    raise
    112                self.gheader = gheader
    113        if rstackID > 0:       
    114            if rfits:
    115                rheader = rfits.getPrimaryHeader()
    116                if not rheader:
    117                    self.logger.errorPair("could not read FITS PHU for ",rstackID)
    118                    raise
    119                self.rheader = rheader
    120        if istackID > 0:       
    121            if ifits:
    122                iheader = ifits.getPrimaryHeader()
    123                if not iheader:
    124                    self.logger.errorPair("could not read FITS PHU for ",istackID)
    125                    raise
    126                self.iheader = iheader
    127        if zstackID > 0:
    128            if zfits:
    129                zheader = zfits.getPrimaryHeader()
    130                if not zheader:
    131                    self.logger.errorPair("could not read FITS PHU for ",zstackID)
    132                    raise
    133                self.zheader = zheader
    134        if ystackID > 0:
    135            if yfits:
    136                yheader = yfits.getPrimaryHeader()
    137                if not yheader:
    138                    self.logger.errorPair("could not read FITS PHU for ",ystackID)
    139                    raise
    140                self.yheader = yheader
    141        # get stack meta data
    142        self.gstackID = gstackID
    143        self.rstackID = rstackID
    144        self.istackID = istackID     
    145        self.zstackID = zstackID
    146        self.ystackID = ystackID
    147 
    148        metastackid = -999
    149        if gstackID > 0:
    150            metastackid = gstackID
    151        if rstackID > 0:
    152            metastackid = rstackID
    153        if istackID > 0:
    154            metastackid = istackID   
    155        if zstackID > 0:
    156            metastackid = zstackID
    157        if ystackID > 0:
    158            metastackid = ystackID
    159        #there is probably a better way to do this
    160        if metastackid < 0:
    161            self.logger.errorPair("can't find any stack ids...?? ","??")
     59       self.filters = ['g', 'r', 'i', 'z', 'y']
     60       self.stackIDs = {}
     61       self.imageIDs = {}
     62       self.fits = {}
     63       self.headerSet = {}
     64
     65       # we have two sets of imageIDs here:
     66
     67       # stackID : this is the id from the gpc1 stack table and (should) match the
     68       # cmf header keyword 'IMAGEID', this is also called EXTERN_ID in dvoImagesTable
     69       
     70       # imageID : this is the DVO-internal image ID for the stack cmf, and is called
     71       # IMAGE_ID in dvoImagesTable
     72
     73       # we just need one valid filter to get the generic metadata
     74       validFilter = 'none'
     75
     76       # get a list of stackIDs, identify the CMFs, read the headers:
     77       for filter in self.filters:
     78           filterName = filter + ".00000"
     79
     80           self.logger.infoPair ("getting stackID for: ", filterName)
     81           stackID = gpc1Db.getStackIDFromSkyIDAndFilter(skychunk.dvoLabel, skyID, filterName)
     82           self.stackIDs[filter] = stackID
     83
     84           if (stackID <= 0):
     85               continue
     86               
     87           validFilter = filter
     88
     89           # from each stack, get fits name from getStackStageCmf
     90           self.logger.infoPair ("finding fits file for: ", filterName)
     91           self.fits[filter] = gpc1Db.getStackStageCmf(skychunk.dvoLabel, stackID)
     92           if not self.fits[filter]:
     93               self.logger.errorPair("could not find cmf file name for ", stackID)
     94               raise
     95
     96           header = self.fits[filter].getPrimaryHeader()
     97           if not header:
     98               self.logger.errorPair("could not read FITS PHU for ", stackID)
     99               raise
     100
     101           self.headerSet[filter] = header
     102
     103           self.logger.infoPair(filter + " stackID = ", stackID)       
     104
     105           if not (str(stackID) == header['IMAGEID']):
     106               self.logger.errorPair("inconsistency: header IMAGEID does not match stackID", str(stackID) + " vs " + header['IMAGEID'])
     107               raise
     108
     109           imageID = self.scratchDb.getImageIDFromExternID(stackID)
     110           self.logger.infoPair(filter + " imageID = ", imageID)       
     111           self.imageIDs[filter] = imageID
     112
     113       # did we find any valid stacks?
     114       if validFilter == 'none':
     115           self.logger.errorPair("can't find any valid stacks...?? ","??")
    162116           raise
    163117   
    164        meta = self.gpc1Db.getStackStageMeta(metastackid) 
    165        ## this should be ok - it takes a stack_id and returns filter/skycell etc.
    166 
    167 
    168        if not meta:
    169            self.logger.errorPair("Could not get stack", "metadata")
     118       validStackID = self.stackIDs[validFilter]
     119
     120       # using the given stack ID, get the generic information: filter, skycell, etc.
     121       metadata = self.gpc1Db.getStackStageMeta(validStackID) 
     122
     123       if not metadata:
     124           self.logger.errorPair("Could not get stack metadata for", validStackID)
    170125           raise
    171126
    172        #self.filter = meta[0];
    173        #self.filter = self.filter[0:1]
    174        #self.filterID = self.scratchDb.getFilterID(self.filter)
    175        self.skycell = meta[1];
    176 
    177        # self.testprint()
    178 
    179        # skycell is, eg "skycell.1133.081"
    180        # we need 1133.081 for skycell, but store as an int, so instead store 1133081
    181        # projection cell is just the 1133 bit
    182        # This Is how it should be done
    183        #self.projectioncell = self.skycell[8:12]
    184        #self.skycell = self.skycell[8:]
    185        #self.skycell = self.skycell.replace(".", "")
    186        #self.projectioncell = self.skycell[8:12]
    187 
    188        # TODO this is the wrong way, but is consistent with SkyCell table in IN data
    189        self.skycell = self.skycell[8:]
    190        self.projectioncell = self.skycell
    191 
    192        # self.testprint()
    193 
    194        # proposed new values. Need to coordinate with the SkyCell table
    195        # this fits in 32 bits for 0 < tessID < 214
    196        # self.skycell = str( (tessID * (10000 * 1000)) + (int(self.projectioncell) * 1000) + cellID )
    197 
    198        self.analysisVer = meta[2];
    199 
    200        #self.expTime = gpc1Db.getStackExpTime(self.id)
     127       validHeader = self.headerSet[validFilter]
     128
     129       tessName = self.getKeyValue(header, 'TESS_ID')
     130       self.tessID = self.scratchDb.getTessID(tessName)
     131
     132       skycellName = self.getKeyValue(header, 'SKYCELL')
     133
     134       # XXX EAM 20140812 : I am hardwiring the parsing logic for RINGS vs LOCAL
     135       if tessName == 'RINGS.V3':
     136           # skycell is, eg "skycell.1133.081"
     137           #                 0123456789012345
     138           self.projectionID = skycellName[8:12]
     139           self.skycellID = skycellName[13:]
     140       else:
     141           # skycell is, eg "skycell.081"
     142           #                 01234567890
     143           self.projectionID = 0
     144           self.skycellID = skycellName[8:11]
     145       if self.skycellID == "":
     146           self.skycellID = -1
     147
     148       self.analysisVer = metadata[2];
     149
     150       # delete PSPS tables
     151       for filter in self.filters:
     152           tableName = filter + "StackMeta"
     153           self.dropTableVerbose(tableName)
     154
     155       self.dropTableVerbose("StackObjectThin")
     156       self.dropTableVerbose("StackObjectRaw")
    201157       
    202        # delete PSPS tables
    203        self.logger.infoPair("dropping table:","gStackMeta")
    204        self.scratchDb.dropTable("gStackMeta")
    205        self.logger.infoPair("dropping table:","rStackMeta")
    206        self.scratchDb.dropTable("rStackMeta")
    207        self.logger.infoPair("dropping table:","iStackMeta")
    208        self.scratchDb.dropTable("iStackMeta")
    209        self.logger.infoPair("dropping table:","zStackMeta")
    210        self.scratchDb.dropTable("zStackMeta")
    211        self.logger.infoPair("dropping table:","yStackMeta")
    212        self.scratchDb.dropTable("yStackMeta")
    213        self.logger.infoPair("dropping table:","StackObject")
    214 
    215        self.scratchDb.dropTable("StackObject")
    216        self.logger.infoPair("dropping table:","StackModelFit")
    217        self.scratchDb.dropTable("SkinnyObject")
    218        self.scratchDb.dropTable("StackModelFit")
    219        self.logger.infoPair("dropping table:","StackApFlx")
    220 
    221        self.scratchDb.dropTable("StackApFlx")
    222        self.logger.infoPair("dropping table:","StackToImage")
    223 
    224        self.scratchDb.dropTable("StackToImage")
    225              # self.testprint()
    226 
    227        # for PV2 we will have (grizy) of stack meta and skychip     
    228 
     158       self.dropTableVerbose("StackModelFitExtra")
     159       self.dropTableVerbose("StackModelFitDeV")
     160       self.dropTableVerbose("StackModelFitExp")
     161       self.dropTableVerbose("StackModelFitSer")
     162
     163       self.dropTableVerbose("StackApFlx")
     164       self.dropTableVerbose("StackApFlxFull")
     165       self.dropTableVerbose("StackApFlxFullC1")
     166       self.dropTableVerbose("StackApFlxFullC2")
     167
     168       self.dropTableVerbose("StackPetrosian")
     169
     170       self.dropTableVerbose("StackToImage")
    229171
    230172       # delete IPP tables
    231        self.scratchDb.dropTable("gSkyChip_psf")
    232        self.scratchDb.dropTable("gSkyChip_xrad")
    233        self.scratchDb.dropTable("gSkyChip_xfit")
    234        self.scratchDb.dropTable("gSkyChip_xsrc")
    235        self.scratchDb.dropTable("rSkyChip_psf")
    236        self.scratchDb.dropTable("rSkyChip_xrad")
    237        self.scratchDb.dropTable("rSkyChip_xfit")
    238        self.scratchDb.dropTable("rSkyChip_xsrc")
    239        self.scratchDb.dropTable("iSkyChip_psf")
    240        self.scratchDb.dropTable("iSkyChip_xrad")
    241        self.scratchDb.dropTable("iSkyChip_xfit")
    242        self.scratchDb.dropTable("iSkyChip_xsrc")
    243        self.scratchDb.dropTable("zSkyChip_psf")
    244        self.scratchDb.dropTable("zSkyChip_xrad")
    245        self.scratchDb.dropTable("zSkyChip_xfit")
    246        self.scratchDb.dropTable("zSkyChip_xsrc")
    247        self.scratchDb.dropTable("ySkyChip_psf")
    248        self.scratchDb.dropTable("ySkyChip_xrad")
    249        self.scratchDb.dropTable("ySkyChip_xfit")
    250        self.scratchDb.dropTable("ySkyChip_xsrc")
     173       if not self.config.retry:
     174           self.logger.info("dropping Stack cmf tables")
     175           for filter in self.filters:
     176               tableName = filter + "SkyChip_psf"
     177               self.scratchDb.dropTable(tableName)
     178               tableName = filter + "SkyChip_xrad"
     179               self.scratchDb.dropTable(tableName)
     180               tableName = filter + "SkyChip_xsrc"
     181               self.scratchDb.dropTable(tableName)
     182               tableName = filter + "SkyChip_xfit"
     183               self.scratchDb.dropTable(tableName)
    251184
    252185       # create an output filename, which is {stackID}.FITS
     
    263196       self.ippToPspsDb.insertStackMeta(self.batchID, "x" , self.stackType)
    264197
    265        # insert sourceID/imageID combo so DVO can look it up
    266        ##if not self.useFullTables:
    267        ##    self.scratchDb.insertNewDvoExternID(self.header['SOURCEID'], self.header['IMAGEID'])
    268 
    269        # self.testprint()
    270 
    271198       # dump stuff to log
    272199       self.logger.infoPair("Stack ID", "%d" % self.id)
    273200       self.logger.infoPair("Stack type", "%s" % self.stackType)
    274        self.logger.infoPair("Skycell", "%s" % self.skycell)
    275        self.logger.infoPair("Projectioncell", "%s" % self.projectioncell)
    276        ##self.logger.infoPair("Filter", "%s" % self.filter)
    277 
    278     '''
    279     Updates a table with stackMetaID
    280     '''
    281     def updateStackMetaID(self, table):
    282 
    283         sql = "UPDATE " + table + "  SET gstackMetaID=" + str(self.gstackID) + " \
    284               , rstackMetaID=" + str(self.rstackID) + " \
    285               , istackMetaID=" + str(self.istackID) + " \
    286               , zstackMetaID=" + str(self.zstackID) + " \
    287               , ystackMetaID=" + str(self.ystackID)   
    288      
    289         self.scratchDb.execute(sql)
    290 
    291     '''
    292     Updates a table with stackTypeID grabbed from FitModel init table
    293     '''
    294     def updateStackTypeID(self, table):
    295 
    296         sql = "UPDATE "+table+" AS a, StackType AS b SET a.stackTypeID=b.stackTypeID WHERE b.name = '" + self.stackType + "'"
    297         self.scratchDb.execute(sql)
    298 
    299 
    300     def testprint(self):
    301       print "here ", self.printline
    302       self.printline += 1
     201       self.logger.infoPair("SkycellID", "%s" % self.skycellID)
     202       self.logger.infoPair("ProjectionID", "%s" % self.projectionID)
     203
     204    ### *********************** main populate functions ************************************
     205
     206    '''
     207    Populates the StackMeta table, mainly from header values found in stack cmf FITS header
     208    '''
     209    def populateStackMeta(self,filter):
     210
     211        header = self.headerSet[filter]
     212        tablename = filter + "StackMeta"
     213        stackID = self.stackIDs[filter]
     214        filterName = filter + ".00000"
     215
     216        self.logger.infoPair("Populating table", tablename)
     217
     218        fwhm_maj    = self.getKeyFloat(header, "%.8f", 'FWHM_MAJ')
     219        fwhm_maj_uq = self.getKeyFloat(header, "%.8f", 'FW_MJ_UQ')
     220        psfmodel    = self.getKeyValue(header, 'PSFMODEL')
     221
     222        # make a table
     223        filterID = self.scratchDb.getFilterID(filter)
     224        self.logger.infoPair("filterID is ",str(filterID))
     225
     226        photoCalID = str(self.scratchDb.getPhotoCalID(stackID))
     227
     228        # mysql is sensitive to values which are ambiugously float.  eg
     229        # a warning is raised if we try to insert '25.' into a float field.
     230        # use getKeyFloat(hdr, format, key) to avoid this problem
     231
     232        sql = "CREATE TABLE " + tablename + " LIKE StackMeta"
     233        try: self.scratchDb.execute(sql)
     234        except: pass
     235
     236        sqlLine = sqlUtility("INSERT INTO " + tablename + " (")
     237
     238        sqlLine.group("stackMetaID",   str(stackID))       
     239        sqlLine.group("batchID",       str(self.batchID))
     240        sqlLine.group("surveyID",      str(self.surveyID))
     241        sqlLine.group("filterID",      str(filterID))           
     242        sqlLine.group("stackTypeID",   str(self.stackTypeID))
     243        sqlLine.group("tessID",        str(self.tessID))           
     244        sqlLine.group("projectionID",  str(self.projectionID))           
     245        sqlLine.group("skyCellID",     str(self.skycellID))           
     246        sqlLine.group("photoCalID",    photoCalID)
     247        sqlLine.group("analysisVer",   str(self.analysisVer))
     248        sqlLine.group("expTime",       self.getKeyFloat(header, "%.5f", 'EXPTIME')) 
     249        sqlLine.group("psfModelID",    psfmodel)           
     250        sqlLine.group("psfFwhm_mean",  fwhm_maj)     
     251        sqlLine.group("psfFwhm_max",   fwhm_maj_uq)   
     252        sqlLine.group("photoZero",     self.getKeyFloat(header, "%.5f", 'FPA.ZP'))
     253        sqlLine.group("ctype1",        header['CTYPE1']) 
     254        sqlLine.group("ctype2",        header['CTYPE2']) 
     255        sqlLine.group("crval1",        self.getKeyFloat(header, "%.8f", 'CRVAL1'))   
     256        sqlLine.group("crval2",        self.getKeyFloat(header, "%.8f", 'CRVAL2'))   
     257        sqlLine.group("crpix1",        self.getKeyFloat(header, "%.8f", 'CRPIX1'))   
     258        sqlLine.group("crpix2",        self.getKeyFloat(header, "%.8f", 'CRPIX2'))   
     259        sqlLine.group("cdelt1",        self.getKeyFloat(header, "%.8e", 'CDELT1'))   
     260        sqlLine.group("cdelt2",        self.getKeyFloat(header, "%.8e", 'CDELT2'))   
     261        sqlLine.group("pc001001",      self.getKeyFloat(header, "%.8e", 'PC001001'))
     262        sqlLine.group("pc001002",      self.getKeyFloat(header, "%.8e", 'PC001002'))
     263        sqlLine.group("pc002001",      self.getKeyFloat(header, "%.8e", 'PC002001'))
     264        sqlLine.group("pc002002",      self.getKeyFloat(header, "%.8e", 'PC002002'))
     265        sqlLine.group("dataRelease",   str(self.skychunk.dataRelease))
     266
     267        sql = sqlLine.make(") VALUES ( ", ")")
     268
     269        try: self.scratchDb.execute(sql)
     270        except:
     271            self.logger.error("problem with SQL: " + sql)
     272            raise
     273
     274        self.tablesToExport.append(tablename)
     275
     276    '''
     277    Populates the StackObjectThin table
     278    '''
     279    def populateStackObjectThin(self):
     280
     281        self.logger.infoPair("Procesing table", "StackObjectThin")
     282
     283        # insert the per-object data (IDs, random stack ID, dataRelease, etc)
     284        self.selectDvoObjIDs()
     285
     286        # add indexes StackObjectThin
     287        self.scratchDb.createIndex("StackObjectThin", "objID")
     288
     289        self.logger.infoPair("inserting filter dependent items into", "StackObjectThin")
     290
     291        for filter in self.filters:
     292            self.logger.infoPair("filter", filter)
     293
     294            stackID = self.stackIDs[filter]
     295            self.logger.infoPair(filter + "stackID = ", stackID)
     296
     297            if stackID <= 0: 
     298                self.logger.infoPair("no stack data for filter" , filter)
     299                continue
     300
     301            imageID = self.imageIDs[filter]
     302            self.logger.infoPair("selecting imageID", imageID)
     303
     304            # at this point, the StackObjectThin table includes objID and ippObjID
     305
     306            # insert detection information for each filter based on the DVO contents
     307            sqlLine = sqlUtility("UPDATE StackObjectThin as a, " + self.scratchDb.dvoDetectionTable + " as b SET")
     308
     309            sqlLine.group("a."+filter+"ippDetectID",   "b.ippDetectID") # eg, gippDetectID (from dvo.measure.detID)
     310            sqlLine.group("a."+filter+"stackDetectID", "b.detectID")    # eg, gstackDetectID (from dvo.measure.extID)
     311            sqlLine.group("a."+filter+"stackMetaID",    str(stackID))   # eg, gstackMetaID (from cmf.IMAGEID)
     312
     313            sqlLine.group("a.dvoRegionID",             "b.catID")       # this is not filter dependent, but is re-written for each filter (if data exists)
     314            sqlLine.group("a.primaryDetection",        "((b.flags & 0x10000) >> 16)") # this is not filter dependent, but is re-written for each filter (if data exists)
     315
     316            sqlLine.group("a."+filter+"haveData",      "'1'")
     317
     318            sqlLine.group("a."+filter+"ra",            "b.ra")
     319            sqlLine.group("a."+filter+"dec",           "b.dec_")
     320
     321            sqlLine.group("a."+filter+"PSFMag",        "b.Mpsf")
     322            sqlLine.group("a."+filter+"PSFMagErr",     "b.dMpsf")
     323            sqlLine.group("a."+filter+"KronMag",       "b.Mkron")
     324            sqlLine.group("a."+filter+"KronMagErr",    "b.dMkron")
     325            sqlLine.group("a."+filter+"ApMag",         "b.Map")
     326            sqlLine.group("a."+filter+"ApMagErr",      "b.dMap")
     327            sqlLine.group("a."+filter+"telluricExt",   "b.telluricExt")
     328
     329            sqlLine.group("a."+filter+"infoFlag2",     "(b.flags << 13)")
     330            sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND b.imageID = " + str(imageID))
     331
     332            try: self.scratchDb.execute(sql)
     333            except:
     334                self.logger.errorPair('failed sql: ', sql)
     335                raise
     336
     337            # insert values coming from the CMF, not carried by DVO
     338            header = self.headerSet[filter]
     339            exptime = self.getKeyFloat(header, "%.5f", "EXPTIME")
     340
     341            sqlLine = sqlUtility("UPDATE StackObjectThin AS a , " + filter + "SkyChip_psf AS b SET")
     342
     343            sqlLine.group("a."+filter+"raErr",         "b.X_PSF_SIG * b.PLTSCALE")
     344            sqlLine.group("a."+filter+"decErr",        "b.Y_PSF_SIG * b.PLTSCALE")
     345            sqlLine.group("a."+filter+"sky",           "b.SKY / " + str(exptime))
     346            sqlLine.group("a."+filter+"skyErr",        "b.SKY_SIGMA / " + str(exptime))
     347            sqlLine.group("a."+filter+"infoFlag",      "b.FLAGS")
     348            sqlLine.group("a."+filter+"infoFlag2",     "b.FLAGS2 | a."+filter+"infoFlag2")
     349            sqlLine.group("a."+filter+"nFrames",       "b.N_FRAMES")
     350
     351            sql = sqlLine.makeEquals("WHERE a." + filter + "ippDetectID=b.IPP_IDET")
     352
     353            # index the (f)ippDetectIDs for the next steps?
     354            # for filter in self.filters:
     355            #     IDname = filter + "ippDetectID"
     356            #     self.scratchDb.createIndex("StackObjectThin", IDname)
     357
     358            try:
     359                self.scratchDb.execute(sql)
     360            except:
     361                self.logger.errorPair('failed sql: ', sql)
     362                raise
     363
     364        self.tablesToExport.append("StackObjectThin")
     365
     366    '''
     367    Populates the StackObjectRaw table
     368    '''
     369    def populateStackObjectRaw(self):
     370
     371        tablename = "StackObjectRaw"
     372
     373        self.logger.infoPair("Procesing table", tablename)
     374        self.insertDvoIDs(tablename, "StackObjectThin")
     375
     376        # if we are going to add a key, do it here so it is useful
     377        self.scratchDb.createIndex(tablename, "objID")
     378
     379        self.logger.infoPair("inserting filter dependent cmf items into", tablename)
     380        for filter in self.filters:
     381            self.logger.infoPair("filter", filter)
     382
     383            stackID = self.stackIDs[filter]
     384            self.logger.infoPair(filter + "stackID = ", stackID)
     385
     386            if stackID <= 0: 
     387                self.logger.infoPair("no stack data for filter" , filter)
     388                continue
     389
     390            header = self.headerSet[filter]
     391            exptime = self.getKeyFloat(header, "%.5f", "EXPTIME")
     392
     393            # insert all the detections
     394            sqlLine = sqlUtility("UPDATE " + tablename + " AS a , " + filter + "SkyChip_psf AS b SET")
     395
     396            sqlLine.group("a."+filter+"haveData",      "'1'")
     397
     398            sqlLine.group("a."+filter+"xPos",          "b.X_PSF")
     399            sqlLine.group("a."+filter+"yPos",          "b.Y_PSF")
     400            sqlLine.group("a."+filter+"xPosErr",       "b.X_PSF_SIG")
     401            sqlLine.group("a."+filter+"yPosErr",       "b.Y_PSF_SIG")
     402            sqlLine.group("a."+filter+"psfMajorFWHM",  "b.PSF_FWHM_MAJ")
     403            sqlLine.group("a."+filter+"psfMinorFWHM",  "b.PSF_FWHM_MIN")
     404            sqlLine.group("a."+filter+"psfTheta",      "b.PSF_THETA")
     405            sqlLine.group("a."+filter+"psfCore",       "b.PSF_CORE")
     406            sqlLine.group("a."+filter+"psfLikelihood", "psfLikelihood(b.EXT_NSIGMA)")
     407            sqlLine.group("a."+filter+"psfQf",         "b.PSF_QF")
     408            sqlLine.group("a."+filter+"psfQfPerfect",  "b.PSF_QF_PERFECT")
     409            sqlLine.group("a."+filter+"psfChiSq",      "b.PSF_CHISQ / b.PSF_NDOF")
     410            sqlLine.group("a."+filter+"momentXX",      "b.MOMENTS_XX")
     411            sqlLine.group("a."+filter+"momentXY",      "b.MOMENTS_XY")
     412            sqlLine.group("a."+filter+"momentYY",      "b.MOMENTS_YY")
     413            sqlLine.group("a."+filter+"momentR1",      "b.MOMENTS_R1")
     414            sqlLine.group("a."+filter+"momentRH",      "b.MOMENTS_RH")
     415            sqlLine.group("a."+filter+"PSFFlux",       "b.PSF_INST_FLUX / " + str(exptime))
     416            sqlLine.group("a."+filter+"PSFFluxErr",    "b.PSF_INST_FLUX_SIG / " + str(exptime))
     417            sqlLine.group("a."+filter+"ApFlux",        "b.AP_FLUX / " + str(exptime))
     418            sqlLine.group("a."+filter+"ApFluxErr",     "b.AP_FLUX_SIG / " + str(exptime))
     419            sqlLine.group("a."+filter+"KronFlux",      "b.KRON_FLUX / " + str(exptime))
     420            sqlLine.group("a."+filter+"KronFluxErr",   "b.KRON_FLUX_ERR / " + str(exptime))
     421            sqlLine.group("a."+filter+"ApFillFac",     "b.AP_NPIX / (3.14159265359 * POW(b.AP_MAG_RADIUS - 0.5, 2))")
     422            sqlLine.group("a."+filter+"ApRadius",      "b.AP_MAG_RADIUS")
     423            sqlLine.group("a."+filter+"KronRad",       "b.MOMENTS_R1 * 2.5")
     424            sqlLine.group("a."+filter+"PlateScale",    "b.PLTSCALE")
     425
     426            sql = sqlLine.makeEquals("WHERE a." + filter + "ippDetectID = b.IPP_IDET")
     427
     428            try:
     429                self.scratchDb.execute(sql)
     430            except:
     431                self.logger.errorPair('failed sql',sql)
     432                return
     433
     434            # insert detection information for each filter based on the DVO contents
     435            sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + self.scratchDb.dvoDetectionTable + " as b SET")
     436            sqlLine.group("a."+filter+"expTime",       "b.expTime")
     437            sqlLine.group("a."+filter+"zp",            "b.zp")
     438
     439            # where should these go?
     440            # sqlLine.group("a."+filter+"airmass",       "b.airmass")
     441
     442            sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND a." + filter + "ippDetectID = b.ippDetectID")
     443
     444            try:
     445                self.scratchDb.execute(sql)
     446            except:
     447                self.logger.errorPair('failed sql',sql)
     448                return
     449
     450
     451        self.deleteRowsWithNoStackData(tablename)
     452        self.tablesToExport.append(tablename)
     453
     454    '''
     455    Populates the StackModelFitExtra table
     456    '''
     457    def populateStackModelFitExtra(self):
     458
     459        self.logger.infoPair("Procesing table", "StackModelFitExtra")
     460        self.insertDvoIDs("StackModelFitExtra", "StackObjectThin")
     461
     462        # if we are going to add a key, do it here so it is useful
     463        # self.scratchDb.createIndex(tablename, "objID")
     464
     465        # currently, none of the fields defined by the table are generated
     466       
     467    '''
     468    Populates the StackModelFitExp table
     469    '''
     470    def populateStackModelFit(self, model, ippModelType):
     471
     472        tablename = "StackModelFit" + model
     473
     474        if self.config.camera == "simtest":
     475            self.logger.infoPair("Skipping table for simtest:", tablename)
     476            return
     477
     478        self.logger.infoPair("Procesing table", tablename)
     479        self.insertDvoIDs(tablename, "StackObjectThin")
     480
     481        # if we are going to add a key, do it here so it is useful
     482        # self.scratchDb.createIndex(table, "objID")
     483
     484        for filter in self.filters:
     485            self.populateStackModelFitFilter(model, ippModelType, filter)
     486
     487        self.deleteRowsWithNoStackData(tablename)
     488        self.tablesToExport.append(tablename)
     489
     490    '''
     491    Updates parameters for a particular model in the StackModelFit table
     492    '''
     493    def populateStackModelFitFilter(self, model, ippModelType, filter):
     494
     495        tablename = "StackModelFit" + model
     496
     497        if self.stackIDs[filter] <= 0:
     498            self.logger.infoPair("no stack data for filter" , filter)
     499            return True
     500
     501        header  = self.headerSet[filter]
     502
     503        # model calibrated magnitude = instrumental magnitude + 2.5*log10(exptime) + ZP (added below from dvoDetectionTable)
     504        magtime = "%.5f" % (2.5*math.log10(float(header['EXPTIME'])))
     505
     506        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + filter + "SkyChip_xfit AS b SET")
     507
     508        sqlLine.group("a."+filter+"haveData",              "'1'")
     509
     510        # model calibrated magnitude = instrumental magnitude + 2.5*log10(exptime) + ZP (added below from dvoDetectionTable)
     511        sqlLine.group("a." + filter + model + "Mag",       "b.EXT_INST_MAG + " + magtime) # need to modify by zero point and 2.5*log10(exptime)
     512        sqlLine.group("a." + filter + model + "MagErr",    "b.EXT_INST_MAG_SIG")
     513                     
     514        sqlLine.group("a." + filter + model + "Radius",    "b.EXT_WIDTH_MAJ")
     515        sqlLine.group("a." + filter + model + "Ab",        "b.EXT_WIDTH_MIN/b.EXT_WIDTH_MAJ")
     516        sqlLine.group("a." + filter + model + "Phi",       "DEGREES(b.EXT_THETA)")
     517
     518        sqlLine.group("a." + filter + model + "RadiusErr", "b.EXT_WIDTH_MAJ_ERR") # these are not correctly defined.
     519        sqlLine.group("a." + filter + model + "AbErr",     "b.EXT_WIDTH_MIN_ERR") # these are not correctly defined.
     520        sqlLine.group("a." + filter + model + "PhiErr",    "b.EXT_THETA_ERR") # these are not correctly defined.
     521
     522        sqlLine.group("a." + filter + model + "Chisq",     "b.EXT_CHISQ / b.EXT_NDOF")
     523
     524        # I have raExp = X_EXT
     525
     526        # This is tricky: RA_EXT is not defined for PS1_SV3 or PS1_V5, but X_EXT is
     527        # XXX EAM 20140812: for PV3, update cmf output to define RA_EXT, DEC_EXT
     528        sqlLine.group("a." + filter + model + "Ra",        "b.X_EXT")
     529        sqlLine.group("a." + filter + model + "Dec",       "b.Y_EXT")
     530        sqlLine.group("a." + filter + model + "RaErr",     "b.X_EXT_SIG") # need to modify by platescale
     531        sqlLine.group("a." + filter + model + "DecErr",    "b.Y_EXT_SIG")
     532
     533        # sersic fit has an extra parameter
     534        if (ippModelType == "PS_MODEL_SERSIC"):
     535            sqlLine.group("a." + filter + model + "Nu",    "b.EXT_PAR_07")
     536            sqlLine.group("a." + filter + model + "NuErr", "'0.1'") # this is not measured at the moment
     537
     538        # missing these two fields?
     539        # sqlLine.group("a." + filter + model + "CF",         "b.XX")
     540        # sqlLine.group("a." + filter + model + "Likelihood", "b.XX")
     541
     542        sql = sqlLine.makeEquals("WHERE a." + filter + "ippDetectID = b.IPP_IDET AND b.MODEL_TYPE = '" + ippModelType + "'")
     543
     544        try: self.scratchDb.execute(sql)
     545        except:
     546            self.logger.error("problem with SQL: " + sql)
     547            raise
     548
     549        # insert detection information for each filter based on the
     550        # DVO contents.  Since I already have extracted
     551        # StackObjectRaw, this is probably faster using that table:
     552        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + self.scratchDb.dvoDetectionTable + " as b SET")
     553        sqlLine.group("a." + filter + model + "Mag",       "a." + filter + model + "Mag + b.zp")
     554        sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND a." + filter + "ippDetectID = b.ippDetectID")
     555
     556        try:
     557            self.scratchDb.execute(sql)
     558        except:
     559            self.logger.errorPair('failed sql',sql)
     560            return
     561
     562        # we have (modulo signs):
     563        # gRaExp  = gra  + (X_EXT - gxPos)*gPlateScale / cos(gdec)
     564        # gDecExp = gdec + (Y_EXT - gyPos)*gPlateScale
     565
     566        rawS  = "c." + filter + "PlateScale"
     567
     568        extR  = "a." + filter + model + "Ra"
     569        rawR  = "b." + filter + "ra"
     570        rawX  = "c." + filter + "xPos"
     571
     572        extD  = "a." + filter + model + "Dec"
     573        rawD  = "b." + filter + "dec"
     574        rawY  = "c." + filter + "yPos"
     575
     576        # dRA / dX = -PlateScale
     577        # b.+filter+ra  - (a.+filter+model+Ra - c.+filter+xPos)*c.+filter+PlateScale / cos(+filter+dec)
     578        # extR = rawR - (extR - rawX)*rawS / 3600.0 / cos(rawD)
     579
     580        # dDEC / dY = +PlateScale
     581        # b.+filter+dec + (a.+filter+model+Dec - c.+filter+xPos)*c.+filter+PlateScale / cos(+filter+dec)
     582        # extD = rawD + (extD - rawY)*rawS / 3600.0
     583
     584        # insert detection information for each filter based on the DVO contents
     585        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, StackObjectThin as b, StackObjectRaw as c SET ")
     586        sqlLine.group(extR, rawR + " - (" + extR + " - " + rawX + ")*" + rawS + " / 3600.0 / cos(radians(" + rawD + "))")
     587        sqlLine.group(extD, rawD + " + (" + extD + " - " + rawY + ")*" + rawS + " / 3600.0")
     588        field = "a." + filter + model + "RaErr"
     589        sqlLine.group(field, field + "*" + rawS)
     590        field = "a." + filter + model + "DecErr"
     591        sqlLine.group(field, field + "*" + rawS)
     592        sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND a.objID = c.objID")
     593
     594        try:
     595            self.scratchDb.execute(sql)
     596        except:
     597            self.logger.errorPair('failed sql',sql)
     598            return
     599
     600    '''
     601    Populates the StackPetrosian table, mainly from dictionary values found in IPP FITS header
     602    '''
     603    def populateStackPetrosian(self):
     604
     605        tablename = "StackPetrosian"
     606
     607        if self.config.camera == "simtest":
     608            self.logger.infoPair("Skipping table for simtest:", tablename)
     609            return
     610
     611        self.logger.infoPair("Procesing table", tablename)
     612        self.insertDvoIDs(tablename, "StackObjectThin")
     613
     614        # if we are going to add a key, do it here so it is useful
     615        # self.scratchDb.createIndex(tablename, "objID")
     616
     617        for filter in self.filters:
     618            self.populateStackPetrosianFilter(filter)
     619
     620        self.deleteRowsWithNoStackData(tablename)
     621        self.tablesToExport.append(tablename)
     622
     623    '''
     624    Populates the StackPetrosian table, mainly from dictionary values found in IPP FITS header
     625    '''
     626    def populateStackPetrosianFilter(self, filter):
     627
     628        tablename = "StackPetrosian"
     629
     630        if self.stackIDs[filter] <= 0:
     631            self.logger.infoPair("no stack data for filter" , filter)
     632            return True
     633
     634        header  = self.headerSet[filter]
     635
     636        # PETRO_MAG is instrumental + 2.5log(exptime) + FPA.ZP
     637        # we want to apply the DVO zero point, so remove FPA.ZP:
     638
     639        hdrZP   = "%.5f" % float(header['FPA.ZP'])
     640        # magtime = "%.5f" % (2.5*math.log10(float(header['EXPTIME'])))
     641
     642        self.logger.infoPair("Adding", "petrosians for extended sources")
     643        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + filter + "SkyChip_xsrc AS b SET")
     644
     645        sqlLine.group("a."+filter+"haveData",         "'1'")
     646
     647        sqlLine.group("a." + filter + "petRadius",    "b.PETRO_RADIUS")
     648        sqlLine.group("a." + filter + "petRadiusErr", "b.PETRO_RADIUS_ERR")
     649        sqlLine.group("a." + filter + "petMag",       "b.PETRO_MAG - " + hdrZP) 
     650        sqlLine.group("a." + filter + "petMagErr",    "1.0 / b.PETRO_MAG_ERR") 
     651        sqlLine.group("a." + filter + "petR50",       "b.PETRO_RADIUS_50")
     652        sqlLine.group("a." + filter + "petR50Err",    "b.PETRO_RADIUS_50_ERR")
     653        sqlLine.group("a." + filter + "petR90",       "b.PETRO_RADIUS_90")
     654        sqlLine.group("a." + filter + "petR90Err",    "b.PETRO_RADIUS_90_ERR")
     655        sqlLine.group("a." + filter + "petCf",        "b.PETRO_FILL")
     656
     657        sql = sqlLine.makeEquals("WHERE a." + filter + "ippDetectID = b.IPP_IDET")
     658
     659        try: self.scratchDb.execute(sql)
     660        except:
     661            self.logger.error("problem with SQL: " + sql)
     662            raise
     663
     664        # modify petMag to apply the zero point
     665        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + self.scratchDb.dvoDetectionTable + " as b SET")
     666        sqlLine.group("a." + filter + "petMag",       "a." + filter + "petMag + b.zp")
     667        sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND a." + filter + "ippDetectID = b.ippDetectID")
     668
     669        try: self.scratchDb.execute(sql)
     670        except:
     671            self.logger.errorPair('failed sql',sql)
     672            return
     673
     674    '''
     675    Populates the StackApFlx table
     676    '''
     677    def populateStackApFlx(self):
     678
     679        tablename = "StackApFlx"
     680
     681        if self.config.camera == "simtest":
     682            self.logger.infoPair("Skipping table for simtest:", tablename)
     683            return
     684
     685        self.logger.infoPair("Procesing table", tablename)
     686        self.insertDvoIDs(tablename, "StackObjectThin")
     687
     688        # if we are going to add a key, do it here so it is useful
     689        self.scratchDb.createIndex(tablename, "objID")
     690
     691        for filter in self.filters:
     692            self.populateStackApFlxFilter(tablename, "", filter)
     693            self.populateStackApFlxFilter(tablename, "C1", filter)
     694            self.populateStackApFlxFilter(tablename, "C2", filter)
     695
     696        self.deleteRowsWithNoStackData(tablename)
     697        self.tablesToExport.append(tablename)
     698
     699    '''
     700    Populates the StackApFlxFull table
     701    '''
     702    def populateStackApFlxFull(self, version):
     703
     704        tablename = "StackApFlxFull" + version
     705
     706        if self.config.camera == "simtest":
     707            self.logger.infoPair("Skipping table for simtest:", tablename)
     708            return
     709
     710        self.logger.infoPair("Procesing table", tablename)
     711        self.insertDvoIDs(tablename, "StackObjectThin")
     712
     713        # if we are going to add a key, do it here so it is useful
     714        self.scratchDb.createIndex(tablename, "objID")
     715
     716        for filter in self.filters:
     717            self.populateStackApFlxFilter(tablename, version, filter)
     718
     719        self.deleteRowsWithNoStackData(tablename)
     720        self.tablesToExport.append(tablename)
    303721
    304722    '''
    305723    Updates aperture fluxes for StackApFkx table
    306724    '''
    307     def updateModelFitFlxs(self, prefix, psfCondition, tablename, filter):
    308         #properly -999 these to start with:
    309         f = filter
    310         if tablename == 'StackModelFit':
    311             sql = "UPDATE " + tablename + " AS a, "+f+"SkyChip_xrad AS b SET \
    312         "+f+prefix+"flxR1=-999, \
    313         "+f+prefix+"flxR1Err=-999, \
    314         "+f+prefix+"flxR1Std=-999, \
    315         "+f+prefix+"flxR1Fill=-999, \
    316         "+f+prefix+"flxR2=-999, \
    317         "+f+prefix+"flxR2Err=-999, \
    318         "+f+prefix+"flxR2Std=-999, \
    319         "+f+prefix+"flxR2Fill=-999, \
    320         "+f+prefix+"flxR3=-999, \
    321         "+f+prefix+"flxR3Err=-999, \
    322         "+f+prefix+"flxR3Std=-999, \
    323         "+f+prefix+"flxR3Fill=-999, \
    324         "+f+prefix+"flxR4=-999, \
    325         "+f+prefix+"flxR4Err=-999, \
    326         "+f+prefix+"flxR4Std=-999, \
    327         "+f+prefix+"flxR4Fill=-999, \
    328         "+f+prefix+"flxR5=-999, \
    329         "+f+prefix+"flxR5Err=-999, \
    330         "+f+prefix+"flxR5Std=-999, \
    331         "+f+prefix+"flxR5Fill=-999, \
    332         "+f+prefix+"flxR6=-999, \
    333         "+f+prefix+"flxR6Err=-999, \
    334         "+f+prefix+"flxR6Std=-999, \
    335         "+f+prefix+"flxR6Fill=-999, \
    336         "+f+prefix+"flxR7=-999, \
    337         "+f+prefix+"flxR7Err=-999, \
    338         "+f+prefix+"flxR7Std=-999, \
    339         "+f+prefix+"flxR7Fill=-999, \
    340         "+f+prefix+"flxR8=-999, \
    341         "+f+prefix+"flxR8Err=-999, \
    342         "+f+prefix+"flxR8Std=-999, \
    343         "+f+prefix+"flxR8Fill=-999, \
    344         "+f+prefix+"flxR9=-999, \
    345         "+f+prefix+"flxR9Err=-999, \
    346         "+f+prefix+"flxR9Std=-999, \
    347         "+f+prefix+"flxR9Fill=-999, \
    348         "+f+prefix+"flxR10=-999, \
    349         "+f+prefix+"flxR10Err=-999, \
    350         "+f+prefix+"flxR10Std=-999, \
    351         "+f+prefix+"flxR10Fill=-999 \
    352         WHERE a."+f+"ippDetectID=b.IPP_IDET "
    353         #self.logger.infoPair("sql", sql)
    354             self.scratchDb.execute(sql)
    355 
    356 
    357         #we have variable numbers of these columns. find out which are in use
    358         sql = "DESCRIBE "+f+"SkyChip_xrad 'aper_fill_%'"
     725    def populateStackApFlxFilter(self, tablename, version, filter):
     726
     727        prefix = "none"
     728
     729        # order of the 3 convolutions is fixed (raw, C1, C2) = (1, 2, 3)
     730        if version == "":   
     731            psfCondition = "(b.table_index % 3 = 1)"
     732            prefix = ""
     733        if version == "C1":
     734            psfCondition = "(b.table_index % 3 = 2)"
     735            prefix = "c1"
     736        if version == "C2":
     737            psfCondition = "(b.table_index % 3 = 0)"
     738            prefix = "c2"
     739
     740        if prefix == "none":
     741            self.logger.errorPair("invalid stack ap flux version", version)
     742            raise
     743
     744        if self.stackIDs[filter] <= 0:
     745            self.logger.infoPair("no stack data for filter" , filter)
     746            return True
     747
     748        minRadius = 1
     749        maxRadius = 10
     750        if tablename == 'StackApFlx':
     751            minRadius = 3
     752            maxRadius = 5
     753
     754        # properly -999 these to start with.  the default should take
     755        # care of this, but does not
     756
     757        sqlLine = sqlUtility("UPDATE " + tablename + " SET")
     758        for radius in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
     759            if radius < minRadius: continue
     760            if radius > maxRadius: continue
     761            sqlLine.group(filter + prefix + "flxR" + str(radius),          "-999")
     762            sqlLine.group(filter + prefix + "flxR" + str(radius) + "Err",  "-999")
     763            sqlLine.group(filter + prefix + "flxR" + str(radius) + "Std",  "-999")
     764            sqlLine.group(filter + prefix + "flxR" + str(radius) + "Fill", "-999")
     765
     766        sql = sqlLine.makeEquals("")
     767
     768        try: self.scratchDb.execute(sql)
     769        except:
     770            self.logger.errorPair('failed sql',sql)
     771            return
     772
     773        # set the flux values from the cmf file
     774        cmfTable = filter + "SkyChip_xrad"
     775
     776        # we have variable numbers of these columns. find out which are in use
     777        sql = "DESCRIBE " + cmfTable + " 'aper_fill_%'"
    359778        rs = self.scratchDb.executeQuery(sql)
    360779        rs.first()
     
    367786        rs.close()
    368787
    369         #use regex to leave just the numbers
    370 
     788        # use regex to select the aperture number (APER_FILL_N)
    371789        numbers = []
    372         min = 1
    373         max = 10
    374         if tablename == 'StackApFlx':
    375             min = 3
    376             max = 5
    377790        for column in columns:
    378791            number = re.sub("APER_FILL_","",column)
    379             if (int(number) >= min and int(number) <=max):
     792            if (int(number) >= minRadius and int(number) <= maxRadius):
    380793                numbers.append(number)
    381794                self.logger.infoPair("Aperture Numbers",number)
    382795
    383         #generate the sql to do the necessary ops on the columns   
    384         sql = "UPDATE " + tablename + " AS a, "+f+"SkyChip_xrad AS b SET "
    385         cnt =0
    386         exptime = self.safeDictionaryAccess(self.header, 'EXPTIME')
     796        # get the exposure time for aperture fluxes
     797        header = self.headerSet[filter]
     798        exptime = self.getKeyFloat(header, "%.5f", "EXPTIME")
     799
     800        # generate the sql to do the necessary ops on the columns   
     801        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + cmfTable + " AS b SET ")
     802
     803        sqlLine.group("a."+filter+"haveData", "'1'")
     804
    387805        for number in numbers:
    388             if (cnt>0):
    389                 sql=sql+" , "
    390             sql=sql+f+prefix+"flxR"+number+"=b.APER_FLUX_"+number +" / " + str(exptime) + ", "
    391             sql=sql+f+prefix+"flxR"+number+"Err=b.APER_FLUX_ERR_"+number +" / " + str(exptime) + ", "
    392             sql=sql+f+prefix+"flxR"+number+"Std=b.APER_FLUX_STDEV_"+number +" / " + str(exptime) + ", "
    393             sql=sql+f+prefix+"flxR"+number+"Fill=b.APER_FILL_"+number + " "
    394             cnt=cnt+1
     806            field = filter + prefix + "flxR" + number
     807            sqlLine.group(field,          "b.APER_FLUX_"       + number + " / " + exptime)
     808            sqlLine.group(field + "Err",  "b.APER_FLUX_ERR_"   + number + " / " + exptime)
     809            sqlLine.group(field + "Std",  "b.APER_FLUX_STDEV_" + number + " / " + exptime)
     810            sqlLine.group(field + "Fill", "b.APER_FILL_"       + number)
    395811           
    396         sql=sql+"WHERE a."+f+"ippDetectID=b.IPP_IDET AND  "+psfCondition   
    397         self.logger.infoPair("sql",sql)
     812        sql = sqlLine.makeEquals("WHERE a." + filter + "ippDetectID = b.IPP_IDET AND  " + psfCondition)
     813
    398814        self.scratchDb.execute(sql)
    399815
    400 
    401     '''
    402     Updates parameters for a particular model in the StackModelFit table
    403     '''
    404     def updateModelFit(self, model, ippModelType, filter, exptime):
    405         f = filter
    406  
    407  # idk what to do about PET
    408 
    409         sql = "DESCRIBE "+f+"SkyChip_xfit 'EXT_COVAR_%'"
     816        # instrumental flux, AB mags, Jy:
     817        # flux_inst = cts / sec
     818        # mag_AB = -2.5*log(flux_inst) + ZP [with appropriate definition of zero point]
     819        # mag_AB = -2.5*log(flux_cgs) - 48.6 [by construction with ~Vega flux in V-band]
     820        # flux_cgs = ten(-0.4*(mag_AB + 48.6))
     821        # flux_cgs = ten(-0.4*((-2.5*log(flux_inst) + ZP) + 48.6))
     822        # flux_cgs = flux_inst * ten(-0.4*(ZP + 48.6))
     823        # flux_Jy  = flux_cgs * 10^23
     824        # flux_Jy  = flux_inst * ten(-0.4*(ZP + 48.6) + 23.0)  [23.0 - 0.4*48.6 = 3.56]
     825        # flux_Jy  = flux_inst * ten(-0.4*ZP + 3.56)
     826        # flux_Jy  = flux_inst * ten(-0.4*ZP) * 3630.78
     827
     828        # modify flux to apply the zero point
     829        sqlLine = sqlUtility("UPDATE " + tablename + " AS a, " + self.scratchDb.dvoDetectionTable + " as b SET")
     830        for number in numbers:
     831            field = filter + prefix + "flxR" + number
     832            sqlLine.group(field,               field         + " * POW(10, 3.56 - 0.4* b.zp)")
     833            sqlLine.group(field + "Err",       field + "err" + " * POW(10, 3.56 - 0.4* b.zp)")
     834            sqlLine.group(field + "Std",       field + "Std" + " * POW(10, 3.56 - 0.4* b.zp)")
     835        sql = sqlLine.makeEquals("WHERE a.objID = b.objID AND a." + filter + "ippDetectID = b.ippDetectID")
     836        self.scratchDb.execute(sql)
     837
     838    '''
     839    Populates the StackToImage table
     840    '''
     841    def populateStackToImage(self):
     842
     843        self.logger.infoPair("Procesing table", "StackToImage")
     844
     845        for filter in self.filters:
     846           
     847            stackmetaID = self.stackIDs[filter]
     848            if stackmetaID > 0:
     849   
     850                imageIDs = self.gpc1Db.getImageIDsForThisStackID(stackmetaID)
     851
     852                for imageID in imageIDs:
     853
     854                    sql = "INSERT INTO StackToImage (stackMetaID, imageID) \
     855                   VALUES (\
     856                   " + str(stackmetaID) + ", " + imageID + ")"
     857                    self.scratchDb.execute(sql)
     858
     859                    # now update StackMeta with correct number of inputs
     860                    sql = "UPDATE "+filter+"StackMeta SET nP2Images = (SELECT COUNT(distinct(floor(imageID/100))) FROM StackToImage where stackMetaID = "+str(stackmetaID)+")"
     861                    self.scratchDb.execute(sql)
     862
     863        self.tablesToExport.append("StackToImage")
     864
     865    ### *********************** Utility Functions ************************************
     866
     867    '''
     868    Drop a table and report the drop
     869    '''
     870    def dropTableVerbose(self, table):
     871        self.logger.infoPair("dropping table:",table)
     872        self.scratchDb.dropTable(table)
     873
     874    '''
     875    get stackTypeID corresponding to our stackType
     876    '''
     877    def getStackTypeID(self):
     878
     879        sql = "SELECT stackTypeID from StackType WHERE name = '" + self.stackType + "'"
    410880        rs = self.scratchDb.executeQuery(sql)
    411         rs.first()
    412         hasResult = rs.next()
    413 
    414 
    415 
    416         sql = "UPDATE StackModelFit AS a, " + f + "SkyChip_xfit AS b SET \
    417         "+f+model+"Radius=b.EXT_WIDTH_MAJ,  \
    418         "+f+model+"Flux=POW(10, -0.4 * b.EXT_INST_MAG) / " + str(exptime) + " ,  \
    419         "+f+model+"FluxErr=ABS(b.EXT_INST_MAG_SIG) * POW(10, -0.4 * b.EXT_INST_MAG) / " + str(exptime) + " / 1.085736, \
    420         "+f+model+"Ab=b.EXT_WIDTH_MAJ/b.EXT_WIDTH_MIN, \
    421         "+f+model+"Phi=b.EXT_THETA  \
    422           \
    423         WHERE a."+f+"ippDetectID=b.IPP_IDET AND b.MODEL_TYPE = '"+ippModelType+"'"
    424 
    425         print sql
     881        if not rs.next():
     882            self.logger.errorPair("cannot get stack type ID from database for", self.stackType)
     883            raise
     884       
     885        ID = rs.getInt(1)
     886        return ID
     887
     888    def deleteRowsWithNoStackData(self, tableName):
     889
     890        self.logger.infoPair("Deleting rows with no stack data from", tableName)
     891        sql = "DELETE FROM " + tableName + " WHERE "
     892
     893        for i in range(len(self.filters)):
     894            filter = self.filters[i]
     895            sql += filter + "haveData is NULL"
     896
     897            if (i < len(self.filters) - 1):
     898                sql += " AND "
     899
     900        self.logger.infoPair('sql',sql)   
    426901        self.scratchDb.execute(sql)
    427902
    428 
    429 
    430         # sersic fit has an extra parameter
    431         if (ippModelType == "PS_MODEL_SERSIC"):
    432             extra_sql = ""
    433             if hasResult:
    434                 extra_sql = ","+f+"serNuErr=SQRT(EXT_COVAR_07_07)"
    435             sql = "UPDATE StackModelFit AS a, "+ f+ "SkyChip_xfit AS b SET \
    436             "+f+"serNu=b.EXT_PAR_07   \
    437             "+extra_sql+" \
    438             WHERE a."+f+"ippDetectID=b.IPP_IDET AND b.MODEL_TYPE = '"+ippModelType+"'"
    439 #           "+f+"serNuErr=SQRT(EXT_COVAR_07_07)  \
    440             self.logger.infoPair("sql",sql)
    441             self.scratchDb.execute(sql)
    442 
    443 
    444     '''
    445     Populates the StackMeta table, mainly from dictionary values found in IPP FITS header
    446     '''
    447     def populateStackMeta(self,filterName):
    448 
    449         self.logger.infoPair("Procesing table", "StackMeta")
    450 
    451         # this should work : set header into (grizy)header and run from there
    452         if filterName == 'g.00000':
    453             f = "g"
    454             self.header = self.gheader
    455             tablename = 'gStackMeta'
    456             stackmetaid = self.gstackID
    457         if filterName == 'r.00000':
    458             f = "r"
    459             tablename = 'rStackMeta'
    460             self.header = self.rheader
    461             stackmetaid = self.rstackID
    462         if filterName == 'i.00000':
    463             f = "i"
    464             tablename = 'iStackMeta'
    465             self.header = self.iheader
    466             stackmetaid = self.istackID
    467         if filterName == 'z.00000':
    468             f = "z"
    469             tablename = 'zStackMeta'
    470             self.header = self.zheader
    471             stackmetaid = self.zstackID
    472         if filterName == 'y.00000':
    473             f = "y"
    474             tablename = 'yStackMeta'
    475             self.header = self.yheader
    476             stackmetaid = self.ystackID
    477 
    478         self.fwhm_maj    = self.safeDictionaryAccess(self.header, 'FWHM_MAJ')
    479         self.fwhm_maj_uq = self.safeDictionaryAccess(self.header, 'FW_MJ_UQ')
    480         self.psfmodel    = self.safeDictionaryAccess(self.header, 'PSFMODEL')
    481         if (self.fwhm_maj    == "NULL"): self.fwhm_maj    = -999
    482         if (self.fwhm_maj_uq == "NULL"): self.fwhm_maj_uq = -999
    483 
    484         # print "fwhm_maj    = ", self.fwhm_maj
    485         # print "fwhm_maj_uq = ", self.fwhm_maj_uq
    486         # print "psfmodel    = ", self.psfmodel
    487 
    488         #make a table
    489 
    490         filterid = self.scratchDb.getFilterID(f)
    491         self.logger.infoPair("filterid is ",str(filterid))
    492 
    493         sql = "CREATE TABLE " + tablename + " LIKE StackMeta"
     903        for filter in self.filters:
     904            column = filter + "haveData"
     905            self.scratchDb.dropColumn(tableName, column)
     906
     907    '''
     908    Applies indexes to the PSPS tables
     909    '''
     910    def alterPspsTables(self):
     911
     912        self.logger.debug("Altering PSPS tables (currently does nothing in stackbatch)")
     913
     914        return True
     915
     916    '''
     917    Applies indexes to the IPP tables
     918    '''
     919    def indexIppTables(self):
     920
     921        for filter in self.filters:
     922            if self.stackIDs[filter] <= 0: 
     923                self.logger.infoPair("no files for filter" , filter)
     924                continue
     925
     926            self.logger.infoPair("Creating indexes on", "IPP tables")
     927            self.scratchDb.createIndex(filter + "SkyChip_psf",  "IPP_IDET")
     928            self.scratchDb.createIndex(filter + "SkyChip_xfit", "IPP_IDET")
     929            self.scratchDb.createIndex(filter + "SkyChip_xrad", "IPP_IDET")
     930            self.scratchDb.createIndex(filter + "SkyChip_xsrc", "IPP_IDET")
     931
     932        return True
     933
     934    '''
     935    select objID (psps object ID) from dvo restricted to this set of imageIDs. also insert
     936    ippObjID and several constants (for a skycell): surveyID, skyCellId, dataRelease
     937    '''
     938    def selectDvoObjIDs(self):
     939
     940        # we need a temporary column for each filter to identify empty rows
     941        for filter in self.filters:
     942            self.scratchDb.addColumn("StackObjectThin", filter + "haveData", "tinyint")
     943
     944        sqlLine = sqlUtility("INSERT INTO StackObjectThin (")
     945       
     946        sqlLine.group("objID",            "objID")
     947        sqlLine.group("ippObjID",         "ippObjID")
     948        sqlLine.group("surveyID",         "'" + str(self.surveyID) + "'")
     949        sqlLine.group("tessID",           "'" + str(self.tessID) + "'")
     950        sqlLine.group("projectionID",     "'" + str(self.projectionID) + "'")
     951        sqlLine.group("skyCellID",        "'" + str(self.skycellID) + "'")
     952        sqlLine.group("dataRelease",      "'" + str(self.skychunk.dataRelease) + "'")
     953        sqlLine.group("randomStackObjID", "FLOOR(RAND()*9223372036854775807)")
     954
     955        whereClause = " WHERE ("
     956        imageIDs = self.imageIDs.values()
     957        for i in range(len(imageIDs)):
     958            imageID = imageIDs[i]
     959            self.logger.infoPair("selecting imageID", imageID)
     960
     961            whereClause += "(" + self.scratchDb.dvoDetectionTable + ".imageID = " + str(imageID) + ")"
     962
     963            if (i < len(imageIDs) - 1):
     964                whereClause += " or "
     965
     966        whereClause += ")"
     967
     968        sql = sqlLine.makeRaw(") SELECT DISTINCT ", "FROM " + self.scratchDb.dvoDetectionTable + whereClause)
     969
    494970        try: self.scratchDb.execute(sql)
    495         except: pass
    496 
    497         sql = "INSERT INTO " + tablename + " (\
    498         stackMetaID \
    499         ,filterID \
    500         ,skyCellID \
    501         ,photoCalID \
    502         ,photoZero \
    503         ,expTime \
    504         ,psfModelID \
    505         ,psfFwhm_mean \
    506         ,psfFwhm_max \
    507         ,ctype1 \
    508         ,ctype2 \
    509         ,crval1 \
    510         ,crval2 \
    511         ,crpix1 \
    512         ,crpix2 \
    513         ,cdelt1 \
    514         ,cdelt2 \
    515         ,pc001001 \
    516         ,pc001002 \
    517         ,pc002001 \
    518         ,pc002002 \
    519          ) VALUES ( \
    520         " + str(stackmetaid) + " \
    521         , " + str(filterid) + "  \
    522         ," + self.skycell + " \
    523         ," + str(self.scratchDb.getPhotoCalID(self.header['IMAGEID'])) + " \
    524         ," + self.header['FPA.ZP'] + " \
    525         ," + self.header['EXPTIME'] + " \
    526         ,'" + self.psfmodel   + "' \
    527         ," + str(self.fwhm_maj)    + " \
    528         ," + str(self.fwhm_maj_uq) + " \
    529         ,'" + self.header['CTYPE1'] + "' \
    530         ,'" + self.header['CTYPE2'] + "' \
    531         ," + self.header['CRVAL1'] + " \
    532         ," + self.header['CRVAL2'] + " \
    533         ," + self.header['CRPIX1'] + " \
    534         ," + self.header['CRPIX2'] + " \
    535         ," + self.header['CDELT1'] + " \
    536         ," + self.header['CDELT2'] + " \
    537         ," + self.header['PC001001'] + " \
    538         ," + self.header['PC001002'] + " \
    539         ," + self.header['PC002001'] + " \
    540         ," + self.header['PC002002'] + " \
    541         )"
    542         self.scratchDb.execute(sql)
    543 
    544 
    545         self.scratchDb.updateAllRows(tablename, "batchID", str(self.batchID))
    546         self.scratchDb.updateAllRows(tablename, "surveyID", str(self.surveyID))
    547     #    self.scratchDb.updateFilterID(tablename, self.scratchDb.getFilterID(filterName))
    548         self.scratchDb.updateAllRows(tablename, "dataRelease", str(self.skychunk.dataRelease))
    549         self.updateStackTypeID(tablename)
    550 
    551     '''
    552     Populates the StackObject table
    553     '''
    554     def populateStackObject(self):
    555 
    556         self.logger.infoPair("Procesing table", "StackObject")
    557        
    558         self.logger.infoPair("inserting non-filter dependent items into", "StackObject")
    559 
    560         #this is dvo crap
    561         #sql = "INSERT INTO StackObject(\
    562         #      objID, \
    563         #      gcobjID, \
    564         #      ippObjID, \
    565         #      surveyID, \
    566         #      skyCellID, \
    567         #      randomStackObjID, \
    568         #      stackDetectRowID, \
    569         #      dvoRegionID, \
    570         #      dataRelease) SELECT \
    571         #      -999,
    572         #      -999,
    573         #      -999,
    574         #      ,
    575              
    576        
    577        
    578 
    579         self.logger.infoPair("inserting filter dependent cmf items into", "StackObject")
    580         filters =['g','r','i','z','y']
    581         for f in filters:
    582           skip = 0
    583           if (f == "g"):
    584               self.logger.infoPair("gstackID = ",self.gstackID)
    585               if self.gstackID > 0: 
    586                   stackid = self.gstackID
    587                   exptime = self.gheader['EXPTIME']
    588               else:
    589                   skip = 1
    590           if (f == "r"):
    591               self.logger.infoPair("rstackID = ",self.rstackID)
    592               if self.rstackID > 0:
    593                   stackid = self.rstackID
    594                   exptime = self.rheader['EXPTIME']
    595               else:
    596                   skip = 1
    597           if (f == "i"):
    598               self.logger.infoPair("istackID = ",self.istackID)
    599               if self.istackID > 0:
    600                   stackid = self.istackID
    601                   exptime = self.iheader['EXPTIME']
    602               else:
    603                   skip = 1
    604           if (f == "z"):
    605               self.logger.infoPair("zstackID = ",self.zstackID)
    606               if self.zstackID > 0:
    607                   stackid = self.zstackID
    608                   exptime = self.zheader['EXPTIME']
    609               else:
    610                   skip = 1
    611           if (f == "y"):
    612               self.logger.infoPair("ystackID = ",self.ystackID)
    613               if self.ystackID > 0:
    614                   stackid = self.ystackID
    615                   exptime = self.yheader['EXPTIME']
    616               else:
    617                   skip = 1
    618 
    619           if skip == 1:
    620               self.logger.infoPair("nothing for filter" , f)
    621           else:
    622              self.logger.infoPair("filter",f)
    623 
    624 
    625 
    626              # insert all the detections
    627              sql = "UPDATE StackObject as a , " + f + "SkyChip_psf as b set \
    628                    a."+f+"xPos = b.X_PSF \
    629                    ,a."+f+"yPos = b.Y_PSF \
    630                    ,a."+f+"xPosErr = b.X_PSF_SIG \
    631                    ,a."+f+"yPosErr = b.Y_PSF_SIG \
    632                    ,a."+f+"PSFFlux = b.PSF_INST_FLUX / " + str(exptime) + " \
    633                    ,a."+f+"PSFFluxErr = b.PSF_INST_FLUX_SIG / " + str(exptime) + " \
    634                    ,a."+f+"sky = b.SKY / " + str(exptime) + " \
    635                    ,a."+f+"skyErr = b.SKY_SIGMA / " + str(exptime) + " \
    636                    ,a."+f+"psfMajorFWHM = b.PSF_MAJOR \
    637                    ,a."+f+"psfMinorFWHM = b.PSF_MINOR \
    638                    ,a."+f+"psfTheta = b.PSF_THETA \
    639                    ,a."+f+"psfCore = NULL \
    640                    ,a."+f+"psfLikelihood = psfLikelihood(b.EXT_NSIGMA) \
    641                    ,a."+f+"infoFlag = b.FLAGS2 << 32 | FLAGS \
    642                    ,a."+f+"psfQf = b.PSF_QF \
    643                    ,a."+f+"psfQfPerfect = b.PSF_QF_PERFECT \
    644                    ,a."+f+"psfChiSq = b.PSF_CHISQ / b.PSF_NDOF \
    645                    ,a."+f+"momentXX = b.MOMENTS_XX \
    646                    ,a."+f+"momentXY = b.MOMENTS_XY \
    647                    ,a."+f+"momentYY = b.MOMENTS_YY \
    648                    ,a."+f+"momentR1 = b.MOMENTS_R1 \
    649                    ,a."+f+"momentRH = b.MOMENTS_RH \
    650                    ,a."+f+"ApFlux = POW(10.0, -0.4*b.AP_MAG) / " + str(exptime) + " \
    651                    ,a."+f+"ApFluxErr = NULL \
    652                    ,a."+f+"ApFillFac = NULL \
    653                    ,a."+f+"KronFlux = b.KRON_FLUX / " + str(exptime) + " \
    654                    ,a."+f+"KronFluxErr = b.KRON_FLUX_ERR / " + str(exptime) + " \
    655                    ,a."+f+"KronRad = b.MOMENTS_R1 * 2.5 \
    656                    ,a."+f+"PSFMag = b.PSF_INST_MAG    \
    657                    ,a."+f+"PSFMagErr = b.PSF_INST_MAG_SIG    \
    658                    ,a."+f+"ApMag = b.AP_MAG    \
    659                    ,a."+f+"ApMagErr = NULL    \
    660                    ,a."+f+"KronMag = NULL    \
    661                    ,a."+f+"KronMagErr = NULL    \
    662                    ,a."+f+"nFrames = b. N_FRAMES \
    663                    WHERE a." + f + "ippDetectID=b.IPP_IDET "
    664              self.logger.infoPair('sql', sql)     
    665              try:
    666                  self.scratchDb.execute(sql)
    667              except:
    668                  self.logger.errorPair('failed sql',sql)
    669                  return
    670              #it is possible to drop some detections from dvo (that are present in the cmf). when that happens we get a 0 for objid
    671         #we drop those...
    672 
    673         self.logger.infoPair("Deleting", "entries with StackObject.objID = 0")
    674         sql="DELETE FROM StackObject where objID = 0"
    675         try:
    676             self.scratchDb.execute(sql)
    677971        except:
    678972            self.logger.errorPair('failed sql',sql)
    679973            return
     974
     975    '''
     976    Insert objid (from dvo) into table from main table
     977    '''
     978    def insertDvoIDs(self, table, mainTable):
     979
     980        # we need a temporary column for each filter to identify empty rows
     981        for filter in self.filters:
     982            self.scratchDb.addColumn(table, filter + "haveData", "tinyint")
     983
     984        fields = "objID, ippObjID, randomStackObjID, primaryDetection, bestDetection, "
     985
     986        for i in range(len(self.filters)):
     987            filter = self.filters[i]
     988            fields += filter + "ippDetectID, "
     989            fields += filter + "stackDetectID, "
     990            fields += filter + "stackMetaID" # careful here: do not add comma to last entry
     991            if (i < len(self.filters) - 1):
     992                fields += ", "
    680993       
    681         try:
    682             self.scratchDb.updateAllRows("StackObject", "surveyID", str(self.surveyID))
     994        sql  = "INSERT INTO " + table + " (" + fields + ") "
     995        sql += "SELECT " + fields + " FROM " + mainTable
     996
     997        try: self.scratchDb.execute(sql)
    683998        except:
    684             self.logger.errorPair('failed update surveyID on','StackObject')
    685             raise
    686 #        self.scratchDb.updateFilterID("StackObject", f+".00000")
    687        
    688         self.scratchDb.updateAllRows("StackObject", "dataRelease", str(self.skychunk.dataRelease))
    689         try:
    690             self.updateStackMetaID("StackObject")
    691         except:
    692             self.logger.errorPair("failed update stack meta id on ", "StackObject")
    693             raise
    694         ##self.updateStackTypeID("StackObject")
    695        
    696         #self.updateDvoIDsAndFlags("StackObject")
    697         #this now updates primary F as well
    698         # response = raw_input("updated dvo ")
    699        
    700         # XXX EAM : note that in mysql versions later than 5.1, this fails
    701         # unless the following is called first:
    702         # set session old_alter_table=1
    703         # follow the command with
    704         # set session old_alter_table=0
    705         # OF COURSE, this fails for mysql version < 5.5...
    706         if self.scratchDb.version > 5.1:
    707             self.scratchDb.execute("set session old_alter_table=1")
    708 
    709         sql = "ALTER IGNORE TABLE StackObject ADD PRIMARY KEY (objID)"
    710        
    711         if self.scratchDb.version > 5.1:
    712             self.scratchDb.execute("set session old_alter_table=0")
    713 
    714         self.scratchDb.execute(sql)
    715         # response = raw_input("add primary key? ")
    716  
    717         ### XXX this should not be a DEEP_STACK only case...
    718         if False and self.stackType == "DEEP_STACK":
    719             ## need to do for all filters?
    720             #if deep stack and instFlux = null and err not null
    721             sql = "UPDATE StackObject AS a, SkyChip_psf AS b \
    722                    SET psfFlux = 2*b.PSF_INST_FLUX_SIG / " + str(self.expTime) + " \
    723                    WHERE psfFlux IS NULL \
    724                    AND a.ippDetectID = b.IPP_IDET  \
    725                    AND b.PSF_INST_FLUX_SIG IS NOT NULL"
    726            
    727             self.scratchDb.execute(sql)
    728             # response = raw_input("add psf flux ")
    729          
    730         #filter dependent
    731         # NOTE : Flux limits : in the current PSPS schema, negative fluxes
    732         # cause problems for sql queries which work in mags as SQL cannot do
    733         # something like (f < 0.0) ? -999 : -2.5*log10(f)
    734         # as a result, the negative fluxes here result in floating point errors
    735         sql = "UPDATE StackObject SET gPSFFlux = 1e20 WHERE gPSFFlux <= 0.0"
    736         self.scratchDb.execute(sql)
    737        
    738         sql = "UPDATE StackObject SET gApFlux = 1e20 WHERE gApFlux <= 0.0"
    739         self.scratchDb.execute(sql)
    740 
    741         sql = "UPDATE StackObject SET gKronFlux = 1e20 WHERE gKronFlux <= 0.0"
    742         self.scratchDb.execute(sql)
    743         sql = "UPDATE StackObject SET rPSFFlux = 1e20 WHERE rPSFFlux <= 0.0"
    744         self.scratchDb.execute(sql)
    745        
    746         sql = "UPDATE StackObject SET rApFlux = 1e20 WHERE rApFlux <= 0.0"
    747         self.scratchDb.execute(sql)
    748 
    749         sql = "UPDATE StackObject SET rKronFlux = 1e20 WHERE rKronFlux <= 0.0"
    750         self.scratchDb.execute(sql)
    751         sql = "UPDATE StackObject SET iPSFFlux = 1e20 WHERE iPSFFlux <= 0.0"
    752         self.scratchDb.execute(sql)
    753        
    754         sql = "UPDATE StackObject SET iApFlux = 1e20 WHERE iApFlux <= 0.0"
    755         self.scratchDb.execute(sql)
    756 
    757         sql = "UPDATE StackObject SET iKronFlux = 1e20 WHERE iKronFlux <= 0.0"
    758         self.scratchDb.execute(sql)
    759         sql = "UPDATE StackObject SET zPSFFlux = 1e20 WHERE zPSFFlux <= 0.0"
    760         self.scratchDb.execute(sql)
    761        
    762         sql = "UPDATE StackObject SET zApFlux = 1e20 WHERE zApFlux <= 0.0"
    763         self.scratchDb.execute(sql)
    764 
    765         sql = "UPDATE StackObject SET zKronFlux = 1e20 WHERE zKronFlux <= 0.0"
    766         self.scratchDb.execute(sql)
    767         sql = "UPDATE StackObject SET yPSFFlux = 1e20 WHERE yPSFFlux <= 0.0"
    768         self.scratchDb.execute(sql)
    769        
    770         sql = "UPDATE StackObject SET yApFlux = 1e20 WHERE yApFlux <= 0.0"
    771         self.scratchDb.execute(sql)
    772 
    773         sql = "UPDATE StackObject SET yKronFlux = 1e20 WHERE yKronFlux <= 0.0"
    774         self.scratchDb.execute(sql)
    775 
    776         #leave null instflux in
    777         #self.scratchDb.reportAndDeleteRowsWithNULLS("StackObject", "instFlux")
    778        
    779         self.scratchDb.reportAndDeleteRowsWithNULLS("StackObject", "objID")
    780         # response = raw_input("delete nulls ")
    781        
    782         sql="DELETE FROM StackObject where objID = 0"
    783        
    784         self.scratchDb.execute(sql)
    785         self.logger.infoPair("Deleting", "entries with StackObject.objID = 0")
    786         # response = raw_input("deleted objID is 0 ")
    787     '''
    788     Populates the SkinnyObject table
    789     '''
    790     def populateSkinnyObject(self):
    791 
    792         self.logger.infoPair("Procesing table", "SkinnyObject")
    793 
    794         sql = "INSERT INTO SkinnyObject (\
    795                objID \
    796                ,ippObjID \
    797                ,projectionCellID \
    798                ) \
    799                SELECT \
    800                DISTINCT objID \
    801                ,ippObjID \
    802                ,projectionCellID \
    803                FROM StackDetection"
    804         self.scratchDb.execute(sql)
    805 
    806         self.scratchDb.updateAllRows("SkinnyObject", "surveyID", str(self.surveyID))
    807         self.scratchDb.updateAllRows("SkinnyObject", "dataRelease", str(self.skychunk.dataRelease))
    808          
    809 
    810     '''
    811     Populates the StackApFlx table
    812     '''
    813     def populateStackApFlx(self):
    814         filter = ['g','r','i','z','y']
    815 
    816         for f in filter:
    817             skip = 0
    818             if (f == 'g'):
    819                 if self.gstackID > 0:
    820                     self.header = self.gheader
    821                 else:
    822                     skip = 1
    823             if (f == 'r'):
    824                 if self.rstackID > 0:
    825                     self.header = self.rheader
    826                 else:
    827                     skip = 1
    828             if (f == 'i'):
    829                 if self.istackID > 0:
    830                     self.header = self.iheader
    831                 else:
    832                     skip = 1
    833             if (f == 'z'):
    834                 if self.zstackID > 0:
    835                     self.header = self.zheader
    836                 else:
    837                     skip = 1
    838             if (f == 'y'):
    839                 if self.ystackID > 0:
    840                     self.header = self.yheader
    841                 else:
    842                     skip =1
    843 
    844             if skip == 0:
    845                 self.logger.infoPair("Adding fluxes", "un-convolved")
    846                 self.updateModelFitFlxs("", "((b.table_index -1) % 3 = 0)", "StackApFlx", f)
    847                 self.logger.infoPair("Adding fluxes", "1st convolved")
    848                 self.updateModelFitFlxs("c1", "((b.table_index -1) % 3 = 1)","StackApFlx",f)
    849                 self.logger.infoPair("Adding fluxes", "2nd convolved")
    850                 self.updateModelFitFlxs("c2", "((b.table_index -1) % 3 = 2)","StackApFlx",f)
    851 
    852                 self.deleteDetectionsNotInStackObject("StackApFlx",f)
    853 
    854         self.scratchDb.reportAndDeleteRowsWithNULLS("StackApFlx", "objID")
    855        
    856 
    857 
    858     '''
    859     Populates the StackModelFit table
    860     '''
    861     def populateStackModelFit(self, filter):
    862         # for each filter
    863         f =filter
    864         if (filter == 'g'):
    865             self.header = self.gheader
    866            
    867         if (filter == 'r'):
    868             self.header = self.rheader
    869         if (filter == 'i'):
    870             self.header = self.iheader
    871         if (filter == 'z'):
    872             self.header = self.zheader
    873         if (filter == 'y'):
    874             self.header = self.yheader
    875            
    876 
    877 
    878 
    879 
    880         self.logger.infoPair("getting","imageID")
    881         imageID = self.scratchDb.getImageIDFromExternID(self.header['IMAGEID'])
    882         self.logger.infoPair("obtained","imageID")
    883         self.logger.infoPair("Procesing table", "StackModelFit")
    884 
    885 
    886         # insert all the detections
    887 
    888         # populate model parameters
    889         self.logger.infoPair("Adding model fit", "deVaucouleurs")
    890         self.updateModelFit("deV", "PS_MODEL_DEV", filter, self.header['EXPTIME'])
    891         self.logger.infoPair("Adding model fit", "exponential")
    892         self.updateModelFit("deV", "PS_MODEL_EXP", filter, self.header['EXPTIME'])
    893         self.logger.infoPair("Adding model fit", "sersic")
    894         self.updateModelFit("deV", "PS_MODEL_SERSIC", filter, self.header['EXPTIME'])
    895  
    896 
    897         self.logger.infoPair("Adding fluxes", "un-convolved")
    898         self.updateModelFitFlxs("", "((b.table_index -1) % 3 = 0)","StackModelFit",f)
    899         self.logger.infoPair("Adding fluxes", "1st convolved")
    900         self.updateModelFitFlxs("c1", "((b.table_index -1) % 3 = 1)","StackModelFit",f)
    901         self.logger.infoPair("Adding fluxes", "2nd convolved")
    902         self.updateModelFitFlxs("c2", "((b.table_index -1) % 3 = 2)","StackModelFit",f)
    903 
    904  
    905         self.logger.infoPair("Adding", "petrosians for extended sources")
    906         sql = "UPDATE StackModelFit as a, "+f+"SkyChip_xsrc AS b SET \
    907         "+f+"petRadius=b.PETRO_RADIUS \
    908         ,"+f+"petRadiusErr=b.PETRO_RADIUS_ERR \
    909         ,"+f+"petFlux=POW(10.0, -0.4 * b.PETRO_MAG) /" + str(self.header['EXPTIME']) + " \
    910         ,"+f+"petFluxErr=-999  \
    911         ,"+f+"petR50=b.PETRO_RADIUS_50 \
    912         ,"+f+"petR50Err=b.PETRO_RADIUS_50_ERR \
    913         ,"+f+"petR90=b.PETRO_RADIUS_90 \
    914         ,"+f+"petR90Err=b.PETRO_RADIUS_90_ERR \
    915         ,"+f+"petCf=b.PETRO_FILL \
    916         WHERE a."+f+"ippDetectID=b.IPP_IDET"
    917         self.scratchDb.execute(sql)
    918 
    919         self.logger.infoPair("Adding", "petFluxErr for non nulls")
    920         sql = "UPDATE StackModelFit as a, "+f+"SkyChip_xsrc AS b SET \
    921         "+f+"petFluxErr=ABS(b.PETRO_MAG_ERR) * POW(10.0, (-0.4*b.PETRO_MAG)) / " + str(self.header['EXPTIME']) + " / 1.085736  \
    922         WHERE a."+f+"ippDetectID=b.IPP_IDET \
    923         AND (b.PETRO_MAG_ERR is not NULL AND b.PETRO_MAG is not NULL AND PETRO_MAG_ERR < 1000.0)"
    924         # added this because when the petromagerr is crazy large (10^29 it out of ranges the flux err calc)
    925         self.logger.infoPair("sql", sql)
    926         self.scratchDb.execute(sql)
    927 
    928 
    929 
    930         self.scratchDb.updateAllRows("StackModelFit", "surveyID", str(self.surveyID))
    931         self.scratchDb.updateAllRows("StackModelFit", "dataRelease", str(self.skychunk.dataRelease))
    932 
    933         self.logger.infoPair("not adding"," PrimaryF to stackApFlx")
    934         sql = "UPDATE StackModelFit AS a, " + self.scratchDb.dvoDetectionTable + " AS b SET \
    935                a.primaryF = ((b.flags & 0x10000) >> 16 ) \
    936                WHERE a.ippDetectID = b.ippDetectID \
    937                AND b.imageID = " + str(imageID)
    938 
    939 #        try:
    940 #            self.scratchDb.execute(sql)
    941 #        except:
    942 #            return
    943 
    944 ##        self.scratchDb.updateAllRows("StackModelFit", "activeFlag", "0")
    945         ##self.updateStackMetaID("StackModelFit")
    946 ##        self.updateStackTypeID("StackModelFit")
    947        
    948         self.scratchDb.reportAndDeleteRowsWithNULLS("StackModelFit", "objID")
    949         self.deleteDetectionsNotInStackObject("StackModelFit", f)
    950 
    951     '''
    952     Reports and deletes detections in this table that are not in StackObject
    953     '''
    954     def deleteDetectionsNotInStackObject(self, table, filter):
    955         f= filter
    956 
    957         sql = "SELECT COUNT(*) FROM " + table + " WHERE "+f+"ippDetectID NOT IN (SELECT "+f+"ippDetectID FROM StackObject)"
    958         rs = self.scratchDb.executeQuery(sql)
    959         rs.first()
    960         nMissing = rs.getInt(1)
    961  
    962         if nMissing < 1: return
    963        
    964         sql = "DELETE FROM " + table + " WHERE "+f+"ippDetectID NOT IN (SELECT "+f+"ippDetectID FROM StackObject)"
    965         self.scratchDb.execute(sql)
    966         self.logger.infoPair("Detections not in StackObject", "%d deleted from %s" % (nMissing, table))
    967        
    968 
    969     '''
    970     Populates the StackToImage table
    971     '''
    972     def populateStackToImage(self):
    973 
    974         self.logger.infoPair("Procesing table", "StackToImage")
    975         filters = ['g','r','i','z','y']
    976         for f in filters:
    977            
    978             if f == 'g':
    979                 stackmetaid = self.gstackID
    980             if f == 'r':
    981                 stackmetaid = self.rstackID
    982             if f == 'i':
    983                 stackmetaid = self.istackID
    984             if f == 'z':
    985                 stackmetaid = self.zstackID
    986             if f == 'y':
    987                 stackmetaid = self.ystackID
    988             if stackmetaid > 0:
    989    
    990                 imageIDs = self.gpc1Db.getImageIDsForThisStackID(stackmetaid)
    991 
    992                 for imageID in imageIDs:
    993                     sql = "INSERT INTO StackToImage (stackMetaID, imageID) \
    994                    VALUES (\
    995                    " + str(stackmetaid) + ", " + imageID + ")"
    996                     self.scratchDb.execute(sql)
    997 
    998         # now update StackMeta with correct number of inputs
    999                     sql = "UPDATE "+f+"StackMeta SET nP2Images = (SELECT COUNT(distinct(floor(imageID/100))) FROM StackToImage where stackMetaID = "+str(stackmetaid)+")"
    1000                     self.scratchDb.execute(sql)
    1001 
    1002     '''
    1003     Generates the randomStackIds
    1004     '''
    1005     def populateRandomsAndSkyCellID(self):
    1006 
    1007         self.logger.infoPair("Generating Randoms","for StackObject")
    1008         sql = "update StackObject set randomStackObjID = FLOOR(RAND()*9223372036854775807) \
    1009               ,skyCellID = " + str(self.skycell)+ " \
    1010               ,surveyID = " + str(self.surveyID)
    1011         try:
    1012             self.scratchDb.execute(sql)
    1013         except:
    1014             self.logger.infoPair("failed sql", sql)
    1015 
    1016     '''
    1017     copies randomStackIds from StackObject to tableName
    1018     '''
    1019     def copyRandomsAndSkyCellIDFromStackObject(self, tableName):
    1020 
    1021         self.logger.infoPair("copying Randoms from StackObject to ", tableName)
    1022         sql = "update " + tableName + " join StackObject using (objID) \
    1023         set " + tableName + ".randomStackObjID = StackObject.randomStackObjID \
    1024         , " + tableName + ".skyCellID = StackObject.skyCellID \
    1025         , " + tableName + ".surveyID = StackObject.surveyID"
    1026         self.logger.infoPair("sql", sql)
    1027         try:
    1028             self.scratchDb.execute(sql)
    1029         except:
    1030             self.logger.infoPair("failed sql", sql)
    1031 
    1032 
    1033        
    1034     def populateStackIPPDetectIDFromDvo(self, tableName, all):
    1035 
    1036         #tableName = "StackObject"
    1037         self.logger.infoPair("Processing table", tableName)
    1038 
    1039         filters = ['g','r','i','z','y']
    1040        
    1041         for f in filters:
    1042             skip = 0
    1043             #first: do we skip this filter
    1044             if f == 'g':
    1045                 if self.gstackID < 0:
    1046                     skip = 1
    1047                 else:
    1048                     self.header=self.gheader
    1049                     stackmetaid = self.gstackID
    1050             elif f == 'r':
    1051                 if self.rstackID < 0:
    1052                     skip = 1
    1053                 else:
    1054                     self.header = self.rheader
    1055                     stackmetaid = self.rstackID
    1056             elif f == 'i':
    1057                 if self.istackID < 0:
    1058                     skip = 1
    1059                 else:
    1060                     self.header = self.iheader
    1061                     stackmetaid = self.istackID
    1062             elif f == 'z':
    1063                 if self.zstackID < 0:
    1064                     skip = 1
    1065                 else:
    1066                     self.header = self.zheader
    1067                     stackmetaid = self.zstackID
    1068             elif f == 'y':
    1069                 if self.ystackID < 0:
    1070                     skip = 1
    1071                 else:
    1072                     self.header = self.yheader
    1073                     stackmetaid = self.ystackID
    1074             if skip == 0:       
    1075                 imageID = self.scratchDb.getImageIDFromExternID(self.header['IMAGEID'])
    1076                 self.logger.infoPair("obtained","imageID")
    1077                 addsql = ""
    1078                 if (all == 1):
    1079                     addsql = "a." + f + "ra = b.ra, \
    1080                       a." + f + "dec = b.dec_, \
    1081                       a." + f + "raErr = b.raErr, \
    1082                       a." + f + "decErr = b.decErr, \
    1083                       a." + f + "zp = b.zp, \
    1084                       a." + f + "expTime = b.expTime,"
    1085 
    1086                    
    1087                 sql = "UPDATE " + tableName + " AS a, "  + self.scratchDb.dvoDetectionTable + " AS b \
    1088                       SET a." + f + "ippDetectID = b.ippDetectID, \
    1089                       " + addsql + " \
    1090                       a." + f + "stackDetectID = b.detectID,   \
    1091                       a." + f + "ippObjID = b.ippObjID, \
    1092                       a." + f + "stackMetaID = " + str(stackmetaid) +  " \
    1093                       WHERE a.objID = b.objID  AND b.imageID = " + str(imageID)
    1094                 self.logger.infoPair('sql',sql)   
    1095                 self.scratchDb.execute(sql)
    1096             else:
    1097                 self.logger.infoPair("skipping ingest of dvo for filter",f)
    1098         #out of the loops - give dataRelase to all       
    1099         self.scratchDb.updateAllRows(tableName, "dataRelease", str(self.skychunk.dataRelease))
    1100 
    1101 
    1102     def deleteNULLippDetectIDs(self, tableName):
    1103 
    1104         self.logger.infoPair("Deleting NULL ippdetectIDs from table", tableName)
    1105         sql = "DELETE FROM " + tableName + " WHERE \
    1106               gippDetectID is NULL AND \
    1107               rippDetectID is NULL AND \
    1108               iippDetectID is NULL AND \
    1109               zippDetectID is NULL AND \
    1110               yippDetectID is NULL "
    1111         self.logger.infoPair('sql',sql)   
    1112         self.scratchDb.execute(sql)
    1113 
    1114     '''
    1115     Applies indexes to the PSPS tables
    1116     '''
    1117     def alterPspsTables(self):
    1118 
    1119         self.logger.debug("Altering PSPS tables")
    1120         # heather uncommented the unique line -- well that no worky
    1121         #self.scratchDb.makeColumnUnique("StackObject", "objID")
    1122         self.scratchDb.createIndex("StackObject", "ippDetectID")
    1123         self.scratchDb.createIndex("StackObject", "stackDetectID")
    1124         self.scratchDb.createIndex("StackApFlx", "ippDetectID")
    1125         self.scratchDb.createIndex("StackModelFit", "ippDetectID")
    1126 
    1127         return True
    1128 
    1129     '''
    1130     Applies indexes to the IPP tables
    1131     '''
    1132     def indexIppTables(self):
    1133 
    1134         self.logger.infoPair("Creating indexes on", "IPP tables")
    1135         self.scratchDb.createIndex("SkyChip_psf", "IPP_IDET")
    1136         self.scratchDb.createIndex("SkyChip_xfit", "IPP_IDET")
    1137         self.scratchDb.createIndex("SkyChip_xrad", "IPP_IDET")
    1138         self.scratchDb.createIndex("SkyChip_xsrc", "IPP_IDET")
    1139 
    1140         return True
    1141     '''
    1142     Insert objid (from dvo) into table
    1143     '''
    1144     def insertDvoIDs(self, table, filterName):
    1145         self.logger.infoPair("getting imageID for ","filter")
    1146         if (filterName == 'g.00000'):
    1147             self.header=self.gheader
    1148         if (filterName == 'r.00000'):
    1149             self.header=self.rheader
    1150         if (filterName == 'i.00000'):
    1151             self.header=self.iheader
    1152         if (filterName == 'z.00000'):
    1153             self.header=self.zheader
    1154         if (filterName == 'y.00000'):
    1155             self.header=self.yheader
    1156 
    1157         imageID = self.scratchDb.getImageIDFromExternID(self.header['IMAGEID'])
    1158         self.logger.infoPair("obtained","imageID")
    1159         self.logger.debug("Updating table '" + table + "' with DVO IDs...")
    1160         sql = "INSERT IGNORE INTO " + table + " ( \
    1161                objID ) \
    1162                SELECT (objID) FROM " + self.scratchDb.dvoDetectionTable + "  \
    1163                WHERE " + self.scratchDb.dvoDetectionTable + ".imageID = " + str(imageID)
    1164         self.logger.infoPair("sql",sql)
    1165         self.scratchDb.execute(sql)
    1166    
    1167 
    1168 
    1169     '''
    1170     Updates provided table with DVO IDs from DVO table
    1171     '''
    1172     def updateDvoIDs(self, table, filterName):
    1173         self.logger.infoPair("getting imageID for ","filter")
    1174         imageID = self.scratchDb.getImageIDFromExternID(self.header['IMAGEID'])
    1175         self.logger.infoPair("obtained","imageID")
    1176         self.logger.debug("Updating table '" + table + "' with DVO IDs...")
    1177         sql = "UPDATE " + table + " AS a, " + self.scratchDb.dvoDetectionTable + " AS b SET \
    1178                a.ippObjID = b.ippObjID, \
    1179                a.stackDetectID = b.detectID, \
    1180                a.objID = b.objID \
    1181                WHERE a.ippDetectID = b.ippDetectID \
    1182                AND b.imageID = " + str(imageID)
    1183         self.scratchDb.execute(sql)
    1184    
    1185     '''
    1186     Updates Flags
    1187     '''
    1188     def updateDvoIDsAndFlags(self, table):
    1189         self.logger.infoPair("getting","imageID")
    1190         imageID = self.scratchDb.getImageIDFromExternID(self.header['IMAGEID'])
    1191         self.logger.infoPair("obtained","imageID")
    1192         self.logger.debug("Updating table '" + table + "' with DVO IDs...")
    1193         sql = "UPDATE " + table + " AS a, " + self.scratchDb.dvoDetectionTable + " AS b SET \
    1194                a.ippObjID = b.ippObjID, \
    1195                a.stackDetectID = b.detectID, \
    1196                a.objID = b.objID, \
    1197                a.infoFlag = b.flags << 45 | a.infoFlag,  \
    1198                a.primaryF = ((b.flags & 0x10000) >> 16 ) \
    1199                WHERE a.ippDetectID = b.ippDetectID \
    1200                AND b.imageID = " + str(imageID)
    1201 
    1202         print "update dvo sql: ", sql
    1203         self.scratchDb.execute(sql)
    1204    
     999            self.logger.errorPair('failed sql',sql)
     1000            return
    12051001   
    12061002    '''
     
    12101006        self.logger.infoPair("starting","populatePspsTables");
    12111007        self.skipBatch = False
    1212         if not self.useFullTables:
    1213              if not self.getIDsFromDVO():
    1214                 return False
    1215         #do some basics first
    1216         # populate stack meta per filter
    1217         # insert objid/stackdetectid per filter to each table           
     1008
     1009        # each of the "populate*" methods below add their tables to the list:
    12181010        self.tablesToExport=[]   
    12191011
    1220         if self.gstackID > 0:       
    1221             self.logger.infoPair("populating","gStackMeta")   
    1222             self.populateStackMeta("g.00000")
    1223             self.insertDvoIDs("StackObject","g.00000")
    1224             self.insertDvoIDs("StackModelFit","g.00000")
    1225             self.insertDvoIDs("StackApFlx","g.00000")
    1226             self.tablesToExport.append("gStackMeta")
    1227         if self.rstackID > 0:   
    1228             self.logger.infoPair("populating","rStackMeta")   
    1229             self.populateStackMeta("r.00000")
    1230             self.insertDvoIDs("StackObject","r.00000")
    1231             self.insertDvoIDs("StackModelFit","r.00000")
    1232             self.insertDvoIDs("StackApFlx","r.00000")
    1233             self.tablesToExport.append("rStackMeta")
    1234         if self.istackID > 0:   
    1235             self.logger.infoPair("populating","iStackMeta")   
    1236             self.populateStackMeta("i.00000")
    1237             self.insertDvoIDs("StackObject","i.00000")
    1238             self.insertDvoIDs("StackModelFit","i.00000")
    1239             self.insertDvoIDs("StackApFlx","i.00000")
    1240             self.tablesToExport.append("iStackMeta")
    1241         if self.zstackID > 0:   
    1242             self.logger.infoPair("populating","zStackMeta")   
    1243             self.populateStackMeta("z.00000")
    1244             self.insertDvoIDs("StackObject","z.00000")
    1245             self.insertDvoIDs("StackModelFit","z.00000")
    1246             self.insertDvoIDs("StackApFlx","z.00000")
    1247             self.tablesToExport.append("zStackMeta")
    1248         if self.ystackID > 0:   
    1249             self.logger.infoPair("populating","yStackMeta")   
    1250             self.populateStackMeta("y.00000")
    1251             self.insertDvoIDs("StackObject","y.00000")
    1252             self.insertDvoIDs("StackModelFit","y.00000")
    1253             self.insertDvoIDs("StackApFlx","y.00000")
    1254             self.tablesToExport.append("yStackMeta")
    1255 
    1256         self.logger.infoPair("populating ","StackObject")
    1257         # need to index on objid and ippdetectid  or it is stupidly slow
    1258         self.scratchDb.createIndex("StackObject", "objID")
    1259         #populate from dvo the (f)ippDetectID into StackObject 
    1260         self.populateStackIPPDetectIDFromDvo("StackObject",1)
    1261         #index the ippDetectids for the next step
    1262         self.scratchDb.createIndex("StackObject", "gippDetectID")
    1263         self.scratchDb.createIndex("StackObject", "rippDetectID")
    1264         self.scratchDb.createIndex("StackObject", "iippDetectID")
    1265         self.scratchDb.createIndex("StackObject", "zippDetectID")
    1266         self.scratchDb.createIndex("StackObject", "yippDetectID")
    1267         self.populateStackObject()
    1268         self.populateRandomsAndSkyCellID()
    1269         # stackObject should be done, pending a few NULL columns (need help)
     1012        # EAM 20140730 : I have revised the StackObjectXX construction
     1013        # process.  The challenge here is that we have dvo-generated
     1014        # objIDs and ippObjIDs for each stack detection in seperate
     1015        # rows, but we want to merge the 5 filter sets into a single
     1016        # set of rows.  The old code was relying on INSERT IGNORE,
     1017        # making it hard to catch errors, and probably not doing the
     1018        # insert very efficiently
     1019       
     1020        # Now we do a first pass with SELECT DISTINCT to get the
     1021        # complete set of objIDs which are associated with detections
     1022        # from one of the relevant images (ie, measure.imageID matches
     1023        # the set of image IDs). 
     1024
     1025        # once we have determined the complete set of desired objects,
     1026        # then we can use an update to set the per-field fields with
     1027        # data selected for each filter.  Once we have constructed
     1028        # this basic common information in StackObjectThin, then we
     1029        # can uses this table to seed the same rows in the other Stack
     1030        # tables
     1031
     1032        for filter in self.filters:
     1033            if self.stackIDs[filter] > 0:       
     1034                self.populateStackMeta(filter)
     1035
     1036        self.populateStackObjectThin()
     1037
     1038        self.populateStackObjectRaw()
    12701039
    12711040        if self.stackType != "NIGHTLY_STACK":
    12721041
     1042            self.logger.infoPair("populating ","StackModelFitExtra")
     1043            self.populateStackModelFitExtra()
     1044
    12731045            self.logger.infoPair("populating ","StackModelFit")
    1274 
    1275             self.scratchDb.createIndex("StackModelFit", "objID")
    1276         #populate from dvo the (f)ippdetectid into stackModelFit
    1277             self.populateStackIPPDetectIDFromDvo("StackModelFit",0)
    1278         #index the ippDetectIds for the next step
    1279             self.scratchDb.createIndex("StackModelFit", "gippDetectID")
    1280             self.scratchDb.createIndex("StackModelFit", "rippDetectID")
    1281             self.scratchDb.createIndex("StackModelFit", "iippDetectID")
    1282             self.scratchDb.createIndex("StackModelFit", "zippDetectID")
    1283             self.scratchDb.createIndex("StackModelFit", "yippDetectID")
    1284         #cull the entries that should not be (how?)       
    1285             self.deleteNULLippDetectIDs("StackModelFit")
    1286         #populate stackModelFit
    1287             if self.gstackID > 0:
    1288                 self.logger.infoPair("populating g filter for stackModelFit, stackmetaid =", self.gstackID)
    1289                 self.populateStackModelFit("g")
    1290             if self.rstackID > 0:
    1291                 self.logger.infoPair("populating r filter for stackModelFit, stackmetaid =", self.rstackID)
    1292                 self.populateStackModelFit("r")
    1293             if self.istackID > 0:
    1294                 self.logger.infoPair("populating i filter for stackModelFit, stackmetaid =", self.istackID)
    1295                 self.populateStackModelFit("i")
    1296             if self.zstackID > 0:
    1297                 self.logger.infoPair("populating z filter for stackModelFit, stackmetaid =", self.zstackID)
    1298                 self.populateStackModelFit("z")
    1299             if self.ystackID > 0:
    1300                 self.logger.infoPair("populating y filter for stackModelFit, stackmetaid =", self.ystackID)
    1301                 self.populateStackModelFit("y")
    1302            
    1303             self.copyRandomsAndSkyCellIDFromStackObject("StackModelFit")
    1304  
    1305             self.logger.infoPair("populating ","StackApFlx")
    1306            
    1307             self.scratchDb.createIndex("StackApFlx", "objID")
    1308         #populate from dvo the (f)ippDetectID into StackApFlx
    1309             self.populateStackIPPDetectIDFromDvo("StackApFlx",0)
    1310         #index the ippDetectIDs for the next step
    1311             self.scratchDb.createIndex("StackApFlx", "gippDetectID")
    1312             self.scratchDb.createIndex("StackApFlx", "rippDetectID")
    1313             self.scratchDb.createIndex("StackApFlx", "iippDetectID")
    1314             self.scratchDb.createIndex("StackApFlx", "zippDetectID")
    1315             self.scratchDb.createIndex("StackApFlx", "yippDetectID")
    1316         #populate StackApFlx
    1317             self.deleteNULLippDetectIDs("StackApFlx")
     1046            self.populateStackModelFit("Exp", "PS_MODEL_EXP")
     1047            self.populateStackModelFit("DeV", "PS_MODEL_DEV")
     1048            self.populateStackModelFit("Ser", "PS_MODEL_SERSIC")
     1049
     1050            self.populateStackPetrosian()
     1051
     1052            self.logger.infoPair("populating ","StackApFlx Tables")
    13181053            self.populateStackApFlx()
    1319             self.copyRandomsAndSkyCellIDFromStackObject("StackApFlx")
    1320         #cull the entries that should not be (how?)
    1321        
    1322        
     1054
     1055            self.populateStackApFlxFull("")
     1056            self.populateStackApFlxFull("C1")
     1057            self.populateStackApFlxFull("C2")
     1058
     1059        # delete rows with no content. for the other tables, this is done in
     1060        # the 'populate' functions, but StackObjectThin needs to retain all rows
     1061        # until those tables are done
     1062        self.deleteRowsWithNoStackData("StackObjectThin")
     1063
    13231064        self.logger.infoPair("populating","StackToImage")
    13241065        self.populateStackToImage()
    13251066       
    1326         self.setMinMaxObjID(["StackObject"])
    1327       #  self.updateStackTypeID("StackModelFit")
    1328 
    1329         ##if self.totalDetections < 1:
    1330         #self.logger.infoPair("populating","SkinnyObject")
    1331         self.populateSkinnyObject()
    1332 
    1333             ##self.logger.error("No detections to publish")
    1334             ##return False
    1335         self.tablesToExport.append("StackToImage")
    1336         self.tablesToExport.append("StackObject")
    1337         self.tablesToExport.append("StackModelFit")
    1338         self.tablesToExport.append("StackApFlx")
    1339         self.tablesToExport.append("SkinnyObject")
     1067        self.setMinMaxObjID(["StackObjectThin"])
     1068
    13401069        self.logger.infoPair("finishing","populatePspsTables");
    13411070        return True
     1071
    13421072    '''
    13431073    overidding this method - use regex to trimoff letter before stack
     
    13451075    def exportPspsTablesToFits(self, regex="(.*)"):
    13461076        return super(StackBatch, self).exportPspsTablesToFits("(Stack.*)")
     1077
     1078    '''
     1079    Imports IPP tables from FITS file
     1080    Accepts a regular expression to match the tables so not all tables need to be imported
     1081    (This regex feature is not currently used...)
     1082    '''
     1083    def importIppTables(self, columns="*", tableRE=""):
     1084       
     1085        if self.config.retry: return True
     1086
     1087        self.logger.infoPair("Importing ST tables with table match expression: ", tableRE)
     1088
     1089        count = 0
     1090        for filter in self.filters:
     1091            if self.stackIDs[filter] <= 0: 
     1092                self.logger.infoPair("no files for filter" , filter)
     1093                continue
     1094
     1095            fileName = self.fits[filter].getPath()
     1096           
     1097            self.logger.infoPair("using filename:",fileName)
     1098           
     1099            try:
     1100                tables = stilts.treads(fileName)
     1101            except:
     1102                self.logger.errorPair("STILTS could not import from", fileName)
     1103                return False
     1104           
     1105            # count = 0
     1106            for table in tables:
     1107             
     1108                match = re.match(tableRE, table.name)
     1109                if not match: continue
     1110
     1111                self.logger.infoPair("Reading IPP table", filter + table.name)
     1112                table = stilts.tpipe(table, cmd='addcol table_index $0')
     1113                table = stilts.tpipe(table, cmd='explodeall')
     1114                 
     1115                # drop any previous tables before import
     1116                self.scratchDb.dropTable(filter + table.name)
     1117                 
     1118                # IPP FITS files are littered with infinities, so remove these
     1119                self.logger.info("Removing Infinity values from all columns")
     1120                table = stilts.tpipe(table, cmd='keepcols "' + columns + '"')
     1121                table = stilts.tpipe(table, cmd='replaceval -Infinity null *')
     1122                table = stilts.tpipe(table, cmd='replaceval Infinity null *')
     1123                 
     1124                try:
     1125                    table.write(self.scratchDb.url + '#' + filter + table.name)
     1126                    count = count + 1
     1127                except:
     1128                    self.logger.exception("Problem writing table '" + filter + table.name + "' to the database")
     1129                     
     1130        self.logger.infoPair("Done. Imported", "%d tables" % count)
     1131        self.indexIppTables()
     1132                     
     1133        return True
Note: See TracChangeset for help on using the changeset viewer.