Source code for exoctk.contam_visibility.f_visibilityPeriods

"""
Series of functions to compute the visibility periods for a given (RA,DEC)
with in some cases the possibility to select a PA value.

Functions derived from the code of Wayne Kinzel provided by Jeff Valenti
Extract from the e-mail of Wayne Kinzel:
As before, the code is not officially tested, nor is it an official STScI
product. Users should be warned that the apparent position of the Sun changes
~+/-0.2 degrees epending upon where JWST is in its orbit.
So do not rely strongly on these results if the target is within ~0.2 degrees
of |ecliptic latitude| 45 degrees or 85 degrees.
For example if a target is at 84.9 degrees latitude and the tool says it is
CVZ, it may not be with the operational orbit.
"""
import math

D2R = math.pi / 180.  # degrees to radians
R2D = 180. / math.pi  # radians to degrees
PI2 = 2. * math.pi  # 2 pi


[docs]def f_computeVisibilityPeriods(ephemeris, mjdmin, mjdmax, ra, dec): """Returns two lists containing the start end end of each visibility period and a list containing a status flag flag = 0 visibility period fully in the search interval flag = -1 start of the visibility period truncated by the start of the search interval flag = -2 end of the visibility period truncated by the end of the search interval flag = +1 the search interval is fully included in the visibility period Parameters ---------- ephemeris: Ephemeris The input ephemeris object. mjdmin: float The beginning of the search interval (modified Julian date). It must be covered by the ephemeris. mjdmax: float The end of the search interval (modified Julian date). It must be covered by the ephemeris. ra: float The input RA coordinate (equatorial coordinate, in rad). dec: float The input DEC coordinate (equatorial coordinate, in rad). Example ------- >>> f_computeVisibilityPeriods(ephemeris, mjdmin, mjdmax, ra, dec) Returns ------- tuple The lists of visibility period starts and ends with flags. """ if (ephemeris.amin > mjdmin): print("""f_computeVisibilityPeriods(): the start of the search\ interval is not covered by the ephemeris.""") print("""Ephemeris start date (modified Julian date):\ {:8.5f}""".format(ephemeris.amin)) print("""Search interval start date (modified Julian date):\ {:8.5f}""".format(mjdmin)) raise ValueError if (ephemeris.amax < mjdmax): print("""f_computeVisibilityPeriods(): the end of the search interval\ is not covered by the ephemeris.""") print("""Ephemeris end date (modified Julian date):\ {:8.5f}""".format(ephemeris.amax)) print("""Search interval end date (modified Julian date):\ {:8.5f}""".format(mjdmax)) raise ValueError # =========================================================== # Scanning the search period # =========================================================== # Flag used to track the beginning and the end of a visibility period iflip = False wstart = mjdmin startList = [] endList = [] statusList = [] # Scannning step size (must be small enough to make sure that # it cannot contain a full vsibility period (we would miss it) scanningStepSize = 0.1 span = int((mjdmax - mjdmin) / scanningStepSize) # Initialisation (first step of the scan is outside from the loop iflag_old = ephemeris.in_FOR(mjdmin, ra, dec) for i in range(span): # Current date (the last step may be partial to remain # within the search interval currentdate = mjdmin + (i + 1) * scanningStepSize if (currentdate >= mjdmax): currentdate = mjdmax iflag = ephemeris.in_FOR(currentdate, ra, dec) # Checking if we are reaching the beginning or the end of a # visibility period (in which case the iflag value will change) if iflag != iflag_old: # Setting the iflip flag to True to keep track of the change # (in order to detect CVZ object which are permanenetly visible) # If iflag = True we are starting a visibility period and use # a bisection method to find the exact transition date # This assumes that there is a single transition in the # interval => it looks like a step size of 0.1 day is # sufficient to ensure that. if (iflag): step = currentdate-scanningStepSize wstart = ephemeris.bisect_by_FOR(currentdate, step, ra, dec) # IF iflag = False we are reaching the end of a visibility period. # Like for the previous case a bisection method is used to locate # accurately the end of the visibility period. else: step = currentdate-scanningStepSize wend = ephemeris.bisect_by_FOR(step, currentdate, ra, dec) startList.append(wstart) endList.append(wend) if (iflip): statusList.append(0) else: statusList.append(-1) iflip = True iflag_old = iflag # If there was a transition and we end up with a valid date, we close the # interval with the end of the search interval if (iflag and iflip): startList.append(wstart) endList.append(currentdate) statusList.append(-2) # There is also the case were the visibility period covers the complete # search interval if (iflag and (not iflip)): startList.append(mjdmin) endList.append(mjdmax) statusList.append(1) # End of the function return startList, endList, statusList
[docs]def f_computeVisibilityPeriodsWithPA(ephemeris, mjdmin, mjdmax, ra, dec, pa): """Returns two lists containing the start end end of each visibility period and a list containing a status flag flag = 0 visibility period fully in the search interval flag = -1 start of the visibility period truncated by the start of the search interval flag = -2 end of the visibility period truncated by the end of the search interval flag = +1 the search interval is fully included in the visibility period Parameters ---------- ephemeris: Ephemeris The input ephemeris object. mjdmin: float The beginning of the search interval (modified Julian date). It must be covered by the ephemeris. mjdmax: float The end of the search interval (modified Julian date). It must be covered by the ephemeris. ra: float The input RA coordinate (equatorial coordinate, in rad). dec: float The input DEC coordinate (equatorial coordinate, in rad). pa: float The position angle. Example ------- >>> f_computeVisibilityPeriodsWithPA(ephemeris, mjdmin, mjdmax, ra, dec, pa) Returns ------- tuple The lists of visibility period starts and ends with flags """ if (ephemeris.amin > mjdmin): print("""f_computeVisibilityPeriodsWithPA(): the start of the search\ interval is not covered by the ephemeris.""") print("""Ephemeris start date (modified Julian date):\ {:8.5f}""".format(ephemeris.amin)) print("""Search interval start date (modified Julian date):\ {:8.5f}""".format(mjdmin)) raise ValueError if (ephemeris.amax < mjdmax): print("""f_computeVisibilityPeriodsWithPA(): the end of the search\ interval is not covered by the ephemeris.""") print("""Ephemeris end date (modified Julian date):\ {:8.5f}""".format(ephemeris.amax)) print("""Search interval end date (modified Julian date):\ {:8.5f}""".format(mjdmax)) raise ValueError # =========================================================== # Scanning the search period # =========================================================== # Flag used to track the beginning and the end of a # visibility period iflip = False wstart = mjdmin startList = [] endList = [] statusList = [] # Scannning step size (must be small enough to make sure that # it cannot contain a full vsibility period (we would miss # it) scanningStepSize = 0.1 span = int((mjdmax - mjdmin) / scanningStepSize) # Initialisation (first step of the scan is outside from the # loop iflag_old = ephemeris.is_valid(mjdmin, ra, dec, pa) for i in range(span): # Current date (the last step may be partial to remain # within the search interval currentdate = mjdmin + (i + 1) * scanningStepSize if (currentdate >= mjdmax): currentdate = mjdmax iflag = ephemeris.is_valid(currentdate, ra, dec, pa) # Checking if we are reaching the beginning or the end of a # visibility period # (in which case the iflag value will change) if iflag != iflag_old: # Setting the iflip flag to True to keep track of the change # (in order to # detect CVZ object which are permanenetly visible) # If iflag = True we are starting a visibility period and use # a bisection method # to find the exact transition date. This assumes that there # is a single # transition in the interval => it looks like a step size of # 0.1 day is # sufficient to ensure that. if (iflag): step = currentdate-scanningStepSize wstart = ephemeris.bisect_by_attitude(currentdate, step, ra, dec, pa) # IF iflag = False we are reaching the end of a visibility period. # Like for the previous case a bisection method is used to locate # accurately the end of the visibility period. else: step = currentdate-scanningStepSize wend = ephemeris.bisect_by_attitude(step, currentdate, ra, dec, pa) startList.append(wstart) endList.append(wend) if (iflip): statusList.append(0) else: statusList.append(-1) iflip = True iflag_old = iflag # If there was a transition and we end up with a valid date, we close # the interval with the end of the search interval if (iflag and iflip): startList.append(wstart) endList.append(currentdate) statusList.append(-2) # There is also the case were the visibility period covers the # complete search interval if (iflag and (not iflip)): startList.append(mjdmin) endList.append(mjdmax) statusList.append(1) # End of the function return startList, endList, statusList
[docs]def f_computeDurationOfVisibilityPeriodWithPA(ephemeris, mjdmin, mjdmax, ra, dec, pa, mjdc): """Computes the duration of a specific visibility period associated to a given (RA,DEC), a given PA and given date flag = 0 visibility period fully in the search interval flag = -1 start of the visibility period truncated by the start of the search interval flag = -2 end of the visibility period truncated by the end of the search interval flag = +1 the search interval is fully included in the visibility period Parameters ---------- ephemeris: Ephemeris The input ephemeris object. mjdmin: float The beginning of the search interval (modified Julian date). It must be covered by the ephemeris. mjdmax: float The end of the search interval (modified Julian date). It must be covered by the ephemeris. ra: float The input RA coordinate (equatorial coordinate, in rad). dec: float The input DEC coordinate (equatorial coordinate, in rad). pa: float The position angle. Example ------- >>> f_computeDurationOfVisibilityPeriodWithPA(ephemeris, mjdmin, mjdmax, ra, dec, pa, mjdc) Returns ------- tuple The lists of visibility period starts and ends with flags. """ if (ephemeris.amin > mjdmin): print("""f_computeDurationOfVisibilityPeriodWithPA(): the start of\ thesearch interval is not covered by the ephemeris.""") print("""Ephemeris start date (modified Julian date):\ {:8.5f}""".format(ephemeris.amin)) print("""Search interval start date (modified Julian date):\ {:8.5f}""".format(mjdmin)) raise ValueError if (ephemeris.amax < mjdmax): print("""f_computeDurationOfVisibilityPeriodWithPA(): the end of the\ search interval is not covered by the ephemeris.""") print("""Ephemeris end date (modified Julian date):\ {:8.5f}""".format(ephemeris.amax)) print("""Search interval end date (modified Julian date):\ {:8.5f}""".format(mjdmax)) raise ValueError if (mjdmin > mjdc): print("""f_computeDurationOfVisibilityPeriodWithPA():\ initial date is not included in the search interval.""") print("""Search interval start date (modified Julian date):\ {:8.5f}""".format(mjdmin)) print("Initial date (modified Julian date): {:8.5f}".format(mjdc)) raise ValueError if (mjdmax < mjdc): print("""f_computeDurationOfVisibilityPeriodWithPA(): initial date is\ not included in the search interval.""") print("""Search interval end date (modified Julian date):\ {:8.5f}""".format(mjdmax)) print("Initial date (modified Julian date): {:8.5f}".format(mjdc)) raise ValueError iflag = ephemeris.is_valid(mjdc, ra, dec, pa) if (not iflag): print("""f_computeDurationOfVisibilityPeriodWithPA(): invalid date\ (not in a vsibility period).""") print("Date (modified Julian date): {:8.5f}".format(mjdc)) raise ValueError # =========================================================== # Looking for the start of the visibility period # =========================================================== scanningStepSize = 0.1 iflipLeft = False currentmjd = mjdc continueFlag = True boundaryFlag = False while (continueFlag): currentmjd -= scanningStepSize if (currentmjd < mjdmin): currentmjd = mjdmin boundaryFlag = True continueFlag = False iflag = ephemeris.is_valid(currentmjd, ra, dec, pa) if (not iflag): wstart = ephemeris.bisect_by_attitude(currentmjd, currentmjd+scanningStepSize, ra, dec, pa) iflipLeft = True continueFlag = False elif (boundaryFlag): wstart = mjdmin iflipRight = False currentmjd = mjdc boundaryFlag = False continueFlag = True while (continueFlag): currentmjd += scanningStepSize if (currentmjd > mjdmax): currentmjd = mjdmax boundaryFlag = True continueFlag = False iflag = ephemeris.is_valid(currentmjd, ra, dec, pa) if (not iflag): wend = ephemeris.bisect_by_attitude(currentmjd-scanningStepSize, currentmjd, ra, dec, pa) iflipRight = True continueFlag = False elif (boundaryFlag): wend = mjdmax if ((not iflipLeft) and (not iflipRight)): status = 1 elif (not iflipLeft): status = -1 elif (not iflipRight): status = -2 else: status = 0 # End of the function return wstart, wend, status