예제 #1
0
def geochk(j_scan, scan_index, start_time, end_time):
    ok_geo = np.empty(shape=s.schsou.geosrci.shape, dtype=bool)
    use_geo = np.empty(shape=s.schsou.geosrci.shape, dtype=int)

    scans = scan_catalog.direct_access_entries
    stations = station_catalog.used(use_direct_access=True)
    sources = source_catalog.entries

    seg_elevation = np.empty(dtype=float, shape=(len(stations), s.schsou.ngeo))

    use_time = True
    last_scan_index = np.zeros(shape=(StationCatalog.maxsta, ))
    approx_time = (start_time + end_time) / 2
    n_reject = 0

    if len(stations) > 20:
        s.wlog(1, "GEOCHK:  Printing only first 20 stations information")
        ms_print = 20
    else:
        ms_print = len(stations)

    s.wlog(1, "             --------------------- ")
    year, day, time_rad = s.timej(approx_time)
    c_time = f2str(s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
    s.wlog(
        1, "Building geodetic segment centered at {} {} {}".format(
            year, day, c_time))
    s.wlog(
        1, "   Using GEOPRT={:>4}     GEOTRIES={:>4}    GEOBACK={:>3}     "
        "GEOSREP={:>3}".format(s.schsou.geoprt, s.schsou.geotries,
                               s.schsou.geoback, s.schsou.geosrep))
    s.wlog(
        1, "         GEOSLEW={:>6.2f}  GEOSLOW={:>7.1f}  GELOWEL={:>6.2f}  "
        "GEOHIEL={:>6.2f}".format(s.schsou.geoslew, s.schsou.geoslow,
                                  s.schsou.geolowel, s.schsou.geohiel))
    s.wlog(1, "         See sched.runlog for details of the build process.")

    if s.schsou.geoprt >= 0:
        s.wlog(
            0, "       Note in fit, SecZ < 4 treated as 4 to avoid favoring "
            "extreme low elevations.")
        s.wlog(0, "Elevations at center for sources considered are: ")
        s.wlog(
            0, "                  Prio " + "   ".join(s.stcode
                                                      for s in stations[:20]))

    elevation_tolerance = 0

    sun_coord = SkyCoord(*s.sunpos(approx_time), unit="rad")
    t_freq = sf_catalog.entries[scans[j_scan - 1].setnum - 1].sffreq[0] / 1000
    required_separation = 60 * (t_freq**-0.6)

    for geo_index in range(s.schsou.ngeo):
        l_scan = scan_index + 1
        n_good = makescn(last_scan_index, l_scan, j_scan,
                         s.schsou.geosrci[geo_index],
                         f2str(s.schcsc.geosrc[geo_index]), approx_time,
                         scans[j_scan - 1].opminel - elevation_tolerance,
                         use_time)

        for i, station in enumerate(stations):
            seg_elevation[i, geo_index] = (station.el1[l_scan - 1] +
                                           station.el2[l_scan - 1]) / 2

        ok_geo[geo_index] = (n_good >= scans[j_scan - 1].opmian)

        source = sources[s.schsou.geosrci[geo_index] - 1]
        source_coord = SkyCoord(source.rap, source.decp, unit="rad")
        source_separation = sun_coord.separation(source_coord).deg

        ok_geo[geo_index] = ok_geo[geo_index] and \
                            (source_separation > required_separation)

        if not ok_geo[geo_index]:
            n_reject += 1
            use_geo[geo_index] = 9

        if ok_geo[geo_index]:
            use_geo[geo_index] = 5
            for i, station in enumerate(stations):
                if station.stascn[l_scan - 1]:
                    if (seg_elevation[i, geo_index] <= s.schsou.geolowel + 10):
                        use_geo[geo_index] = 4
            for i, station in enumerate(stations):
                if station.stascn[l_scan - 1]:
                    if (seg_elevation[i, geo_index] <= s.schsou.geolowel):
                        use_geo[geo_index] = 3

            n_low = 0
            n_high = 0
            for i, station in enumerate(stations):
                if station.stascn[l_scan - 1] and \
                   (seg_elevation[i, geo_index] >
                    (scans[j_scan - 1].opminel - elevation_tolerance)) and \
                   (seg_elevation[i, geo_index] <= s.schsou.geolowel):
                    n_low += 1
                if station.stascn[l_scan - 1] and \
                   (seg_elevation[i, geo_index] >= s.schsou.geohiel):
                    n_high += 1

            if ((n_low >= 1) and (n_high >= 3)) or (n_low >= 3):
                use_geo[geo_index] = 2
            if (n_low >= 2) and (n_high >= 2):
                use_geo[geo_index] = 1

        if s.schsou.geoprt >= 0:
            msg = "{:>5d} {:<8} {:>5d}".format(
                geo_index + 1, f2str(s.schcsc.geosrc[geo_index]),
                use_geo[geo_index])
            msg += "".join(
                "{:5.0f}".format(el) if el > (scans[l_scan - 1].opminel -
                                              elevation_tolerance) else "   --"
                for el in seg_elevation[:, geo_index])
            if source_separation <= required_separation:
                msg += "   Too near sun: {:5.0f} deg.".format(
                    source_separation)
            s.wlog(0, msg)

    if n_reject == s.schsou.ngeo:
        s.errlog("GEOCHK:  None of the sources specified for a geodetic "
                 "segment are up at OPMINANT antennas.")

    return ok_geo, use_geo, seg_elevation
예제 #2
0
def addpeak(last_scan_index, scans, stations, setups, peak_groups, peak_opt,
            insert_adjust, scan_index):
    if s.schcon.debug:
        s.wlog(0, "ADDPEAK starting")

    scan = scans[scan_index - 1]

    if (not s.schcon.autopeak) or ((scan.point >= -1) and (peak_opt == 0)):
        return peak_opt, insert_adjust

    assert(s.schpeakn.npkgrp > 0), "ADDPEAK: Want automatic pointing, but "\
        "there are no groups"

    t_gap = np.empty(dtype=float, shape=(len(stations), ))
    try_group = np.full(fill_value=False, shape=(len(peak_groups), ))
    try_group2 = np.full(fill_value=False, shape=(len(peak_groups), ))
    # last_*_scan objects are passed to FORTRAN, so require a fixed size,
    # only len(stations) is actually used
    last_target_scan = np.empty(dtype=int, shape=(StationCatalog.maxsta, ))
    last_pointing_scan = np.empty(dtype=int, shape=(StationCatalog.maxsta, ))
    sr_ok = np.empty(dtype=bool, shape=(s.schpeakn.pksrnum.shape[0], ))
    sr_ok2 = np.empty(dtype=bool, shape=(s.schpeakn.pksrnum.shape[0], ))
    slew_max = np.empty(dtype=float, shape=(s.schpeakn.pksrnum.shape[0], ))
    slew_min = np.empty(dtype=float, shape=(s.schpeakn.pksrnum.shape[0], ))
    if peak_opt == 0:
        if s.schcon.pkwatch:
            s.wlog(0, " ")
            year, day1, start = s.timej(scan.startj)
            stime = f2str(s.tformwrp(start, "T", 0, 2, 2, "::@"))
            s.wlog(
                0, "ADDPEAK: Trying to add pointing scan for target scan "
                "{} {} {}".format(scan_index, scan.scnsrc, stime))

        try_group = np.full(shape=(s.schpeakn.npkgrp, ), fill_value=False)
        try_group2 = np.full(shape=(s.schpeakn.npkgrp, ), fill_value=False)
        n_up = np.full(shape=(s.schpeakn.npkgrp, ), fill_value=0)
        m_settle = np.full(shape=(s.schpeakn.npkgrp, ), fill_value=0.0)

        n_good = 0
        for station in stations:
            group_index = station.pkgroup
            if station.stascn[scan_index - 1] and (group_index != 0) and \
               ((f2str(station.up1[scan_index - 1]) == "") or
                (f2str(station.up2[scan_index - 1]) == "")):
                n_good += 1
                n_up[group_index - 1] += 1

        if n_good == 0:
            if s.schcon.pkwatch:
                s.wlog(
                    0, "ADDPEAK:  Source down or below OPMINEL at all "
                    "stations.")
            return peak_opt, insert_adjust

        for station_index, station in enumerate(stations):
            if station.stascn[scan_index - 1] and (station.pkgroup > 0):
                setup = setups[station.nsetup[scan_index - 1] - 1]
                group_index = station.pkgroup
                freq_test = setup.freqref[0]
                peak_group = peak_groups[group_index - 1]
                if (peak_group.pkminfq < freq_test):
                    if (last_scan_index[station_index] != 0):
                        last_scan = scans[last_scan_index[station_index] - 1]
                        t_gap[station_index] = scan.startj - last_scan.stopj
                        lastptg = (last_scan.point in {0, group_index}) and \
                                  (t_gap[station_index] < 600. / secpday)
                        if (not lastptg) and (n_up[group_index - 1] > 0):
                            if t_gap[station_index] > peak_group.pkdwell:
                                try_group[group_index - 1] = True
                            if t_gap[station_index] > 2 * peak_group.pkdwell:
                                try_group2[group_index - 1] = True
                    else:
                        t_gap[station_index] = 10000
                        try_group[group_index - 1] = n_up[group_index - 1] > 0
                        try_group2[group_index - 1] = n_up[group_index - 1] > 0

            last_target_scan[station_index] = last_scan_index[station_index]
            last_pointing_scan[station_index] = last_scan_index[station_index]

        n_try = np.count_nonzero(try_group) + np.count_nonzero(try_group2)

        if s.schcon.pkwatch:
            if n_try >= 1:
                for group_index, peak_group in enumerate(peak_groups):
                    if try_group2[group_index]:
                        s.wlog(
                            0, "ADDPEAK: Pointing group {}:  Will try to "
                            "add double pointing scans.".format(group_index +
                                                                1))
                    elif try_group[group_index]:
                        s.wlog(
                            0, "ADDPEAK: Pointing group {}:  Will try to "
                            "add one pointing scan.".format(group_index + 1))
                    else:
                        if n_up[group_index - 1] > 0:
                            s.wlog(
                                0, "ADDPEAK: Pointing group {}:  No "
                                "stations up in scan.".format(group_index + 1))
                        else:
                            s.wlog(
                                0, "ADDPEAK: Pointing group {}:  Gap too "
                                "short to add pointing scans.".format(
                                    group_index + 1))
            else:
                s.wlog(
                    0, "ADDPEAK: Insufficient time to add pointing or "
                    "last scan was pointing.")

        if n_try == 0:
            return peak_opt, insert_adjust

        keep_origen = scan.origen
        scan.origen = 4
        for k_scan in range(scan_index, scan_index + n_try):
            scndup(k_scan, scan_index - 1, True, "ADDPEAK")

        n_added = 0
        m_scan = scan_index + n_try
        for group_index, peak_group in enumerate(peak_groups, 1):
            if try_group[group_index - 1]:
                if s.schcon.pkwatch:
                    s.wlog(
                        0, "ADDPEAK:  Working on pointing group {}".format(
                            group_index))
                    tab_head = True

                k_scan = scan_index + n_added
                got_station = False
                for station in stations:
                    station.stascn[k_scan - 1] = \
                        station.stascn[m_scan - 1] and \
                        (station.pkgroup == group_index) and \
                        ((f2str(station.up1[m_scan - 1]) == "") or
                         (f2str(station.up2[m_scan - 1]) == ""))
                    if station.stascn[k_scan - 1]:
                        got_station = True

                if got_station:
                    for p_src in range(1, peak_group.npksrc + 1):
                        stop_k = scans[m_scan - 1].startj - 20.0 * onesec
                        start_k = stop_k - peak_group.pkdwell
                        k_src = peak_group.pksrnum[p_src - 1]
                        s.srinsert(k_scan, k_src, peak_group.pksrc[p_src - 1],
                                   start_k, stop_k, last_scan_index, m_scan)

                        sr_ok[p_src - 1] = True
                        sr_ok2[p_src - 1] = True
                        watch_it = False
                        min_el = 100
                        max_el = 0
                        min_slew = 1000
                        max_slew = 0
                        min_tot = 10000
                        for station in stations:
                            if station.stascn[k_scan - 1] and \
                               (station.el1[k_scan - 1] < peak_group.pkminel):
                                sr_ok[p_src - 1] = False
                                sr_ok2[p_src - 1] = False

                            if s.schcon.pkwatch:
                                if station.stascn[k_scan - 1] and \
                                   (f2str(station.up1[k_scan - 1]) == "") and \
                                   (f2str(station.up2[k_scan - 1]) == ""):
                                    watch_it = True

                                if station.stascn[k_scan - 1]:
                                    min_el = min(min_el,
                                                 station.el1[k_scan - 1])
                                    max_el = max(max_el,
                                                 station.el1[k_scan - 1])
                                    min_slew = min(
                                        min_slew,
                                        station.tslew[m_scan - 1] * secpday)
                                    max_slew = max(
                                        max_slew,
                                        station.tslew[m_scan - 1] * secpday)

                        if sr_ok[p_src - 1]:
                            for station_index, station in enumerate(stations):
                                if station.stascn[k_scan - 1]:
                                    tot_time = peak_group.pkdwell + \
                                        station.tslew[k_scan - 1] + \
                                        station.tslew[m_scan - 1]
                                    if t_gap[station_index] < tot_time:
                                        sr_ok[p_src - 1] = False
                                    min_tot = min(min_tot, tot_time * secpday)

                                    tot_time2 = 2 * peak_group.pkdwell + \
                                                station.tslew[k_scan - 1] + \
                                                station.tslew[m_scan - 1] + \
                                                station.tsettle / secpday
                                    if t_gap[station_index] < tot_time2:
                                        sr_ok2[p_src - 1] = False

                                    m_settle[group_index - 1] = \
                                        max(m_settle[group_index - 1],
                                            station.tsettle)

                        slew_max[p_src - 1] = 0
                        if sr_ok[p_src - 1]:
                            for station in stations:
                                if station.stascn[k_scan - 1]:
                                    slew_max[p_src - 1] = max(
                                        slew_max[p_src - 1],
                                        station.tslew[m_scan - 1])

                        if s.schcon.pkwatch and watch_it:
                            if tab_head:
                                s.wlog(
                                    0, " Num   Source      Slew times (sec) "
                                    "Elevations (deg)  Scans OK  Min T")
                                tab_head = False

                            s.wlog(
                                0, "{:>6} {:<12}"
                                "{:>6.0f} to {:<6.0f} "
                                "{:>6.0f} to {:<6.0f}"
                                "    {} {}   {:>7.0f}".format(
                                    p_src, peak_group.pksrc[p_src - 1],
                                    min_slew, max_slew, min_el, max_el,
                                    bool2str(sr_ok[p_src - 1]),
                                    bool2str(sr_ok2[p_src - 1]),
                                    float(min_tot)))

                    use_p_src = 0
                    slew_min = 1
                    for p_src in range(1, peak_group.npksrc + 1):
                        if sr_ok[p_src - 1]:
                            if (0 < slew_max[p_src - 1] < slew_min):
                                slew_min = slew_max[p_src - 1]
                                use_p_src = p_src

                    if use_p_src != 0:
                        p_src = use_p_src
                        k_src = peak_group.pksrnum[p_src - 1]

                        add2 = try_group2[group_index - 1] and sr_ok2[p_src -
                                                                      1]

                        j_scan = k_scan
                        ok_scan = 0
                        stop_k = scans[m_scan - 1].startj - slew_min
                        start_k = stop_k - peak_group.pkdwell

                        if add2:
                            n_added += 2
                            ok_scan = 2

                            stop2 = start_k - m_settle[group_index -
                                                       1] / secpday
                            start2 = stop2 - peak_group.pkdwell

                            s.srinsert(k_scan, k_src,
                                       peak_group.pksrc[p_src - 1], start2,
                                       stop2, last_scan_index, m_scan)
                            scans[k_scan - 1].point = group_index

                            j_scan = k_scan + 1
                            for station_index, station in enumerate(stations):
                                if station.stascn[k_scan - 1]:
                                    last_pointing_scan[station_index] = j_scan

                        else:
                            j_scan = k_scan
                            n_added += 1
                            ok_scan = 1

                        s.srinsert(j_scan, k_src, peak_group.pksrc[p_src - 1],
                                   start_k, stop_k, last_pointing_scan, m_scan)
                        scans[j_scan - 1].point = group_index

                        if s.schcon.pkwatch:
                            s.wlog(
                                0, "ADDPEAK: Adding {} scan(s) on {} for "
                                "pointing group {}".format(
                                    ok_scan, peak_group.pksrc[p_src - 1],
                                    group_index))

                        for station_index, station in enumerate(stations):
                            if station.stascn[j_scan - 1]:
                                last_target_scan[station_index] = j_scan

                    else:
                        if s.schcon.pkwatch:
                            s.wlog(
                                0, "ADDPEAK: No pointing sources available "
                                "for pointing group {}".format(group_index))

                else:
                    if s.schcon.pkwatch:
                        s.wlog(
                            0, "ADDPEAK:  No stations for group {} in this "
                            "scan. ".format(group_index))

            # end of if try_group[group_index]
        # end of loop of peak groups

        k_scan = scan_index + n_added
        if k_scan != m_scan:
            scndup(k_scan - 1, m_scan - 1, True, "ADDPEAK2")
        scans[k_scan - 1].origen = keep_origen

        n_good = s.scngeo(last_target_scan, k_scan)
        scans[k_scan - 1].point = -999

        if n_added > 0:
            peak_opt = n_added
        else:
            peak_opt = 0

    else:  # peak_opt != 0
        if peak_opt > 0:
            peak_opt -= 1

    if peak_opt >= 1:
        insert_adjust = False

    return peak_opt, insert_adjust
예제 #3
0
def optcells(last_scan_index, k_scan, scan_index):
    global cell_time, last_j_scan, weight_station

    if s.schcon.debug:
        s.wlog(1, "Starting OPTCELLS")

    done = False
    keep = True
    adjust = True

    stations = StationCatalog().used(use_direct_access=True)
    scans = ScanCatalog().direct_access_entries

    if k_scan == 1:
        if s.schn1.nscans > max_input_scans:
            s.errlog(" OPTCELLS:  Too many input scans for cell optimizer "
                     "- max: {}".format(max_input_scans))

        if s.schcon.opdur <= 0:
            s.errlog(" OPTCELLS: For OPTMODE=CELLS, OPDUR must be given.")

        adjust = False
        scans[scan_index - 1].startj = scans[0].startj
        approx_time = scans[scan_index - 1].startj
        last_j_scan = 0

        cell_time.fill(scans[0].startj - 0.5 / 24)
        baseline = np.zeros(dtype=float, shape=(len(stations), len(stations)))
        for (i, station1), (j, station2) in itertools.combinations(
                enumerate(stations), 2):
            baseline[i, j] = math.sqrt((station1.xpos - station2.xpos)**2 +
                                       (station1.ypos - station2.ypos)**2 +
                                       (station1.zpos - station2.zpos)**2)
        baseline += baseline.T
        mean_base = np.sum(baseline) / (len(stations) * (len(stations) - 1))
        weight_station = np.square(
            np.sum(baseline, axis=1) / ((len(stations) - 1) * mean_base))
    else:
        approx_time = scans[scan_index - 2].stopj

    got_station = np.zeros(dtype=int, shape=(s.schn1.nscans, ))
    ok_station = np.full(fill_value=False,
                         dtype=bool,
                         shape=(s.schn1.nscans, len(stations)))
    el_cell_index = np.empty(dtype=int, shape=(s.schn1.nscans, len(stations)))
    az_cell_index = np.empty(dtype=int, shape=(s.schn1.nscans, len(stations)))
    time_source = np.empty(dtype=float, shape=(s.schn1.nscans, ))
    points = np.zeros(dtype=float, shape=(s.schn1.nscans, ))
    for j_scan, scan in enumerate(scans[:s.schn1.nscans]):
        if j_scan + 1 != last_j_scan:
            for i, station in enumerate(stations):
                if station.stascn[j_scan]:
                    last_time, station.tonsrc[j_scan] = s.stageo(
                        j_scan + 1, i + 1, approx_time, last_scan_index[i],
                        "OPTCELLS")
                    if (f2str(station.up1[j_scan]) == "") and \
                       (f2str(station.up2[j_scan]) == "") and \
                       (station.el1[j_scan] > scan.opminel) and \
                       (station.el2[j_scan] > scan.opminel):
                        ok_station[j_scan, i] = True
                        got_station[j_scan] += 1

                        az_test = (station.az1[j_scan] + az_coff) % 360

                        if station.el1[j_scan] < el_cell[0]:
                            el_cell_index[j_scan, i] = 1
                        elif station.el1[j_scan] < el_cell[1]:
                            el_cell_index[j_scan, i] = 2
                        else:
                            el_cell_index[j_scan, i] = 3

                        if el_cell_index[j_scan, i] == 3:
                            az_cell_index[j_scan, i] = 1
                        else:
                            if az_test < az_cell[0]:
                                az_cell_index[j_scan, i] = 1
                            elif az_test < az_cell[1]:
                                az_cell_index[j_scan, i] = 2
                            else:
                                az_cell_index[j_scan, i] = 3

            time_source[j_scan] = 1e10
            all_0 = True
            for i, station in enumerate(stations):
                if ok_station[j_scan, i] and (last_scan_index[i] != 0):
                    all_0 = False
                    time_source[j_scan] = min(time_source[j_scan],
                                              station.tonsrc[j_scan])
                    if s.schcon.opnosub and (scan_index > s.schn1.scan1):
                        time_source[j_scan] = max(time_source[j_scan],
                                                  scans[scan_index - 2].stopj)
            if all_0:
                time_source[j_scan] = scans[0].startj

            if got_station[j_scan] >= scan.opmian:
                for i, station in enumerate(stations):
                    if ok_station[j_scan, i]:
                        eci = el_cell_index[j_scan, i]
                        aci = az_cell_index[j_scan, i]

                        weight_multiplier = 1
                        if eci == 1:
                            for iaz in range(1, 4):
                                if iaz != aci:
                                    pt_add = 1440 * \
                                             (time_source[j_scan] -
                                              cell_time[eci - 1, iaz - 1, i])
                                    weight_multiplier += pt_add ** 2 / \
                                        (s.schcon.optlowt ** 2 + pt_add ** 2)

                        lc_time = cell_time[eci - 1, aci - 1, i]

                        pt_add = 1440 * (time_source[j_scan] - lc_time)
                        points[j_scan] += weight_station[i] * pt_add * \
                                          weight_multiplier

    max_points = np.max(points)

    time1 = 1e10
    for j_scan, scan in enumerate(scans[:s.schn1.nscans]):
        if got_station[j_scan] >= scan.opmian:
            time1 = min(time1, time_source[j_scan])

    for j_scan, scan in enumerate(scans[:s.schn1.nscans]):
        if got_station[j_scan] >= scan.opmian:
            sl_adj = 1440 * (time_source[j_scan] - time1)
            weight_multiplier = s.schcon.optslew**2 / (sl_adj**2 +
                                                       s.schcon.optslew**2)
            points *= weight_multiplier

    look_back = 6
    station_skip = np.zeros(dtype=int, shape=(len(stations), ))
    if scan_index > s.schn1.scan1 + 2:
        i_skip1 = max(scan_index - look_back, s.schn1.scan1)
        for l, l_scan in enumerate(scans[i_skip1 - 1:scan_index - 1]):
            for i, station in enumerate(stations):
                if not (station.stascn[l] and
                        (station.el1[l] > l_scan.opminel)):
                    station_skip[i] += 1

    for j, scan in enumerate(scans[:s.schn1.nscans]):
        max_skip = 0
        for i, station in enumerate(stations):
            if not (station.stascn[j_scan] and
                    (station.el1[j_scan] > scan.opminel)):
                max_skip = max(max_skip, station_skip[i])

        if max_skip > look_back // 3:
            points[j_scan] *= 0.2

    max_scan = np.argmax(points)
    max_apt = points[max_scan]
    if max_apt > -1e10:
        j_scan = max_scan + 1
    else:
        s.errlog("OPTCELLS: Something weird went wrong with POINTS.")

    scndup(scan_index - 1, j_scan - 1, False, "OPTCELLS")
    scan = scans[scan_index - 1]
    scan.startj = time_source[j_scan - 1]
    scan.stopj = scan.startj + scan.dur

    last_j_scan = j_scan

    year, day, time_rad = s.timej(scan.startj)
    time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
    s.wlog(
        0, " Source, time, maxpts, maxapt: {:<12} {:>4d} {} "
        "{:>9.3f} {:>9.3f}".format(scan.scnsrc, day, time_text, max_points,
                                   max_apt))

    for i, station in enumerate(stations):
        if ok_station[j_scan - 1, i]:
            cell_time[el_cell_index[j_scan - 1, i] - 1,
                      az_cell_index[j_scan - 1, i] - 1, i] = scan.startj
            station.stascn[scan_index - 1] = True
        else:
            station.stascn[scan_index - 1] = False

    return adjust, keep, done
예제 #4
0
def opthas(last_scan_index, k_scan, scan_index):
    global n_out, scan_used, dur_total, ref_station_index, \
        ha_min, ha_max, ha_begin, ha_end, t_ha_min, t_ha_max, t_use, t_avail, \
        source_used, source_look, \
        skip_time, skip_inc, n_skip, sd_total, \
        op_ha_t, op_ha_wid_t

    scans = scan_catalog.direct_access_entries
    stations = station_catalog.used(use_direct_access=True)

    if k_scan == 1:
        # initialize for multiple calls to this function
        n_out = 0
        skip_time = 0
        n_skip = 0
        skip_inc = 5 * 60 / secpday
        if s.schn1.nscans > max_ins:
            s.errlog(
                "OPHAS: Too many requested scans for OPTMODE=HAS.  Max: {} "
                "Requested: {}".format(max_ins, s.schn1.nscans))
        if s.schcon.opdur <= 0:
            s.errlog("OPHAS: Please specify OPDUR for OPTMODE=HAS")

        min_duration = min(scan.dur for scan in scans[:s.schn1.nscans])
        if (s.schcon.opdur * sidereal - min_duration) > 1:
            s.errlog("OPHAS: OPTMODE=HAS not meant for observations over "
                     "24 hours sidereal + min scan dur.")

        ht_stop = scans[0].startj + s.schcon.opdur

        _, ref_station_index, _ = s.stano(f2str(s.schsco.ophasta))
        source_catalog = SourceCatalog()
        source_used = np.zeros(shape=(len(source_catalog.entries), ),
                               dtype=int)
        source_look = np.zeros(shape=(s.schn1.nscans, ), dtype=int)
        dur_total = 0
        sd_total = 0
        for i, scan in enumerate(scans[:s.schn1.nscans]):
            source_index = scan.srcnum
            source_used[source_index - 1] += 1
            source_look[i] = source_used[source_index - 1]
            scan_used[i] = 0
            dur_total += scan.dur

        if dur_total > s.schcon.opdur:
            s.wlog(
                1, "OPTHAS: ** The total time in requested scans of "
                "{} hours".format(dur_total * 24))
            s.wlog(
                1, "           exceeds the experiment duration (OPDUR) of "
                "{} hours.".format(s.schcon.opdur * 24))
            s.wlog(1, "           Not all scans can be scheduled.")

        ref_station = stations[ref_station_index - 1]
        for j_scan, scan in enumerate(scans[:s.schn1.nscans]):
            ha_min[j_scan], ha_max[j_scan], t_ha_min[j_scan], t_ha_max[j_scan] \
                = s.halim(j_scan + 1, ref_station_index)

            ref_station.ha1[j_scan], ref_station.el1[j_scan], \
                ref_station.az1[j_scan], ref_station.lst1[j_scan], \
                ref_station.pa1[j_scan] = s.schgeo(
                    j_scan + 1, ref_station_index, scans[0].startj)
            ref_station.ha2[j_scan], ref_station.el2[j_scan], \
                ref_station.az2[j_scan], ref_station.lst2[j_scan], \
                ref_station.pa2[j_scan] = s.schgeo(
                    j_scan + 1, ref_station_index, ht_stop - scan.dur)

            ha_begin[j_scan] = ref_station.ha1[j_scan]
            ha_end[j_scan] = ref_station.ha2[j_scan]

            t_avail[j_scan], t_use[j_scan] = s.haavai(
                t_ha_min[j_scan], t_ha_max[j_scan], scans[0].startj,
                ht_stop - scan.dur, source_used[scan.srcnum - 1],
                source_look[j_scan])

            if t_avail[j_scan] == -1:
                s.wlog(1, " ")
                s.wlog(
                    1, " ****** {} is never above OPMINEL and the horizon at "
                    "OPMINANT stations at once.".format(scan.scnsrc))
                s.errlog("Leave out the source or change OPMINANT or OPMINEL")

            if scan.opha == 0:
                op_ha_t[j_scan] = t_use[j_scan]
            else:
                op_ha_t[j_scan] = (scan.opha - ha_begin[j_scan]) \
                                  / sidereal + scans[0].startj
                if op_ha_t[j_scan] < scans[0].startj:
                    op_ha_t[j_scan] += 24 / sidereal
                    if op_ha_t[j_scan] > scans[0].startj + s.schcon.opdur:
                        s.wlog(
                            1, "OPHAS: Requested hour angle outside range: "
                            "scan, source, OPHA: {} {} {}".format(
                                j_scan + 1, scan.scnsrc, scan.opha))

            if scan.ophawid == 0:
                op_ha_wid_t[j_scan] = 0.7 * t_avail[j_scan] \
                                      / source_used[scan.srcnum - 1]
            else:
                op_ha_wid_t[j_scan] = scan.ophawid / secpday
    else:
        ref_station = stations[ref_station_index - 1]

    if n_out > s.schn1.nscans:
        done = True

    else:
        done = False
        found_scan = False
        while not found_scan:
            if k_scan == 1:
                approx_time = scans[0].startj + skip_time
                adjust = False
            elif skip_time != 0:
                approx_time = scans[scan_index - 2].stopj + skip_time
                adjust = False
                if approx_time > scans[0].startj + s.schcon.opdur:
                    done = True
                    break
            else:
                approx_time = scans[scan_index - 2].stopj
                adjust = True

            weight_max = 0
            weight_max_scan = -1
            if s.schcon.opprtlev >= 3:
                s.wlog(
                    0, "              Scan   Source     New scan time "
                    "Opt scan time  TIMEWT  SLEWWT  RISEWT   SETWT   SCNWT "
                    "    dT      WID  SlewSec")

            for j_scan, scan in enumerate(scans[:s.schn1.nscans]):
                if scan_used[j_scan] == 0:
                    scan_weight[j_scan] = 0
                    ref_station.ha1[j_scan], ref_station.el1[j_scan], \
                        ref_station.az1[j_scan], ref_station.lst1[j_scan], \
                        ref_station.pa1[j_scan] = s.schgeo(
                            j_scan + 1, ref_station_index, approx_time)
                    if (ref_station.ha1[j_scan] >= ha_min[j_scan]) and \
                       (ref_station.ha1[j_scan] <= ha_max[j_scan]):
                        at_source = 0
                        for i, station in enumerate(stations):
                            if station.stascn[j_scan]:
                                _, station.tonsrc[j_scan] = s.stageo(
                                    j_scan + 1, i + 1, approx_time,
                                    last_scan_index[i], "OPTHAS")
                                if (k_scan > 1) and \
                                   (f2str(station.up1[j_scan]) == ""):
                                    at_source = max(at_source,
                                                    station.tonsrc[j_scan])

                        if k_scan > 1:
                            op_slew = (at_source - scans[scan_index - 2].stopj) \
                                      * secpday
                        else:
                            op_slew = 0

                        source_separation = 1
                        if k_scan > 1:
                            for last_scan in scans[s.schn1.scan1 -
                                                   1:s.schn1.scanl]:
                                if scan.scnsrc == last_scan.scnsrc:
                                    time_space = approx_time - last_scan.stopj
                                    source_separation = min(
                                        source_separation, time_space)

                        if (source_separation < (scan.opminsep *
                                                 op_ha_wid_t[j_scan])) or \
                            (abs(approx_time - op_ha_t[j_scan]) >
                             scan.ophmaxdt / secpday):
                            scan_weight[j_scan] = 0
                        else:
                            time_weight = scan.ophawt * \
                                      (0.5 + (1 / math.pi) * math.atan(
                                          1.5 * (approx_time - op_ha_t[j_scan])
                                          / op_ha_wid_t[j_scan]))

                            slew_weight = 0
                            if (scan.scnsrc != scans[scan_index - 2].scnsrc) \
                               and (scan.opslewti > 0):
                                slew_weight = max(
                                    0,
                                    scan.opslewwt *
                                    (1 - op_slew / scan.opslewti))

                            rise_weight = 0
                            set_weight = 0
                            if scan.ophlimti > 0:
                                rise_weight = max(
                                    0,
                                    scan.ophlimwt *
                                    (1 - abs(ref_station.ha1[j_scan] -
                                             ha_min[j_scan]) * 3600 /
                                     scan.ophlimti))
                                set_weight = max(
                                    0,
                                    scan.ophlimwt *
                                    (1 - abs(ref_station.ha1[j_scan] -
                                             ha_max[j_scan]) * 3600 /
                                     scan.ophlimti))

                            scan_weight[j_scan] = time_weight + slew_weight \
                                                  + rise_weight + set_weight
                            if scan_weight[j_scan] > weight_max:
                                weight_max = scan_weight[j_scan]
                                weight_max_scan = j_scan

                            if s.schcon.opprtlev >= 3:
                                year, day1, time_rad = s.timej(approx_time)
                                start_time_text = f2str(
                                    s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
                                year, day2, time_rad = s.timej(op_ha_t[j_scan])
                                opt_time_text = f2str(
                                    s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
                                s.wlog(
                                    0, " SCAN WEIGHT {:>5d} {:<12} {:>4d} {} "
                                    "{:>4d} {} {:>7.2f} {:>7.2f} {:>7.2f} "
                                    "{:>7.2f} {:>7.2f} {:>7.2f} {:>7.2f} "
                                    "{:>7.2f}".format(
                                        j_scan + 1, scan.scnsrc, day1,
                                        start_time_text, day2, opt_time_text,
                                        time_weight, slew_weight, rise_weight,
                                        set_weight, scan_weight[j_scan],
                                        (approx_time - op_ha_t[j_scan]) * 24,
                                        op_ha_wid_t[j_scan] * 24, op_slew))

            if weight_max_scan >= 0:
                n_out += 1
                scndup(scan_index - 1, weight_max_scan, False, "OPTHAS")
                new_scan = scans[scan_index - 1]
                new_scan.startj = approx_time
                new_scan.stopj = new_scan.startj + new_scan.dur
                scan_used[weight_max_scan] = scan_index
                skip_time = 0
                sd_total += new_scan.dur

                if s.schcon.opprtlev >= 2:
                    year, day, time_rad = s.timej(approx_time)
                    time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2,
                                                 "::@"))
                    s.wlog(
                        0, "USE SCAN {:>5d} {} {:>5d} {}   HA={:>10.2f}  "
                        "Weight: {:10.3f}".format(
                            weight_max_scan + 1, scans[weight_max_scan].scnsrc,
                            day, time_text, ref_station.ha1[weight_max_scan],
                            weight_max))
                found_scan = True
            else:
                skip_time += skip_inc
                n_skip += 1
                if s.schcon.opprtlev >= 1:
                    year, day, time_rad = s.timej(approx_time)
                    time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2,
                                                 "::@"))
                    s.wlog(
                        0, "OPTHAS:  Skipping {:>6.2f} min at {} {:>7.2f} "
                        "min after scan {:>5d} because no scans are "
                        "available.".format(skip_inc * secpday / 60, time_text,
                                            skip_time * secpday / 60,
                                            scan_index))

        if found_scan and (s.schcon.opdur > 0) and \
           (new_scan.stopj > scans[0].startj + s.schcon.opdur):
            s.wlog(
                1, "OPTHAS:  Schedule stopped because requested total "
                "duration reached")
            done = True

    if done:
        s.wlog(0, " ")
        s.wlog(0, "OPTHAS:  HAS mode schedule made.")

        s.wlog(0, " ")
        if s.schcon.opprtlev <= 0:
            s.wlog(0, "         OPPRTLEV={}:  Minimum information printed.".\
                   format(s.schcon.opprtlev))
        elif s.schcon.opprtlev == 1:
            s.wlog(
                0, "         OPPRTLEV=1:  Include summary of fate of each "
                "input scan.")
        elif s.schcon.opprtlev == 2:
            s.wlog(
                0, "         OPPRTLEV=2:  Minimum feedback as scans chosen "
                "plus fate of input scans.")
        elif s.schcon.opprtlev >= 3:
            s.wlog(
                0, "         OPPRTLEV={}:  Details of each scan choice plus "
                "summaries.".format(s.schcon.opprtlev))

        s.wlog(0, "         Requested scans: {}".format(s.schn1.nscans))
        s.wlog(0, "         Scheduled scans: {}".format(n_out))
        s.wlog(
            0, "         Sum of requested durations: {:>7.3f} hr.".format(
                dur_total * 24))
        s.wlog(
            0, "         Sum of scheduled durations: {:>7.3f} hr.".format(
                sd_total * 24))

        year, day, time_rad = s.timej(scans[s.schn1.scan1 - 1].startj)
        time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
        s.wlog(0,
               "         Start day and time: {:>5d} {}".format(day, time_text))

        year, day, time_rad = s.timej(scans[s.schn1.scanl - 1].stopj)
        time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
        s.wlog(
            0, "         Stop day and time and total duration (hr): {:>5d} {}"
            " {:>12.3f}".format(day, time_text,
                                (scans[s.schn1.scanl - 1].stopj -
                                 scans[s.schn1.scan1 - 1].startj) * 24))

        s.wlog(
            0, "         Requested duration (hours) {:>8.2f}".format(
                s.schcon.opdur * 24))

        s.wlog(
            0, "         Maximum allowed deviation from optimum time "
            "(hr; scan 1) {:>8.3f}".format(scans[0].ophmaxdt / 3600))

        s.wlog(
            0, "         Number of {:>7.3f} minutes skips because of no scan "
            "available: {}".format(skip_inc * secpday / 60, n_skip))

        s.wlog(
            0, "         Total time in skips: {:>8.3f} minutes.  "
            "(Some may be after last scan)".format(skip_inc * n_skip *
                                                   secpday / 60))

        if s.schcon.opprtlev >= 1:
            s.wlog(0, " ")
            s.wlog(0, "OPTHAS:  Input scan information.  Columns are:")
            s.wlog(0, "         Output scan number and time ")
            s.wlog(
                0, "         Reference station hour angle.  "
                "for scheduled scan.")
            s.wlog(
                0, "         Allowed reference station hour angle range "
                "(for scan start).")
            s.wlog(
                0, "         Reference station hour angles for beginning "
                "and end of observations.")
            s.wlog(0, "         Total hours this source is available.")
            s.wlog(
                0, "         The reference station is: {}".format(
                    ref_station.station))
            s.wlog(
                0, "  Input    Source    Output      Time          HA        "
                "Time        HA      HA      HA      HA  Available     "
                "Rise         Set")
            s.wlog(
                0, "   Scan               Scan   Day    hms       "
                "Scan        Opt       Min     Max    Start    End    Hours")

            for j, scan in enumerate(scans[:s.schn1.nscans]):
                if scan_used[j] != 0:
                    year, day1, time_rad = s.timej(scans[scan_used[j] -
                                                         1].startj)
                    start_time_text = f2str(
                        s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
                    ha_p = ref_station.ha1[scan_used[j] - 1]
                else:
                    day1 = 0
                    start_time_text = " "
                    ha_p = 0

                year, day2, time_rad = s.timej(op_ha_t[j])
                opt_time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2,
                                                 "::@"))
                year, day_rise, time_rad = s.timej(t_ha_min[j])
                rise_time_text = f2str(
                    s.tformwrp(time_rad, "T", 0, 2, 2, "::@"))
                year, day_set, time_rad = s.timej(t_ha_max[j])
                set_time_text = f2str(s.tformwrp(time_rad, "T", 0, 2, 2,
                                                 "::@"))
                s.wlog(
                    0, "{:>5d}   {:<12} {:>5d} {:>5d}  {:<8} {:>8.3f} {:>4d}"
                    "  {} {:>7.3f} {:>7.3f} {:>7.3f} {:>7.3f} {:>7.3f} {:>4d}"
                    " {} {:>4d} {}".format(
                        j + 1, scan.scnsrc, scan_used[j], day1,
                        start_time_text, ha_p, day2, opt_time_text, ha_min[j],
                        ha_max[j], ha_begin[j], ha_end[j], t_avail[j] * 24,
                        day_rise, rise_time_text, day_set, set_time_text))

        s.wlog(
            1, "OPTHAS: There were {} requested scans and "
            "{} Scheduled scans.".format(s.schn1.nscans, n_out))
        s.wlog(1, "OPTHAS: See the sched.runlog for details.")

    return adjust, True, done
