IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 11, 2015, 1:31:50 PM (12 years ago)
Author:
eugene
Message:

merge changes from trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20140904/ippToPsps/jython/diffobjectbatch.py

    r36697 r37801  
     1#!/usr/bin/env jython
     2
     3import os.path
     4import sys
     5
     6import stilts
     7from java.lang import *
     8from java.sql import *
     9
     10from xml.etree.ElementTree import ElementTree, Element, tostring
     11
     12from batch import Batch
     13from gpc1db import Gpc1Db
     14from ipptopspsdb import IppToPspsDb
     15from scratchdb import ScratchDb
     16from dvoobjects import DvoObjects
     17from sqlUtility import sqlUtility
     18
     19import logging.config
     20
     21'''
     22DiffObjectBatch class
     23
     24This class, a sub-class of Batch, processes individual DVO region file pairs (cpt and cps files). The cpt file contains a list of all objects in that region, the cps file contains the magnitudes and so has a row per filter per object (so, generally, has rows = 5 x number of objects). The Photcode.dat table us used to figure out the number and order of filters as they appear in the cps file.
     25
     26'''
     27class DiffObjectBatch(Batch):
     28
     29    '''
     30    Constructor
     31    '''
     32    def __init__(self,
     33                 logger,
     34                 config,
     35                 skychunk,
     36                 gpc1Db,
     37                 ippToPspsDb,
     38                 scratchDb,
     39                 dvoID,
     40                 batchID):
     41
     42       super(DiffObjectBatch, self).__init__(
     43               logger,
     44               config,
     45               skychunk,
     46               gpc1Db,
     47               ippToPspsDb,
     48               scratchDb,
     49               dvoID,
     50               batchID,
     51               "DO",
     52               None)
     53
     54       try:
     55           self.dvoObjects = DvoObjects(self.logger, self.config, self.skychunk, self.ippToPspsDb, self.scratchDb)
     56       except:
     57           self.logger.errorPair("Unable to create instance of", "DvoObjects")
     58           raise
     59
     60       # create an output filename, which is {dvoINDEX}.FITS
     61       self.outputFitsFile = "%08d.FITS" % self.id
     62       self.outputFitsPath = "%s/%s" % (self.localOutPath, self.outputFitsFile)
     63
     64       # dump stuff to log
     65       self.logger.infoPair("DVO INDEX", "%d" % self.id)
     66
     67    '''
     68    Overriden from batch base-class. We import from DVO directly for objects
     69    '''
     70    def importIppTables(self, columns="*", filter=""):
     71
     72        self.region = self.scratchDb.getRegionNameFromThisDvoIndex(self.id)
     73        self.ippToPspsDb.insertObjectMeta(self.batchID, self.region)
     74        self.dvoObjects.nativeIngestRegion(self.region)
     75
     76        cptTableName = self.scratchDb.getDbFriendlyTableName(self.region + ".cpt")
     77        if not self.scratchDb.tableExists(cptTableName):
     78            return False
     79
     80        return True
     81
     82    '''
     83    Applies indexes to the PSPS tables
     84    '''
     85    def alterPspsTables(self):
     86
     87        return True
     88
     89    '''
     90    Applies indexes to the IPP tables
     91    '''
     92    def indexIppTables(self):
     93
     94        # since dvopsps is now used, no action is needed here
     95        # self.logger.infoPair("Creating indexes on", "IPP tables")
     96
     97        return True
     98
     99    '''
     100    Inserts stuff for all mags
     101    '''
     102    def updateMeanObjectFromCps(self, cpsTable):
     103
     104        # list of all filters PSPS is interested in
     105        # XXX EAM : 2014.07.24 : this list should probably be in a config file somewhere
     106        interestedFilters = ['g', 'r', 'i', 'z', 'y']
     107       
     108        filters = self.scratchDb.getOrderedListOfFiltersFromPhotcodesTable(interestedFilters)
     109   
     110        # get a count of the available filters
     111        filterCount = self.scratchDb.getCountOfFiltersFromPhotcodesTable()
     112
     113        self.logger.infoPair("Available filters in Photcodes", filters)
     114
     115        # the 'code' now defines the order in the cps file that the mags are listed for a given filter
     116        self.logger.infoPair("Adding magnitudes from", "cps table")
     117        for filter in filters:
     118
     119            filterID = self.scratchDb.getFilterID(filter[1])
     120
     121            # NOTE: Manipulation of FLAGS from cpsTable is to move ID_SECF_OBJ_EXT flag (0x01000000)
     122            # from bit 24 to bit 13 so that it fits into the SMALLINT Object.Flags
     123            # XXX EAM : 20140724 this manipulation is no longer needed : [grizy]Flags is now 4 byte (was 8 byte!)
     124
     125            # set the MeanObject fields based largely on dvopsps cps fields:
     126
     127            # XXX EAM 20140724 : filterCount is meant to match
     128            # Nsecfilt, but is potentially not determined correctly.
     129            # use a call to a dvo-native command which knows how to
     130            # find Nsecfilt (or save in the db with dvopsps)
     131
     132            # the math below depends on filterCount = Nsecfilt and MeanObject.row being 1 counting but cps being 0 counting?
     133            # cps.row has a count of MeanObject.row * Nsecfilt + Nfilter
     134            #  " + cpsTable + " AS cps ON (cps.row = (MeanObject.row* " + str(filterCount) + ")-(" + str(filterCount) + " - " + str(filter[0]) + ")) \
     135
     136            sql = "UPDATE DiffDetObject JOIN \
     137                   " + cpsTable + " AS cps ON (cps.row = (DiffDetObject.row* " + str(filterCount) + ")-(" + str(filterCount) + " - " + str(filter[0]) + ")) \
     138                   SET \
     139                    DiffDetObject." + filter[1] + "QfPerfect      = PSF_QF_PERF_MAX "
     140
     141            try: self.scratchDb.execute(sql)
     142            except:
     143                self.logger.errorPair("failed update DiffDetObject", sql)
     144                raise
     145
     146    '''
     147    Inserts stuff for all mags
     148    '''
     149    def updateDiffObjectFromCps(self, cpsTable):
     150
     151        # list of all filters PSPS is interested in
     152        interestedFilters = ['g', 'r', 'i', 'z', 'y']
     153       
     154        filters = self.scratchDb.getOrderedListOfFiltersFromPhotcodesTable(interestedFilters)
     155   
     156        # get a count of the available filters
     157        filterCount = self.scratchDb.getCountOfFiltersFromPhotcodesTable()
     158        # filterCount = len(filters)
     159
     160        self.logger.infoPair("Available filters in Photcodes", filters)
     161
     162        # the 'code' now defines the order in the cps file that the mags are listed for a given filter
     163        self.logger.infoPair("Adding magnitudes from", "cps table")
     164        for filter in filters:
     165
     166            filterID = self.scratchDb.getFilterID(filter[1])
     167
     168            # XXX EAM 20140724 : this is quite awkward, add a objRow and ncode value to mysql db table?
     169            # sqlLine = sqlUtility()
     170
     171            sql  = "UPDATE DiffDetObject JOIN "
     172            sql += cpsTable + " AS cps "
     173            sql += "ON (cps.row = (DiffDetObject.row * "
     174            sql += str(filterCount) + ")-("
     175            sql += str(filterCount) + " - "
     176            sql += str(filter[0])
     177            sql += ")) "
     178
     179            sql += "SET DiffDetObject.n" + filter[1] + " = NCODE, "
     180            sql += "DiffDetObject.nDetections = DiffDetObject.nDetections + cps.NSTACK_DET"
     181            self.logger.info(sql)
     182            self.scratchDb.execute(sql)
     183
     184        # XXX this does not seem like a good thing to leave in SQL
     185        self.logger.infoPair("Calculating nDetections from", "n[filters]")
     186        for filter in filters:
     187            # now do a sum of n[filters], but do not include the ones with -999
     188            sql  = "UPDATE DiffDetObject "
     189            sql += "SET nDetections = nDetections + n" + filter[1]
     190            sql += " WHERE n" + filter[1] + " != -999"
     191            self.scratchDb.execute(sql)
     192
     193    '''
     194    give objectName to objectThin
     195    XXX EAM 20140714 : This seems quite inefficient in SQL, move to dvopsps?
     196    '''
     197    def updateDiffObjName(self):
     198    ##this is a 2 part update:
     199
     200        self.logger.infoPair("updating diffObjName", "using means")
     201    ## use mean ra and dec (dec >= 0)
     202        sql = "update DiffDetObject set diffObjName =  concat('PS1.2 J', \
     203        lpad(floor(ra/15.),2,'0'), \
     204        lpad((ra/15.-(floor(ra/15.)))*60. ,2,'0'), \
     205        lpad(format(((ra/15.-(floor(ra/15.)))*60.-floor((ra/15.-(floor(ra/15.)))*60.))*60.,2),4,'0'), \
     206        '+', \
     207        lpad(floor(dec_),2,'0'), \
     208        lpad((dec_-(floor(dec_)))*60. ,2,'0'), \
     209        lpad(format(((dec_-(floor(dec_)))*60.-floor((dec_-(floor(dec_)))*60.))*60.,2),4,'0') \
     210        ) where ra > -999 and dec_ > -999 and dec_ >= 0"
     211        try:
     212            self.scratchDb.execute(sql)
     213        except:
     214            self.logger.errorPair("failed sql", sql)
     215            return False
     216 
     217    ## use mean ra and dec (dec < 0)
     218
     219        sql = "update DiffDetObject set diffObjName =  concat('PS1.2 J', \
     220        lpad(floor(ra/15.),2,'0'), \
     221        lpad((ra/15.-(floor(ra/15.)))*60. ,2,'0'), \
     222        lpad(format(((ra/15.-(floor(ra/15.)))*60.-floor((ra/15.-(floor(ra/15.)))*60.))*60.,2),4,'0'), \
     223        '-', \
     224        lpad(floor(dec_),2,'0'), \
     225        lpad((dec_-(floor(dec_)))*60. ,2,'0'), \
     226        lpad(format(((dec_-(floor(dec_)))*60.-floor((dec_-(floor(dec_)))*60.))*60.,2),4,'0') \
     227        ) where ra > -999 and dec_ > -999 and dec_ < 0"
     228
     229        try:
     230            self.scratchDb.execute(sql)
     231        except:
     232            self.logger.errorPair("failed sql", sql)
     233            return False
     234
     235    '''
     236    Populates the DiffObject table
     237    '''
     238    def populateDiffObjectTable(self):
     239
     240        cptTableName = self.scratchDb.getDbFriendlyTableName(self.region + ".cpt")
     241        cpsTableName = self.scratchDb.getDbFriendlyTableName(self.region + ".cps")
     242
     243        if False:
     244            # XXX EAM 20140724 : this is probably wrong : flux measurements can be 0.0 or negative: please review
     245            self.logger.infoPair("setting to null  > 1e-38 and < 1e-38 in", "cps FLUX_KRON_ERR")
     246            sql = "UPDATE " + cpsTableName + " set FLUX_KRON_ERR = NULL where FLUX_KRON_ERR < 1e-37 AND FLUX_KRON_ERR > -1e-37 "
     247            self.exitProgram("review this code" + sql)
     248     
     249            try:
     250                self.scratchDb.execute(sql)
     251            except:
     252                self.logger.errorPair("Couldn't squash out of range stuff", sql)
     253                return False
     254
     255            self.logger.infoPair("setting to null  > 1e-38 and < 1e-38 in", "cps FLUX_KRON")
     256            sql = "UPDATE " + cpsTableName + " set FLUX_KRON = NULL where FLUX_KRON < 1e-37 AND FLUX_KRON > -1e-37 "
     257     
     258            try:
     259                self.scratchDb.execute(sql)
     260            except:
     261                self.logger.errorPair("Couldn't squash out of range stuff", sql)
     262                return False
     263
     264       
     265        self.logger.info("Populating DiffDetObject")
     266        self.logger.info("Inserting objects from cpt file")
     267
     268        # note "dec" is a reserved word in MySQL
     269        # XXX EAM 20140724 : do not use INGORE unless we discover unavoidable problems...
     270        # INSERT IGNORE INTO ObjectThin
     271
     272        sqlLine = sqlUtility("INSERT INTO DiffDetObject (")
     273
     274        sqlLine.group("diffObjID",           "EXT_ID")
     275        sqlLine.group("ippObjID",        "OBJ_ID + (CAT_ID << 32)") # NOTE: shift by 32 bits exactly
     276        sqlLine.group("surveyID",        "'" + str(self.surveyID) + "'")
     277        sqlLine.group("randomID",        "FLOOR(RAND("+str(self.batchID)+")*9223372036854775807)") # XXX where does this number come from??
     278        sqlLine.group("batchID",         "'" + str(self.batchID) + "'")
     279        sqlLine.group("dvoRegionID",     "CAT_ID")
     280        sqlLine.group("skycellID",       "SKYCELL_ID")
     281        sqlLine.group("dataRelease",     "'" + str(self.skychunk.dataRelease) + "'")
     282        sqlLine.group("objInfoFlag",     "FLAGS")
     283        sqlLine.group("qualityFlag",     "FLAGS >> 24 & 0xFF")
     284        sqlLine.group("consistencyFlag", "'0'")
     285        sqlLine.group("ra",          "RA_MEAN")
     286        sqlLine.group("dec_",         "DEC_MEAN")
     287        sqlLine.group("raErr",       "RA_ERR")
     288        sqlLine.group("decErr",      "DEC_ERR")
     289        sqlLine.group("nDetections",      "'0'")
     290        sql = sqlLine.makeRaw(") SELECT ", " FROM " + cptTableName)
     291
     292        try:
     293            self.scratchDb.execute(sql)
     294        except:
     295            self.logger.errorPair("Couldn't populate DiffDetObject table", sql)
     296            return False
     297 
     298        # add row count columns so we can perform joins to get colors
     299        self.logger.infoPair("Adding 'row' columns to", "DiffDetObject and cps tables")
     300        self.scratchDb.addRowCountColumn("DiffDetObject", "row")
     301        self.scratchDb.addRowCountColumn(cpsTableName, "row")
     302
     303##        self.insertMeanMags(cpsTableName)
     304## this is the new version
     305        self.logger.infoPair("update diffObjName for ","DiffDetObject")
     306        self.updateDiffObjName()
     307
     308        self.logger.infoPair("update DiffDetObject from ","cps table")
     309
     310        self.updateDiffObjectFromCps(cpsTableName)
     311
     312        # XXX EAM 20140724 : is this necessary??
     313        #objects can have out of range ra dec in dvo - need to find and kill them at the end
     314
     315        self.logger.infoPair("Determining", "ra/dec range")
     316
     317        raMin = self.scratchDb.getFromdvoSkyTable("R_MIN",self.region)
     318        raMax = self.scratchDb.getFromdvoSkyTable("R_MAX",self.region)
     319        decMin = self.scratchDb.getFromdvoSkyTable("D_MIN",self.region)
     320        decMax = self.scratchDb.getFromdvoSkyTable("D_MAX",self.region)
     321
     322        self.logger.infoPair("R_MIN", raMin)
     323        self.logger.infoPair("R_MAX", raMax)
     324        self.logger.infoPair("D_MIN", decMin)
     325        self.logger.infoPair("D_MAX", decMax)
     326        #count out of range
     327
     328        sql = "SELECT count(*) FROM DiffDetObject where \
     329              DiffDetObject.dec_ > (" + str(decMax) + " + .0033) \
     330              or DiffDetObject.dec_ < (" + str(decMin) + " - .0033) \
     331              or DiffDetObject.ra > (" + str(raMax) + " + .0033) \
     332              or DiffDetObject.ra < (" + str(raMin) + " - .0033)"       
     333   
     334        rs = self.scratchDb.executeQuery(sql)
     335        rs.first()
     336        nToDelete = rs.getInt(1)
     337       
     338        #delete out of range
     339       
     340 
     341        sql = "DELETE FROM DiffDetObject where \
     342              DiffDetObject.dec_ > (" + str(decMax) + " + .0033) or \
     343              DiffDetObject.dec_ < (" + str(decMin) + " - .0033) or \
     344              DiffDetObject.ra > (" + str(raMax) + " + .0033) or \
     345              DiffDetObject.ra < (" + str(raMin) + " - .0033)"
     346        self.logger.infoPair("Deleting", str(nToDelete) + " objects outside of ra/dec range")
     347
     348        try:
     349            self.scratchDb.execute(sql)
     350        except:
     351            self.logger.errorPair("Couldn't cull outsiders from DiffDetObject table", sql)
     352            return False
     353
     354        self.logger.infoPair("Dropping row column from", "DiffDetObject table")
     355        self.scratchDb.dropColumn("DiffDetObject", "row")
     356        ##self.logger.infoPair("Purging from scratch Db", self.region + " region")
     357
     358        ##Don't do this till after MeanObject
     359        ##self.dvoObjects.purgeRegion(self.region)
     360
     361        self.setMinMaxDiffObjID(["DiffDetObject"])
     362
     363        return True
     364
     365    '''
     366    Updates table and generates pspsuniqueids
     367    '''
     368
     369    def updatePspsUniqueIDs(self,table):
     370        sql = "UPDATE "+table+" join (select @r:=@r+1 rownum, diffobjID from \
     371        (select @r:=0) r, "+table+" t) as foo using (diffobjID) set \
     372        uniquePspsDOid = ((" +str(self.batchID)+ "*1000000000 ) + rownum)"
     373        try: self.scratchDb.execute(sql)
     374        except:
     375            self.logger.errorPair('failed sql',sql)
     376            return
     377
     378
     379
     380    '''
     381    Does the processing, i.e. pulling stuff from IPP tables into PSPS tables
     382    '''
     383    def populatePspsTables(self):
     384
     385        if not self.populateDiffObjectTable(): return False
     386
     387        # now remove the objID duplicates. We could not do this before as cpt/cps tables relate by row number
     388        self.logger.infoPair("Forcing uniqueness on", "objID in DIffObject table")
     389        rowCountBefore = self.scratchDb.getRowCount("DiffDetObject")
     390
     391        # XXX EAM : note that in mysql versions later than 5.1, this fails
     392        # unless the following is called first:
     393        # set session old_alter_table=1
     394        # follow the command with
     395        # set session old_alter_table=0
     396        # OF COURSE, this fails for mysql version < 5.5...
     397        if self.scratchDb.version > 5.1:
     398            self.scratchDb.execute("set session old_alter_table=1")
     399           
     400        self.scratchDb.execute("ALTER IGNORE TABLE DiffDetObject ADD UNIQUE INDEX(diffObjID)")
     401        if self.scratchDb.version > 5.1:
     402            self.scratchDb.execute("set session old_alter_table=0")
     403
     404        rowCountAfter = self.scratchDb.getRowCount("DiffDetObject")
     405        self.logger.infoPair("Number of duplicated diffobjIDs removed", "%d out of %d" % ((rowCountBefore - rowCountAfter), rowCountBefore))
     406
     407        self.scratchDb.execute("ALTER TABLE DiffDetObject CHANGE dec_ `dec` double")
     408
     409        self.updatePspsUniqueIDs("DiffDetObject")
     410
     411        self.dvoObjects.purgeRegion(self.region)
     412
     413        #this is abuse of something but this is how I get the object batches to crash to further investigate them
     414       
     415 
     416#        rowCountAfter = self.scratchDb.getRowCount("Object")
     417        return True
     418#        return False
Note: See TracChangeset for help on using the changeset viewer.