- Timestamp:
- Sep 6, 2011, 11:00:22 AM (15 years ago)
- Location:
- branches/eam_branches/ipp-20110710/ippToPsps/jython
- Files:
-
- 2 edited
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
Note:
See TracChangeset
for help on using the changeset viewer.
