Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.stsci.edu/spst/UnixTransition/doc/exposure_util.py
Дата изменения: Fri Feb 28 14:46:09 2014
Дата индексирования: Sat Mar 1 16:38:52 2014
Кодировка:

Поисковые слова: annular solar eclipse
#
#MODULE exposure_util
#
#***********************************************************************
"""

**PURPOSE** --
A module for dealing with exposures.

The exposure class here was previously in gen_otr.py.

**DEVELOPER** --
Don Chance and Danny Jones

**MODIFICATION HISTORY** --
Initial implementaion 10/05/04
add functions to get opmode, config; check for existance of SPSS_DB
added is_parallel function. dc 3/1/05
fix bug introduced with changes to proposal object. dc 3/15/05
add get_qesiparms. dc 9/29/08
fix print_otr when no PI exists dc 1/15/13
add method to get qexposure data. dc 2/3/14
Add special case for interpretation of spectral elements for COS. mdr 2/5/14
"""
#***********************************************************************
__version__ = "14.02.05"

import spss_sys_util
import stpydb
import string
import time_util

class exposure:
""" Class representing an exposure.
"""

if spss_sys_util.get_environ_variable("SPSS_DB"):
spss_db = spss_sys_util.get_environ_variable("SPSS_DB")[0]
else:
spss_db = None

if spss_sys_util.get_environ_variable("ASSIST_DB"):
assist_db = spss_sys_util.get_environ_variable("ASSIST_DB")[0]
else:
assist_db = None

def __init__(self, dict):
""" Constructor for the exposure class.
The "dict" parameter is the result of a query to QELOGSHEET placed in
a dictionary.
"""

# Set up attributes from input dictionary.
self.proposal_id = dict["proposal_id"]
self.obset_id = dict["obset_id"]
self.alignment_id = dict["alignment_id"]
self.exposure_id = dict["exposure_id"]
self.version_num = dict["version_num"]
self.number = dict["exp"]
self.linenum = dict['linenum']
self.target = dict["targname"]
self.config = dict["config"]
self.opmode = dict["opmode"]
self.exptime = dict["exptime"]
self.apertures = [dict["ap_1"], dict["ap_2"],
dict["ap_3"], dict["ap_4"]]
self.spectral_elements = [dict["sp_1"], dict["sp_2"],
dict["sp_3"], dict["sp_4"]]

# Modify apertures and spectral_elements attributes based upon
# each particular instrument. Ignore all apertures/spec-els that
# are not needed by the report.
self.special_apertures_and_spectral_elements()
self.apertures = filter(lambda x:string.strip(x) != "", self.apertures)
self.spectral_elements = filter(lambda x:string.strip(x) != "",
self.spectral_elements)
self.qesiparms = {}
self.qexposure = {}


def __repr__(self):
return self.proposal_id + ":" + self.obset_id + ":" + self.alignment_id + ":" + self.exposure_id + ":" + self.version_num

def get_qexposure_data(self):
"""Add qexposure data to this object
"""
r = {}
if exposure.spss_db:
db = stpydb.stpydb(dbmsName=exposure.spss_db)
db.query('select * from qexposure')
db.query("where proposal_id = '%s'" % self.proposal_id)
db.query("and obset_id = '%s'" % self.obset_id)
db.query("and alignment_id = '%s'" % self.alignment_id)
db.query("and exposure_id = '%s'" % self.exposure_id)
while db.execute(r):
pass
self.qexposure = r
return r

def get_obsrec(self):
""" Retrieve the observation record for an exposure from SPST database.
Returns a 2-tuple:
tuple[0] is a TIME_UTIL.window object containing the estimated
time where the exposure will execute.
tuple[1] is a string containing the observation number.
If the observation record does not exist, both tuple elements
will be set None.
"""
if exposure.spss_db:
db_conn = stpydb.stpydb(dbmsName=exposure.spss_db)
db_query = "select qob.pred_strt_tm, qob.pred_stop_tm," + \
" qol.ob_number" + \
" from qolink qol, qobservation qob" + \
" where qol.proposal_id = '%s'" % self.proposal_id + \
" and qol.obset_id = '%s'" % self.obset_id + \
" and qol.alignment_id = '%s'" % self.alignment_id + \
" and qol.exposure_id = '%s'" % self.exposure_id + \
" and qol.version_num = '%s'" % self.version_num + \
" and qob.proposal_id = qol.proposal_id" + \
" and qob.obset_id = qol.obset_id" + \
" and qob.version_num = qol.version_num" + \
" and qob.ob_number = qol.ob_number" + \
" and qob.program_id = qol.program_id"
db_conn.query(db_query)
info = {}
if db_conn.execute(info) is not None:
db_conn.clear()
return (time_util.window(time_util.spss_time(info["pred_strt_tm"]),
time_util.spss_time(info["pred_stop_tm"])),
info["ob_number"])
return None, None


def get_qesiparms(self):
"""Return the qesiparm name/value pairs as a dictionary.
"""
if exposure.spss_db:
db_conn = stpydb.stpydb(dbmsName=exposure.spss_db)
db_conn.query("select si_par_name, si_par_value")
db_conn.query("from qesiparm")
db_conn.query("where proposal_id = '%s'" % self.proposal_id)
db_conn.query("and obset_id = '%s'" % self.obset_id)
db_conn.query("and alignment_id = '%s '" % self.alignment_id)
db_conn.query("and exposure_id = '%s'" % self.exposure_id)
db_conn.query("and version_num = '%s'" % self.version_num)
r = []
while db_conn.execute(r):
self.qesiparms[r[0]] = r[1]

