Changeset 32337 for branches/eam_branches/ipp-20110710/ippToPsps/jython
- Timestamp:
- Sep 6, 2011, 11:00:22 AM (15 years ago)
- Location:
- branches/eam_branches/ipp-20110710/ippToPsps/jython
- Files:
-
- 4 deleted
- 14 edited
- 16 copied
-
. (modified) (1 prop)
-
batch.py (modified) (23 diffs)
-
cleanup.py (copied) (copied from trunk/ippToPsps/jython/cleanup.py )
-
config.xml (deleted)
-
configs (copied) (copied from trunk/ippToPsps/jython/configs )
-
configs/bostonmd4.xml (copied) (copied from trunk/ippToPsps/jython/configs/bostonmd4.xml )
-
configs/lap20110621.xml (copied) (copied from trunk/ippToPsps/jython/configs/lap20110621.xml )
-
configs/lap20110809.xml (copied) (copied from trunk/ippToPsps/jython/configs/lap20110809.xml )
-
configs/sas12.xml (copied) (copied from trunk/ippToPsps/jython/configs/sas12.xml )
-
configs/sas123.xml (copied) (copied from trunk/ippToPsps/jython/configs/sas123.xml )
-
configs/sasFootprint.xml (copied) (copied from trunk/ippToPsps/jython/configs/sasFootprint.xml )
-
configs/simtest.xml (copied) (copied from trunk/ippToPsps/jython/configs/simtest.xml )
-
configs/test.xml (copied) (copied from trunk/ippToPsps/jython/configs/test.xml )
-
datastore.py (modified) (5 diffs)
-
demo.fits (deleted)
-
detectionbatch.py (modified) (17 diffs)
-
dvoToMySQL.py (modified) (9 diffs)
-
fits.py (modified) (4 diffs)
-
gpc1db.py (modified) (8 diffs)
-
initbatch.py (modified) (3 diffs)
-
ipptopsps.py (deleted)
-
ipptopspsdb.py (modified) (7 diffs)
-
load.py (copied) (copied from trunk/ippToPsps/jython/load.py )
-
logging.conf (deleted)
-
metrics.py (copied) (copied from trunk/ippToPsps/jython/metrics.py )
-
mysql.py (modified) (3 diffs)
-
odm.py (copied) (copied from trunk/ippToPsps/jython/odm.py )
-
plots (copied) (copied from trunk/ippToPsps/jython/plots )
-
pollOdm.py (copied) (copied from trunk/ippToPsps/jython/pollOdm.py )
-
pslogger.py (modified) (1 diff)
-
removeFromDatastore.py (modified) (1 diff)
-
reportloadfailures.py (copied) (copied from trunk/ippToPsps/jython/reportloadfailures.py )
-
scratchdb.py (modified) (12 diffs)
-
stackbatch.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110710/ippToPsps/jython
-
Property svn:ignore
set to
*.class
-
Property svn:ignore
set to
-
branches/eam_branches/ipp-20110710/ippToPsps/jython/batch.py
r31840 r32337 11 11 from subprocess import call, PIPE, Popen 12 12 13 from datastore import Datastore14 13 from scratchdb import ScratchDb 15 14 from gpc1db import Gpc1Db … … 35 34 def __init__(self, 36 35 logger, 36 configPath, 37 37 doc, 38 38 gpc1Db, … … 40 40 id, 41 41 batchType, 42 fits, 43 survey=""): 42 fits): 44 43 45 44 self.everythingOK = False 46 45 self.readHeader = False 46 self.configPath = configPath 47 47 self.doc = doc 48 48 self.fits = fits 49 self.header = self.fits.getPrimaryHeader()50 49 51 50 # set up logging … … 53 52 self.logger.infoSeparator() 54 53 self.logger.debug("Batch class constructor") 54 55 # check FITS file is ok - TODO could be neater 56 if self.fits: 57 self.header = self.fits.getPrimaryHeader() 58 if not self.header: return 55 59 56 60 # set up class variables … … 60 64 self.batchType = batchType; 61 65 self.pspsVoTableFilePath = "../config/" + batchType + "/tables.vot" 62 self.survey = survey 63 64 # get dvo info from config 65 dvoName = self.doc.find("dvo/name").text 66 67 # get info from config 68 self.survey = self.doc.find("options/survey").text 69 self.pspsSurvey = self.doc.find("options/pspsSurvey").text 70 self.dvoGpc1Label = self.doc.find("dvo/gpc1Label").text 66 71 self.dvoLocation = self.doc.find("dvo/location").text 67 72 self.useFullTables = int(self.doc.find("dvo/useFullTables").text) 68 73 self.scratchDb = ScratchDb(logger, self.doc, self.useFullTables) 74 75 if not self.scratchDb.everythingOK: return 69 76 70 77 # TODO … … 75 82 else: 76 83 self.surveyID = -1; 77 78 84 79 85 # get some options from the config … … 81 87 self.dataRelease = int(self.doc.find("metadata/dataRelease").text) 82 88 83 # get datastore info from config84 self.datastore = Datastore(self.logger )89 # create datastore object 90 self.datastore = Datastore(self.logger, self.doc) 85 91 86 92 # create a new batch 87 93 self.batchID = self.ippToPspsDb.createNewBatch( 88 self. getPspsBatchType(),94 self.batchType, 89 95 self.id, 90 s urvey,91 dvoName,96 self.survey, 97 self.dvoGpc1Label, 92 98 self.datastore.product) 93 99 94 100 # get local storage location from config 95 self.batchName = "B%08d" % self.batchID 96 self.subDir = self.doc.find("localOutPath").text + "/" + self.getPspsBatchType() + "/" + dvoName 97 self.localOutPath = self.subDir + "/" + self.batchName 101 self.batchName = Batch.getNameFromID(self.batchID) 102 self.basePath = self.doc.find("localOutPath").text 103 self.subDir = Batch.getSubDir( 104 self.basePath, 105 self.batchType, 106 self.dvoGpc1Label) 107 108 self.localOutPath = Batch.getOutputPath( 109 self.basePath, 110 self.batchType, 111 self.dvoGpc1Label, 112 self.batchID) 113 98 114 if not os.path.exists(self.localOutPath): os.makedirs(self.localOutPath) 99 115 … … 105 121 if not self.useFullTables: self.scratchDb.createDvoTables() 106 122 107 self.everythingOK = True 108 109 ''' 110 Destructor 111 ''' 112 def __del__(self): 113 114 self.logger.debug("Batch destructor") 115 116 ''' 117 Prints metadata to the log 118 ''' 119 def printMe(self): 120 123 # dump stuff to the log 124 self.logger.infoTitle("New " + self.batchType + " batch") 121 125 self.logger.infoPair("Batch name", self.batchName) 122 126 self.logger.infoPair("Survey", self.survey) 123 127 self.logger.infoPair("Survey ID", "%d" % self.surveyID) 128 self.logger.infoPair("Publishing to PSPS as survey", self.pspsSurvey) 124 129 self.logger.infoPair("DVO location", self.dvoLocation) 125 self.logger.infoPair("Use full DVO tables?", "%d" % self.useFullTables) 130 self.logger.infoBool("Use full DVO tables?", self.useFullTables) 131 132 if self.fits: 133 self.logger.infoPair("Input FITS file", self.fits.getOriginalPath()) 134 self.logger.infoPair("Input FITS primary header", "%s cards found" % self.fits.getPrimaryHeaderCardCount()) 135 126 136 self.logger.infoPair("Output path", self.localOutPath) 127 137 138 self.everythingOK = True 139 140 ''' 141 Static method to generated batch name from batch ID 142 ''' 143 @staticmethod 144 def getNameFromID(id): 145 return "B%08d" % id 146 147 ''' 148 Static method to generated sub directory for batch on local disk 149 ''' 150 @staticmethod 151 def getSubDir(basePath, batchType, dvoLabel): 152 return basePath + "/" + batchType + "/" + dvoLabel 153 154 ''' 155 Static method to generated output path for batch 156 ''' 157 @staticmethod 158 def getOutputPath(basePath, batchType, dvoLabel, id): 159 return Batch.getSubDir(basePath, batchType, dvoLabel) + "/" + Batch.getNameFromID(id) 160 161 ''' 162 Static method to get name of tar file 163 ''' 164 @staticmethod 165 def getTarFile(id): 166 return Batch.getNameFromID(id) + ".tar" 167 168 ''' 169 Static method to get path of tar file 170 ''' 171 @staticmethod 172 def getTarPath(basePath, batchType, dvoLabel, id): 173 return Batch.getSubDir(basePath, batchType, dvoLabel) + "/" + Batch.getTarFile(id) 174 175 ''' 176 Static method to get name of tarball file 177 ''' 178 @staticmethod 179 def getTarballFile(id): 180 return Batch.getTarFile(id) + ".gz" 181 182 ''' 183 Static method to get path of tarball file 184 ''' 185 @staticmethod 186 def getTarballPath(basePath, batchType, dvoLabel, id): 187 return Batch.getSubDir(basePath, batchType, dvoLabel) + "/" + Batch.getTarballFile(id) 188 189 ''' 190 Static method to delete this batch from local disk 191 ''' 192 @staticmethod 193 def deleteFromDisk(logger, basePath, batchType, dvoLabel, id): 194 195 tarballPath = Batch.getTarballPath(basePath, batchType, dvoLabel, id) 196 dirPath = Batch.getOutputPath(basePath, batchType, dvoLabel, id) 197 198 if not os.path.exists(tarballPath): 199 logger.errorPair("Could not find", tarballPath) 200 return 1 201 202 try: 203 os.remove(tarballPath) 204 logger.infoPair("Deleted", tarballPath) 205 except: 206 logger.errorPair("Could not delete", tarballPath) 207 return 0 208 209 return 1 210 211 ''' 212 Destructor 213 ''' 214 def __del__(self): 215 216 self.logger.debug("Batch destructor") 217 218 ''' 219 Looks for a dictionary entry. If it is not there, then replaces it with the supplied default 220 if, and only if, in test mode 221 ''' 222 def safeDictionaryAccessWithDefault(self, header, key, default): 223 224 value = self.safeDictionaryAccess(header, key) 225 226 if value != "NULL": return value 227 else: 228 if not self.testMode: return "NULL" 229 header[key] = default 230 self.logger.infoPair("Hardcoding " + key + " to", header[key]) 231 return header[key] 232 128 233 ''' 129 234 Returns the string value from this dictionary or else "NULL" … … 132 237 133 238 if key in header: return header[key] 134 else: return "NULL" 239 else: 240 self.logger.errorPair("Missing header field", key) 241 return "NULL" 135 242 136 243 ''' … … 146 253 # batch information 147 254 root.attrib['name'] = self.batchName 148 root.attrib['type'] = self. getPspsBatchType()255 root.attrib['type'] = self.batchType 149 256 root.attrib['timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 150 if self.survey != "": 151 root.attrib['survey'] = self.getBatchFriendlySurveyType() 257 if self.batchType != "IN": root.attrib['survey'] = self.pspsSurvey 152 258 try: self.minObjID 153 259 except: pass … … 158 264 159 265 # get md5sum 160 p = Popen("md5sum " + self.outputFitsPath, shell=True, stdout=PIPE)161 p.wait()162 out = p.stdout.read()163 md5sum = out[0:out.rfind(" ")]266 #p = Popen("md5sum " + self.outputFitsPath, shell=True, stdout=PIPE) 267 #p.wait() 268 #out = p.stdout.read() 269 #md5sum = out[0:out.rfind(" ")] 164 270 165 271 # get file size 166 fileSize = os.path.getsize(self.outputFitsPath)272 #fileSize = os.path.getsize(self.outputFitsPath) 167 273 168 274 # file information … … 170 276 root.append(child) 171 277 child.attrib['name'] = self.outputFitsFile 172 child.attrib['bytes'] = str(fileSize)173 child.attrib['md5'] = md5sum278 #child.attrib['bytes'] = str(fileSize) 279 #child.attrib['md5'] = md5sum 174 280 175 281 # now create doc and write to file … … 187 293 Publishes this batch to the datastore 188 294 ''' 189 def publishToDatastore(self):295 def tarZipAndpublishToDatastore(self): 190 296 191 297 # set up filenams and paths 192 tarFile = self.batchName + ".tar" 193 tarPath = self.subDir + "/" + tarFile 194 195 tarballFile = tarFile + ".gz" 196 tarballPath = self.subDir + "/" + tarballFile 298 tarFile = Batch.getTarFile(self.batchID) 299 tarPath = Batch.getTarPath(self.basePath, self.batchType, self.dvoGpc1Label, self.batchID) 300 tarballFile = Batch.getTarballFile(self.batchID) 301 tarballPath = Batch.getTarballPath(self.basePath, self.batchType, self.dvoGpc1Label, self.batchID) 197 302 198 303 # tar directory … … 211 316 212 317 # now publish to the datastore 213 if self.datastore.publish(self.batchName, self.subDir, tarballFile, "tgz"): 214 self.ippToPspsDb.updateLoadedToDatastore(self.batchID, 1) 215 216 ''' 217 Gets PSPS-friendly survey type 218 ''' 219 def getBatchFriendlySurveyType(self): 220 221 #return "SCR" # TODO 222 try: 223 self.survey 224 except: 225 return "NA" 226 227 if self.survey == "3PI": return "3PI" 228 elif self.survey == "MD04": return "MD4" 318 Batch.publishToDatastore(self.datastore, self.ippToPspsDb, self.batchID, self.batchName, self.subDir, tarballFile) 319 320 ''' 321 Static method to publish a batch to the datastore 322 ''' 323 @staticmethod 324 def publishToDatastore(datastore, ippToPspsDb, batchID, batchName, subDir, tarballFile): 325 326 if datastore.publish(batchName, subDir, tarballFile, "tgz"): 327 ippToPspsDb.updateLoadedToDatastore(batchID, 1) 229 328 else: 230 self.logger.error("Don't know this survey: '" + self.survey + "'") 231 return "NA" 232 233 ''' 234 Gets PSPS friendly batch type TODO only use PSPS batch names, P2, ST etc 235 ''' 236 def getPspsBatchType(self): 237 238 if self.batchType == "init": return "IN" 239 elif self.batchType == "detection": return "P2" 240 elif self.batchType == "stack": return "ST" 241 else: self.logger.error("Don't know this batch type: " + self.survey) 329 ippToPspsDb.updateLoadedToDatastore(batchID, -1) 330 242 331 243 332 ''' … … 267 356 rs.close() 268 357 269 self.ippToPspsDb.update MinMaxObjID(self.batchID, self.minObjID, self.maxObjID)358 self.ippToPspsDb.updateDetectionStats(self.batchID, self.minObjID, self.maxObjID, self.totalDetections) 270 359 self.logger.infoPair("Total detections", "%ld" % self.totalDetections) 271 360 self.logger.infoPair("Min objID", "%ld" % self.minObjID) … … 283 372 self.tablesToExport.append(table.name) 284 373 285 self.alterPspsTables();374 return self.alterPspsTables(); 286 375 287 376 ''' … … 303 392 Accepts a regular expression filter so not all tables need to be imported 304 393 ''' 305 def importIppTables(self, filter=""):394 def importIppTables(self, columns="*", filter=""): 306 395 307 396 self.logger.infoPair("Importing tables with filter", filter) … … 313 402 match = re.match(filter, table.name) 314 403 if not match: continue 315 self.logger. infoPair("Reading IPP table", table.name)404 self.logger.debugPair("Reading IPP table", table.name) 316 405 table = stilts.tpipe(table, cmd='explodeall') 317 406 … … 321 410 # IPP FITS files are littered with infinities, so remove these 322 411 self.logger.debug("Removing Infinity values from all columns") 412 table = stilts.tpipe(table, cmd='keepcols "' + columns + '"') 323 413 table = stilts.tpipe(table, cmd='replaceval -Infinity null *') 324 414 table = stilts.tpipe(table, cmd='replaceval Infinity null *') … … 330 420 except: 331 421 self.logger.exception("Problem writing table '" + table.name + "' to the database") 332 333 422 334 423 self.logger.infoPair("Done. Imported", "%d tables" % count) … … 374 463 except: 375 464 self.logger.exception("Could not write to FITS") 465 self.ippToPspsDb.updateProcessed(self.batchID, -1) 376 466 return False 377 467 … … 400 490 ''' 401 491 def populatePspsTables(self): 402 self.logger.warn(" Not implemented yet")492 self.logger.warn("populatePspsTables not implemented yet") 403 493 404 494 ''' … … 407 497 def getIDsFromDVO(self): 408 498 499 if self.scratchDb.getRowCount("dvoMeta") < 1: 500 self.logger.error("No DVO IDs found in dvoMeta") 501 return False 502 409 503 # TODO path to DVO prog hardcoded temporarily 410 cmd = "../src/dvograbber " + self. dvoLocation504 cmd = "../src/dvograbber " + self.configPath + " " + self.dvoLocation 411 505 self.logger.infoPair("Running DVO", cmd) 412 506 p = Popen(cmd, shell=True, stdout=PIPE) 413 507 p.wait() 414 508 # out = p.stdout.read() 415 self.logger.infoPair("DVO access", "complete") 416 417 if self.scratchDb.getRowCount("dvoDetection")< 1:418 self.logger.error ("No DVOIDs found")509 510 rowCount = self.scratchDb.getRowCount("dvoDetection") 511 if rowCount < 1: 512 self.logger.errorPair("DVO error", "No IDs found") 419 513 return False 514 515 self.logger.infoPair("DVO access complete. Found", "%d detections" % rowCount) 420 516 421 517 return True 422 518 423 519 ''' 424 Checks whether this batch has already been processed and published. To be implemented by all subclasses425 '''426 def alreadyProcessed(self):427 self.logger.error("Not implemented")428 429 430 '''431 520 Creates and publishes a batch 521 TODO all methdds call below should throw exceptions on failure 432 522 ''' 433 523 def run(self): 434 524 435 if not self.everythingOK: return 436 437 self.createEmptyPspsTables() 525 if not self.everythingOK: 526 self.logger.error("Aborting this batch due to (hopefully) previously reported errors") 527 self.ippToPspsDb.updateProcessed(self.batchID, -1) 528 return 529 530 if not self.createEmptyPspsTables(): 531 self.logger.error("Aborting this batch due to (hopefully) previously reported errors") 532 self.ippToPspsDb.updateProcessed(self.batchID, -1) 533 return 534 438 535 self.importIppTables() 439 if self.populatePspsTables(): 440 if self.exportPspsTablesToFits(): 536 if not self.populatePspsTables(): 537 self.logger.errorPair("Aborting this batch", "unable to populate PSPS tables") 538 self.ippToPspsDb.updateProcessed(self.batchID, -1) 539 else: 540 if not self.exportPspsTablesToFits(): 541 self.logger.errorPair("Aborting this batch", "unable to export tables to FITS file") 542 else: 441 543 self.writeBatchManifest() 442 if int(self.doc.find("options/publishToDatastore").text): self. publishToDatastore()544 if int(self.doc.find("options/publishToDatastore").text): self.tarZipAndpublishToDatastore() 443 545 if int(self.doc.find("options/reportNulls").text): self.reportNullsInAllPspsTables(False) 444 546 445 self.logger.infoPair("Batch......", "complete") 446 self.logger.infoSeparator() 447 448 547 from datastore import Datastore 548 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/datastore.py
r31839 r32337 5 5 import logging 6 6 import sys 7 import re 7 8 from xml.etree.ElementTree import ElementTree, Element, tostring 8 9 9 10 10 ''' … … 17 17 18 18 ''' 19 def __init__(self, logger ):19 def __init__(self, logger, doc): 20 20 21 21 # setup logger 22 22 self.logger = logger 23 self.doc = doc 23 24 self.logger.debug("Datastore constructor") 24 25 25 26 # open config 26 doc = ElementTree(file="config.xml")27 27 self.product = doc.find("datastore/product").text 28 28 self.type = doc.find("datastore/type").text … … 51 51 52 52 if p.returncode != 0: 53 self.logger.error ("Datastore publishfailed")53 self.logger.errorPair("Datastore publish", "failed") 54 54 ret = False 55 55 else: … … 57 57 ret = True 58 58 59 60 59 tempFile.close() 61 60 return ret 62 61 62 ''' 63 Removes an item from the datastore 63 64 64 ''' 65 Removes an item to the datastore 65 NB this will return a success if the batch is not found on the datastore 66 66 ''' 67 67 def remove(self, name): … … 72 72 --product " + self.product 73 73 74 p = Popen(command, shell=True, stdout=PIPE )74 p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE) 75 75 p.wait() 76 output, errors = p.communicate() 76 77 77 78 if p.returncode != 0: 78 self.logger.error("Datastore removal of " + name + " failed") 79 ret = False 79 if re.search("not found in", errors): 80 self.logger.infoPair("Datastore batch not found", name) 81 ret = True 82 else: 83 self.logger.infoPair("Datastore removal FAILED", name) 84 ret = False 80 85 else: 86 self.logger.infoPair("Datastore removal successful", name) 81 87 ret = True 82 self.logger.infoPair("Datastore removal successful", name)83 88 84 89 return ret 85 90 91 ''' 92 Removes a range of items from the datastore 93 ''' 94 def removeRange(self, first, last): 95 96 firstInt = int(first[1:]) 97 lastInt = int(last[1:]) 98 99 for i in range(firstInt, lastInt): 100 101 self.remove(Batch.getNameFromID(i)) 102 103 from batch import Batch -
branches/eam_branches/ipp-20110710/ippToPsps/jython/detectionbatch.py
r31848 r32337 30 30 def __init__(self, 31 31 logger, 32 configPath, 32 33 configDoc, 33 34 gpc1Db, … … 37 38 super(DetectionBatch, self).__init__( 38 39 logger, 40 configPath, 39 41 configDoc, 40 42 gpc1Db, 41 43 ippToPspsDb, 42 44 camID, 43 "detection", 44 gpc1Db.getCameraStageSmf(camID), 45 #"MD04") # TODO 46 "3PI") 45 "P2", 46 gpc1Db.getCameraStageSmf(camID)) 47 47 48 48 if not self.everythingOK: return … … 50 50 # get camera meta data 51 51 meta = self.gpc1Db.getCameraStageMeta(self.id) 52 if not meta: 53 self.everythingOK = False 54 return 55 52 56 self.expID = meta[0]; 53 57 self.expName = meta[1]; … … 80 84 #self.endY = 8 81 85 86 # get a fre primary header values. if in test mode, then use defaults 87 if self.safeDictionaryAccessWithDefault(self.header, 'MJD-OBS', "1") == "NULL": 88 self.everythingOK = False 89 return 90 91 if self.safeDictionaryAccessWithDefault(self.header, 'EXPTIME', "1") == "NULL": 92 self.everythingOK = False 93 return 94 95 if self.safeDictionaryAccessWithDefault(self.header, 'FILTERID', "g.0000") == "NULL": 96 self.everythingOK = False 97 return 98 82 99 self.obsTime = float(self.header['MJD-OBS']) + (float(self.header['EXPTIME']) / 172800.0) 83 100 84 101 # set up some defauts 85 102 self.calibModNum = 0 86 87 103 self.totalNumPhotoRef = 0 88 104 89 # get filterID using init table 105 90 106 self.filter = self.header['FILTERID'][0:1] 107 self.filterID = self.scratchDb.getFilterID(self.filter) 91 108 92 109 # insert what we know about this stack batch into the stack table 93 110 self.ippToPspsDb.insertDetectionMeta(self.batchID, self.expID, self.filter) 94 111 95 ''' 96 Prints metadata to the log 97 ''' 98 def printMe(self): 99 100 super(DetectionBatch, self).printMe() 101 102 self.logger.infoPair("Cam ID", "%d" % self.id) 103 self.logger.infoPair("Exp ID", "%d" % self.expID) 104 self.logger.infoPair("Exp name", "%s" % self.expName) 105 self.logger.infoPair("Distribution group", "%s" % self.distGroup) 112 # dump stuff to log 113 self.logger.infoPair("Cam ID", "%d" % self.id) 114 self.logger.infoPair("Exp ID", "%d" % self.expID) 115 self.logger.infoPair("Exp name", "%s" % self.expName) 116 self.logger.infoPair("Distribution group", "%s" % self.distGroup) 106 117 107 118 ''' … … 164 175 ,' ' \ 165 176 ,' ' \ 166 ," + self. header['ZPT_ERR']+ " \167 ," + self. header['MJD-OBS']+ " \168 ," + self. header['EXPREQ']+ " \169 ," + self. header['AIRMASS']+ " \170 ," + self. header['RA']+ " \171 ," + self. header['DEC']+ " \172 ,'" + self. header['CTYPE1']+ "' \173 ,'" + self. header['CTYPE2']+ "' \174 ," + self. header['CRVAL1']+ " \175 ," + self. header['CRVAL2']+ " \176 ," + self. header['CRPIX1']+ " \177 ," + self. header['CRPIX2']+ " \178 ," + self. header['CDELT1']+ " \179 ," + self. header['CDELT2']+ " \180 ," + self. header['PC001001']+ " \181 ," + self. header['PC001002']+ " \182 ," + self. header['PC002001']+ " \183 ," + self. header['PC002002']+ " \184 ," + self. header['NPLYTERM']+ " \185 ," + self. header['PCA1X3Y0']+ " \186 ," + self. header['PCA1X2Y1']+ " \187 ," + self. header['PCA1X1Y2']+ " \188 ," + self. header['PCA1X0Y3']+ " \189 ," + self. header['PCA1X2Y0']+ " \190 ," + self. header['PCA1X1Y1']+ " \191 ," + self. header['PCA1X0Y2']+ " \192 ," + self. header['PCA2X3Y0']+ " \193 ," + self. header['PCA2X2Y1']+ " \194 ," + self. header['PCA2X1Y2']+ " \195 ," + self. header['PCA2X0Y3']+ " \196 ," + self. header['PCA2X2Y0']+ " \197 ," + self. header['PCA2X1Y1']+ " \198 ," + self. header['PCA2X0Y2']+ " \177 ," + self.safeDictionaryAccess(self.header, 'ZPT_ERR') + " \ 178 ," + self.safeDictionaryAccess(self.header, 'MJD-OBS') + " \ 179 ," + self.safeDictionaryAccess(self.header, 'EXPREQ') + " \ 180 ," + self.safeDictionaryAccess(self.header, 'AIRMASS') + " \ 181 ," + self.safeDictionaryAccess(self.header, 'RA') + " \ 182 ," + self.safeDictionaryAccess(self.header, 'DEC') + " \ 183 ,'" + self.safeDictionaryAccess(self.header, 'CTYPE1') + "' \ 184 ,'" + self.safeDictionaryAccess(self.header, 'CTYPE2') + "' \ 185 ," + self.safeDictionaryAccess(self.header, 'CRVAL1') + " \ 186 ," + self.safeDictionaryAccess(self.header, 'CRVAL2') + " \ 187 ," + self.safeDictionaryAccess(self.header, 'CRPIX1') + " \ 188 ," + self.safeDictionaryAccess(self.header, 'CRPIX2') + " \ 189 ," + self.safeDictionaryAccess(self.header, 'CDELT1') + " \ 190 ," + self.safeDictionaryAccess(self.header, 'CDELT2') + " \ 191 ," + self.safeDictionaryAccess(self.header, 'PC001001') + " \ 192 ," + self.safeDictionaryAccess(self.header, 'PC001002') + " \ 193 ," + self.safeDictionaryAccess(self.header, 'PC002001') + " \ 194 ," + self.safeDictionaryAccess(self.header, 'PC002002') + " \ 195 ," + self.safeDictionaryAccess(self.header, 'NPLYTERM') + " \ 196 ," + self.safeDictionaryAccess(self.header, 'PCA1X3Y0') + " \ 197 ," + self.safeDictionaryAccess(self.header, 'PCA1X2Y1') + " \ 198 ," + self.safeDictionaryAccess(self.header, 'PCA1X1Y2') + " \ 199 ," + self.safeDictionaryAccess(self.header, 'PCA1X0Y3') + " \ 200 ," + self.safeDictionaryAccess(self.header, 'PCA1X2Y0') + " \ 201 ," + self.safeDictionaryAccess(self.header, 'PCA1X1Y1') + " \ 202 ," + self.safeDictionaryAccess(self.header, 'PCA1X0Y2') + " \ 203 ," + self.safeDictionaryAccess(self.header, 'PCA2X3Y0') + " \ 204 ," + self.safeDictionaryAccess(self.header, 'PCA2X2Y1') + " \ 205 ," + self.safeDictionaryAccess(self.header, 'PCA2X1Y2') + " \ 206 ," + self.safeDictionaryAccess(self.header, 'PCA2X0Y3') + " \ 207 ," + self.safeDictionaryAccess(self.header, 'PCA2X2Y0') + " \ 208 ," + self.safeDictionaryAccess(self.header, 'PCA2X1Y1') + " \ 209 ," + self.safeDictionaryAccess(self.header, 'PCA2X0Y2') + " \ 199 210 )" 200 211 self.scratchDb.execute(sql) … … 357 368 Populates the Detection table for this OTA 358 369 ''' 359 def populateDetectionTable(self, ota): 360 361 tableName = "Detection_" + ota 362 370 def populateDetectionTable(self, ota, results): 371 372 pspsTableName = "Detection_" + ota 373 ippTableName = ota + "_psf" 374 375 results['ORIGINALTOTAL'] = self.scratchDb.getRowCount(ippTableName) 376 363 377 # drop then re-create table 364 self.scratchDb.dropTable( tableName)365 sql = "CREATE TABLE " + tableName + " LIKE Detection"378 self.scratchDb.dropTable(pspsTableName) 379 sql = "CREATE TABLE " + pspsTableName + " LIKE Detection" 366 380 try: self.scratchDb.execute(sql) 367 381 except: pass 382 383 # delete all detections with PSF_INST_MAG < 17.5, as decreed by Gene 384 BEFORE = self.scratchDb.getRowCount(ippTableName) 385 sql = "DELETE FROM " + ippTableName + " WHERE PSF_INST_MAG < -17.5" 386 self.scratchDb.execute(sql) 387 #DELETED = BEFORE - self.scratchDb.getRowCount(ippTableName) 388 results['SATDET'] = BEFORE - self.scratchDb.getRowCount(ippTableName) 389 #self.logger.infoPair("Saturated detections", "%d deleted" % DELETED) 368 390 369 391 # insert all detections into table 370 sql = "INSERT IGNORE INTO " + tableName + " ( \392 sql = "INSERT IGNORE INTO " + pspsTableName + " ( \ 371 393 ippDetectID \ 394 ,filterID \ 395 ,surveyID \ 396 ,obsTime \ 372 397 ,xPos \ 373 398 ,yPos \ … … 380 405 ,psfWidMinor \ 381 406 ,psfTheta \ 407 ,psfLikelihood \ 382 408 ,psfCf \ 383 409 ,momentXX \ … … 391 417 ,skyErr \ 392 418 ,sgSep \ 419 ,activeFlag \ 420 ,assocDate \ 421 ,historyModNum \ 422 ,dataRelease \ 393 423 ) \ 394 424 SELECT \ 395 425 IPP_IDET \ 426 , " + str(self.filterID) + "\ 427 , " + str(self.surveyID) + " \ 428 ," + str(self.obsTime) + " \ 396 429 ,X_PSF \ 397 430 ,Y_PSF \ … … 404 437 ,PSF_MINOR \ 405 438 ,PSF_THETA \ 439 ,psfLikelihood(EXT_NSIGMA) \ 406 440 ,PSF_QF \ 407 441 ,MOMENTS_XX \ … … 415 449 ,SKY_SIGMA \ 416 450 ,EXT_NSIGMA \ 417 FROM " + ota + "_psf" 418 self.scratchDb.execute(sql) 419 420 # set obsTime 421 sql = "UPDATE " + tableName + " SET obsTime = %f, assocDate = '%s', activeFlag = 0" % (self.obsTime, self.dateStr) 422 self.scratchDb.execute(sql) 423 self.scratchDb.updateAllRows(tableName, "dataRelease", str(self.dataRelease)) 424 self.scratchDb.updateAllRows(tableName, "historyModNum", "0") 425 426 self.scratchDb.updateAllRows(tableName, "surveyID", str(self.surveyID)) 427 self.scratchDb.updateFilterID(tableName, self.filter) 451 , 0 \ 452 , '" + self.dateStr + "' \ 453 , 0 \ 454 , " + str(self.dataRelease) + "\ 455 FROM " + ippTableName 456 self.scratchDb.execute(sql) 428 457 429 458 # now delete bad flux and bad chip positions 430 self.scratchDb.reportAndDeleteRowsWithNULLS(tableName, "instFlux") 431 self.scratchDb.reportAndDeleteRowsWithNULLS(tableName, "peakADU") 459 sql="DELETE FROM " + pspsTableName + " WHERE instFlux < 0.0000001" # TODO clearly a hack = 0 not allowed for instFlux 460 self.scratchDb.execute(sql) 461 462 # update cosmic ray and extended likelihoods 463 sql="UPDATE " + pspsTableName + " SET extendedLikelihood = 0, crLikelihood = 1.0 - psfLikelihood WHERE sgSep <= 0" 464 self.scratchDb.execute(sql) 465 sql="UPDATE " + pspsTableName + " SET crLikelihood = 0, extendedLikelihood = 1.0 - psfLikelihood WHERE sgSep > 0" 466 self.scratchDb.execute(sql) 467 468 # remove detections will NULL inst flux or NULL peak ADU 469 results['NULLINSTFLUX'] = self.scratchDb.reportAndDeleteRowsWithNULLS(pspsTableName, "instFlux") 470 results['NULLPEAKADU'] = self.scratchDb.reportAndDeleteRowsWithNULLS(pspsTableName, "peakADU") 432 471 433 472 ''' … … 499 538 self.scratchDb.makeColumnPrimaryKey("Detection", "ippDetectID") 500 539 501 '''502 Applies indexes to the IPP tables503 '''504 def indexIppTables(self):505 506 self.logger.infoPair("Creating indexes on", "IPP tables")507 508 for x in range(self.startX, self.endX):509 for y in range(self.startY, self.endY):510 511 # dodge the corners512 if x==0 and y==0: continue513 if x==0 and y==7: continue514 if x==7 and y==0: continue515 if x==7 and y==7: continue516 517 extension = "XY%d%d_psf" % (x, y)518 self.scratchDb.createIndex(extension, "IPP_IDET")519 520 '''521 Updates provided table with DVO IDs from DVO table522 '''523 def updateDvoIDs(self, table, sourceID, externID):524 525 imageID = self.scratchDb.getImageIDFromExternID(sourceID, externID)526 self.logger.debug("Updating table '" + table + "' with DVO IDs using imageID = %d" % imageID)527 sql = "UPDATE IGNORE " + table + " AS a, " + self.scratchDb.dvoDetection + " AS b SET \528 a.ippObjID = b.ippObjID, \529 a.detectID = b.detectID, \530 a.objID = b.objID, \531 a.infoFlag = b.flags << 32 | a.infoFlag \532 WHERE a.ippDetectID = b.ippDetectID \533 AND b.sourceID = " + str(sourceID) + " \534 AND b.imageID = " + str(imageID)535 536 self.scratchDb.execute(sql)537 538 '''539 Generates psf, cosmic ray and extended source likelihoods540 '''541 def populateLikelihoods(self, tableName):542 543 sql = "SELECT ippDetectID, psfLikelihood, crLikelihood, extendedLikelihood, sgSep FROM " + tableName544 rs = self.scratchDb.executeUpdatableQuery(sql)545 546 sqrt2 = Math.sqrt(2)547 548 while rs.next():549 550 sgSep = rs.getDouble(5)551 psfLikelihood = Erf.erfc(Math.abs(sgSep)/sqrt2)552 553 if sgSep > 0:554 crLikelihood = 0555 extendedLikelihood = 1.0 - psfLikelihood556 else:557 crLikelihood = 1.0 - psfLikelihood558 extendedLikelihood = 0559 560 # update columns561 rs.updateDouble(2, psfLikelihood )562 rs.updateDouble(3, crLikelihood )563 rs.updateDouble(4, extendedLikelihood )564 565 # now 'commit' to database566 rs.updateRow();567 568 569 '''570 Does the processing, i.e. pulling stuff from IPP tables into PSPS tables571 '''572 def populatePspsTables(self):573 574 540 self.populateFrameMeta() 575 541 576 542 # dictionary objects to hold sourceIDs and imageIDs for later 577 s ourceIDs = {}578 imageIDs = {}543 self.sourceIDs = {} 544 self.imageIDs = {} 579 545 580 546 # loop through all OTAs and populate ImageMeta extensions … … 595 561 header = self.fits.findAndReadHeader(ota + ".hdr") 596 562 if not header: 597 self.logger.error ("No header found for OTA " +ota)563 self.logger.errorPair("No header found for OTA", ota) 598 564 continue 565 566 # check we have valid sourceID/imageID pair from the header 567 if self.safeDictionaryAccess(header, 'SOURCEID') == "NULL": continue 568 if self.safeDictionaryAccess(header, 'IMAGEID') == "NULL": continue 599 569 600 570 # store sourceID/imageID combo in Db so DVO can look up later 601 571 if not self.useFullTables: 602 self.scratchDb.insertNewDvoImage(header['SOURCEID'], header['IMAGEID']) 603 604 # check we have valid sourceID/imageID pair from the header 605 if 'SOURCEID' not in header or 'IMAGEID' not in header: 606 self.logger.error("Can't read SOURCEID/IMAGEID pair from " + ota + " header") 607 continue 572 self.scratchDb.insertNewDvoExternID(header['SOURCEID'], header['IMAGEID']) 608 573 609 574 # store these for later 610 s ourceIDs[ota] = header['SOURCEID']611 imageIDs[ota] = header['IMAGEID']575 self.sourceIDs[ota] = header['SOURCEID'] 576 self.imageIDs[ota] = header['IMAGEID'] 612 577 613 578 # populate ImageMeta … … 616 581 617 582 # now run DVO code to get all IDs 618 if not self.useFullTables: self.getIDsFromDVO() 583 if not self.useFullTables: 584 if not self.getIDsFromDVO(): return False 585 586 return True 587 588 589 ''' 590 Applies indexes to the IPP tables 591 ''' 592 def indexIppTables(self): 593 594 self.logger.infoPair("Creating indexes on", "IPP tables") 595 596 for x in range(self.startX, self.endX): 597 for y in range(self.startY, self.endY): 598 599 # dodge the corners 600 if x==0 and y==0: continue 601 if x==0 and y==7: continue 602 if x==7 and y==0: continue 603 if x==7 and y==7: continue 604 605 extension = "XY%d%d_psf" % (x, y) 606 self.scratchDb.createIndex(extension, "IPP_IDET") 607 608 ''' 609 Updates provided table with DVO IDs from DVO table 610 ''' 611 def updateDvoIDs(self, table, sourceID, externID): 612 613 imageID = self.scratchDb.getImageIDFromExternID(sourceID, externID) 614 self.logger.debug("Updating table '" + table + "' with DVO IDs using imageID = %d" % imageID) 615 sql = "UPDATE IGNORE " + table + " AS a, " + self.scratchDb.dvoDetectionTable + " AS b SET \ 616 a.ippObjID = b.ippObjID, \ 617 a.detectID = b.detectID, \ 618 a.objID = b.objID, \ 619 a.infoFlag = b.flags << 32 | a.infoFlag \ 620 WHERE a.ippDetectID = b.ippDetectID \ 621 AND b.sourceID = " + str(sourceID) + " \ 622 AND b.imageID = " + str(imageID) 623 624 self.scratchDb.execute(sql) 625 626 627 ''' 628 Does the processing, i.e. pulling stuff from IPP tables into PSPS tables 629 ''' 630 def populatePspsTables(self): 619 631 620 632 # loop through all OTAs again to update with DVO IDs … … 623 635 tables = [] 624 636 otaCount = 0 637 results = {} 638 totalOriginal = totalSatDet = totalNulIInstFlux = totalNullPeakFlux = totalNullObjID = totalDetections = 0 639 self.logger.info("+-------+---------------+---------------+---------------+---------------+---------------+---------------+") 640 self.logger.info("| OTA | Initial total | Sat Det | NULL instFlux | NULL peak ADU | NULL obj ID | Remainder |") 641 self.logger.info("+-------+---------------+---------------+---------------+---------------+---------------+---------------+") 625 642 for x in range(self.startX, self.endX): 626 643 for y in range(self.startY, self.endY): … … 633 650 634 651 ota = "XY%d%d" % (x, y) 635 if ota not in sourceIDs: continue 636 637 self.logger.infoMiniSeparator() 652 if ota not in self.sourceIDs: continue 653 654 #self.logger.infoTitle("Processing " + ota) 655 if not self.scratchDb.astrometricSolutionOK(ota): 656 self.logger.info("| %5s | ------------- Bad astrometric solution : rejecting ------------ |" % ota) 657 continue 638 658 639 659 # populate remainder of tables 640 self.populateDetectionTable(ota )660 self.populateDetectionTable(ota, results) 641 661 642 662 # now add DVO IDs 643 self.updateDvoIDs("Detection_" + ota, s ourceIDs[ota],imageIDs[ota])644 self.scratchDb.reportAndDeleteRowsWithNULLS("Detection_" + ota, "objID")663 self.updateDvoIDs("Detection_" + ota, self.sourceIDs[ota], self.imageIDs[ota]) 664 results['NULLOBJID'] = self.scratchDb.reportAndDeleteRowsWithNULLS("Detection_" + ota, "objID") 645 665 self.updateImageID("Detection_" + ota, x, y) 646 self.populateLikelihoods("Detection_" + ota) 647 648 # check we have something in this Detection table 649 if self.scratchDb.getRowCount("Detection_" + ota) < 1: 650 self.logger.infoPair("Skipping empty table for ota", ota) 666 rowCount = self.scratchDb.getRowCount("Detection_" + ota) 667 self.logger.info("| %5s | %13d | %13d | %13d | %13d | %13d | %13d |", 668 ota, 669 results['ORIGINALTOTAL'], 670 results['SATDET'], 671 results['NULLINSTFLUX'], 672 results['NULLPEAKADU'], 673 results['NULLOBJID'], 674 rowCount) 675 676 totalOriginal = totalOriginal + results['ORIGINALTOTAL'] 677 totalSatDet = totalSatDet + results['SATDET'] 678 totalNulIInstFlux = totalNulIInstFlux + results['NULLINSTFLUX'] 679 totalNullPeakFlux = totalNullPeakFlux + results['NULLPEAKADU'] 680 totalNullObjID = totalNullObjID + results['NULLOBJID'] 681 totalDetections = totalDetections + rowCount 682 683 # check we have something in this Detection table TODO add this to table above 684 if rowCount < 1: 685 self.logger.debugPair("Skipping empty table for ota", ota) 651 686 continue; 652 687 653 688 # update ImageMeta with count of detections for this OTA and photoCodeID 654 689 sql = "UPDATE ImageMeta_" + ota + " \ 655 SET nDetect = %d, photoCalID = %d" % (self.scratchDb.getRowCount("Detection_" + ota), self.scratchDb.getPhotoCalID(s ourceIDs[ota],imageIDs[ota]))690 SET nDetect = %d, photoCalID = %d" % (self.scratchDb.getRowCount("Detection_" + ota), self.scratchDb.getPhotoCalID(self.sourceIDs[ota], self.imageIDs[ota])) 656 691 self.scratchDb.execute(sql) 657 692 … … 668 703 otaCount = otaCount + 1 669 704 705 # print totals 706 self.logger.info("+-------+---------------+---------------+---------------+---------------+---------------+---------------+") 707 self.logger.info("| Total | %13d | %13d | %13d | %13d | %13d | %13d |", 708 totalOriginal, 709 totalSatDet, 710 totalNulIInstFlux, 711 totalNullPeakFlux, 712 totalNullObjID, 713 totalDetections) 714 self.logger.info("+-------+---------------+---------------+---------------+---------------+---------------+---------------+") 715 670 716 # if we only have one table export, i.e. FrameMeta, then get out of here 671 717 if len(self.tablesToExport) == 1: … … 708 754 if self.testMode: regex = "XY33.psf" 709 755 else : regex = ".*.psf" 710 711 return super(DetectionBatch, self).importIppTables(regex) 756 757 columns = "IPP_IDET X_PSF Y_PSF X_PSF_SIG Y_PSF_SIG PSF_INST_MAG PSF_INST_MAG_SIG PEAK_FLUX_AS_MAG PSF_MAJOR PSF_MINOR PSF_THETA EXT_NSIGMA PSF_QF MOMENTS_XX MOMENTS_XY MOMENTS_YY AP_MAG KRON_FLUX KRON_FLUX_ERR FLAGS SKY SKY_SIGMA EXT_NSIGMA" 758 759 return super(DetectionBatch, self).importIppTables(columns, regex) 712 760 713 761 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/dvoToMySQL.py
r31398 r32337 10 10 from subprocess import call, PIPE, Popen 11 11 12 from gpc1db import Gpc1Db12 from pslogger import PSLogger 13 13 from scratchdb import ScratchDb 14 14 … … 27 27 28 28 ''' 29 def __init__(self, logger, pathToDvo):29 def __init__(self, logger, doc, RESETTABLES): 30 30 31 31 # set up logging 32 32 self.logger = logger 33 self.pathToDvo = pathToDvo 34 self.logger.debug("DvoToMySql class constructor") 35 36 self.logger.debug("Important DVO database at " + self.pathToDvo) 37 38 # open config 39 doc = ElementTree(file="config.xml") 40 41 # create database objects 42 self.scratchDb = ScratchDb(logger) 43 self.gpc1Db = Gpc1Db(self.logger) 33 self.doc = doc 34 self.logger.infoSeparator() 35 self.dvoLocation = self.doc.find("dvo/location").text 36 37 # create database object 38 self.scratchDb = ScratchDb(logger, self.doc, 1) 39 40 # some log stuff 41 self.logger.infoPair("Started", "dvoToMySql") 42 self.logger.infoPair("Importing DVO database at", self.dvoLocation) 44 43 45 44 # create DVO tables 46 #self.scratchDb.createDvoTables()45 if RESETTABLES: self.scratchDb.resetDvoToMysqlTables() 47 46 48 47 # import Images.dat table 49 sql = "DELETE FROM dvoMetaFull" 50 self.scratchDb.stmt.execute(sql) 51 52 imagesTableName = self.importFits(self.pathToDvo, 48 self.logger.infoPair("Deleting from table", self.scratchDb.dvoMetaTable) 49 sql = "DELETE FROM " + self.scratchDb.dvoMetaTable 50 self.scratchDb.execute(sql) 51 52 imagesTableName = self.importFits(self.dvoLocation, 53 53 "", 54 54 "Images.dat", 55 " IMAGE_ID SOURCE_ID CCDNUM EXTERN_ID FLAGS PHOTCODE NSTAR")56 self.scratchDb.createIndex(imagesTableName, " IMAGE_ID")55 "SOURCE_ID IMAGE_ID CCDNUM EXTERN_ID FLAGS PHOTCODE NSTAR") 56 self.scratchDb.createIndex(imagesTableName, "EXTERN_ID") 57 57 58 58 # insert into dvoMetaFull 59 self.logger.info("Inserting all image meta data into database") 60 sql = "INSERT INTO dvoMetaNew ( \ 59 # NB what we and smf files call IMAGE_ID, DVO calls EXTERN_ID. We are sticking 60 # with the smf name 61 self.logger.infoPair("Populating", "all image meta data") 62 sql = "INSERT INTO " + self.scratchDb.dvoMetaTable + " ( \ 61 63 sourceID, \ 62 64 imageID, \ … … 71 73 PHOTCODE \ 72 74 FROM " + imagesTableName 73 self.scratchDb. stmt.execute(sql)75 self.scratchDb.execute(sql) 74 76 75 77 subdirs = ['n0000'] … … 77 79 for subdir in subdirs: 78 80 79 files = glob.glob( pathToDvo+ "/" + subdir + "/*.cpm")81 files = glob.glob(self.dvoLocation + "/" + subdir + "/*.cpm") 80 82 81 83 #files = ['0247.06', '0244.06', '0244.10'] … … 85 87 # get just filename, without extension 86 88 file = os.path.basename(os.path.splitext(file)[0]) 87 self.logger.info ("---------------------------------------------: " + file)89 self.logger.infoSeparator() 88 90 89 91 if self.scratchDb.alreadyImportedThisDvoTable(file): continue 90 92 91 93 # import cpm table and index 92 cpmTableName = self.importFits(self. pathToDvo,94 cpmTableName = self.importFits(self.dvoLocation, 93 95 subdir, 94 96 file + ".cpm", 95 97 "IMAGE_ID DET_ID OBJ_ID CAT_ID EXT_ID DB_FLAGS") 98 self.scratchDb.createIndex(cpmTableName, "IMAGE_ID") 96 99 self.scratchDb.createIndex(cpmTableName, "CAT_ID") 97 100 self.scratchDb.createIndex(cpmTableName, "OBJ_ID") 98 101 99 102 # import cpt table and index 100 cptTableName = self.importFits(self. pathToDvo,103 cptTableName = self.importFits(self.dvoLocation, 101 104 subdir, 102 105 file + ".cpt", 103 106 "OBJ_ID CAT_ID EXT_ID") 107 self.scratchDb.createIndex(cptTableName, "IMAGE_ID") 104 108 self.scratchDb.createIndex(cptTableName, "CAT_ID") 105 109 self.scratchDb.createIndex(cptTableName, "OBJ_ID") 106 110 107 111 # shove SOURCE_IDs into measurement table 108 self.logger.info ("Adding SOURCE_IDs into measurements table")109 sql = "ALTER TABLE " +cpmTableName+" ADD COLUMN (SOURCE_ID SMALLINT)"110 self.scratchDb. stmt.execute(sql)111 sql = "UPDATE " +cpmTableName+" AS a, "+imagesTableName+" AS b \112 self.logger.infoPair("Adding", "SOURCE_IDs") 113 sql = "ALTER TABLE " + cpmTableName + " ADD COLUMN (SOURCE_ID SMALLINT)" 114 self.scratchDb.execute(sql) 115 sql = "UPDATE " + cpmTableName + " AS a, " + imagesTableName + " AS b \ 112 116 SET a.SOURCE_ID = b.SOURCE_ID \ 113 117 WHERE a.IMAGE_ID = b.IMAGE_ID" 114 self.scratchDb. stmt.execute(sql)118 self.scratchDb.execute(sql) 115 119 116 120 # shove PSPS objID in measurement table 117 self.logger.info ("Adding PSPS objID into measurements table")121 self.logger.infoPair("Adding","PSPS objIDs") 118 122 sql = "ALTER TABLE "+cpmTableName+" ADD COLUMN (PSPS_OBJ_ID BIGINT)" 119 self.scratchDb. stmt.execute(sql)123 self.scratchDb.execute(sql) 120 124 sql = "UPDATE "+cpmTableName+" AS a, "+cptTableName+" AS b \ 121 125 SET a.PSPS_OBJ_ID = b.EXT_ID \ 122 126 WHERE a.CAT_ID = b.CAT_ID \ 123 127 AND a.OBJ_ID = b.OBJ_ID" 124 self.scratchDb.stmt.execute(sql) 125 126 self.logger.info("Putting everything into dvoDetectionFull table") 127 sql = "INSERT IGNORE INTO dvoDetectionFull (\ 128 self.scratchDb.execute(sql) 129 130 # NB we use an INSERT IGNORE here. This is because of a known issue where multiple DVO cpm 131 # files can include the same detection, with the same IMAGE_ID/DET_ID pairing, but different 132 # PSPS object IDs assigned in the corresponding cpt file. This is believed to be a chip-boundary 133 # issue within DVO. So, for now, we take the first IMAGE_ID/DET_ID detection we find, and ignore the rest 134 self.logger.infoPair("Populating", self.scratchDb.dvoDetectionTable) 135 sql = "INSERT IGNORE INTO " + self.scratchDb.dvoDetectionTable + " (\ 128 136 sourceID \ 129 137 ,imageID \ … … 142 150 ,DB_FLAGS \ 143 151 FROM " + cpmTableName 144 self.scratchDb.stmt.execute(sql) 152 try: 153 self.scratchDb.execute(sql) 154 except: 155 self.logger.error("FAILED: " + sql) 156 return 145 157 146 158 # now drop what we don't need 147 self.logger.info ("Dropping tables")159 self.logger.infoPair("Dropping table", cpmTableName) 148 160 self.scratchDb.dropTable(cpmTableName) 161 self.logger.infoPair("Dropping table", cptTableName) 149 162 self.scratchDb.dropTable(cptTableName) 150 163 … … 173 186 tableName = tableName.replace('.', '_') 174 187 175 self.logger.info("Attempting to import tables from '" + fullPath + "' to '" + tableName + "'") 188 self.logger.infoPair("Importing tables from file", fullPath) 189 self.logger.infoPair("Writing to database table", tableName) 176 190 177 191 tables = stilts.treads(fullPath) … … 180 194 for table in tables: 181 195 182 self.logger.info ("Reading IPP table " + table.name + " from FITS file")196 self.logger.infoPair("Reading IPP table", table.name) 183 197 table = stilts.tpipe(table, cmd='explodeall') 184 198 185 199 # IPP FITS files are littered with infinities, so remove these 186 self.logger.info ("Removing Infinity values from all columns")200 self.logger.infoPair("Removing", "infinity values") 187 201 table = stilts.tpipe(table, cmd='replaceval -Infinity null *') 188 202 table = stilts.tpipe(table, cmd='replaceval Infinity null *') 189 203 190 204 #try: 191 self.logger.info ("Writing FITS table todatabase")205 self.logger.infoPair("Writing FITS table to", "database") 192 206 table.cmd_keepcols(columns).write(self.scratchDb.url + '#' + tableName) 193 207 #except: … … 195 209 count = count + 1 196 210 197 self.logger.info ("Done. Imported%d tables" % count)211 self.logger.infoPair("Finished importing", "%d tables" % count) 198 212 199 213 return tableName 200 214 201 logging.config.fileConfig("logging.conf") 202 logger = logging.getLogger("dvotomysql") 203 logger.info("Starting") 204 205 dvoToMySql = DvoToMySql(logger, "/data/ipp005.0/gpc1/catdirs/MD04.merges/MD04.merge") 206 #dvoToMySql = DvoToMySql(logger, "/export/ippc00.1/rhenders/MD04.merge") 207 208 logger.info("Program complete") 209 215 216 ''' 217 Start of program. 218 ''' 219 220 if len(sys.argv) > 1: CONFIG = sys.argv[1] 221 else: 222 print "** Usage: " + sys.argv[0] + " <configPath> [reset]" 223 sys.exit(1) 224 225 # open config file 226 configDoc = ElementTree(file=CONFIG) 227 228 logging.setLoggerClass(PSLogger) 229 logger = logging.getLogger("dvoToMySQL") 230 logger.setup(configDoc, "dvoToMySQL", 0, 1) 231 232 RESETTABLES = 0 233 234 if len(sys.argv) > 2 and sys.argv[2] == "reset": 235 response = raw_input("* Are you ABSOLUTELY sure you want to recreate the DVO tables (y/n)? ") 236 if response == "y": RESETTABLES = 1 237 else: sys.exit(1) 238 239 dvoToMySql = DvoToMySql(logger, configDoc, RESETTABLES) 240 241 logger.infoPair("Program...", "complete") 242 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/fits.py
r31849 r32337 17 17 def __init__(self, logger, doc, originalPath): 18 18 19 # set class variables 19 20 self.originalPath = originalPath 20 21 self.logger = logger 21 22 self.doc = doc 23 self.header = None 22 24 self.localDir = self.doc.find("localOutPath").text 23 25 24 # does itexist?26 # does this file even exist? 25 27 if not os.path.isfile(self.originalPath): 26 self.logger.error ("Cannot read file at '" + self.originalPath + "'")28 self.logger.errorPair("Cannot read file", self.originalPath) 27 29 return 28 30 29 self.logger.infoPair("FITS file", self.originalPath) 31 # ok, we have a file, now copy it locally to save on NFS overhead 32 self.logger.debugPair("FITS file", self.originalPath) 30 33 self.localCopyPath = self.localDir + "/temp.fits" 31 34 shutil.copy2(self.originalPath, self.localCopyPath) 32 35 36 # open the local copy and parse the ridiculou plain-text header 33 37 self.file = open(self.localCopyPath) 34 38 self.header = self.parseHeader() 35 self.logger.infoPair("FITS local copy", self.localCopyPath) 36 self.logger.infoPair("FITS primary header", "%d cards found" % len(self.header)) 39 self.logger.debugPair("FITS local copy", self.localCopyPath) 40 self.logger.debugPair("FITS primary header", "%d cards found" % len(self.header)) 41 42 # move file pointer back to the start of the file 37 43 self.rewindToStart() 38 44 39 45 ''' 40 Returns the path to this FITS file 46 Returns count of 'cards' found in primary header 47 ''' 48 def getPrimaryHeaderCardCount(self): 49 return len(self.header) 50 51 ''' 52 Returns the path to the LOCAL COPY of this FITS file 41 53 ''' 42 54 def getPath(self): 43 55 return self.localCopyPath 56 57 ''' 58 Returns the path to the LOCAL COPY of this FITS file 59 ''' 60 def getOriginalPath(self): 61 return self.originalPath 44 62 45 63 ''' … … 57 75 else: return "NULL" 58 76 59 77 ''' 78 Moves the file pointer back to the start of this file 79 ''' 60 80 def rewindToStart(self): 61 81 self.file.seek(0, 0) … … 63 83 64 84 ''' 65 Finds and reads a header extension 85 Finds and reads a header extension. 86 87 2880 is the magic number that the FITS format uses to break up data: extensions always begin on multiples of 2880 bytes 66 88 ''' 67 89 def findAndReadHeader(self, name): … … 91 113 92 114 self.file.seek(origIndex, 0) 93 self.logger.error ("...could not read header in extension '" + name + "'")115 self.logger.errorPair("Could not read header", name) 94 116 return 95 #else: self.logger.info("...read header at '" + name + "' and found " + str(len(header)) + " header cards") 117 else: 118 self.logger.debug("...read header at '" + name + "' and found " + str(len(header)) + " header cards") 96 119 97 120 return header -
branches/eam_branches/ipp-20110710/ippToPsps/jython/gpc1db.py
r31846 r32337 69 69 sql = "SELECT DISTINCT stage_id \ 70 70 FROM addRun \ 71 WHERE stage = '" + stage + "' \ 72 AND dvodb = '" + dvoDb + "'" 71 JOIN minidvodbRun USING(minidvodb_name) \ 72 JOIN minidvodbProcessed USING(minidvodb_id) \ 73 WHERE minidvodbRun.minidvodb_group = '" + dvoDb + "' \ 74 AND minidvodbRun.state = 'merged' \ 75 AND minidvodbProcessed.fault = 0 \ 76 AND addRun.stage = '" + stage + "' \ 77 AND addRun.state = 'full'" 73 78 74 79 elif batchType == "ST": … … 78 83 FROM staticskyInput \ 79 84 JOIN addRun ON(staticskyInput.sky_id = addRun.stage_id) \ 80 WHERE stage = '" + stage + "' \ 81 AND dvodb = '" + dvoDb + "'" 82 85 JOIN minidvodbRun USING(minidvodb_name) \ 86 JOIN minidvodbProcessed USING(minidvodb_id) \ 87 WHERE minidvodbRun.minidvodb_group = '" + dvoDb + "' \ 88 AND minidvodbRun.state = 'merged' \ 89 AND minidvodbProcessed.fault = 0 \ 90 AND addRun.stage = '" + stage + "' \ 91 AND addRun.state = 'full'" 92 83 93 try: 84 94 rs = self.executeQuery(sql) … … 144 154 rs = self.executeQuery(sql) 145 155 rs.first() 156 except: 157 self.logger.errorPair("Can't query for", "stack meta data") 158 159 try: 146 160 meta.append(rs.getString(1)) 147 161 meta.append(rs.getString(2)) 148 162 meta.append(rs.getString(3)) 149 163 except: 150 self.logger.e xception("Can't query for stack meta")151 164 self.logger.errorPair("getStackStageMeta()", "empty meta data") 165 152 166 return meta 153 167 … … 168 182 rs = self.executeQuery(sql) 169 183 rs.first() 184 except: 185 self.logger.errorPair("Can't query for", "camera meta data") 186 187 try: 170 188 meta.append(rs.getInt(1)) 171 189 meta.append(rs.getString(2)) … … 175 193 meta.append(rs.getString(6)) 176 194 except: 177 self.logger.e xception("Can't query for camera meta")195 self.logger.errorPair("getCameraStageMeta()", "empty meta data") 178 196 179 197 return meta … … 195 213 rs.first() 196 214 except: 197 self.logger.exception("Can't query for camera smfs") 198 215 self.logger.errorPair("Can't query for smf file for cam_id", str(camID)) 216 return None 217 218 try: 199 219 # get path to base dir of cmf files 200 path = rs.getString(1) 201 path = path[0:path.rfind("/")] 220 path = rs.getString(1) 221 path = path[0:path.rfind("/")] 222 except: 223 self.logger.errorPair("No smf files found for cam_id", str(camID) ) 224 return None 202 225 203 # list all cmf files if a neb path226 # list all smf files if a neb path 204 227 files = [] 205 228 if path.startswith("neb"): … … 211 234 # or not a neb path 212 235 else: 213 files = glob.glob(path + "/*. cmf")214 215 if len(files) < 1: return "NULL"236 files = glob.glob(path + "/*.smf") 237 238 if len(files) < 1: return None 216 239 217 240 return Fits(self.logger, self.doc, files[0]) # TODO just returning first file - check … … 251 274 252 275 self.logger.error("Could not find stack cmf") 253 return "NULL"276 return None 254 277 255 278 ''' -
branches/eam_branches/ipp-20110710/ippToPsps/jython/initbatch.py
r31287 r32337 1 1 #!/usr/bin/env jython 2 2 3 import sys 3 4 import stilts 4 5 import logging … … 6 7 from java.lang import * 7 8 from java.sql import * 9 10 from xml.etree.ElementTree import ElementTree, Element, tostring 11 8 12 from batch import Batch 13 from pslogger import PSLogger 14 from gpc1db import Gpc1Db 15 from ipptopspsdb import IppToPspsDb 16 from stackbatch import StackBatch 17 from detectionbatch import DetectionBatch 9 18 10 19 ''' … … 16 25 Constructor 17 26 ''' 18 def __init__(self, logger): 19 super(InitBatch, self).__init__(logger, "init") 27 def __init__(self, 28 logger, 29 configPath, 30 configDoc, 31 gpc1Db, 32 ippToPspsDb): 33 super(InitBatch, self).__init__(logger, 34 configPath, 35 configDoc, 36 gpc1Db, 37 ippToPspsDb, 38 0, 39 "IN", 40 None) 20 41 21 42 self.outputFitsFile = "00000000.FITS"; 22 43 self.outputFitsPath = self.localOutPath + "/" + self.outputFitsFile 23 44 24 logging.config.fileConfig("logging.conf") 25 logger = logging.getLogger("initbatch") 26 initBatch = InitBatch(logger) 27 initBatch.createEmptyPspsTables() 28 initBatch.exportPspsTablesToFits() 29 initBatch.writeBatchManifest() 45 ''' 46 Empty implementation 47 ''' 48 def importIppTables(self, filter=""): 49 self.logger.debug("importIppTables method here to satidfy base-class") 50 51 52 ''' 53 Implementing base class method, though not necessary 54 ''' 55 def populatePspsTables(self): 56 self.logger.debug("No processing required for this batch type") 57 return 1 58 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/ipptopspsdb.py
r31842 r32337 57 57 58 58 ''' 59 TODO 60 ''' 61 def getUnprocessedIDsForThisStage(self, dvoDb, batchType, startDate): 62 63 if batchType == "P2": # TODO define these someplace 64 65 stage = "cam" 66 sql = "SELECT DISTINCT stage_id \ 67 FROM gpc1.addRun \ 68 WHERE stage = '" + stage + "' \ 69 AND dvodb = '" + dvoDb + "' \ 70 AND stage_id NOT IN " 71 72 elif batchType == "ST": 73 74 stage = "staticsky" 75 sql = "SELECT DISTINCT stack_id \ 76 FROM gpc1.staticskyInput \ 77 JOIN gpc1.addRun ON(gpc1.staticskyInput.sky_id = gpc1.addRun.stage_id) \ 78 WHERE stage = '" + stage + "' \ 79 AND dvodb = '" + dvoDb + "' \ 80 AND stack_id NOT IN " 81 82 sql = sql + "(SELECT stage_id \ 83 FROM batch \ 84 WHERE batch_type = '" + batchType + "' \ 85 AND timestamp > '" + startDate + "' \ 86 AND loaded_to_datastore)" 59 Returns a list of processed batch IDs that are merged but not yet deleted 60 ''' 61 def getLoadedToODMButNotDeletedBatchIDs(self, batchType, epoch, dvoGpc1Label, column): 62 63 sql = "SELECT DISTINCT batch_id \ 64 FROM batch \ 65 WHERE timestamp > '" + epoch + "' \ 66 AND batch_type = '" + batchType + "' \ 67 AND dvo_db = '" + dvoGpc1Label + "' \ 68 AND loaded_to_ODM != 0 \ 69 AND " + column + " = 0" 87 70 88 71 ids = [] … … 92 75 ids.append(rs.getInt(1)) 93 76 except: 94 self.logger.exception("Can't query for ids in DVO")77 self.logger.exception("Can't query for merged batch ids in ipptopsps Db") 95 78 96 79 rs.close() 97 80 98 self.logger.debug("Found %d unprocessed items in DVO database '%s' for stage='%s'" % (len(ids), dvoDb, stage))81 self.logger.debug("Found %d merged but un-deleted items" % len(ids)) 99 82 100 83 return ids 101 84 102 85 ''' 103 TODO 104 ''' 105 def getLastBatchPublished(self, batchType): 106 107 sql = "SELECT TIMESTAMPDIFF(MINUTE, timestamp, now())/60.0 \ 86 Returns a list of processed batch IDs that are merged but not deleted from local disk 87 ''' 88 def getLoadedToODMButNotDeletedFromLocalDisk(self, batchType, epoch, dvoGpc1Label): 89 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_local") 90 91 ''' 92 Returns a list of processed batch IDs that are merged but not deleted from datastore 93 ''' 94 def getLoadedToODMButNotDeletedFromDatastore(self, batchType, epoch, dvoGpc1Label): 95 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_datastore") 96 97 ''' 98 Returns a list of processed batch IDs that are merged but not deleted from DXLayer 99 ''' 100 def getLoadedToODMButNotDeletedFromDXLayer(self, batchType, epoch, dvoGpc1Label): 101 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_dxlayer") 102 103 104 ''' 105 Returns a list of processed batch IDs that are not loaded to the datastore 106 ''' 107 def getProcessedButFailedDatastoreBatchIDs(self, epoch, dvoGpc1Label, batchType): 108 109 sql = "SELECT DISTINCT batch_id \ 110 FROM batch \ 111 WHERE timestamp > '" + epoch + "' \ 112 AND batch_type = '" + batchType + "' \ 113 AND dvo_db = '" + dvoGpc1Label + "' \ 114 AND processed = 1\ 115 AND loaded_to_datastore = -1" 116 117 ids = [] 118 try: 119 rs = self.executeQuery(sql) 120 while (rs.next()): 121 ids.append(rs.getInt(1)) 122 except: 123 self.logger.exception("Can't query for processed batch ids not loaded to datastore ipptopsps Db") 124 125 rs.close() 126 127 self.logger.debug("Found %d processed but-not-on-datastore items" % len(ids)) 128 129 return ids 130 131 ''' 132 Returns a list of processed batch IDs that have not yet been loaded to the ODM 133 ''' 134 def getBatchIDsUnloadedToODM(self, epoch, dvoGpc1Label): 135 136 sql = "SELECT DISTINCT batch_id \ 137 FROM batch \ 138 WHERE timestamp > '" + epoch + "' \ 139 AND dvo_db = '" + dvoGpc1Label + "' \ 140 AND loaded_to_datastore = 1 \ 141 AND loaded_to_ODM = 0" 142 143 144 ids = [] 145 try: 146 rs = self.executeQuery(sql) 147 while (rs.next()): 148 ids.append(rs.getInt(1)) 149 except: 150 self.logger.exception("Can't query for unloaded batch ids in ipptopsps Db") 151 152 rs.close() 153 154 self.logger.debug("Found %d unloaded items" % len(ids)) 155 156 return ids 157 158 ''' 159 Returns a list of processed batch IDs that have not failed to load and are not yet merged, for this epoch and dvo label 160 ''' 161 def getUnfinishedBatchIDs(self, epoch, dvoGpc1Label): 162 163 sql = "SELECT DISTINCT batch_id \ 164 FROM batch \ 165 WHERE timestamp > '" + epoch + "' \ 166 AND dvo_db = '" + dvoGpc1Label + "' \ 167 AND loaded_to_datastore = 1 \ 168 AND merged != 1 \ 169 AND loaded_to_ODM != -1" 170 171 172 ids = [] 173 try: 174 rs = self.executeQuery(sql) 175 while (rs.next()): 176 ids.append(rs.getInt(1)) 177 except: 178 self.logger.exception("Can't query for unfinished batch ids in ipptopsps Db") 179 180 rs.close() 181 182 self.logger.debug("Found %d unfinished items" % len(ids)) 183 184 return ids 185 186 ''' 187 Returns a list of batch IDs for this epoch and dvo label for which the specified column is set to value 188 ''' 189 def getBatchIDs(self, epoch, dvoGpc1Label, column, value): 190 191 sql = "SELECT DISTINCT batch_id \ 192 FROM batch \ 193 WHERE timestamp > '" + epoch + "' \ 194 AND dvo_db = '" + dvoGpc1Label + "' \ 195 AND " + column + " = " + str(value) 196 197 ids = [] 198 try: 199 rs = self.executeQuery(sql) 200 while (rs.next()): 201 ids.append(rs.getInt(1)) 202 except: 203 self.logger.exception("Can't query for batch ids with " + column + " = " + str(value) + " in ipptopsps Db") 204 205 rs.close() 206 207 self.logger.debug("Found %d batches with %s = %d" % (len(ids), column, value)) 208 209 return ids 210 211 ''' 212 Returns a list of IDs for this batch type, epoch and dvo label (i.e. either 213 cam_ids or stack_ids) for which the specified column is set to value 214 ''' 215 def getStageIDs(self, batchType, epoch, dvoGpc1Label, column, value): 216 217 sql = "SELECT DISTINCT stage_id \ 108 218 FROM batch \ 109 219 WHERE batch_type = '" + batchType + "' \ 110 AND loaded_to_datastore \ 220 AND timestamp > '" + epoch + "' \ 221 AND dvo_db = '" + dvoGpc1Label + "' \ 222 AND " + column + " = " + str(value) 223 224 ids = [] 225 try: 226 rs = self.executeQuery(sql) 227 while (rs.next()): 228 ids.append(rs.getInt(1)) 229 except: 230 self.logger.exception("Can't query for ids with " + column + " = " + str(value) + " in ipptopsps Db") 231 232 rs.close() 233 234 self.logger.debug("Found %d batches with %s = 1 for batch type='%s'" % (len(ids), column, batchType)) 235 236 return ids 237 238 ''' 239 Series of getter methods that utilise getBatchIDs() method above 240 ''' 241 def getloadedToDatastoreBatchIDs(self, epoch, dvoGpc1Label): 242 return self.getBatchIDs(epoch, dvoGpc1Label, "loaded_to_datastore", 1) 243 def getFailedLoadedToODMBatchIDs(self, epoch, dvoGpc1Label): 244 return self.getBatchIDs(epoch, dvoGpc1Label, "loaded_to_ODM", -1) 245 246 ''' 247 Series of getter methods that utilise getStageIDs() method above 248 ''' 249 def getProcessedIDs(self, batchType, epoch, dvoGpc1Label): 250 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "processed", 1) 251 def getloadedToDatastoreIDs(self, batchType, epoch, dvoGpc1Label): 252 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_datastore", 1) 253 def getLoadedToODMIDs(self, batchType, epoch, dvoGpc1Label): 254 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_ODM", 1) 255 def getMergeWorthyIDs(self, batchType, epoch, dvoGpc1Label): 256 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merge_worthy", 1) 257 def getMergedIDs(self, batchType, epoch, dvoGpc1Label): 258 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merged", 1) 259 260 ''' 261 Returns the time (as a string) that the last batch was published to the datastore for 262 this epoch, dvo label and batch type 263 ''' 264 def getTimeOfLastBatchPublished(self, batchType, epoch, dvoGpc1Label): 265 266 minutes = None 267 268 sql = "SELECT TIMESTAMPDIFF(MINUTE, timestamp, now()) \ 269 FROM batch \ 270 WHERE batch_type = '" + batchType + "' \ 271 AND loaded_to_datastore = 1 \ 272 AND timestamp > '" + epoch + "' \ 273 AND dvo_db = '" + dvoGpc1Label + "' \ 111 274 ORDER BY timestamp DESC LIMIT 1" 112 275 113 276 try: 114 277 rs = self.executeQuery(sql) 115 rs.first() 116 hours = rs.getFloat(1) 278 if rs.first(): minutes = rs.getFloat(1) 117 279 except: 118 280 self.logger.exception("Unable to get last batch published") 119 281 120 return hours 282 if not minutes: return "Never" 283 284 hours = minutes/60.0 285 days = hours/24.0 286 weeks = days/7.0 287 288 if minutes < 60: return "%.1f minutes ago" % minutes 289 elif hours < 48: return "%.1f hours ago" % hours 290 elif days < 7: return "%.1f days ago" % days 291 return "%.1f weeks ago" % weeks 121 292 122 293 ''' … … 172 343 return bpm 173 344 174 175 '''176 TODO177 '''178 def getTotalFailedBatches(self, batchType, startTime, endTime=""):179 180 sql = "SELECT COUNT(DISTINCT stage_id) \181 FROM batch \182 WHERE timestamp > '" + startTime + "' \183 AND batch_type = '" + batchType + "' \184 AND !processed \185 AND stage_id NOT IN \186 (SELECT DISTINCT stage_id \187 FROM batch \188 WHERE timestamp > '" + startTime + "' \189 AND batch_type = '" + batchType + "' \190 AND loaded_to_datastore)"191 192 try:193 rs = self.executeQuery(sql)194 rs.first()195 total = rs.getInt(1)196 except:197 self.logger.exception("Unable to count failed batches")198 199 return total200 '''201 TODO202 '''203 def getTotalBatchesPublished(self, batchType, startTime, endTime=""):204 205 sql = "SELECT COUNT(*) \206 FROM batch \207 WHERE timestamp > '" + startTime + "' \208 AND batch_type = '" + batchType + "' \209 AND loaded_to_datastore"210 211 try:212 rs = self.executeQuery(sql)213 rs.first()214 total = rs.getInt(1)215 except:216 self.logger.exception("Unable to count batches")217 218 return total219 220 345 ''' 221 346 Updates min/max object ID on this table and batch 222 347 ''' 223 def update MinMaxObjID(self, batchID, minObjID, maxObjID):348 def updateDetectionStats(self, batchID, minObjID, maxObjID, totalDetections): 224 349 225 350 sql = "UPDATE batch SET \ 226 351 min_obj_id = " + str(minObjID) + ", \ 227 max_obj_id = " + str(maxObjID) + " \ 352 max_obj_id = " + str(maxObjID) + ", \ 353 total_detections = " + str(totalDetections) + " \ 228 354 WHERE batch_id = " + str(batchID) 229 355 … … 231 357 232 358 ''' 359 Updates a batch-table column 360 ''' 361 def updateColumn(self, batchID, column, value): 362 363 sql = "UPDATE batch \ 364 SET " + column + " = " + str(value) + " \ 365 WHERE batch_id = " + str(batchID) 366 367 self.execute(sql) 368 369 ''' 233 370 Updates batch processed field 234 371 ''' 235 372 def updateProcessed(self, batchID, processed): 236 373 self.updateColumn(batchID, "processed", processed) 374 375 ''' 376 Updates batch deleted local field 377 ''' 378 def updateDeletedLocal(self, batchID, value): 379 self.updateColumn(batchID, "deleted_local", value) 380 381 ''' 382 Updates batch deleted datastore field 383 ''' 384 def updateDeletedDatastore(self, batchID, value): 385 self.updateColumn(batchID, "deleted_datastore", value) 386 387 ''' 388 Updates batch deleted dxlayer field 389 ''' 390 def updateDeletedDxlayer(self, batchID, value): 391 self.updateColumn(batchID, "deleted_dxlayer", value) 392 393 ''' 394 Updates batch loaded_to_datastore field 395 ''' 396 def updateLoadedToDatastore(self, batchID, loadedToDatastore): 397 self.updateColumn(batchID, "loaded_to_datastore", loadedToDatastore) 398 399 ''' 400 Updates ODM status for this batch 401 ''' 402 def updateOdmStatus(self, batchID, odmStatus): 403 404 if odmStatus['LOADFAILED'] == 1: loadedToODM = -1 405 else: loadedToODM = odmStatus['LOADEDTOODM'] 237 406 sql = "UPDATE batch \ 238 SET processed = " + str(processed) + " \ 407 SET loaded_to_ODM = " + str(loadedToODM) + ", \ 408 merge_worthy = " + str(odmStatus['MERGEWORTHY']) + ", \ 409 merged = " + str(odmStatus['MERGED']) + " \ 239 410 WHERE batch_id = " + str(batchID) 240 411 … … 242 413 243 414 ''' 244 Updates batch loaded_to_datastore field245 '''246 def updateLoadedToDatastore(self, batchID, loadedToDatastore):247 248 sql = "UPDATE batch \249 SET loaded_to_datastore = " + str(loadedToDatastore) + " \250 WHERE batch_id = " + str(batchID)251 252 self.execute(sql)253 254 '''255 415 Have we already processed and published this batch? 256 416 ''' 257 def alreadyProcessed(self, stage_id):417 def alreadyProcessed(self, batchType, stage_id, epoch, dvoGpc1Label): 258 418 259 419 sql = "SELECT COUNT(*) \ 260 420 FROM batch \ 261 421 WHERE stage_id = " + str(stage_id) + " \ 262 AND processed \ 263 AND loaded_to_datastore" 422 AND batch_type = '" + batchType + "' \ 423 AND timestamp > '" + epoch + "' \ 424 AND dvo_db = '" + dvoGpc1Label + "' \ 425 AND processed = 1 \ 426 AND loaded_to_datastore != 0" 264 427 265 428 try: … … 267 430 rs.first() 268 431 if rs.getInt(1) > 0: 269 self.logger.error ("Batch with stage_id = "+str(stage_id) + " has already been processed and published to datastore")432 self.logger.errorPair(str(stage_id) + " has already been published", "skipping") 270 433 return True 271 434 else: … … 273 436 except: 274 437 self.logger.exception("Unable to check whether this batch has already been processed") 438 439 ''' 440 Has this stage_id consistently failed to process? 441 ''' 442 def consistentlyFailed(self, batchType, stage_id, epoch, dvoGpc1Label, count): 443 444 sql = "SELECT COUNT(*) \ 445 FROM batch \ 446 WHERE stage_id = " + str(stage_id) + " \ 447 AND batch_type = '" + batchType + "' \ 448 AND timestamp > '" + epoch + "' \ 449 AND dvo_db = '" + dvoGpc1Label + "' \ 450 AND processed = -1" 451 452 try: 453 rs = self.executeQuery(sql) 454 rs.first() 455 if rs.getInt(1) >= count: 456 self.logger.errorPair(str(stage_id) + " has failed %d times" % count, "skipping") 457 return True 458 else: 459 return False 460 except: 461 self.logger.exception("Unable to check whether this batch has consistently failed") 275 462 276 463 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/mysql.py
r31844 r32337 36 36 # set up JDBC connection 37 37 self.url = "jdbc:mysql://"+self.dbHost+"/"+self.dbName+"?user="+self.dbUser+"&password="+self.dbPass 38 self.con = DriverManager.getConnection(self.url) 39 self.connectionID = self.getLastConnectionID() 40 self.logger.debug("MySQL connection to %s with ID %d" % (dbType, self.connectionID)) 41 42 #self.stmt = self.con.createStatement() 38 try: 39 self.con = DriverManager.getConnection(self.url) 40 self.connectionID = self.getLastConnectionID() 41 self.logger.debug("MySQL connection to %s with ID %d" % (dbType, self.connectionID)) 42 except: 43 self.logger.error("Unable to connect to " + self.url) 44 self.everythingOK = False 45 return 46 47 self.everythingOK = True 43 48 44 49 … … 210 215 nBad = rs.getInt(1) 211 216 212 sql="DELETE from " + tableName + " WHERE " + columnName + " = " + value 213 self.execute(sql) 214 self.logger.info("%s '%s' values in %s %5d deleted" % (columnName, value, tableName, nBad)) 217 sql="DELETE FROM " + tableName + " WHERE " + columnName + " = " + value 218 self.execute(sql) 219 self.logger.debugPair("%s rows with %s" % (columnName, value), "%d deleted" % nBad) 220 221 return nBad 215 222 216 223 ''' … … 224 231 nBad = rs.getInt(1) 225 232 226 sql="DELETE from " + tableName + " WHERE " + columnName + " IS NULL" 227 self.execute(sql) 228 self.logger.infoPair("NULLs deleted from %s" % tableName, "%-5d %s" % (nBad, columnName)) 233 sql="DELETE FROM " + tableName + " WHERE " + columnName + " IS NULL" 234 self.execute(sql) 235 self.logger.debugPair("NULL %s values" % columnName, "%d deleted" % nBad) 236 237 return nBad 229 238 230 239 ''' -
branches/eam_branches/ipp-20110710/ippToPsps/jython/pslogger.py
r31843 r32337 1 1 import logging.config 2 2 import datetime 3 import os 4 import sys 3 5 4 6 class PSLogger(logging.getLoggerClass()): 7 8 ''' 9 Sets up logging using values from the ippToPsps config file 10 ''' 11 def setup(self, doc, name, stdout=1, sendToFile=0): 12 13 formatter = logging.Formatter('%(asctime)s | %(levelname)7s | %(message)s', '%Y-%m-%d %H:%M:%S') 14 self.setLevel(logging.INFO) 15 16 if sendToFile: 17 PATH = doc.find("localOutPath").text + "/log" 18 if not os.path.exists(PATH): os.makedirs(PATH) 19 DVOLABEL = doc.find("dvo/gpc1Label").text 20 FULLPATH = PATH + "/" + name + "_" + DVOLABEL + ".log" 21 22 # opens file to be appended 23 hdlr = logging.FileHandler(FULLPATH, "a") 24 hdlr.setFormatter(formatter) 25 self.addHandler(hdlr) 26 27 if stdout: 28 stdout = logging.StreamHandler(sys.__stdout__) 29 #stdout.setFormatter(formatter) 30 self.addHandler(stdout) 31 32 if sendToFile: print "Writing log to: " + FULLPATH 5 33 6 34 def infoPair(self, first, second): 7 35 self.info("%-40s%s" % (first, second)) 8 36 37 def errorPair(self, first, second): 38 self.error("%-40s%s" % (first, second)) 39 40 def debugPair(self, first, second): 41 self.debug("%-40s%s" % (first, second)) 42 43 def infoTitle(self, str): 44 self.info("") 45 self.info("%40s" % (str)) 46 self.info("") 47 48 def infoBool(self, first, bool): 49 if bool: str = "yes" 50 else: str = "no" 51 self.info("%-40s%s" % (first, str)) 52 53 def errorBool(self, first, bool): 54 if bool: str = "yes" 55 else: str = "no" 56 self.error("%-40s%s" % (first, str)) 57 9 58 def infoSeparator(self): 10 59 self.info("--------------------------------------------------------------------------") 11 60 12 def infoMiniSeparator(self):13 self.info("---------------------------")14 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/removeFromDatastore.py
r31289 r32337 5 5 import sys 6 6 import getopt 7 from pslogger import PSLogger 8 9 from xml.etree.ElementTree import ElementTree, Element, tostring 7 10 8 11 9 logging.config.fileConfig("logging.conf") 10 logger = logging.getLogger("datastore") 12 if len(sys.argv) < 3: 13 print "** Usage: " + sys.argv[0] + " <configPath> <firstBatchToRemove> [<lastBatchToRemove>]" 14 sys.exit(1) 11 15 16 CONFIG = sys.argv[1] 17 configDoc = ElementTree(file=CONFIG) 12 18 19 logging.setLoggerClass(PSLogger) 20 logger = logging.getLogger("removeFromDatastore") 21 logger.setup(configDoc, "removeFromDatastore") 13 22 23 datastore = Datastore(logger, configDoc) 14 24 15 datastore = Datastore(logger) 16 datastore.remove(str(sys.argv[1])) 25 if len(sys.argv) < 4: 26 datastore.remove(str(sys.argv[2])) 27 else: 28 datastore.removeRange(str(sys.argv[2]), str(sys.argv[3])) 17 29 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/scratchdb.py
r31841 r32337 23 23 24 24 if useFull: 25 self.dvoMeta = "dvoMetaNew" 26 self.dvoDetection = "dvoDetectionFull" 25 self.dvoMetaTable = "dvoMetaFull" 26 self.dvoDetectionTable = "dvoDetectionFull" 27 self.dvoDoneTable = "dvoDone" 27 28 else: 28 self.dvoMeta = "dvoMeta" 29 self.dvoDetection = "dvoDetection" 30 31 self.logger.debug("ScratchDb constructor, using DVO tables: " + self.dvoMeta + " and " + self.dvoDetection) 29 self.dvoMetaTable = "dvoMeta" 30 self.dvoDetectionTable = "dvoDetection" 31 32 self.logger.debugPair("Using DVO meta table", self.dvoMetaTable) 33 self.logger.debugPair("Using DVO detection table", self.dvoDetectionTable) 32 34 33 35 ''' … … 37 39 38 40 self.logger.debug("ScratchDb destructor") 41 42 43 ''' 44 Creates a stored procedure for psfLikelihood. This uses an implementation of the complimentary error function taken from Numerical Recipes in C. 45 ''' 46 def createPsfLikelihoodFunction(self): 47 sql = "DELIMITER $$ \ 48 DROP FUNCTION IF EXISTS `psfLikelihood` $$ \ 49 CREATE FUNCTION `psfLikelihood`(x REAL) RETURNS REAL \ 50 DETERMINISTIC \ 51 COMMENT 'Returns the psfLikelihood using the complimentary error function with fractional error everywhere less than 1.2 x 10-7. From Numerical Recipes in C' \ 52 BEGIN \ 53 DECLARE ans REAL; \ 54 DECLARE t REAL; \ 55 DECLARE z REAL; \ 56 SET x = ABS(x) / 1.4142135623731; \ 57 SET z=ABS(x); \ 58 SET t=1.0 / (1.0 + 0.5*z); \ 59 SET ans = t * EXP(-z*z-1.26551223+t*(1.00002368+t*(.37409196+t*(.09678418+t*(-.18628806+t*(.27886807+t*(-1.13520398+t*(1.48851587+t*(-.82215223+t*.17087277))))))))); \ 60 IF x < 0.0 THEN \ 61 SET ans = 2.0 - ans; \ 62 END IF; \ 63 RETURN ans; \ 64 END $$ \ 65 DELIMITER ;" 66 67 try: 68 self.execute(sql) 69 self.logger.debugPair("Installed stored procedure", "psfLikelihood") 70 return True 71 except: 72 self.logger.errorPair("Could not install stored procedure", "psfLikelihood") 73 return False 39 74 40 75 ''' … … 47 82 rs = self.executeQuery(sql) 48 83 rs.first() 49 return rs.getInt(1) 50 except: 51 self.logger.exception("No survey ID found for this survey: '" + self.survey + "'") 52 return -1 84 surveyID = rs.getInt(1) 85 except: 86 self.logger.errorPair("No survey ID found for survey", name) 87 surveyID = -1 88 89 return surveyID 90 91 ''' 92 Gets filter ID for this filter name 93 ''' 94 def getFilterID(self, name): 95 96 sql = "SELECT filterID FROM Filter WHERE filterType = '" + name + "'" 97 try: 98 rs = self.executeQuery(sql) 99 rs.first() 100 filterID = rs.getInt(1) 101 except: 102 self.logger.errorPair("No filter ID found for filter", name) 103 filterID = -1 104 105 return filterID 106 107 ''' 108 Gets imageID from extern ID 109 ''' 110 def getImageIDFromExternID(self, sourceID, externID): 111 112 imageID = -1 113 114 sql = "SELECT imageID FROM " + self.dvoMetaTable + " WHERE sourceID = %s AND externID = %s" % (sourceID, externID) 115 try: 116 rs = self.executeQuery(sql) 117 rs.first() 118 imageID = rs.getInt(1) 119 except: 120 self.logger.errorPair("Unable to get imageID from dvo using", sql) 121 122 return imageID 53 123 54 124 ''' … … 59 129 flags = 0 60 130 61 sql = "SELECT flags FROM " + self.dvoMeta + " WHERE sourceID = %s AND externID = %s" % (sourceID, externID)131 sql = "SELECT flags FROM " + self.dvoMetaTable + " WHERE sourceID = %s AND externID = %s" % (sourceID, externID) 62 132 try: 63 133 rs = self.executeQuery(sql) … … 65 135 flags = rs.getInt(1) 66 136 except: 67 self.logger.e xception("Unable to get flags from dvo table using " +sql)137 self.logger.errorPair("Unable to get flags from dvo using", sql) 68 138 return flags 69 139 70 140 ''' 71 Gets imageID from extern ID72 ''' 73 def get ImageIDFromExternID(self, sourceID, externID):74 75 imageID= -176 77 sql = "SELECT imageID FROM " + self.dvoMeta+ " WHERE sourceID = %s AND externID = %s" % (sourceID, externID)141 Gets photcode (aka photoCalID from dvo table) 142 ''' 143 def getPhotoCalID(self, sourceID, externID): 144 145 photcode = -1 146 147 sql = "SELECT photcode FROM " + self.dvoMetaTable + " WHERE sourceID = %s AND externID = %s" % (sourceID, externID) 78 148 try: 79 149 rs = self.executeQuery(sql) 80 150 rs.first() 81 imageID = rs.getInt(1)82 except:83 self.logger.exception("Unable to get imageID from dvo meta table using " + sql)84 85 return imageID86 87 '''88 Gets photcode (aka photoCalID from dvo table)89 '''90 def getPhotoCalID(self, sourceID, externID):91 92 photcode = -193 94 sql = "SELECT photcode FROM " + self.dvoMeta + " WHERE sourceID = %s AND externID = %s" % (sourceID, externID)95 try:96 rs = self.executeQuery(sql)97 rs.first()98 151 photcode = rs.getInt(1) 99 152 except: 100 self.logger.e xception("Unable to get photcode from dvo table with: " +sql)153 self.logger.errorPair("Unable to get photcode from dvo with", sql) 101 154 102 155 return photcode … … 113 166 Inserts a new sourceID/imageID combo into dvoMeta 114 167 ''' 115 def insertNewDvo Image(self, sourceID, imageID):168 def insertNewDvoExternID(self, sourceID, externID): 116 169 117 170 sql = "INSERT INTO dvoMeta ( \ 118 171 sourceID, \ 119 imageID, \120 172 externID \ 121 173 ) VALUES (\ 122 174 " + str(sourceID) + ", \ 123 " + str(imageID) + " , \ 124 " + str(imageID) + " \ 175 " + str(externID) + " \ 125 176 )" 126 177 self.execute(sql) … … 135 186 136 187 ''' 188 Checks whether the astrometric solution is ok for this chip 189 TODO the value of 50 for numAstroRef is hardcoded here, but this should be temporary anyway 190 ''' 191 def astrometricSolutionOK(self, ota): 192 193 sql = "SELECT numAstroRef FROM ImageMeta_" + ota 194 195 try: 196 rs = self.executeQuery(sql) 197 rs.first() 198 if rs.getInt(1) < 50: 199 self.logger.debug("Bad astrometric solution for", ota) 200 return False 201 else: 202 return True 203 except: 204 self.logger.debug("Unable to check astrometric solution") 205 206 return True 207 208 ''' 137 209 Have we already imported this DVO table? 138 210 ''' … … 145 217 rs.first() 146 218 if rs.getInt(1) > 0: 147 self.logger.error ("DVO tables " + name + " have already been imported")219 self.logger.errorPair("Already imported DVO tables for", name) 148 220 return True 149 221 else: … … 158 230 def createDvoTables(self): 159 231 160 self.logger. infoPair("Creating DVO table", "dvoMeta")232 self.logger.debugPair("Creating DVO table", "dvoMeta") 161 233 162 234 sql = "DROP TABLE dvoMeta" … … 174 246 flags INT, \ 175 247 photcode INT, \ 176 PRIMARY KEY (sourceID, imageID ) \248 PRIMARY KEY (sourceID, imageID, externID) \ 177 249 )" 178 250 … … 181 253 self.logger.error("Unable to create DVO meta-data database table") 182 254 183 self.logger. infoPair("Creating DVO table", "dvoDetection")255 self.logger.debugPair("Creating DVO table", "dvoDetection") 184 256 sql = "CREATE TABLE dvoDetection ( \ 185 257 sourceID INT, \ … … 192 264 PRIMARY KEY (sourceID, imageID, ippDetectID) \ 193 265 )" 194 #INDEX (sourceID), \195 #INDEX (imageID), \196 #INDEX (ippDetectID) \197 266 198 267 try: self.execute(sql) 199 268 except: 200 269 self.logger.error("Unable to create DVO detection database table") 270 271 272 ''' 273 Drops and recreates tables necessary for dvoToMySQL program. Be very careful before using this... 274 ''' 275 def resetDvoToMysqlTables(self): 276 277 self.logger.infoPair("Dropping table", self.dvoMetaTable) 278 self.dropTable(self.dvoMetaTable) 279 self.logger.infoPair("Dropping table", self.dvoDetectionTable) 280 self.dropTable(self.dvoDetectionTable) 281 self.logger.infoPair("Dropping table", self.dvoDoneTable) 282 self.dropTable(self.dvoDoneTable) 283 284 self.logger.infoPair("Creating table", self.dvoMetaTable) 285 sql = "CREATE TABLE " + self.dvoMetaTable + " LIKE dvoMeta" 286 try: self.execute(sql) 287 except: self.logger.errorPair("Unable to create table", self.dvoMetaTable) 288 289 self.logger.infoPair("Creating table", self.dvoDetectionTable) 290 sql = "CREATE TABLE " + self.dvoDetectionTable + " LIKE dvoDetection" 291 try: self.execute(sql) 292 except: self.logger.errorPair("Unable to create table", self.dvoDetectionTable) 293 294 self.logger.infoPair("Creating table", self.dvoDoneTable ) 295 sql = "CREATE TABLE " + self.dvoDoneTable + " (name VARCHAR(100))" 296 try: self.execute(sql) 297 except: self.logger.errorPair("Unable to create table", self.dvoDoneTable) 298 299 300 -
branches/eam_branches/ipp-20110710/ippToPsps/jython/stackbatch.py
r31847 r32337 27 27 def __init__(self, 28 28 logger, 29 configPath, 29 30 configDoc, 30 31 gpc1Db, … … 34 35 super(StackBatch, self).__init__( 35 36 logger, 37 configPath, 36 38 configDoc, 37 39 gpc1Db, 38 40 ippToPspsDb, 39 41 stackID, 40 "stack", 41 gpc1Db.getStackStageCmf(stackID), 42 "3PI") # TODO 42 "ST", 43 gpc1Db.getStackStageCmf(stackID)) 43 44 44 45 if not self.everythingOK: return … … 48 49 # get stack meta data 49 50 meta = self.gpc1Db.getStackStageMeta(self.id) 51 if not meta: 52 self.everythingOK = False 53 return 54 50 55 self.filter = meta[0]; 51 56 self.filter = self.filter[0:1] 52 57 self.skycell = meta[1]; 53 self.skycell = self.skycell[8:] 58 # TODO HACK fix this 59 self.skycell = self.skycell[8:12] 54 60 # mangling e.g. 0683.043 into 0683043 for now until we have a schema change 55 self.skycell = self.skycell.replace(".", "")61 #self.skycell = self.skycell.replace(".", "") 56 62 self.analysisVer = meta[2]; 57 63 … … 87 93 # insert sourceID/imageID combo so DVO can look it up 88 94 if not self.useFullTables: 89 self.scratchDb.insertNewDvoImage(self.header['SOURCEID'], self.header['IMAGEID']) 90 91 ''' 92 Prints metadata to the log 93 ''' 94 def printMe(self): 95 96 super(StackBatch, self).printMe() 97 95 self.scratchDb.insertNewDvoExternID(self.header['SOURCEID'], self.header['IMAGEID']) 96 97 98 # dump stuff to log 98 99 self.logger.infoPair("Stack ID", "%d" % self.id) 99 100 self.logger.infoPair("Stack type", "%s" % self.stackType) 100 101 self.logger.infoPair("Skycell", "%s" % self.skycell) 101 102 self.logger.infoPair("Filter", "%s" % self.filter) 103 102 104 103 105 … … 383 385 self.updateStackTypeID("StackDetection") 384 386 self.updateDvoIDs("StackDetection") 385 sql = "ALTER TABLE StackDetection ADD PRIMARY KEY (objID, stackDetectID)"386 self.scratchDb.execute(sql) 387 387 sql = "ALTER IGNORE TABLE StackDetection ADD PRIMARY KEY (objID)" 388 self.scratchDb.execute(sql) 389 388 390 if self.stackType == "DEEP_STACK": 389 391 … … 392 394 SET instFlux = 2*b.PSF_INST_FLUX_SIG \ 393 395 WHERE instFlux IS NULL \ 396 AND a.ippDetectID = b.IPP_IDET \ 394 397 AND b.PSF_INST_FLUX_SIG IS NOT NULL" 395 398 self.scratchDb.execute(sql) 396 # instFlux = 2*PSF_INST_FLUX_SIG397 399 398 400 self.scratchDb.reportAndDeleteRowsWithNULLS("StackDetection", "instFlux") … … 588 590 589 591 imageID = self.scratchDb.getImageIDFromExternID(self.header['SOURCEID'], self.header['IMAGEID']) 590 591 592 self.logger.debug("Updating table '" + table + "' with DVO IDs...") 592 sql = "UPDATE IGNORE " + table + " AS a, " + self.scratchDb.dvoDetection+ " AS b SET \593 sql = "UPDATE " + table + " AS a, " + self.scratchDb.dvoDetectionTable + " AS b SET \ 593 594 a.ippObjID = b.ippObjID, \ 594 595 a.stackDetectID = b.detectID, \
Note:
See TracChangeset
for help on using the changeset viewer.