예제 #5
0
def schopt():
    if s.schcon.debug:
        s.wlog(0, "SCHOPT: Starting.")

    scan_catalog = ScanCatalog()
    scans = scan_catalog.direct_access_entries

    station_catalog = StationCatalog()
    stations = station_catalog.used(use_direct_access=True)

    source_catalog = SourceCatalog()
    sources = source_catalog.read()

    pc_catalog = PhaseCenterCatalog()
    phase_centers = pc_catalog.read()

    setups = SetupCatalog().read()
    peak_catalog = PeakCatalog()
    peak_groups = peak_catalog.read()

    # content of setup file catalog used in geochk (->addgeo->geomake->geochk)
    # call here once
    SetupFileCatalog().read()

    for scan in scans:
        scan.origen = 1

    optmode = f2str(s.schsco.optmode)
    if (optmode not in {"NONE", "SCANS"}) or \
       s.schcon.autopeak or s.schsou.anygeo:
        # get the int value of nscans,
        # else (increment) operations affect nscans directly,
        # since it's a dimensionless np.array
        scan_index = int(s.schn1.nscans)
        s.schn1.scan1 = scan_index + 1
    else:
        scan_index = 0
        s.schn1.scan1 = 1

    s.wlog(
        0,
        "SCHOPT:  First output scan will be number {}".format(s.schn1.scan1))

    done = False
    peak_opt = 0
    geo_opt = 0
    k_scan = 0
    last_scan_index = np.zeros(shape=(station_catalog.maxsta, ), dtype=int)
    last_s_scan_index = np.zeros(shape=(station_catalog.maxsta, ), dtype=int)
    while not done:
        scan_index += 1
        if scan_index > scan_catalog.maxscan:
            s.errlog("SCHOPT:  Trying to generate too many scans. Max: {}".\
                     format(scan_catalog.maxscan))

        scan = scans[scan_index - 1]
        if (peak_opt != 0) or (geo_opt != 0):
            keep = True
        else:
            k_scan += 1
            assert ((k_scan == scan_index) or (scan_index >= s.schn1.nscans))
            if optmode == "NONE":
                adjust, keep, done = optnone(k_scan, scan_index)
            elif optmode == "SCANS":
                adjust, keep, done = optskd(last_scan_index, k_scan,
                                            scan_index)
            elif optmode == "CELLS":
                adjust, keep, done = optcells(last_scan_index, k_scan,
                                              scan_index)
                scan.origen = 2
            elif optmode == "CSUB":
                s.errlog("SCHOPT: OPTMODE CSUB is not supported in pySCHED")
            elif optmode == "UPTIME":
                last_scan_index, adjust, keep, done = optupt(
                    last_scan_index, k_scan, scan_index)
                scan.origen = 2
            elif optmode == "HAS":
                adjust, keep, done = opthas(last_scan_index, k_scan,
                                            scan_index)
                scan.origen = 2
            elif optmode == "HIGHEL":
                k_scan, adjust, keep, done = opthiel(last_scan_index, k_scan,
                                                     scan_index)
                scan.origen = 2
            else:
                s.errlog("SCHOPT: Invalid OPTMODE: {}".format(optmode))

            if keep and (not done):
                s.opttim(last_scan_index, last_s_scan_index, scan_index,
                         adjust, False, False)
                if (s.schcon.opdur != 0) and \
                   (scan.stopj >
                    scans[s.schn1.scan1 - 1].startj + s.schcon.opdur) and \
                   (optmode != "HAS"):
                    done = True

                n_good = s.scngeo(last_scan_index, scan_index)

        insert_adjust = adjust
        if keep and (not done):
            if (peak_opt == 0) and ((scan.geolen > 0) or (geo_opt >= 1)):
                insert_adjust = False
                geo_opt, keep = addgeo(last_scan_index, scan_index, geo_opt,
                                       scans, stations)

            peak_opt, insert_adjust = addpeak(last_scan_index, scans, stations,
                                              setups, peak_groups, peak_opt,
                                              insert_adjust, scan_index)
            peak_catalog.write()
            keep = s.makeptg(last_scan_index, scan_index, keep)

        if keep and (not done):
            s.opttim(last_scan_index, last_s_scan_index, scan_index,
                     insert_adjust, False, True)
            n_good = s.scngeo(last_scan_index, scan_index)
            n_good = s.autodown(last_scan_index, scan_index)

            keep = keep and ((n_good >= scan.opmian) or
                             (optmode in {"CSUB", "HAS"}) or (scan.point >= 0))
            if not keep:
                for station in stations:
                    station.stascn[scan_index - 1] = False
            else:
                s.settps(scan_index, last_scan_index)

                for station_index, station in enumerate(stations, 1):
                    if station.stascn[scan_index - 1] and s.schn1.vlbitp and \
                       (not s.schcon.noset) and station.usedisk:
                        s.diskpos(scan_index, station_index, last_scan_index)

                if (optmode not in {"NONE", "UPTIME"}) or s.schsou.anygeo:
                    s.optsch(scan_index)

                source = sources[scan.srcnum - 1]
                source.sused = True
                if not scan.norec:
                    source.usedrec = True
                if scan.idopsrc != 0:
                    sources[scan.idopsrc - 1].sused = True
                if scan.ivlaphs != 0:
                    sources[scan.ivlaphs - 1].sused = True
                if scan.icent != 0:
                    source.usedcent = True
                    for source_index in phase_centers[scan.icent - 1].ctrsrci:
                        sources[source_index - 1].usedphs = True

            for station_index, station in enumerate(stations):
                if station.stascn[scan_index - 1]:
                    last_scan_index[station_index] = scan_index
                    if scan.origen < 4:
                        last_s_scan_index[station_index] = scan_index

            s.schn1.scanl = scan_index

    if s.schcon.debug:
        s.wlog(0, "SCHOPT: 9.")

    if s.schn1.scanl == 0:
        s.wlog(1, "SCHOPT: Did not schedule any scans")
        s.errlog(" Abort")

    source_catalog.write()
    s.accsrc(False)
    gotall = s.srcflg()

    if not gotall:
        s.errlog("SCHOPT: Not all sources found; programming problem.")

    s.getpairs()

    year, day1, start = s.timej(scans[s.schn1.scan1 - 1].startj)
    year, day2, stop = s.timej(scans[s.schn1.scanl - 1].stopj)

    time1 = f2str(s.tformwrp(start, "T", 0, 2, 2, "::@"))
    time2 = f2str(s.tformwrp(stop, "T", 0, 2, 2, "::@"))
    s.wlog(
        0, "SCHOPT:  There will be {number} output scans ({first} - {last}) "
        "from {day1}/{time1} to {day2}/{time2}".format(number=s.schn1.scanl -
                                                       s.schn1.scan1 + 1,
                                                       first=s.schn1.scan1,
                                                       last=s.schn1.scanl,
                                                       day1=day1,
                                                       day2=day2,
                                                       time1=time1,
                                                       time2=time2))

    s.schtim()
    s.sch24()

    if s.schcon.debug:
        s.wlog(0, "SCHOPT: Done.")