return self.qesiparms


def special_apertures_and_spectral_elements(self):
""" Remove subset of apertures and spec-els depending on instrument.
No values are returned, but the lists represented by the apertures
and spectral_elements attributes of the object may be modified.
"""

# Modify the apertures and spectral_elements attributes based upon
# the instrument, which is contained within the first few characters
# of the exposure's configuration. When new instruments are
# added to the spacecraft, only this method needs to be modified.
if self.config[:4] == "WFPC":
if self.spectral_elements[2] == "NOCHANGE":
self.spectral_elements[2] = " "
elif self.config[:3] == "FGS":
if self.spectral_elements[0] == "NOCHANGE":
self.spectral_elements[0] = self.spectral_elements[1]
self.spectral_elements[1] = " "
elif self.config[:3] == "NIC":
if self.opmode in ["ACCUM", "ACQ", "BRTOBJ", "MULTI", "RAMP"]:
self.spectral_elements = [self.spectral_elements[0]]
elif self.config[:4] == "STIS":
self.apertures = [self.apertures[0]]
elif self.config == "COS/FUV":
self.spectral_elements = [self.spectral_elements[0]]
elif self.config == "COS/NUV":
self.spectral_elements = [self.spectral_elements[1]]

return


def print_otr(self, otr_type, su_info, prop_info):
""" Generate lines for exposure in POTR or Final OTR.
Returns string containing the lines to be appended to the OTR.
"""

# For final OTRs, check existence of observation records (obsrecs).
observation_window = None
observation_num = None
if (otr_type == "F"):
observation_window, observation_num = self.get_obsrec()

# If obsrecs are to be taken into account, the intersection of the
# obsrec windows and the SU's scheduled place should be reported.
# OBSR/GENERATE populates the end time of an observation record as
# the start time of the next observation record, which is inaccurate
# for the last exposure of an SU.
if observation_window is not None:
intersect_time = su_info.get('scheduled_time').intersection(observation_window)
if intersect_time:
begin_time = str(intersect_time.starttime())
end_time = str(intersect_time.endtime())
else:
begin_time = str(su_info.get('scheduled_time').starttime())
end_time = str(su_info.get('scheduled_time').endtime())
else:
begin_time = str(su_info.get('scheduled_time').starttime())
end_time = str(su_info.get('scheduled_time').endtime())

# Set up a template for the many fields that will appear in the report.
fields = 11 * [""] + [0.0] + 4 * [""]
line_format = "%-8s %-8s %-8s %-7s %-10s %-6s %-10s %-8s %-6s " + \
"%-12s %-12s %8.2f %-2s %-2s %-2s %-2s\n"

# Populate those fields.
pi_list = prop_info[self.proposal_id].get_pi()
if pi_list[0] is not None:
pi = pi_list[0][:10]
else:
pi = " - "

fields[0:9] = [begin_time[:8], begin_time[9:], end_time[9:],
su_info["sunit_id"][:7],
pi,
self.number[:6], self.target[:10], self.config[:8],
self.opmode[:6]]
if self.apertures != []:
fields[9] = self.apertures[0][:12]
if self.spectral_elements != []:
fields[10] = self.spectral_elements[0][:12]
fields[11:15] = [self.exptime, self.obset_id, self.alignment_id,
self.exposure_id]
if (otr_type == "F") and (observation_num is not None):
fields[15] = observation_num
return (line_format % tuple(fields)) + \
self.additional_ap_and_sp(82 * " " + "%-12s %-12s\n")


def additional_ap_and_sp(self, format_str):
""" Generate lines for the 2nd and subsequent apertures and spec-els.
Returns string containing the lines to be appended to the OTR.
"""

# Determine the maximum number of additional lines to be printed.
current_line = 0
out_string = ""
lines_per_exposure = max(len(self.apertures),
len(self.spectral_elements))

# For each addtional line, print only the aperture and/or spec-el.
while current_line < (lines_per_exposure - 1):
fields = ["", ""]
current_line = current_line + 1
if len(self.apertures) >= current_line + 1:
fields[0] = self.apertures[current_line][:12]
if len(self.spectral_elements) >= current_line + 1:
fields[1] = self.spectral_elements[current_line][:12]
out_string = out_string + (format_str % tuple(fields))
return out_string

def get_opmode(self):
return self.opmode

def get_config(self):
return self.config

def is_parallel(self):
parallel = False
if exposure.assist_db:
db_conn = stpydb.stpydb(dbmsName=exposure.assist_db)
db_conn.query("select special_requirement")
db_conn.query("from exposure_special_reqs")
db_conn.query("where prop_id=%s" % self.proposal_id)
db_conn.query("and line_num='%s'" % self.linenum)
info = []
while db_conn.execute(info):
if string.find(info[0], "PAR") != -1:
parallel = True
return parallel

def is_coronographic(self):
if exposure.assist_db:
db_conn = stpydb.stpydb(dbmsName=exposure.assist_db)
db_conn.query("select line_num")
db_conn.query("from exposure")
db_conn.query("where prop_id=%s" % self.proposal_id)
db_conn.query("and line_num='%s'" % self.linenum)
db_conn.query("and (ap like '%WEDGE%' or ap like '%OCCULT%' or ap like '%CORON%')")
info = []
while db_conn.execute(info):
pass
return db_conn.rowcount