def get_parfile_from_id(parfile_id, existdb=None, verify_md5=True): """Return the path to the raw file that has the given ID number. Optionally double check the file's MD5 sum, to make sure nothing strange has happened. Inputs: parfile_id: The ID number of the raw file to get a path for. existdb: A (optional) existing database connection object. (Default: Establish a db connection) verify_md5: If True, double check the file's MD5 sum. (Default: Perform MD5 check.) Output: fn: The full file path. """ notify.print_info("Looking-up raw file with ID=%d" % parfile_id, 2) # Use the existing DB connection, or open a new one if None was provided db = existdb or database.Database() db.connect() select = db.select([db.parfiles.c.filename, db.parfiles.c.filepath, db.parfiles.c.md5sum]).where( db.parfiles.c.parfile_id == parfile_id ) result = db.execute(select) rows = result.fetchall() result.close() if not existdb: # Close the DB connection we opened db.close() if len(rows) == 1: filename = rows[0]["filename"] filepath = rows[0]["filepath"] md5sum_from_db = rows[0]["md5sum"] else: raise errors.InconsistentDatabaseError( "Bad number of files (%d) " "with parfile_id=%d" % (len(rows), parfile_id) ) fullpath = os.path.join(filepath, filename) # Make sure the file exists datafile.verify_file_path(fullpath) if verify_md5: notify.print_info( "Confirming MD5 sum of %s matches what is " "stored in DB (%s)" % (fullpath, md5sum_from_db), 2 ) md5sum_file = datafile.get_md5sum(fullpath) if md5sum_from_db != md5sum_file: raise errors.FileError( "md5sum check of %s failed! MD5 from " "DB (%s) != MD5 from file (%s)" % (fullpath, md5sum_from_db, md5sum_file) ) return fullpath
def prep_parfile(fn): """Prepare parfile for archiving/loading. Also, perform some checks on the parfile to make sure we won't run into problems later. Checks performed: - Existence of file. - Read/write access for file (so it can be moved). Input: fn: The name of the parfile to check. Outputs: params: A dictionary of parameters contained in the file. NOTE: parameters that look like ints or floats are cast as such. """ # Check existence of file datafile.verify_file_path(fn) # Check file permissions allow for writing and reading if not os.access(fn, os.R_OK): raise errors.FileError("File (%s) is not readable!" % fn) # Grab parameters from file f = open(fn, "r") params = {} for line in f.readlines(): # Ignore blank lines line = line.strip() if not line: continue key, valstr = line.split()[:2] if int_re.match(valstr): # Looks like an int. Cast to int. val = int(valstr) elif float_re.match(valstr): # Looks like a float. Change 'D' to 'E' and cast to float. val = float(valstr.upper().replace("D", "E")) else: # Doesn't seem like a number. Leave as string. val = valstr params[key.lower()] = val if "psrj" in params: params["pulsar_id"] = cache.get_pulsarid(params["psrj"]) params["name"] = params["psrj"] elif "psrb" in params: params["pulsar_id"] = cache.get_pulsarid(params["psrb"]) params["name"] = params["psrb"] else: params["pulsar_id"] = cache.get_pulsarid(params["psr"]) params["name"] = params["psr"] # Translate a few parameters if "binary" in params: params["binary_model"] = params["binary"] if "e" in params: params["ecc"] = params["e"] # Do some error checking if "sini" in params and isinstance(params["sini"], str): # 'SINI' parameter can be 'KIN' in this case omit 'SINI' from # the database. params.pop("sini") # normalise pulsar name params["name"] = cache.get_prefname(params["name"]) params["user_id"] = cache.get_userid() return params