- Timestamp:
- Jan 11, 2015, 1:31:50 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20140904/ippToPsps/jython/diffobjectbatch.py
r36697 r37801 1 #!/usr/bin/env jython 2 3 import os.path 4 import sys 5 6 import stilts 7 from java.lang import * 8 from java.sql import * 9 10 from xml.etree.ElementTree import ElementTree, Element, tostring 11 12 from batch import Batch 13 from gpc1db import Gpc1Db 14 from ipptopspsdb import IppToPspsDb 15 from scratchdb import ScratchDb 16 from dvoobjects import DvoObjects 17 from sqlUtility import sqlUtility 18 19 import logging.config 20 21 ''' 22 DiffObjectBatch class 23 24 This 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 ''' 27 class 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.
