IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 5, 2012, 5:19:48 PM (14 years ago)
Author:
mhuber
Message:

merging latest r33407 trunk changes to meh_branches/ppstack_test

Location:
branches/meh_branches/ppstack_test
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/meh_branches/ppstack_test

  • branches/meh_branches/ppstack_test/ippToPsps/jython/batch.py

    r32118 r33415  
    2121
    2222'''
    23 Base class of all batch types.
     23Abstract base class of all batch types.
    2424'''
    2525class Batch(object):
     
    2727    '''
    2828    Constructor
    29 
    30     >>> batch = Batch(1,2,3,4,5,6,7)
    31     >>> print batch.pspsVoTableFilePath
    32     "../config/2/tables.vot"
    3329    '''
    3430    def __init__(self,
    3531                 logger,
    36                  configPath,
    37                  doc,
     32                 config,
    3833                 gpc1Db,
    3934                 ippToPspsDb,
     35                 scratchDb,
    4036                 id,
     37                 batchID,
    4138                 batchType,
    42                  fits):
     39                 fits,
     40                 useFullTables):
    4341
    4442        self.everythingOK = False
    4543        self.readHeader = False
    46         self.configPath = configPath
    47         self.doc = doc
     44        self.config = config
    4845        self.fits = fits
    49         if self.fits: self.header = self.fits.getPrimaryHeader()
     46        self.useFullTables = useFullTables
    5047
    5148        # set up logging
     
    5653        # set up class variables
    5754        self.id = id
     55        self.batchID = batchID
    5856        self.gpc1Db = gpc1Db
    5957        self.ippToPspsDb = ippToPspsDb
     58        self.scratchDb = scratchDb
    6059        self.batchType = batchType;
    6160        self.pspsVoTableFilePath = "../config/" + batchType + "/tables.vot"
    6261
    63         # get info from config
    64         self.survey = self.doc.find("options/survey").text
    65         self.pspsSurvey = self.doc.find("options/pspsSurvey").text
    66         dvoGpc1Label = self.doc.find("dvo/gpc1Label").text
    67         self.dvoLocation = self.doc.find("dvo/location").text
    68         self.useFullTables = int(self.doc.find("dvo/useFullTables").text)
    69         self.scratchDb = ScratchDb(logger, self.doc, self.useFullTables)
    70 
    71         if not self.scratchDb.everythingOK: return
     62        # check FITS file is ok
     63        if self.fits:
     64            self.header = self.fits.getPrimaryHeader()
     65
     66            # now check that the fits header is readable
     67            if not self.header:
     68                logger.errorPair("Could not read FITS for id", "%d" % id)
     69                return
     70
     71        # if no fits file, and this is not an IN batch, then get out of here
     72        else:
     73           if batchType != "IN":
     74               logger.errorPair("Could not read FITS for id", "%d" % id)
     75               return
     76
     77        self.scratchDb.setUseFullTables(self.useFullTables)
    7278
    7379        # TODO
    7480        self.tablesToExport = []
    7581
    76         if self.survey != "":
    77             self.surveyID = self.scratchDb.getSurveyID(self.survey)
     82        if self.config.survey != "":
     83            self.surveyID = self.scratchDb.getSurveyID(self.config.survey)
    7884        else:
    7985            self.surveyID = -1;
    80 
    8186       
    82         # get some options from the config
    83         self.testMode = int(self.doc.find("options/testMode").text)
    84         self.dataRelease = int(self.doc.find("metadata/dataRelease").text)
    85 
    8687        # create datastore object
    87         self.datastore = Datastore(self.logger, self.doc)
    88 
    89         # create a new batch
    90         self.batchID = self.ippToPspsDb.createNewBatch(
    91                 self.batchType,
    92                 self.id,
    93                 self.survey,
    94                 dvoGpc1Label,
    95                 self.datastore.product)
     88        self.datastore = Datastore(self.logger, self.config, self.ippToPspsDb)
    9689
    9790        # get local storage location from config
    9891        self.batchName = Batch.getNameFromID(self.batchID)
    99         basePath = self.doc.find("localOutPath").text
    10092        self.subDir = Batch.getSubDir(
    101                 basePath,
     93                self.config.basePath,
    10294                self.batchType,
    103                 dvoGpc1Label)
     95                self.config.dvoLabel)
    10496
    10597        self.localOutPath = Batch.getOutputPath(
    106                 basePath,
     98                self.config.basePath,
    10799                self.batchType,
    108                 dvoGpc1Label,
     100                self.config.dvoLabel,
    109101                self.batchID)
    110102
     
    121113        self.logger.infoTitle("New " + self.batchType + " batch")
    122114        self.logger.infoPair("Batch name", self.batchName)
    123         self.logger.infoPair("Survey", self.survey)
    124115        self.logger.infoPair("Survey ID", "%d" % self.surveyID)
    125         self.logger.infoPair("Publishing to PSPS as survey", self.pspsSurvey)
    126         self.logger.infoPair("DVO location", self.dvoLocation)
    127116        self.logger.infoBool("Use full DVO tables?", self.useFullTables)
    128117
     
    157146
    158147    '''
     148    Static method to get name of tar file
     149    '''
     150    @staticmethod
     151    def getTarFile(id):
     152        return Batch.getNameFromID(id) + ".tar"
     153
     154    '''
     155    Static method to get path of tar file
     156    '''
     157    @staticmethod
     158    def getTarPath(basePath, batchType, dvoLabel, id):
     159        return Batch.getSubDir(basePath, batchType, dvoLabel) + "/" + Batch.getTarFile(id)
     160
     161    '''
     162    Static method to get name of tarball file
     163    '''
     164    @staticmethod
     165    def getTarballFile(id):
     166        return Batch.getTarFile(id) + ".gz"
     167
     168    '''
     169    Static method to get path of tarball file
     170    '''
     171    @staticmethod
     172    def getTarballPath(basePath, batchType, dvoLabel, id):
     173        return Batch.getSubDir(basePath, batchType, dvoLabel) + "/" + Batch.getTarballFile(id)
     174
     175    ''' 
     176    Static method to delete this batch from local disk
     177    '''
     178    @staticmethod
     179    def deleteFromDisk(logger, basePath, batchType, dvoLabel, id):
     180       
     181        tarballPath = Batch.getTarballPath(basePath, batchType, dvoLabel, id)
     182        dirPath = Batch.getOutputPath(basePath, batchType, dvoLabel, id)
     183
     184        if not os.path.exists(tarballPath):
     185            logger.errorPair("Could not find", tarballPath)
     186            return 1
     187
     188        try:
     189            os.remove(tarballPath)
     190            logger.infoPair("Deleted", tarballPath)
     191        except:
     192            logger.errorPair("Could not delete", tarballPath)
     193            return 0
     194   
     195        return 1
     196
     197    '''
    159198    Destructor
    160199    '''
     
    173212         if value != "NULL": return value
    174213         else:
    175              if not self.testMode: return "NULL"
     214             if not self.config.test: return "NULL"
    176215             header[key] = default
    177216             self.logger.infoPair("Hardcoding " + key + " to", header[key])
     
    194233
    195234        outPath = self.localOutPath + "/BatchManifest.xml"
    196         tmpPath = "./tmp.xml"
     235        tmpPath = self.localOutPath + "/tmp.xml"
    197236        self.logger.infoPair("Creating manifest", outPath)
    198237        root = Element('manifest')
     
    202241        root.attrib['type'] = self.batchType
    203242        root.attrib['timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    204         if self.batchType != "IN": root.attrib['survey'] = self.pspsSurvey
     243        if self.batchType != "IN": root.attrib['survey'] = self.config.pspsSurvey
    205244        try: self.minObjID
    206245        except: pass
     
    210249        else: root.attrib['maxObjId'] = str(self.maxObjID)
    211250
    212         # get md5sum
    213         p = Popen("md5sum " + self.outputFitsPath, shell=True, stdout=PIPE)
    214         p.wait()
    215         out = p.stdout.read()
    216         md5sum = out[0:out.rfind(" ")]
    217 
    218         # get file size
    219         fileSize = os.path.getsize(self.outputFitsPath)
    220 
    221251        # file information
    222252        child = Element('file')
    223253        root.append(child)
    224254        child.attrib['name'] = self.outputFitsFile
    225         child.attrib['bytes'] = str(fileSize)
    226         child.attrib['md5'] = md5sum
    227255
    228256        # now create doc and write to file
     
    240268    Publishes this batch to the datastore
    241269    '''
    242     def publishToDatastore(self):
     270    def tarAndZip(self):
    243271     
    244272        # set up filenams and paths
    245         tarFile = self.batchName + ".tar"
    246         tarPath = self.subDir + "/" + tarFile
    247 
    248         tarballFile = tarFile + ".gz"
    249         tarballPath = self.subDir + "/" + tarballFile
     273        tarFile = Batch.getTarFile(self.batchID)
     274        tarPath = Batch.getTarPath(self.config.basePath, self.batchType, self.config.dvoLabel, self.batchID)
     275        tarballFile = Batch.getTarballFile(self.batchID)
     276        tarballPath = Batch.getTarballPath(self.config.basePath, self.batchType, self.config.dvoLabel, self.batchID)
    250277
    251278        # tar directory
    252         p = Popen("tar -cvf " + tarPath + "\
    253                 -C " + self.subDir + " \
    254                 " + self.batchName, shell=True, stdout=PIPE)
     279        cmd = "tar -cvf " + tarPath + " -C " + self.subDir + " " + self.batchName
     280        self.logger.infoPair("Creating tar archive", cmd)
     281        p = Popen(cmd, shell=True, stdout=PIPE)
    255282        p.wait()
    256283
     284        if p.returncode != 0:
     285            self.logger.errorPair("tar command", "failed")
     286            return False
     287
    257288        # zip tar archive
    258         p = Popen("gzip -c " + tarPath + " > " + tarballPath, shell=True, stdout=PIPE)
     289        cmd = "gzip -c " + tarPath + " > " + tarballPath
     290        self.logger.infoPair("Compressing tar archive", cmd)
     291        p = Popen(cmd, shell=True, stdout=PIPE)
    259292        p.wait()
     293
     294        if p.returncode != 0:
     295            self.logger.errorPair("gzip command", "failed")
     296            return False
     297
     298        # only now can we report that the batch has successfully processed
     299        self.ippToPspsDb.updateProcessed(self.batchID, 1)
    260300
    261301        # delete tar file and original directory
     
    263303        shutil.rmtree(self.localOutPath)
    264304
    265         # now publish to the datastore
    266         if self.datastore.publish(self.batchName, self.subDir, tarballFile, "tgz"):
    267             self.ippToPspsDb.updateLoadedToDatastore(self.batchID, 1)
     305        return True
     306
     307    '''
     308    Static method to publish a batch to the datastore
     309    '''
     310    @staticmethod
     311    def publishToDatastore(datastore, batchID, batchName, subDir, tarballFile):
     312        datastore.publish(batchName, subDir, tarballFile, "tgz")
    268313
    269314    '''
     
    293338            rs.close()
    294339
    295         self.ippToPspsDb.updateMinMaxObjID(self.batchID, self.minObjID, self.maxObjID)
     340        self.ippToPspsDb.updateDetectionStats(self.batchID, self.minObjID, self.maxObjID, self.totalDetections)
    296341        self.logger.infoPair("Total detections", "%ld" % self.totalDetections)
    297342        self.logger.infoPair("Min objID", "%ld" % self.minObjID)
     
    309354             self.tablesToExport.append(table.name)
    310355
    311          self.alterPspsTables();
     356         return self.alterPspsTables();
    312357
    313358    '''
     
    329374    Accepts a regular expression filter so not all tables need to be imported
    330375    '''
    331     def importIppTables(self, filter=""):
     376    def importIppTables(self, columns="*", filter=""):
    332377
    333378      self.logger.infoPair("Importing tables with filter", filter)
    334       tables = stilts.treads(self.fits.getPath())
     379
     380      try:
     381          tables = stilts.treads(self.fits.getPath())
     382      except:
     383          self.logger.errorPair("STILTS could not import from", self.fits.getPath())
     384          return False
    335385
    336386      count = 0
     
    347397          # IPP FITS files are littered with infinities, so remove these
    348398          self.logger.debug("Removing Infinity values from all columns")
     399          table = stilts.tpipe(table, cmd='keepcols "' + columns + '"')
    349400          table = stilts.tpipe(table, cmd='replaceval -Infinity null *')
    350401          table = stilts.tpipe(table, cmd='replaceval Infinity null *')
     
    396447        try:
    397448            stilts.twrites(_tables, self.outputFitsPath, fmt='fits')
    398             self.ippToPspsDb.updateProcessed(self.batchID, 1)
    399449        except:
    400450            self.logger.exception("Could not write to FITS")
     451            self.ippToPspsDb.updateProcessed(self.batchID, -1)
    401452            return False
    402453
     
    432483    def getIDsFromDVO(self):
    433484
    434         if self.scratchDb.getRowCount("dvoMeta") < 1:
    435             self.logger.error("No DVO IDs found in dvoMeta")
     485        if self.scratchDb.getRowCount(self.scratchDb.dvoImagesTable) < 1:
     486            self.logger.errorInfo("No DVO images found in", self.scratchDb.dvoImagesTable)
    436487            return False
    437488
    438489        # TODO path to DVO prog hardcoded temporarily
    439         cmd = "../src/dvograbber " + self.configPath + " " + self.dvoLocation
     490        cmd = "../src/dvograbber " + self.config.settingsPath + " " + self.scratchDb.dbName + " " + self.config.dvoLocation
    440491        self.logger.infoPair("Running DVO", cmd)
    441492        p = Popen(cmd, shell=True, stdout=PIPE)
    442493        p.wait()
    443         #        out = p.stdout.read()
    444494
    445495        rowCount = self.scratchDb.getRowCount("dvoDetection")
     
    453503
    454504    '''
    455     Checks whether this batch has already been processed and published. To be implemented by all subclasses
    456     '''
    457     def alreadyProcessed(self):
    458         self.logger.warn("alreadyProcessed not implemented")
    459 
    460 
    461     '''
    462505    Creates and publishes a batch
     506    TODO all methods call below should throw exceptions on failure
    463507    '''
    464508    def run(self):
     
    466510        if not self.everythingOK:
    467511            self.logger.error("Aborting this batch due to (hopefully) previously reported errors")
     512            self.ippToPspsDb.updateProcessed(self.batchID, -1)
    468513            return
    469514
    470         self.createEmptyPspsTables()
     515        if not self.createEmptyPspsTables():
     516            self.logger.error("Aborting this batch due to (hopefully) previously reported errors")
     517            self.ippToPspsDb.updateProcessed(self.batchID, -1)
     518            return
     519
    471520        self.importIppTables()
    472         if self.populatePspsTables():
    473             if self.exportPspsTablesToFits():
     521        if not self.populatePspsTables():
     522            self.logger.errorPair("Aborting this batch", "unable to populate PSPS tables")
     523            self.ippToPspsDb.updateProcessed(self.batchID, -1)
     524        else:
     525            if not self.exportPspsTablesToFits():
     526                self.logger.errorPair("Aborting this batch", "unable to export tables to FITS file")
     527            else:
    474528                self.writeBatchManifest()
    475                 if int(self.doc.find("options/publishToDatastore").text): self.publishToDatastore()
    476                 if int(self.doc.find("options/reportNulls").text): self.reportNullsInAllPspsTables(False)
    477 
    478         self.logger.infoPair("Batch......", "complete")
     529                if self.config.datastorePublishing:
     530                    # tar and zip ready for publication to datastore
     531                    if self.tarAndZip():
     532                        # now publish to the datastore
     533                        tarballFile = Batch.getTarballFile(self.batchID)
     534                        Batch.publishToDatastore(self.datastore, self.batchID, self.batchName, self.subDir, tarballFile)
    479535
    480536from datastore import Datastore
Note: See TracChangeset for help on using the changeset viewer.