IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 12, 2015, 12:24:24 PM (12 years ago)
Author:
eugene
Message:

various updates merged from trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-pv3-20140717-merge/ippToPsps/jython/stackbatch.py

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