def opthiel(last_scan_index, k_scan, scan_index): global skip, missed done = False keep = True adjust = True stations = StationCatalog().used(use_direct_access=True) scans = ScanCatalog().direct_access_entries if k_scan > s.schn1.nscans: done = True return k_scan, adjust, keep, done scan = scans[k_scan - 1] scan.higroup = max(scan.higroup, 1) if k_scan + scan.higroup - 1 > s.schn1.nscans: s.errlog("OPTHIEL: HIGROUP in last scan too large.") if scan.higroup == 1: scndup(scan_index - 1, k_scan - 1, True, "OPTHIEL") return k_scan, adjust, keep, done approx_time = s.schn1.tfirst for i, station in enumerate(stations): use_station = np.any(station.stascn[k_scan - 1:k_scan - 1 + scan.higroup]) if use_station and (last_scan_index[i] != 0): approx_time = max( approx_time, scans[last_scan_index[i] - 1].stopj + scans[scan_index - 1].gap) group_max_low_el = -100 for j in range(scan.higroup): j_k_scan = k_scan - 1 + j j_scan_index = scan_index - 1 + j scndup(j_scan_index, j_k_scan, True, "OPTHIEL") scan_low_el = 100 for i, station in enumerate(stations): if station.stascn[j_scan_index]: s.stageo(j_scan_index + 1, i + 1, approx_time, last_scan_index[i], "OPTHIEL") average_el = (station.el1[j_scan_index] + station.el2[j_scan_index]) / 2 scan_low_el = min(scan_low_el, average_el) if scan_low_el > group_max_low_el: group_max_low_el = scan_low_el max_scan = j_scan_index scndup(scan_index - 1, max_scan, True, "OPTHIEL") k_scan += scan.higroup - 1 return k_scan, adjust, keep, done
def makescn(last_scan_index, scan_index, j_scan, source_index, source_name, approx_time, min_elevation, use_time): if s.schcon.debug: s.wlog(0, "MAKESCN starting.") scndup(scan_index - 1, j_scan - 1, False, "MAKESCN") scans = scan_catalog.direct_access_entries scans[scan_index - 1].srcnum = source_index scans[scan_index - 1].scnsrc = source_name.ljust(s.schc2b.scnsrc.itemsize) stations = station_catalog.used(use_direct_access=True) n_good = 0 ok_sta = np.full(fill_value=False, dtype=bool, shape=(len(stations),)) for i, station in enumerate(stations): if station.stascn[j_scan - 1]: last_time, available_time = s.stageo(scan_index, i + 1, approx_time, last_scan_index[i], "MAKESCN") if (f2str(station.up1[scan_index - 1]) == "") and \ (f2str(station.up2[scan_index - 1]) == "") and \ (station.el1[scan_index - 1] > min_elevation) and \ (station.el2[scan_index - 1] > min_elevation): ok_sta[i] = True n_good += 1 for i, station in enumerate(stations): station.stascn[scan_index - 1] = station.stascn[scan_index - 1] and \ ok_sta[i] if n_good >= 1: scans[scan_index - 1].startj = approx_time s.opttim(last_scan_index, last_scan_index, scan_index, True, use_time, False) n_good = s.scngeo(last_scan_index, scan_index) return n_good
def gmkscn(last_scan_index, scan_index, j_scan, source_index, source_name, approx_time, min_elevation, keep_station, scan_stascn, g_mode): if s.schcon.debug: s.wlog(0, "GMKSCN starting.") scan_catalog = ScanCatalog() station_catalog = StationCatalog() scans = scan_catalog.direct_access_entries stations = station_catalog.used(use_direct_access=True) n_good = 0 # go to python/zero indexing for scan index scan_index -= 1 j_scan -= 1 scndup(scan_index, j_scan, False, "GMKSCN") scan = scans[scan_index] scan.srcnum = source_index scan.scnsrc = source_name ok_sta = np.empty(dtype=bool, shape=(len(stations), )) if g_mode == "SET": for i, station in enumerate(stations): ok_sta[i] = False if station.stascn[j_scan]: last_time, available_time = s.stageo(scan_index + 1, i + 1, approx_time, last_scan_index[i], "GMKSCN") if (f2str(station.up1[scan_index]) == "") and \ (f2str(station.up2[scan_index]) == "") and \ (station.el1[scan_index] > min_elevation) and \ (station.el2[scan_index] > min_elevation): ok_sta[i] = True n_good += 1 for i, station in enumerate(stations): station.stascn[scan_index] = station.stascn[j_scan] and ok_sta[i] if n_good >= 1: scan.startj = approx_time s.opttim(last_scan_index, last_scan_index, scan_index + 1, True, False, False) n_good = s.scngeo(last_scan_index, scan_index + 1) if (n_good >= scans[j_scan].opmian) and (scan_index + 1 > s.schn1.scan1): in_scan = [s for s in stations if s.stascn[scan_index]] in_scan.sort(key=lambda s: -s.tonsrc[scan_index]) if len(in_scan) > 0: t_med = in_scan[min(2, len(in_scan) - 1)].tonsrc[scan_index] else: s.errlog("GMKSCN: INSCN zero. Programming error") for i, station in enumerate(stations): if station.stascn[scan_index] and \ (i + 1 != keep_station) and \ (last_scan_index[i] != 0) and \ (station.tonsrc[scan_index] > t_med + s.schsou.geoslow / secpday): if station.el1[scan_index] < s.schsou.geolowel: n_good = 0 if s.schsou.geoprt >= 2: s.wlog( 0, "**gmkscn: Dropping scan - low el for " "slow ant {} {} {} {}".format( i + 1, scan_index + 1, source_name, station.el1[scan_index])) else: n_good = max(n_good - 1, 0) station.stascn[scan_index] = False ok_sta[i] = False if s.schsou.geoprt >= 2: s.wlog( 0, "++gmkscn: Dropping station {} Scan {} {}" " Geosrc: {} for long slew.".format( i + 1, scan_index + 1, s.schn1.scan1, source_name)) scan_stascn[:] = [s.stascn[scan_index] for s in stations] elif g_mode == "FORCE": for i, station in enumerate(stations): station.stascn[scan_index] = scan_stascn[i] ok_sta[:] = scan_stascn[:ok_sta.shape[0]] n_good = np.count_nonzero(ok_sta) if n_good >= 1: scan.startj = approx_time s.opttim(last_scan_index, last_scan_index, scan_index + 1, True, False, False) n_good = s.scngeo(last_scan_index, scan_index + 1) else: s.errlog("GMKSCN: Bad GMODE. Programming error.") return n_good, ok_sta, scan_stascn
def optupt(last_scan_index, k_scan, scan_index): global in_scan done = False keep = True adjust = False stations = StationCatalog().used(use_direct_access=True) scans = ScanCatalog().direct_access_entries if k_scan == 1: s.wlog( 0, "OPTUPT: OPTMODE=UPTIME was specified. Station files " "(sch, crd, ") s.wlog(0, " vex, and drudg) will not be written.") in_scan = 1 scans[scan_index - 1].startj = scans[0].startj if s.schcon.opdur <= 0: s.errlog(" OPTCUPT: For OPTMODE=UPTIME, OPDUR must be given.") s.wlog( 0, " There are {} input scans with sources: ".format( s.schn1.nscans)) sources = set() for j_scan, scan in enumerate(scans[:s.schn1.nscans]): s.wlog(0, " {:>5d}: {}".format(j_scan + 1, scans[j_scan].scnsrc)) sources.add(scans[j_scan].scnsrc) if len(sources) < s.schn1.nscans: s.wlog(1, " There were duplicate sources. ") s.wlog( 1, " This is probably not what you wanted for " "OPTMODE=UPTIME.") else: scans[scan_index - 1].startj = scans[scan_index - 2].stopj + \ scans[in_scan - 1].gap scans[scan_index - 1].stopj = scans[scan_index - 1].startj + \ scans[in_scan - 1].dur if scans[scan_index - 1].stopj > scans[0].startj + s.schcon.opdur: if in_scan >= s.schn1.nscans: done = True keep = False else: in_scan += 1 scans[scan_index - 1].startj = scans[0].startj scans[scan_index - 1].stopj = scans[scan_index - 1].startj + \ scans[in_scan - 1].dur last_scan_index.fill(0) if not done: scndup(scan_index - 1, in_scan - 1, False, "OPTUPT") for i, station in enumerate(stations): if station.stascn[scan_index - 1]: s.stageo(scan_index, i + 1, scans[scan_index - 1].startj, 0, "OPTUPT") station.stascn[scan_index - 1] = \ (f2str(station.up1[scan_index - 1]) == "") and \ (f2str(station.up2[scan_index - 1]) == "") and \ ((station.el1[scan_index - 1] + station.el2[scan_index - 1]) / 2 > scans[scan_index - 1].opminel) return last_scan_index, adjust, keep, done
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
def optskd(last_scan_index, k_scan, scan_index): global skip, missed if k_scan > s.schn1.nscans: return False, False, True if k_scan != scan_index: scndup(scan_index, k_scan, True, "OPTSKD") scans = ScanCatalog().direct_access_entries stations = StationCatalog().used(use_direct_access=True) scan = scans[scan_index - 1] adjust = (scan.duronly == 1) if scan_index == 1: skip.fill(s.schcon.opskip) missed = 0 if not adjust: approx_time = scan.startj else: approx_time = s.schn1.tfirst for i, station in enumerate(stations): if station.stascn[scan_index - 1] and (last_scan_index[i] != 0): approx_time = max( approx_time, scans[last_scan_index[i] - 1].stopj + scan.gap) n_good = 0 n_prio = 0 begin_time = s.schn1.tfirst ok_sta = np.full(fill_value=False, dtype=bool, shape=(len(stations, ))) for i, station in enumerate(stations): if station.stascn[scan_index - 1]: last_time, avail_time = s.stageo(scan_index, i + 1, approx_time, last_scan_index[i], "OPTSKD") if (f2str(station.up1[scan_index - 1]) == "") and \ (f2str(station.up2[scan_index - 1]) == "") and \ (station.el1[scan_index - 1] > scan.opminel) and \ (station.el2[scan_index - 1] > scan.opminel): ok_sta[i] = True n_good += 1 if last_scan_index[i] != 0: avail_time = max( avail_time, scans[last_scan_index[i] - 1].stopj + scan.gap) begin_time = max(begin_time, avail_time) opelprio = s.schcon.opelprio if (opelprio[0] < station.el1[scan_index - 1] < opelprio[1]) or \ (opelprio[2] < station.el1[scan_index - 1] < opelprio[3]): n_prio += 1 if (not adjust) or (begin_time == s.schn1.tfirst): begin_time = approx_time source_index = scan.srcnum keep = (n_good >= max(scan.opmian, 1)) and \ ((skip[source_index - 1] >= s.schcon.opskip) or (n_prio >= 1)) if f2str(s.schsco.obstyp) not in {"NONE", "PTVLBA"}: keep = keep or ((n_good >= 1) and (scan.pntvlba or scan.tanvlba or scan.dopn3db)) keep = keep and (missed >= scan.opmiss) if keep: skip[source_index - 1] = 0 if adjust: scan.startj = begin_time scan.stopj = begin_time + scan.dur for i, station in enumerate(stations): station.stascn[scan_index - 1] = (ok_sta[i] or s.schcon.opnosub) missed = 0 else: if n_good >= scan.opmian: skip[source_index - 1] += 1 for station in stations: station.stascn[scan_index - 1] = False missed += 1 return adjust, keep, False
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