def times(lst, start, stop, day, year): # the parameter LST is both a boolean flag (implemented by floats) # and a string for the LST station use_lst = True if isinstance(lst, (float, int)): if lst == 0: lst = "VLA" else: use_lst = False elif isinstance(lst, str): lst = lst.upper() if use_lst: indices = np.argwhere(s.schcst.station == util.resize_string( lst, s.schcst.station.itemsize, "lst").encode()) if len(indices) == 0: s.errlog("TIMES: LST specified but station not in catalog") s.schn1.lststa = indices[0] + 1 s.schn1.lst = True else: s.schn1.lst = False for index in range(s.schn1.nscans): s.schn2a.duronly[index] = 0 if s.schn2b.dur[index] > 0: s.schn2a.duronly[index] += 1 if start[index] != parameter.unset: s.schn2a.duronly[index] += 2 if stop[index] != parameter.unset: s.schn2a.duronly[index] += 4 s.sattim(index+1, start[index], stop[index], day[index], year[index]) s.schn1.iatutc = s.sla_dat(s.schn2c.startj[0])
def gintent(intents, entries, scan_index): entry = entries[scan_index] if len(intents) > 0: entry.nscint = len(intents) for intent_index, intent in enumerate(intents): # find in stored intents padded = util.resize_string(intent, s.schc2c.intent.itemsize, "intents") stored_indices = np.argwhere( s.schc2c.intent[:s.schn2a.nintent] == padded.encode()) if len(stored_indices) == 0: if s.schn2a.nintent >= len(s.schc2c.intent): s.errlog("GINTENT: Too many distinct intents. " "Max {} Report need for more.".format( len(s.schc2c.intent))) s.schc2c.intent[s.schn2a.nintent] = padded s.schn2a.nintent += 1 entry.iscint[intent_index] = s.schn2a.nintent else: entry.iscint[intent_index] = stored_indices[0] + 1 if "NONE" in (intent.upper() for intent in intents): if len(intents) > 1: s.errlog("GINTENT: Please do not mix 'NONE' with " "other INTENTs") entry.iscint[0] = 0 entry.nscint = 0 else: if scan_index + 1 > s.schn1.scan1: prev = entries[scan_index - 1] entry.nscint, entry.iscint = prev.nscint, prev.iscint
def ifdbbc(dbbc_version, e_firmware): if s.schcon.debug: s.wlog(1, "IFDBBC: Starting") max_bbc = 16 max_if = 4 ifbbc = np.zeros((max_bbc, max_if)) if dbbc_version == "ASTRO": mif = 4 for if_ in range(mif): ifbbc[if_ * 4:(if_ + 1) * 4, if_] = 1 elif dbbc_version == "GEO": mif = 2 for if_ in range(mif): ifbbc[if_ * 8:(if_ + 1) * 8, if_] = 1 elif dbbc_version == "HYBRID": mif = 3 ifbbc[0:4, 0] = 1 ifbbc[4:8, 1] = 1 ifbbc[8:16, 2] = 1 else: s.wlog(1, "IFDBBC: DBBCVER not recognised: {}".format(dbbc_version)) s.errlog("catalog error") if e_firmware: # 32 MHz (only in E) DDC mode can only do odd (count starting at 1) BBCs ifbbc[1::2, :] = 0 return ifbbc, mif
def schrep(values, entries, index, marker, start, stop, day, year): global group, repeat if s.schcon.debug: s.wlog(0, "SCHREP starting.") # if we get a repeat request, store it such that we can execute it when # the requested number of scan (group) has been parsed if marker == -1: repeat = int(values["repeat"]) group = int(values["group"]) if repeat != 0: marker = index elif values["repeat"] > 1: s.errlog("SCHREP: Cannot do nested or overlapping loops.") if s.schcon.debug: s.wlog( 0, "SCHREP: Scan - {} Repeat and group: {} {}".format( index + 1, repeat, group)) if (marker != -1) and (index + 1 >= group + marker): for r in range(repeat - 1): for g in range(group): index += 1 scndup(index, marker, False, "SCHREP", use_direct_access=False) start[index] = parameter.unset stop[index] = parameter.unset day[index] = day[marker] year[index] = year[marker] marker += 1 marker = -1 return index, marker
def infdb(values, present, entries, index): entry = entries[index] if s.schcon.debug and (index < 2): s.wlog(0, "INFDB: Starting") if ((entry.crdch1 != 0) or (entry.crdsetch[0] != 0)) and \ (entry.crdnch == 0): s.errlog("'INFDB: If CRDCH1 or CRDSETCH is set, " "CRDNCH must also be set.") if (entry.crdch1 != 0) and (entry.crdsetch[0] != 0): s.errlog("INFDB: Do not use both CRDCH1 and CRDSETCH!") maxcrd = s.schn2a.crdsetch.shape[0] if entry.crdnch > maxcrd: s.errlog("INFDB: CRDNCH set too high. Maximum is {}. It is {} " "in input scan {}".format(maxcrd, entry.crdnch, index + 1)) if entry.crdch1 != 0: entry.crdsetch = [entry.crdch1 + i for i in range(entry.crdnch)] default = False if index > 0: default = entries[index - 1].crddop entry.crddop = toggle(values, present, "crddop", "crdnodop", default) entry.gotcrd = entry.crddop or any(freq > 0 for freq in entry.crdfreq) if ((entry.crdnch < 1) or (entry.crdnch > maxcrd)) and \ entry.gotcrd: s.wlog(1, "INFDB: CRDNCH is required and must be between 1 and {}".\ format(maxcrd)) s.wlog(1, " when CRDFREQ or CRDDOP is specified.") s.errlog(" CRDNCH is {} on scan {}".format( entry.crdnch, index + 1)) if entry.crddop and (entry.crdsetch[0] < 1): s.errlog("INFDB: If invoking DOPCRD, please also set CRDCH1 or " "CRDSETCH") if entry.dopsrc == "": entry.dopsrc = entry.scnsrc if entry.dopcal: s.wlog(1, "INFREQ: Use DOPPLER, not DOPCAL.") else: default = False if index > 0: default = entries[index - 1].dopcal entry.dopcal = toggle(values, present, "doppler", "nodop", default) # dopincr's scan index dimension is the first, instead of the last, # so it doesn't fit into the catalog logic, write into the common block # manually here s.schn2b.dopincr[index, :] = values["dopincr"] if (index != 0) and (entry.freq[0] != 0) and \ (entry.setnum != entries[index-1].setnum) and \ (entry.freq[0] == entries[index-1].freq[0]): s.wlog(1, "INFDB: Setup changed and specified frequency didn't. ") s.wlog(1, " Is this really what you wanted? ") s.wlog(1, " Use FREQ=0 to get the new setup default.")
def toggle(values, present, key1, key2, default): if (key1 in present) and (key2 in present): s.errlog("TOGGLE: You can't set both {} and {}!".format(key1, key2)) elif (key1 not in present) and (key2 not in present): return default elif key1 in present: return values[key1] else: return not values[key2]
def check(value, allowed, not_supported, station, element_type): if value not in allowed: s.errlog("STREAD: Invalid {} type {} for {}".format( element_type, value, station)) if value in not_supported: s.errlog("STREAD: {} type {} no longer supported by " "SCHED. Station: {}".format( element_type[0].upper() + element_type[1:], value, station))
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 setexpnd(): if s.schcon.debug: s.wlog(0, "SETEXPND: Starting.") for i in range(s.setn1.nset): s.setstdef(i+1) catalog = SetupCatalog() catalog.read() setup_entries = catalog.scheduled() copy_to = len(setup_entries) for setup_entry in setup_entries: for station in setup_entry.setsta[setup_entry.setsta != ""]: if copy_to >= len(catalog.entries): s.wlog(1, "SETEXPND: There are too many setup groups after " "creating new ones") s.wlog(1, " for each station in the input setups.") s.wlog(1, " Maximum is {} which is setups times " "stations.".format(len(catalog.entries))) s.errlog("SETEXPND: You need fewer setups or a bigger MSET in " "SCHED.") dest = catalog.entries[copy_to] dest.__dict__.update(copy.deepcopy(setup_entry.__dict__)) dest.setsta[0] = station copy_to += 1 if copy_to == len(setup_entries): s.errlog("SETEXPND: None of the specified setups are used.") # move the new entries to the front and invalidate the others catalog.entries = catalog.entries[len(setup_entries):] + \ catalog.entries[:len(setup_entries)] s.setn1.nset = copy_to - len(setup_entries) station_catalog = StationCatalog() station_catalog.read() stations = station_catalog.used() for ks, setup_entry in enumerate(catalog.scheduled(), 1): setup_entry.listks = ks station_index = next(s.schn1.stanum[station.ischsta-1] for station in stations if station.station == setup_entry.setsta[0]) if station_index is None: s.wlog(1, "SETEXPND: Did not get station number. " "Programming problem.") s.wlog(1, " Station: {}".format(setup_entry.setsta[0])) s.errset(ks) setup_entry.isetsta = station_index catalog.write(range(s.setn1.nset)) for lsta in range(s.schn1.nsta): for iscn in range(s.schn1.nscans): s.schn2a.nsetup[iscn, lsta] = s.gnset(iscn+1, lsta+1)
def stmsg(): s.schcon.readlog = False logfile = "sched.runlog" s.schsco.logfile = util.resize_string(logfile, s.schsco.logfile.itemsize, "logfile") open_stat = "OLD" if os.path.exists(logfile) else "NEW" error_msg, error_code = s.openwrap(parameter.ilog, logfile, "TEXT", open_stat) if error_code != 1: s.wlog(1, f"STMSG: CANNOT OPEN LOG FILE {logfile}") s.wlog(1, f" Error text: {error_msg}") s.error(" Check why log file cannot be opened") s.wlog(1, " ") s.wlog(1, f" Welcome to pySCHED version {pysched_version} " "based on ") s.wlog( 1, f" SCHED version: {s.vern.vernum:.6} " f"{util.f2str(s.verc.version)}") s.wlog(1, " ") s.wlog( 1, "The manual is at http://www.aoc.nrao.edu/software/sched/" "index.html") s.wlog( 1, "Bug reports, feature requests and other discussions can be " "posted on the GitHub page:") s.wlog(1, " https://github.com/jive-vlbi/sched") s.wlog( 1, f"pySCHED will use the catalogs under {checkout_dir} unless " "$SCHED is set.") s.wlog(1, f"Most run time messages will be in {logfile}") s.schsco.freqver = util.resize_string("None used", s.schsco.freqver.itemsize, "freqver") s.wlog(1, " ") s.wlog(1, f"Check 'sched.py -h' for command line paramters.") s.wlog(1, "Some useful commands to give now if running interactively:") s.wlog(1, " SCHedule=<filename> : Specify input file.") s.wlog( 1, " PLOT : Invokes uv, xy, rd, and uptime " "plotting.") s.wlog( 1, " FREQLIST=lowF,highF : Make frequency list (MHz). " "Then exit.") s.wlog(1, " EXIT : Leave program.") s.wlog( 1, " / : End of inputs - run program " "(or EXIT).") s.wlog(1, " ") if s.rdcatn.srcvel.shape[0] < s.schn2b.freq.shape[0]: s.errlog("STMSG: Programming error. MVEL .LT. MAXCHN")
def satini(input_iterator): global record_defaults, state_defaults input_iterator.set_defaults(record_defaults, state_defaults) if s.schcon.debug: s.wlog(0, "SATINI: starting.") catalog = SatelliteCatalog() attribute_to_key = dict(zip(catalog.attributes, catalog.attributes)) start = int(s.schsat.nsat) index = start for record in input_iterator: values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) if "endsat" in present: break entry = catalog.entries[index] entry.set_keyin_values(values, attribute_to_key) index += 1 s.wlog( 0, "SATINI: Satellite {} {} {}".format(index, entry.satname, entry.satnum)) for attribute in ["kerfile", "satfile", "tlefile"]: s.wlog( 0, "' {}: {}".format(attribute.upper(), getattr(entry, attribute))) error = False if ("satfile" in present) and ("tlefile" in present): s.wlog( 1, "A satellite can only have a SATFILE or a TLEFILE, " "not both.") error = True if ("satfile" not in present) and ("tlefile" not in present): s.wlog(1, "'SATINI: A satellite must have a SATFILE or a TLEFILE.") error = True if error: s.wlog( 1, " The problem occurred with satellite {} {}".format( index, entry.satname)) s.wlog(1, "' SATFILE: {}".format(entry.satfile)) s.wlog(1, "' TLEFILE: {}".format(entry.tlefile)) s.errlog(" Exactly one of the file names should be specified.") s.schsat.nsat = index catalog.write(range(start, index))
def extend_with(cls, filename, error_message): """ Write a new catalog entry directly into the common blocks and return the (Fortran based) index of the entry """ catalog = cls() catalog.read() # create an entry for the setup file if it is new index = next((index for index, entry in enumerate(catalog.scheduled()) if entry.setfile == filename), None) if (index is None) and (s.schsf.nsetf < catalog.max_setup_files): index = int(s.schsf.nsetf) catalog.entries[index].setfile = filename s.schsf.nsetf += 1 catalog.write(range(index, int(s.schsf.nsetf))) elif (index is None): s.errlog(error_message) return index + 1
def invla(values, present, entries, index, case): warn = True if s.schcon.debug and ((index < 2) or (case != 1)): s.wlog(0, "INVLA: Starting with case: {}".format(case)) if case == 1: entry = entries[index] default = False if index > 0: default = (entries[index - 1].vlatsys == "T") entry.vlatsys = "T" if toggle(values, present, "vlantsys", "vlatsys", default) \ else " " if entry.vlaphs == "": entry.vlaphs = entry.scnsrc if warn and (("vlabw" in present) or ("vlaband" in present)): s.wlog( 1, "INVLA: -- WARNING -- VLABW or VLABAND specified in " "main schedule.") s.wlog(1, "INVLA: They will be ignored.") s.wlog(1, "INVLA: Specify them in the setup files.") warn = False elif case == 2: s.schc3.vlatype = util.resize_string(values["vlatype"], s.schc3.vlatype.itemsize, "vlatype") s.schn3.vlausern = values["vlausern"] s.schn1.iatutc = values["iatutc"] if not s.schcon.noset: if [station[:3] for station in s.schc1.staname[:s.schn1.nsta]].\ count(b"VLA") >= 2: s.wrtmsg(1, "INVLA", "multipleVLA") else: s.errlog("INVLA: Bad case.") s.schn3.vlarfant = values["vlarfant"]
def rfreq(input_iterator): if s.schcon.debug: s.wlog(0, "RFREQ: Starting to read line frequencies") maxlch = s.schlin.restfreq.shape[0] record_defaults = { "lineset": ["", util.upper], "restfreq": [[0.], util.extend_to(maxlch)], "endlines": [None, util.noop], } input_iterator.set_defaults(record_defaults, {}) attribute_to_key = { "linename": "lineset", "restfreq": "restfreq", } catalog = LineRestFrequencyCatalog() start = int(s.schlin.nlgp) index = start found_end = False for record in input_iterator: values, present = util.merge_record_with_defaults( record, record_defaults, {}) if "endlines" in present: found_end = True break if index >= catalog.maxlgp: s.errlog(" SCHED only set up to use {} rest frequency groups.".\ format(catalog.maxlgp)) entry = catalog.entries[index] entry.set_keyin_values(values, attribute_to_key) index += 1 if not found_end: s.errlog("RFREQ: Input data ended while reading spectral line rest " "frequencies.") catalog.write(range(start, index)) s.schlin.nlgp = index
def apply_tape_offset(scans, scan_offset, stations, setups): for scan_index, scan in enumerate(scans, scan_offset): stations_in_scan = [ station for station in stations if station.stascn[scan_index] ] tape_starts = { station.tpstart[scan_index] for station in stations_in_scan } if len(tape_starts) == 0: continue if len(tape_starts) > 1: # -1 and +1: from FORTRAN index <-> python index min_pause = max(station.tpstart[scan_index] / setup[station.nsetup[scan_index] - 1].speedup for station in stations_in_scan) s.prtscn(scan_index + 1, "VXSCHK") s.errlog("Station tape starts differ, set MINPAUSE to {}s to " "produce VEX file!".format(round(min_pause * secpday))) tape_start = tape_starts.pop() scan.startj -= tape_start
def rdpeak_open(stdin): if (s.schcon.debug): s.wlog(0, "RDPEAK starting") s.schpeakn.dopoint = s.schcon.autopeak or \ (s.schn2a.point[:s.schn1.nscans] >= 0).any() peakfile = bytes(s.schsco.peakfile).decode().strip() if (peakfile.upper() == "NONE") or not s.schpeakn.dopoint: return try: f = open(peakfile, "r") except Exception as e: s.wlog(1, str(e)) s.wlog(1, "RDPEAK: Automatic insertion and/or conversion of scans " "was requested.") s.wlog(1, " PEAKFILE needed, but could not be opened.") s.wlog(1, " Problem is with file: ") s.wlog(1, peakfile) s.wlog(1, " Note that file peak.cmd could be used") s.wlog(1, " It is with the standard catalogs.") s.errlog(" Fix PEAKFILE or do not invoke AUTOPEAK or POINT.") with f: rdpeak_implementation(key.KeyfileIterator(f), stdin)
def getset(): if s.schcon.debug: s.wlog(0, "GETSET: Starting.") for index, entry in enumerate(SetupFileCatalog().read()): setfilename = entry.setfile if setfilename in {"DUMMY", "DEFAULT"}: s.errlog(" SETUP file required. ") else: if setfilename not in \ (entry.setname for entry in SetupCatalog().read()): try: f = open(setfilename, "r") except Exception as e: s.wlog(1, str(e)) s.errlog("RDSET: Problem opening setup file") with f: input_iterator = key.KeyfileLister(f) rdset(setfilename, input_iterator, index + 1) s.setn2a.fifmin[:, :s.setn1.nset].setfield(0., dtype=s.setn2a.fifmin.dtype) s.setn2a.fifmax[:, :s.setn1.nset].setfield(1e15, dtype=s.setn2a.fifmax.dtype) s.setn2a.corinv[:, :s.setn1.nset].setfield(0., dtype=s.setn2a.corinv.dtype)
def getsta(stdin, values, index, gotvex, mjd1): global last_station_file maxsta = StationCatalog.maxcat if s.schcon.debug and (index < 2): s.wlog(1, "GETSTA: starting.") if index == 0: last_station_file = "" station_file = util.expand_file_name(values["stafile"]) s.schcst.stafile = util.resize_string(station_file, s.schcst.stafile.itemsize, "stafile") s.schcst.locafile = util.resize_string( util.expand_file_name(values["locfile"]), s.schcst.locafile.itemsize, "locfile") if (station_file.upper() != "NONE") and (station_file != last_station_file): try: f = open(station_file, "r") except Exception as e: s.putout(str(e)) s.error("Station catalog: {} not opened".format(station_file)) else: with f: input_iterator = key.KeyfileLister(f) stread(input_iterator, stdin, mjd1) last_station_file = station_file if (index == 0) and (len(values["stations"]) == 0): s.errlog("GETSTA: No stations specified!") elif len(values["stations"]) == 0: s.schn2a.stascn[index] = s.schn2a.stascn[index - 1] else: s.schn2a.stascn[index] = False for station in values["stations"]: ksta, ista, doit = s.stano(station) if doit: if ksta == 0: s.wlog(1, "GETSTA: Station {} not found in catalogs".\ format(station)) s.errlog("GETSTA: Note -- specify station catalog " "before end of first scan input") if ista == 0: s.schn1.nsta += 1 if s.schn1.nsta > maxsta: s.errlog("'SCHIN: Too many stations!") ista = s.schn1.nsta s.schc1.staname[ista - 1] = s.schcst.station[ksta - 1] s.schn1.stanum[ista - 1] = ksta s.schsta.ischsta[ksta - 1] = ista control = bytes(s.schcst.control[s.schn1.stanum[ista-1]]).\ decode().strip() if control == "VEX ": gotvex = True if control == "VSOP": s.schcon.dovsop = True if s.schc1.staname[ista - 1][:4] != b"VLBA": s.schn5.allvlba = False else: s.schn1.gotvlba = True s.schn2a.stascn[index][ista - 1] = True return gotvex
def rdpeak_implementation(input_iterator, stdin): global first_call if first_call: s.schpeakn.pkgroup.fill(0) s.schpeakn.npkgrp = 0 first_call = False input_name = "Program input" if input_iterator.input_ is stdin \ else input_iterator.input_.name state_defaults = { "srcfile": [schdefs("refpointing"), util.noop], "setup": ["", util.expand_file_name], "setupl": ["", util.expand_file_name], "minfreq": [60e3, util.noop], "minel": [30., util.noop], "dwell": [60., util.multiply_by(1 / 86400.)], "linename": ["", util.upper], "vlamode": ["", util.upper], } record_defaults = { "stations": [[], util.foreach(util.upper)], "sources": [[], util.foreach(util.upper)], "lineinit": [None, util.noop], "endpeak": [None, util.noop], } input_iterator.set_defaults(record_defaults, state_defaults) # map from catalog entry attributes to keyin keywords attribute_to_key = { "pklines": "linename", "pvlamode": "vlamode", "pkdwell": "dwell", "pkminfq": "minfreq", "pkminel": "minel", "psetfile": "setup", "plsetfil": "setupl", "pksta": "stations", "pksrc": "sources", } catalog = PeakCatalog() start = int(s.schpeakn.npkgrp) index = start for record in input_iterator: values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) if "endpeak" in present: break if "lineinit" in present: rfreq(input_iterator) continue if index >= catalog.maxpeak: s.errlog("RDPEAK: Too many reference pointing groups (Max {}) " "in: {}".format(catalog.maxpeak, input_name)) entry = catalog.entries[index] entry.set_keyin_values(values, attribute_to_key) if entry.plsetfil == "": entry.plsetfil = entry.psetfile s.wlog(1, "RDPEAK: WARNING: Your peak command file does not " "have a separate setup file") s.wlog(1, " for spectral line (narrow band) sources. " "You may encounter errors" ) s.wlog(1, " because the digital backends require " "sample rate = 2 times bandwidth ") s.wlog(1, " and the sample rate can only be changed " "with a new setup file.") def check_pointing_setup(filename): return SetupFileCatalog.extend_with( filename, "RDPEAK: Exceeded limit on number of setup files while adding " "ones needed for reference pointing.") entry.pklset = check_pointing_setup(entry.psetfile) entry.pklsetl = check_pointing_setup(entry.plsetfil) if (len(entry.pksta) == 0) and index > 0: entry.pksta = catalog.entries[index-1].pksta elif len(entry.pksta) == 0: s.errlog("RDPEAK: First peak group has no stations.") if (len(entry.pksrc) == 0) and index > 0: entry.pksrc = catalog.entries[index-1].pksrc elif len(entry.pksrc) == 0: s.errlog("RDPEAK: First peak group has no sources.") index += 1 if index == 0: s.wlog(0, "RDPEAK: No pointing instruction groups found in ") s.wlog(0, input_name) s.schpeakn.npkgrp = index s.schpeakc.psrcfile = util.resize_string(util.expand_file_name( state_defaults["srcfile"][0]), s.schpeakc.psrcfile.itemsize, "srcfile") catalog.write(range(start, index))
def getfreq(): freqfile = bytes(s.schsco.freqfile).decode().strip() s.wlog(0, "GETFREQ: Reading frequency file: {}".format(freqfile)) try: f = open(freqfile, "r") except Exception as e: s.wlog(1, str(e)) s.errlog("GETFREQ: Problem opening frequency file") else: with f: keyin_data = read_keyfile(f) catalog = FrequencyCatalog() if len(keyin_data) > catalog.maxfreq: s.errlog("GETFREQ: Too many frequency groups. ") maxsta = s.frqc.fstnam.shape[0] state_defaults = {"version": ["", util.noop]} record_defaults = { "station": [[""] * maxsta, util.foreach(util.upper)], "name": ["", util.noop], "note": ["", util.noop], "priority": [0., util.noop], "ifname": [[], util.noop], "altifn": [[], util.noop], "fe": [[], util.foreach(util.lower)], "pol": [[], util.foreach(util.upper)], "rf1": [[], util.noop], "rf2": [[], util.noop], "lo1": [[], util.noop], "ch1rf1": [[], util.noop], "ch1rf2": [[], util.noop], "dualx": [1., util.to_bool], "syn": [[0., 0., 0.], util.noop], "lcp50cm": ["NARROW", util.upper], "rcp50cm": ["NARROW", util.upper], "vlabw": [None, util.noop], # not used "vlaband": [None, util.noop], # not used "flukea": [None, util.noop], # not used "flukeb": [None, util.noop], # not used "vlafeab": [None, util.noop], # not used "vlafecd": [None, util.noop], # not used "vlasyna": [None, util.noop], # not used "vlasynb": [None, util.noop], # not used "fefilter": [None, util.noop], # not used "tscal": [None, lambda x: x if x is None else x.upper()] } # map from frequency catalog entry attributes to keyin keywords attribute_to_key = { "frname": "name", "frnote": "note", "fstnam": "station", "prio": "priority", "fifnam": "ifname", "faltif": "altifn", "tscal": "tscal" } # above are the exceptions to the rule: remove first 'f' to go from # attribute to key attribute_to_key.update({ attribute: attribute[1:] for attribute in catalog.attributes if attribute not in attribute_to_key.keys() }) for index, record in enumerate(keyin_data): values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) # copy all values to the common block placeholder entry = catalog.entries[index] entry.set_keyin_values(values, attribute_to_key) if entry.tscal not in (None, "CONT", "GAP"): raise RuntimeError("Unknown TSCAL in frequency catalog for {} " "entry {}: {}".format(entry.station, entry.name, entry.tscal)) catalog.write(range(len(keyin_data))) s.frqn.nfreq = len(keyin_data) s.schsco.freqver = util.resize_string(state_defaults["version"][0], s.schsco.freqver.itemsize, "version") s.listfreq()
def gettim(values, entries, index, start, stop, day, year, mjd1): day[index] = values["day"] month = values["month"] year[index] = values["year"] if year[index] < 100 and year[index] != 0: s.errlog("GETTIM: Don''t use 2 digit year!") if (day[index] != 0) and (month > 1): year[index], day[index], error = s.sla_calyd( year[index], month, day[index]) if error == 2: s.errlog("GETTIM: Bad month ") if error == -1: s.errlog("GETTIM: Unlikely year ") start[index] = values["start"] / 86400. \ if values["start"] != parameter.unset else parameter.unset stop[index] = values["stop"] / 86400. \ if values["stop"] != parameter.unset else parameter.unset entry = entries[index] if index == 0: if day[index] > 366: myear, mday, mut = s.lst2ut(0., day[index], 0.) mjd1, error = s.sla_cldj(myear, 1, mday) if error not in [0, 3]: s.errlog("GETTIM: Problem converting day to MJD") else: mjd1, error = s.sla_cldj(year[index], 1, day[index]) if error not in [0, 3]: s.errlog("GETTIM: Problem getting MJD of first scan before " "station catalog read.") if (values["dwell"][0] != parameter.unset) and \ (values["duration"] != parameter.unset): s.errlog("GETTIM: Don''t specify both DUR and DWELL! Input scan: {}".\ format(index+1)) elif values["dwell"][0] != parameter.unset: entry.dwell = True entry.dur = values["dwell"][0] / 86400. entry.nowait = values["dwell"][1] entry.mindw = values["dwell"][2] / 86400. elif values["duration"] != parameter.unset: entry.dwell = False entry.dur = values["duration"] / 86400. entry.nowait, entry.mindw = (0, 0.) else: if index == 0: entry.dwell = False entry.dur, entry.nowait, entry.mindw = (0., 0, 0.) else: prev = entries[index - 1] entry.dwell, entry.dur, entry.nowait, entry.mindw = \ prev.dwell, prev.dur, prev.nowait, prev.mindw s.schn1.dwells |= entry.dwell return mjd1
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 rdset(setreq, input_iterator, isetf): s.setn1.sdebug = s.schcon.debug if s.setn1.sdebug: print("RDSET SDEBUG=", s.setn1.sdebug) if s.schcon.debug: s.wlog(0, "RDSET: Reading setup {} {}".format(isetf, setreq)) catalog = SetupCatalog() start = int(s.setn1.nset) index = start if next((entry for entry in catalog.entries[:index] \ if entry.setname == setreq), None) is not None: s.wlog(1, "RDSET: Duplicate setup file name? ") s.wlog(1, "RDSET:{}".format(setreq)) s.errlog("Check setup file names") s.wlog(0, "RDSET: Reading setup file: {}".format(setreq)) mchan = s.setn2a.freqref.shape[0] maxpc = s.setc2.pcalx1.shape[0] state_defaults = { "logging": ["STANDARD", util.noop], "noisefrq": ["VLBA", util.upper], "fe": [["omit"] * 4, util.foreach(util.lower)], "noise": [["low-s"] * 4, util.noop], "ifdist": [[0] * 4, util.foreach( lambda x: x.lower() if isinstance(x, str) else str(int(x)))], "azcolim": [0., util.noop], "elcolim": [0., util.noop], "ptincr": [0., util.noop], "ptoff": [0., util.noop], "period": [1, util.noop], "level": [-1, util.noop], "samprate": [0., util.noop], "dualx": [1., util.to_bool], "synth": [[0.] * 3, util.noop], "frswitch": [1., util.to_bool], "tpmode": [0., util.noop], "format": ["", util.upper], "modetest": [1., util.to_bool], "dbe": ["", util.upper], "swtchdur": [15., util.noop], "firmfile": ["", util.noop], "barrel": ["not_set", util.lower], "tpspeedh": [0., util.noop], "tpspeedl": [0., util.noop], "tpspeed": [0., util.noop], "lcp50cm": ["DEF", util.upper], "rcp50cm": ["DEF", util.upper], "rchan": ["", util.upper], "lchan": ["", util.upper], "nchan": [0, int], "band": ["", util.lower], "firstlo": [[parameter.unset], util.extend_to(mchan)], "bbsyn": [[0.] * mchan, util.noop], "bbsyn2": [[0.] * mchan, util.noop], "bbfilter": [[0.], util.extend_to(mchan)], "sideband": [[" "], util.chain(util.foreach(util.upper), util.extend_to(mchan))], "netside": [[" "], util.chain(util.foreach(util.upper), util.extend_to(mchan))], "ifchan": [[""] * mchan, util.foreach(util.upper)], "bits": [[1], util.extend_to(mchan)], "bbc": [[0.] * mchan, util.noop], "freqoff": [[0.] * mchan, util.noop], "freqref": [[0.], util.extend_to(mchan)], "pol": [[""], util.chain(util.foreach(util.upper), util.extend_to(mchan))], "track1": [[0.] * mchan, util.noop], "track2": [[0.] * mchan, util.noop], "track3": [[0.] * mchan, util.noop], "track4": [[0.] * mchan, util.noop], "track5": [[0.] * mchan, util.noop], "track6": [[0.] * mchan, util.noop], "track7": [[0.] * mchan, util.noop], "track8": [[0.] * mchan, util.noop], "string1": ["", util.noop], "string2": ["", util.noop], "string3": ["", util.noop], "string4": ["", util.noop], "pcal": ["1MHZ", util.upper], "pcalxb1": [[""] * maxpc, util.foreach(util.upper)], "pcalxb2": [[""] * maxpc, util.foreach(util.upper)], "pcalfr1": [[0.] * maxpc, util.noop], "pcalfr2": [[0.] * maxpc, util.noop], "m4patch": ["astro", util.upper], "dbbcfw": ["", util.chain( lambda x: str(x).rstrip("0").rstrip(".") if type(x) == float else x, util.upper)], } record_defaults = { "station": [[""] * s.setc2.setsta.shape[0], util.foreach(util.upper)], "endset": [None, util.noop], } input_iterator.set_defaults(record_defaults, state_defaults) old_vla_parameters = {"flukeset", "flukea", "flukeb", "vlafeab", "vlafecd", "vlasyna", "vlasynb", "fefilter", "vlaif", "vlarot", "vlaband", "vlabw"} record_defaults.update( {key: [None, util.noop] for key in old_vla_parameters}) attribute_to_key = { "setsta": "station", "speedh": "tpspeedh", "speedl": "tpspeedl", "sidebd": "sideband", "pcalx1": "pcalxb1", "pcalx2": "pcalxb2", "bbfilt": "bbfilter", "spcal": "pcal", } # update with default identity mapping, # skip keys not stored directly attribute_names = set(itertools.chain(state_defaults.keys(), record_defaults.keys())) - \ {"tpspeed", "freqoff", "track1", "track2", "track3", "track4", "track5", "track6", "track7", "track8", "string1", "string2", "string3", "string4", "endset", } - \ old_vla_parameters attribute_to_key.update({attribute: attribute for attribute in attribute_names if attribute not in attribute_to_key.values()}) for record in input_iterator: values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) if "endset" in present: break if index >= catalog.maxsetup: s.errlog("RDSET: Too many setup groups ") entry = catalog.entries[index] entry.set_keyin_values(values, attribute_to_key) entry.setname = setreq entry.isetnum = isetf if entry.ptoff <= 0.: entry.ptoff = 6. * entry.ptincr if (entry.speedl == 0.) and (values["tpspeed"] != 0.): entry.speedl = values["tpspeed"] if entry.nchan > mchan: s.errlog("RDSET: Too many channels in {}".format(setreq)) justvla = all(station[:3] in ("VLA", "") for station in entry.setsta) \ and (entry.format == "NONE") and (entry.nchan == 0) if not justvla: if entry.nchan < 1: s.errlog("RDSET: NCHAN must be greater than 0.") entry.freqref = [entry.freqref[i] + values["freqoff"][i] for i in range(entry.nchan)] for ichan in range(entry.nchan): pol_map = {"R": "RCP", "L": "LCP"} if entry.pol[ichan] in pol_map.keys(): entry.pol[ichan] = pol_map[entry.pol[ichan]] elif (entry.ifchan[ichan] in pol_map.keys()) and \ (entry.pol[ichan] == ""): entry.pol[ichan] = pol_map[entry.ifchan[ichan]] if entry.ifchan[ichan] == "R": entry.ifchan[ichan] = entry.rchan if entry.ifchan[ichan] == "L": entry.ifchan[ichan] = entry.lchan entry.track = [values["track" + n] for n in "12345678"] #enf of if not justvla entry.string_bn = [values["string" + n] for n in "1234"] if any(values[key] is not None for key in old_vla_parameters): s.wlog(1, "RDSET - WARNING: Old VLA parameters used in input " "setup: {}".format(index + 1)) s.wlog(1, " They are no longer used and will be " "removed soon. ") pcal_map = { "OFF": "off", "1MHZ": "1MHz", "5MHZ": "5MHz" } if entry.spcal in pcal_map.keys(): entry.spcal = pcal_map[entry.spcal] else: s.errlog("CHKSET: Invalid PCAL specification: {}".format( entry.spcal)) if (entry.dbbcfw not in ("", "104", "105", "105E", "105F", "106E", "106F", "107")) and \ (entry.dbbcfw not in dbbc_firmware_warnings): s.wlog(1, "RDSET - WARNING: {} is not a known DBBC firmware " "version.".format(entry.dbbcfw)) s.wlog(1, " Heuristics might still work, but check " "schedule carefully.") dbbc_firmware_warnings.add(entry.dbbcfw) index += 1 s.setn1.nset = index catalog.write(range(start, index))
def chkset(ks): global itout, warn2cm setup_entry = SetupCatalog().read()[ks - 1] station_catalog = StationCatalog() station_catalog.read() station_catalog.read_non_scan_scheduled_attributes() station_entry = station_catalog.entries[setup_entry.isetsta - 1] if s.schcon.debug: s.wlog(0, "CHKSET: Starting on {} in:".format(setup_entry.setsta[0])) s.wlog(0, " {}".format(setup_entry.setname)) errs = False sampwarn = True if s.schn1.notape and (setup_entry.format != "NONE"): obstype = f2str(s.schsco.obstyp) s.wlog( itout, "CHKSET: *** WARNING - OBSTYPE={} but setup has " "FORMAT={}".format(obstype, setup_entry.format)) s.wlog(itout, " No tapes will be recorded with this OBSTYPE.") if obstype == "NONE": s.wlog( itout, " NONE is the default OBSTYPE. " "Did you forget to specify it?") else: s.wlog(itout, " Was this intended?") itout = 0 if not s.schn1.vlaonly: if s.schn1.mark2 and (setup_entry.format != "MARKII"): s.wlog( 1, "CHKSET: For OBSTYP=MKII, FORMAT must be MARKII, not: " "{}".format(setup_entry.format)) errs = True if (s.schcon.dovex or s.schcon.dovsop) and setup_entry.frswitch: s.wlog(1, "CHKSET: Cannot frequency switch with VEX or VSOP file.") if len(setup_entry.channel) < 1: s.wlog( 1, "CHKSET: Setup file must have at least 1 channel unless " "OBSTYPE=VLA.") s.errlog("CHKSET: The error is in {}".format(setup_entry.setname)) overwarn = False for ich, channel in enumerate(setup_entry.channel): if channel.sidebd not in ("U", "L"): s.wlog( 1, "CHKSET: Sideband not U or L in {}".format( setup_entry.setname)) errs = True if channel.pol[:3] not in ("RCP", "LCP", "X", "Y"): s.wlog(1, "CHKSET: In setup {} polarization of chan {} " "not given or deduced (should be RCP, LCP, X or Y).".\ format(setup_entry.setname, ich+1)) errs = True for jch, other in enumerate(setup_entry.channel[ich + 1:], ich + 1): if (channel.pol != other.pol) and \ (channel.ifchan == other.ifchan): s.wlog( 1, "CHKSET: In setup {} IF channel {} is " "assigned to {} in chan {} and to {} in chan {} " "Not possible.".format(setup_entry.setname, channel.ifchan, channel.pol, ich + 1, channel.pol, jch + 1)) errs = True if s.schn1.vlbitp: if channel.bbfilt > 0.5001 * setup_entry.samprate: s.wlog(1, "CHKSET: Bandwidth more than half of sample rate") errs = True if (channel.bbfilt < 0.4999 * setup_entry.samprate) \ and sampwarn: s.wlog(0, "CHKSET note: Oversampling specified.") sampwarn = False if ich > 0: freq_i = freq_range(channel) for jch, other in enumerate(setup_entry.channel[:ich - 1]): if channel.pol == other.pol: freq_j = freq_range(other) if (freq_j[0] <= freq_i[0] < freq_j[1]) or \ (freq_j[0] < freq_i[1] <= freq_j[1]): overwarn = True # end of channel loop if overwarn: s.wlog( 1, "CHKSET: Setup file: {} Has overlapping channels. " "Intended?".format(setup_entry.setname)) if station_entry.dar.startswith("RDBE"): errs = s.chkrdbe(ks, errs) if station_entry.dar.startswith("DBBC"): errs = chkdbbc(ks, setup_entry, station_entry) or errs if station_entry.dar == "eMERL": errs = check_emerlin(setup_entry, station_entry) or errs if station_entry.dar == "WIDAR": errs = s.chkwidar(ks, errs) if station_entry.dar in ("VLBA", "VLBAG", "VLBA4"): errs = s.chkvdar(ks, station_entry.nbbc, errs) if station_entry.dar == "VLBA4": errs = s.chkv4dar(ks, errs) if station_entry.dar == "VLBAG": errs = s.chkgdar(ks, errs) if station_entry.dar == "MKIV": errs = s.chk4dar(ks, station_entry.nbbc, errs) if station_entry.dar == "CDAS": errs = s.chkcdas(ks, errs) if s.schn1.vlbitp: if station_entry.usedisk: errs = s.chkdisk(ks, errs) if station_entry.recorder in ("VLBA", "MKIV", "VLBA4") and \ (setup_entry.format != "NONE"): errs = s.chkspd(ks, errs) if len(np.unique(setup_entry.bits)) > 1: s.wlog( 1, "CHKSET: All channels must use the same number of " "bits.") errs = True # end of if not vlaonly if warn2cm and (15100 < setup_entry.channel[0].freqref < 15500) and \ setup_entry.setsta[0].startswith("VLBA") and (setup_entry.totbps < 1000): s.wlog(1, " ") s.wlog( 1, "CHKSET: See sched.runlog for information on 2cm " "frequencies.") s.wrtmsg(0, "CHKSET", "warn2cm") warn2cm = False if setup_entry.setsta[0].startswith("VLBA"): errs = s.chkvlba(ks, errs) if setup_entry.setsta[0].startswith("VLA"): errs = s.chkvla(ks, errs) if errs: s.wlog(1, "CHKSET: Freq groups used or checked:") frequencies = FrequencyCatalog().read() for ich, channel in enumerate(setup_entry.channel): if channel.ifreqnum > 0: s.wlog( 1, " Channel: {} Frequency Group: {}".format( ich + 1, frequencies[channel.ifreqnum - 1].frname)) s.errset(ks)
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 schin(stdin): global record_defaults, state_defaults catalog = ScanCatalog() year = np.zeros(shape=(catalog.maxscan, ), dtype="int32") day = np.zeros(shape=(catalog.maxscan, ), dtype="int32") stop = np.zeros(shape=(catalog.maxscan, ), dtype="double") start = np.zeros(shape=(catalog.maxscan, ), dtype="double") mjd1 = 0 if state_defaults["schedule"][0] == "": input_ = stdin else: try: input_ = open(util.expand_file_name(state_defaults["schedule"][0]), "r") except Exception as e: s.wlog(1, str(e)) s.errlog("SCHFILES: Problem opening schedule file {}".format( state_defaults["schedule"][0])) # the iterator might change, from file/stdin to (another) file, input_iterator = key.KeyfileIterator(input_, record_defaults, state_defaults) s.schn1.nsta = 0 s.schsat.nsat = 0 marker = -1 s.schsta.msta = 0 s.schsou.msrc = 0 s.schsf.nsetf = 0 s.schn1.scan1 = 1 s.schsou.ngeo = 0 gotsat = False doinit = True s.schn1.dwells = False dostwarn = True s.schcon.dovex = True gotvex = False s.schcon.coverlet = False s.schn5.allvlba = True s.schsou.anygeo = False s.schn1.fuzzy = False s.schn1.gotvlba = False s.schn1.gotpreem = False s.schn2a.srcnum.fill(0) s.schn2a.idopsrc.fill(0) s.schn3.ivlaphs.fill(0) s.schn3.vlainteg.fill(0) s.schsou.sused.fill(False) s.schsou.usedrec.fill(False) s.schsou.usedphs.fill(False) s.schsou.usedcent.fill(False) s.schn1.srcatn.fill(0) s.schsou.srlstn.fill(0) s.schsou.didndop.fill(0) s.schsou.dopped.fill(False) s.schcsc.csused.fill(b' ') s.schsou.planet.fill(False) s.schsou.satel.fill(False) s.schsou.satn.fill(0) s.schn2a.nintent = 0 s.schc2c.intent.fill(b' ' * s.schc2c.intent.itemsize) s.schn2a.nscint.fill(0) s.schn2a.iscint.fill(0) restart = False index = 0 while True: try: record = next(input_iterator) # a weird one, only dwell[0]'s default does not carry over state_defaults["dwell"][0][0] = parameter.unset # make a new scanexps overwrite the old list, # instead of the default behaviour of slicing into it old_scanexps = state_defaults["scanexps"][0] state_defaults["scanexps"][0] = [] if restart: old_values, old_present = values, present values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) values.update({ k: old_values[k] for k in keep_for_next if k not in present }) present.update(old_present & keep_for_next) restart = False else: values, present = util.merge_record_with_defaults( record, record_defaults, state_defaults) if "scanexps" not in present: state_defaults["scanexps"][0] = old_scanexps values["scanexps"] = old_scanexps if "exit" in present: if index == 0: s.wlog(1, "SCHIN: EXIT requested. Shutting down.") s.delscr(False) sys.exit(0) break s.schcon.debug = values["debug"] s.schcon.overwrit = values["overwrite"] s.schcon.override = values["override"] s.schsco.msgfile = util.resize_string( util.expand_file_name(values["msgfile"]), s.schsco.msgfile.itemsize, "msgfile") if s.schcon.debug and (index < 3): s.wlog(0, "DIVERT: Starting") s.schcon.freqlist = values["freqlist"] if "freqlist" in present: s.schsco.freqfile = util.resize_string( util.expand_file_name(values["freqfile"]), s.schsco.freqfile.itemsize, "freqfile") getfreq() s.wlog(1, "DIVERT: Frequency table written. Stopping.") sys.exit(0) s.schcon.noset = values["nosetup"] s.schcon.plot = values["plot"] s.schcon.pubplot = values["pubplot"] schedule = util.expand_file_name(values["schedule"]) if (schedule != "") and \ ((input_iterator.input_ is stdin) or (input_iterator.input_.name != schedule)): if s.schcon.debug: s.wlog(0, "SCHFILES: About to open {}".format(schedule)) if input_iterator.input_ is not stdin: input_iterator.input_.close() try: input_ = open(schedule, "r") input_iterator = key.KeyfileIterator( input_, record_defaults, state_defaults) restart = True continue # read next record from new iterator except Exception as e: s.wlog(1, str(e)) s.errlog("SCHFILES: Problem opening schedule file {}".\ format(schedule)) gotsat, restart = schfiles(input_iterator, stdin, values, present, gotsat) input_iterator.set_defaults(record_defaults, state_defaults) if restart: continue if index > catalog.maxscan: s.errlog("SCHIN: Too many scans, maximum {}".format( catalog.maxscan)) entry = catalog.entries[index] s.schsco.dosta = util.resize_string(values["dosta"], s.schsco.dosta.itemsize, "dosta") if (values["dosta"] != "ALL") and dostwarn: s.wlog(0, "SCHIN: DOSTA specified as {}".format(values["dosta"])) s.wlog(0, " Some stations may be skipped.") dostwarn = False # nopeak overwrites peak and its default if "nopeak" in present: state_defaults["peak"][0] = values["peak"] = -1. if ("scanexps" in present) and \ ("NONE" in (v.upper() for v in values["scanexps"])): state_defaults["scanexps"][0] = values["scanexps"] = [] entry.set_keyin_values(values, attribute_to_key) mjd1 = gettim(values, catalog.entries, index, start, stop, day, year, mjd1) gotvex = getsta(stdin, values, index, gotvex, mjd1) if entry.scnsrc == "": s.errlog("SCHIN: Need source name - blank specified.") if entry.geolen > 0: s.schsou.anygeo = True entry.geoiscn = index + 1 pcal_map = {"OFF": "off", "1MHZ": "1MHz", "5MHZ": "5MHz"} if entry.pcal in pcal_map.keys(): entry.pcal = pcal_map[entry.pcal] elif entry.pcal != "": s.errlog("SCHIN: Invalid PCAL ({}) specified in scan {}".\ format(entry.pcal, index+1)) if entry.preempt == "EXTRA": s.schn1.fuzzy = True elif entry.preempt == "--": if entry.geolen > 0.: entry.preempt = "NO" else: entry.preempt = "OK" if entry.preempt != "OK": s.schn1.gotpreem = True gintent(values["intents"], catalog.entries, index) # toggle pairs if index == 0: get_default = lambda attribute: False else: prev_entry = catalog.entries[index - 1] get_default = lambda attribute: getattr(prev_entry, attribute) for attribute, key1, key2 in (("notsys", "notsys", "tsys"), ("norec", "norecord", "record"), ("pntvlba", "ptvlba", "noptvlba"), ("tanvlba", "tavlba", "notavlba"), ("dopn3db", "pn3db", "nopn3db")): setattr( entry, attribute, toggle(values, present, key1, key2, get_default(attribute))) s.schcon.autopeak = values["autopeak"] s.schcon.pkwatch = values["pkwatch"] s.schsco.peakfile = util.resize_string( util.expand_file_name(values["peakfile"]), s.schsco.peakfile.itemsize, "peakfile") entry.setnum = SetupFileCatalog.extend_with( util.expand_file_name(values["setup"]), " SCHIN: Too many setup files. ") infdb(values, present, catalog.entries, index) invla(values, present, catalog.entries, index, 1) index, marker = schrep(values, catalog.entries, index, marker, start, stop, day, year) if "nchan" in present: s.wlog(1, "SCHIN: NCHAN in main schedule now ignored.") if s.schcon.debug: s.wlog(0, "SCHIN: Finished reading scan: {}".format(index + 1)) index += 1 except StopIteration: break # end of scan reading loop if input_iterator.input_ is not stdin: input_iterator.input_.close() s.schn1.nscans = index s.schn1.scanl = s.schn1.nscans if index <= 0: s.errlog("SCHIN: No input scans") s.schn1.wrap24 = values["wrap24"] if s.schn1.wrap24: for from_ in range(s.schn1.scanl): if from_ > 0: if (start[from_] != parameter.unset) or \ (stop[from_] != parameter.unset): s.errlog("SCHIN: Do not use START or STOP times " "after scan 1 with WRAP24. See scan: {}".\ format(from_+1)) to = from_ + s.schn1.nscans scndup(to, from_, False, "SCHIN", use_direct_access=False) catalog.entries[to].annot = catalog.entries[from_].annot start[to] = parameter.unset stop[to] = parameter.unset day[to] = day[from_] year[to] = year[from_] s.schn1.scanl = 2 * s.schn1.nscans s.schn1.nscans = s.schn1.scanl index *= 2 s.schc1.expt = util.resize_string(values["expt"], s.schc1.expt.itemsize, "expt") s.schc1.expcode = util.resize_string(values["expcode"], s.schc1.expcode.itemsize, "expcode") s.schcon.linepg = values["linepg"] s.schn5.tpref = values["tpref"] s.schn4.ptdur = values["ptdur"] s.schcon.precdate = values["precdate"] s.schcon.dovex = (values["dovex"] or gotvex) s.schcon.vextest = values["vextest"] s.schcon.domka = values["domka"] s.schsco.ephfile = util.resize_string( util.expand_file_name(values["ephfile"]), s.schsco.ephfile.itemsize, "ephfile") s.chkcode(s.schc1.expcode) obstype = values["obstype"] if obstype[:4] == "MARK": obstype = "MK" + obstype[4:] s.schsco.obstyp = util.resize_string(obstype, s.schsco.obstyp.itemsize, "obstype") s.schn1.mark2 = (obstype == "MKII") s.schn1.vlbitp = (obstype in ("VLBA", "MKIII", "VLBI", "MKIV")) s.schn1.vlaonly = (obstype == "VLA") s.schn1.notape = (obstype in ("VLA", "NONE", "PTVLBA", "CONFIG")) s.schn1.config = (obstype == "CONFIG") if not (s.schn1.mark2 or s.schn1.vlbitp or s.schn1.vlaonly or obstype in ("NONE", "PTVLBA", "CONFIG")): s.wlog(1, " SCHIN: Invalid OBSTYPE: {}".format(obstype)) s.errlog(" SCHIN: OBSTYPE must be MKII, MKIII, VLBA, MKIV, " "VLBI, VLA, NONE, or CONFIG") s.schn1.doscans = values["doscans"] if ((s.schn1.doscans[0] == 0) != (s.schn1.doscans[1] == 0)): s.errlog("If using DOSCANS, specify both!") s.schsco.optmode = util.resize_string(values["optmode"], s.schsco.optmode.itemsize, "optmode") s.schcon.opdur = values["opdur"] s.schcon.opnosub = values["opnosub"] s.schcon.opskip = values["opskip"] s.schcon.optslew = values["optslew"] s.schcon.optlowt = values["optlowt"] s.schsco.ophasta = util.resize_string(values["ophasta"], s.schsco.ophasta.itemsize, "ophasta") s.schcon.tapesync = values["tapesync"] s.schcon.opprtlev = values["opprtlev"] s.schcon.opelprio = values["opelprio"] s.schcon.maplim = values["maplim"] s.schcon.gridnr = values["gridnr"] s.schcon.gridnt = values["gridnt"] s.schcon.gridmin = values["gridmin"] s.schcon.gridmax = values["gridmax"] s.schcon.gridw0 = values["gridw0"] s.schcon.gridstep = values["gridstep"] s.schsco.gridmeas = util.resize_string(values["gridmeas"], s.schsco.gridmeas.itemsize, "gridmeas") s.schcon.gridvla = values["gridvla"] s.schcon.gridused = False s.schcon.nmfs = values["uvmfs"][0] s.schcon.mfsrat = values["uvmfs"][1] mgeo = s.schsou.geosrci.shape[0] geosrcs = [ util.resize_string(src, s.schcsc.geosrc.itemsize, "geosrcs") for src in values["geosrcs"] ] s.schsou.ngeo = len(geosrcs[:mgeo]) for i, src in enumerate(geosrcs): s.schcsc.geosrc[i] = src if s.schsou.anygeo and s.schsou.ngeo == 0: s.errlog("Geodetic segments requested, but no GEOSRCS given.") if s.schsou.anygeo: for entry in catalog.entries: if entry.scnsrc == "GEOSEG": entry.scnsrc = geosrcs[0] s.schsou.geoprt = values["geoprt"] s.schsou.geotries = values["geotries"] s.schsou.geoback = values["geoback"] s.schsou.geoslew = values["geoslew"] s.schsou.geoslow = values["geoslow"] s.schsou.geosrep = values["geosrep"] s.schsou.geohiel = values["geohiel"] s.schsou.geolowel = values["geolowel"] getcov(values) getcor(values) s.schn4.rotpat = values["rotpat"] s.schn4.foc = values["focoff"] s.schn4.rot = values["rotoff"] if "tapefile" in present: s.errlog("TAPEFILE given but tape initialization no longer " "supported by SCHED") s.tptpns() for i, sumitem in enumerate(values["sumitem"]): s.schsco.sumitem[i] = util.resize_string(sumitem, s.schsco.sumitem.itemsize, "sumitem") if values["sumitem"][0] == "": s.schsco.sumitem[0] = "ELA".ljust(s.schsco.sumitem.itemsize) s.schsco.sumitem[1] = "DWELL".ljust(s.schsco.sumitem.itemsize) invla(values, set(), catalog.entries, index, 2) # index is dummy in case 2 if s.schcon.debug: s.wlog(0, "SCHIN: About to read catalogs.") catalog.write(range(index)) times(values["lst"], start, stop, day, year) s.schcsc.srcfile = util.resize_string( util.expand_file_name(values["srcfile"]), s.schcsc.srcfile.itemsize, "srcfile") s.schcsc.srcfile2 = util.resize_string( util.expand_file_name(values["srcfile2"]), s.schcsc.srcfile2.itemsize, "srcfile2") sttant(values["tantsta1"], values["tantsta2"]) s.schsco.freqfile = util.resize_string( util.expand_file_name(values["freqfile"]), s.schsco.freqfile.itemsize, "freqfile") s.schcon.freqlist = values["freqlist"] if "autotape" in present: s.wlog(1, "SCHIN: Obsolete parameter AUTOTAPE given. Ignored.") if "tape" in present: s.wlog(1, "'SCHIN: Obsolete parameter TAPE given. Ignored.") if "fastfor" in present: s.wlog(1, "SCHIN: Obsolete parameter FASTFOR given. Ignored.") if "reverse" in present: s.wlog(1, "SCHIN: Obsolete parameter REVERSE given. Ignored.")
def scndup(to, from_, copyall, caller, use_direct_access=True): if s.schcon.debug: s.wlog(0, "SCNDUP: Duplicating scan {} to scan {}. Called by: {} " "copyall = {}".format(from_+1, to+1, caller, copyall)) s.wlog(0, "SCNDUP: ANNOT: {}".format(f2str(s.schc2a.annot[from_]))) if to >= ScanCatalog.maxscan: s.errlog("SCHDUP: Output scan number {} too big for arrays of " "dimension: {}".format(to+1, ScanCatalog.maxscan)) # copy the scan if use_direct_access: for block, items in scan_catalog.block_items.items(): for attr in items: if copyall or (attr not in copyall_attributes): array = getattr(block, attr) array[..., to] = array[..., from_] entries = scan_catalog.entries for attr in scan_catalog.extended_attributes: setattr(entries[to], attr, copy.deepcopy(getattr(entries[from_], attr))) else: entries = scan_catalog.entries if not copyall: original = {k: getattr(entries[to], k) for k in copyall_attributes} # copy entry dict so the all references to entry are updated entries[to].__dict__ = copy.deepcopy(entries[from_].__dict__) if not copyall: for k, v in original.items(): setattr(entries[to], k, v) s.schn2a.nsetup[to, :] = s.schn2a.nsetup[from_, :] s.schn2a.fseti[to, :] = s.schn2a.fseti[from_, :] s.schn2a.stascn[to, :] = s.schn2a.stascn[from_, :] s.schn2b.dopincr[to, :] = s.schn2b.dopincr[from_, :] if not copyall: # reset some entries if use_direct_access: s.schn2a.duronly[to] = 1 s.schc2a.annot[to] = "".ljust(s.schc2a.annot.itemsize) else: entries[to].duronly = 1 entries[to].annot = "" else: # copy station entries s.schn5.tpstart[to, :] = s.schn5.tpstart[from_, :] s.schn5.tcorr[to, :] = s.schn5.tcorr[from_, :] s.schn5.gbytes[to, :] = s.schn5.gbytes[from_, :] s.schn6.lst1[to, :] = s.schn6.lst1[from_, :] s.schn6.lst2[to, :] = s.schn6.lst2[from_, :] s.schn6.tonsrc[to, :] = s.schn6.tonsrc[from_, :] s.schn6.tslew[to, :] = s.schn6.tslew[from_, :] s.schn6.el1[to, :] = s.schn6.el1[from_, :] s.schn6.az1[to, :] = s.schn6.az1[from_, :] s.schn6.ha1[to, :] = s.schn6.ha1[from_, :] s.schn6.pa1[to, :] = s.schn6.pa1[from_, :] s.schc6.up1[to, :] = s.schc6.up1[from_, :] s.schn6.el2[to, :] = s.schn6.el2[from_, :] s.schn6.az2[to, :] = s.schn6.az2[from_, :] s.schn6.ha2[to, :] = s.schn6.ha2[from_, :] s.schn6.pa2[to, :] = s.schn6.pa2[from_, :] s.schc6.up2[to, :] = s.schc6.up2[from_, :] if not use_direct_access: # update the scan related attributes of stations in the catalog station_catalog.read_scheduled_attributes_for_scan(to)
def stread(input_iterator, stdin, mjd1): if input_iterator.input_ is stdin: infile = "Program_input" locfile = "NOLOC" else: infile = input_iterator.input_.name locfile = util.f2str(s.schcst.locafile) # 100 - 25: magic number copied from stread.f s.wlog(0, "STREAD: Reading station catalog: {}".format(infile[-(100 - 25):])) s.wlog(0, "STREAD: Reading locations file: {}".format(locfile)) if locfile.upper not in ("NONE", "NOLOC"): try: f = open(locfile, "r") except Exception as e: noloc = True else: with f: location_keyin_data = key.read_keyfile(f) noloc = False else: noloc = True mdb = s.rdcatn.dbx.shape[0] if (not noloc) and (len(location_keyin_data) > mdb): s.error( "RDLOC: Too many stations in location file. Max: {}".format(mdb)) station_state_defaults = { "version": ["", util.noop], } station_record_defaults = { "station": ["NONAME", util.upper], "stcode": ["XX", util.noop], "dbname": ["", util.noop], "dbcode": ["", util.noop], "frame": ["XX", util.noop], "elev": [0., util.noop], "lat": [0., util.multiply_by(parameter.raddeg / 3600.)], "long": [0., util.multiply_by(parameter.raddeg / 3600.)], "zalim": [None, util.noop], "x": [0., util.noop], "y": [0., util.noop], "z": [0., util.noop], "dxdt": [0., util.noop], "dydt": [0., util.noop], "dzdt": [0., util.noop], "epoch": [0., util.noop], "descrip": ["", util.noop], "control": ["NONE", util.upper], "dar": ["NONE", util.noop], "recorder": ["NONE", util.noop], "ndrives": [2., util.noop], "nheads": [1., util.noop], "disk": ["", util.noop], # two spellings, disk has preference over disc "disc": ["NONE", util.noop], "disk": ["NONE", util.noop], "mediadef": ["NONE", util.noop], "nbbc": [8., util.noop], "dbbcver": ["ASTRO", util.noop], "hor_az": [[], util.noop], "hor_el": [[], util.noop], "ax1lim": [[-90., 450.], util.noop], "ax2lim": [[2., 90.], util.noop], "ax1rate": [1000., util.noop], "ax2rate": [1000., util.noop], "ax1acc": [[1000., 0], util.noop], "ax2acc": [[1000., 0], util.noop], "mount": ["ALTAZ", util.noop], "axistype": [0., util.noop], "axisoff": [0., util.noop], "tsettle": [0., util.noop], "minsetup": [0., util.noop], "tscal": ["GAP", util.upper], "maxsrchr": [1e6, util.noop], "tlevset": [0., util.noop], "endcat": [0., util.noop], } input_iterator.set_defaults(station_record_defaults, station_state_defaults) location_state_defaults = { "version": ["Not known", util.noop], } location_record_defaults = { "dbname": ["", util.noop], "dbcode": ["", util.noop], "frame": ["", util.noop], "axistype": ["", util.noop], "axisoff": [0., util.noop], "x": [0., util.noop], "y": [0., util.noop], "z": [0., util.noop], "dxdt": [0., util.noop], "dydt": [0., util.noop], "dzdt": [0., util.noop], "epoch": [0., util.noop], "begin": [0., util.noop], "end": [1e5, util.noop], } locations = collections.defaultdict(list) if not noloc: for loc in location_keyin_data: values, present = util.merge_record_with_defaults( loc, location_record_defaults, location_state_defaults) locations[values["dbname"]].append(values) # warn about location close together with time overlap # don't warn about known cases compare_locations = [ loc for loc in sum(locations.values(), []) if loc["dbname"] not in ( "MIAMI20", "SINTOTU") and not loc["dbname"].startswith("VLA") ] for loc_a, loc_b in itertools.combinations(compare_locations, 2): separation = math.sqrt(sum([(loc_a[d] - loc_b[d])**2 for d in "xyz"])) time_overlap = (min(loc_a["end"], loc_b["end"]) > max( loc_a["begin"], loc_b["begin"])) if (separation < 10.) and time_overlap: s.wlog( 0, "RDLOC: Locations.dat stations {} and {} appear to " "be the same (time and position). Sep (m):{:10.2f}".format( loc_a["dbname"], loc_b["dbname"], separation)) # update the station values with station and location file catalog values station_catalog = StationCatalog() warnxyz = True locwarn = True # map from station catalog entry attributes to keyin keywords attribute_to_key = dict( zip(station_catalog.attributes, station_catalog.attributes)) attribute_to_key.update({ "long_bn": "long", "horaz": "hor_az", "horel": "hor_el", "xpos": "x", "ypos": "y", "zpos": "z", "dxpos": "dxdt", "dypos": "dydt", "dzpos": "dzdt", "mjdrate": "epoch", "axoff": "axisoff", "stndriv": "ndrives" }) start = int(s.schsta.msta) index = start seen = set(entry.station for entry in station_catalog.entries[:index]) for record in input_iterator: station_values, present = util.merge_record_with_defaults( record, station_record_defaults, station_state_defaults) if "endcat" in present: break if index >= len(station_catalog.entries): s.errlog(" STREAD: Too many stations in catalog, max {} " " Last station: {}".format( len(station_catalog.entries), station_catalog.entries[-1].station)) if station_values["station"] in seen: s.wlog(0, "STREAD: Ignoring extra station catalog entry for {}".\ format(station_values["station"])) continue else: seen.add(station_values["station"]) # disc/disk confusion cases if "disk" not in present: station_values["disk"] = station_values["disc"] if station_values["mediadef"] == "DISC": station_values["mediadef"] = "DISK" # copy all values to the common block placeholder entry = station_catalog.entries[index] entry.set_keyin_values(station_values, attribute_to_key) entry.stcodeu = entry.stcode.upper() # fill in x, y, z from elev, lat, long (or reverse) gotxyz = ((entry.xpos, entry.ypos, entry.zpos) != (0., 0., 0.)) gotllh = ((entry.elev, entry.lat, entry.long_bn) != (0., 0., 0.)) if gotxyz and gotllh and warnxyz: s.putout("RDSTA: Both XYZ and Lat/Long coordinates given for some " "stations.") s.putout(" There is nothing to insure they agree.") warnxyz = False conversion_mode = None # 0: llh -> xyz, 1: xyz -> llh if gotxyz and (not gotllh or (entry.elev > 1e6)): conversion_mode = 1 elif gotllh and not gotxyz: conversion_mode = 0 elif not gotllh and not gotxyz: if noloc or (len(locations) == 0): if locwarn: if locfile.upper() == "NOLOC": s.putout("RDSTA: **Cannot use locations catalog with " "in-line stations catalog.") elif locfile.upper() != "NONE": s.putout("RDSTA: Could not open locations catalog: " "{}".format(locfile)) locwarn = False s.putout("RDSTA: No coordinates for {}".format( station_values["station"])) else: # get xyz from locations catalog station_locations = locations.get(station_values["dbname"]) if station_locations is not None: for location in station_locations: if location["begin"] <= mjd1 < location["end"]: for attribute in [ "xpos", "ypos", "zpos", "dxpos", "dypos", "dzpos", "mjdrate", "axoff" ]: setattr(entry, attribute, location[attribute_to_key[attribute]]) conversion_mode = 1 break if conversion_mode is None: s.putout("RDSTA: No coordinates in stations or locations " "file for {} dbname: {}".format( station_values["station"], station_values["dbname"])) s.putout("RDSTA: Check date range in addition to names.") if conversion_mode is not None: (entry.long_bn, entry.lat, entry.elev, entry.xpos, entry.ypos, entry.zpos, ier) = \ s.geoxyz(conversion_mode, entry.long_bn, entry.lat, entry.elev, entry.xpos, entry.ypos, entry.zpos) if ier != 0: s.putout("RDSTA: Problem with coordinate conversions for {}".\ format(station_values["station"])) if entry.ax1acc[1] == 0: entry.ax1acc[1] = entry.ax1acc[0] if entry.ax2acc[1] == 0: entry.ax2acc[1] = entry.ax2acc[0] entry.naxlim = min(len(entry.ax1lim), len(entry.ax2lim)) // 2 if "zalim" not in present: if entry.mount == "ALTAZ": entry.zalim = 90. - entry.ax2lim[0] else: entry.zalim = 90. control = station_values["control"] entry.vlbadar = ((len(control) >= 5) and (control[4] == 'V')) dar = station_values["dar"] entry.useonsrc = ((dar.startswith("RDBE") and control.startswith("VLBA")) or ((dar == "WIDAR") and (control == "VEX"))) def check(value, allowed, not_supported, station, element_type): if value not in allowed: s.errlog("STREAD: Invalid {} type {} for {}".format( element_type, value, station)) if value in not_supported: s.errlog("STREAD: {} type {} no longer supported by " "SCHED. Station: {}".format( element_type[0].upper() + element_type[1:], value, station)) check(entry.control, ("VLA", "VLBA", "NRAO", "NRAOV", "SNAP", "VEX", "SN50", "VSOP", "NONE"), ("SNAP", "SN50"), entry.station, "control") if entry.control.startswith("VLA"): s.errlog("STREAD: Control type VLA (old system card images) no " "longer supported. Use VEX.") check(entry.dar, ("VLBA", "RDBE", "RDBE2", "DBBC", "DBBC3", "VLBAG", "MKIV", "MKIII", "S2", "K4", "K5", "VERA", "VSOP", "VLBA4", "LBA", "R1002", "WIDAR", "CDAS", "eMERL", "NONE"), ("MKIII", "S2"), entry.station, "DAR") check(entry.recorder, ("VLBA", "MKIV", "VLBA4", "MKIII", "S2", "K4", "K5", "VERA", "VSOP", "MARK5A", "MARK5B", "MARK5C", "NONE"), ("MKIII", "S2"), entry.station, "recorder") check(entry.disk, ("MARK5A", "MARK5B", "MARK5C", "LBADR", "NONE"), tuple(), entry.station, "DISK") check(entry.mediadef, ("TAPE", "DISK", "NONE"), tuple(), entry.station, "MEDIADEF") if (entry.xpos, entry.ypos, entry.zpos) == (0., 0., 0.): s.errlog("STREAD: Location required for {}: infile={}, locfile={}".\ format(entry.station, infile, locfile)) if entry.tscal not in ("CONT", "GAP"): s.errlog("STREAD: Unknown TSCAL for {}: {}".format( entry.station, entry.tscal)) index += 1 s.schsta.msta = index s.schcst.stver = util.resize_string(station_state_defaults["version"][0], s.schcst.stver.itemsize, "version") s.schcst.locaver = util.resize_string( location_state_defaults["version"][0], s.schcst.locaver.itemsize, "version") station_catalog.write(range(start, index))
def getcov(values): s.schco.schver = values["version"] for attribute in [ "piname", "phone", "email", "fax", "obsphone", "obsmode" ]: setattr( s.schsco, attribute, util.resize_string(values[attribute], getattr(s.schsco, attribute).itemsize, attribute)) for i in range(4): address = "address" + str(i + 1) s.schsco.address[i] = util.resize_string(values[address], s.schsco.address.itemsize, address) note = "note" + str(i + 1) s.schsco.note[i] = util.resize_string(values[note], s.schsco.note.itemsize, note) if s.schcon.debug: s.wlog(0, "GETCOV: Checking cover information.") missing = False if s.schco.schver == 0.: s.wlog(1, " Schedule version is missing. ") missing = True if values["piname"] == "": s.wlog(1, " No PINAME given. ") missing = True if values["address1"] == "": s.wlog(1, " No address specified.") missing = True if values["phone"] == "": s.wlog(1, " No PI phone number specified.") missing = True if (values["email"] == "") and (values["fax"] == ""): s.wlog(1, " No email address or fax number specified.") missing = True if missing: s.wlog(1, "GETCOV: Cover information incomplete or missing.") if not s.schn1.notape and not s.schcon.plot: s.errlog("GETCOV: Cover information is required for VLBI " "observations.") if s.schcon.plot: s.wlog( 1, "GETCOV: Sched will plot, but not write telescope " "control files.") text = [ "Schedule Version: {:10.2f}".format(float(s.schco.schver)), "Processed by SCHED version: {:6.2f} {}".format( float(s.vern.vernum), bytes(s.verc.version).decode()), "PI: {}".format( values["piname"]), "Address: {}".format(values["address1"]), " {}".format(values["address2"]), " {}".format( values["address3"]), " {}".format(values["address4"]), "Phone: {}".format(values["phone"]), "EMAIL: {}".format( values["email"]), "Fax: {}".format(values["fax"]), "Phone during observation: {}".format(values["obsphone"]), "Observing mode: {}".format(values["obsmode"]), "Notes: {}".format( values["note1"]), " {}".format(values["note2"]), " {}".format(values["note3"]), " {}".format(values["note4"]) ] line = next((line for line in text if line.find("!") != -1), None) if line is not None: s.wlog( 1, "GETCOV: Please do not use exclamation marks in the cover " "information.") s.wlog( 1, " They mess up the parsing of the CRD files at the " "VLBA stations.") s.wlog(1, " One was found in the line: ") s.wlog(1, line) s.errlog("SCHIN: Remove exclamation marks.") for index, line in enumerate(text): s.schsco.cover[index] = util.resize_string(line, s.schsco.cover.itemsize, "cover")
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