def initializeRoach(dl, acc_len, rid, cfg): result, fpga = Bpsr.connectRoach(dl, rid) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] initializeRoach: could not connect to ROACH") return ("fail", 0) result, response = programRoach(dl, fpga, rid) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] initializeRoach: could not program ROACH") return ("fail", 0) result, response = configureRoach(dl, fpga, rid, cfg) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] initializeRoach: could not configure ROACH") return ("fail", fpga) result, response = accLenRoach(dl, fpga, acc_len, rid) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] initializeRoach: could not set acc_len on roach") return ("fail", fpga) result, response = levelSetRoach(dl, fpga, rid) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] initializeRoach: could not set levels on ROACH") return ("fail", fpga) return ("ok", fpga)
def dumpADCRoach (dl, fpga, reg, n_dumps=1): data = [] try: data = numpy.array(struct.unpack('>4096b', fpga.read(reg,1024*4,0))) except RuntimeError: Dada.logMsg(-1, dl, "dumpADCRoach: failed to read register " + str(reg)) data = numpy.zeros (1024) time.sleep (1) if (n_dumps <= 1): return data for i in range(n_dumps-1): new = [] try: new = numpy.array(struct.unpack('>4096b', fpga.read(reg,1024*4,0))) except RuntimeError: Dada.logMsg(-1, dl, "[" + roach_name + "] dumpADCRoach: failed to read register " + str(reg)) new = numpy.zeros (1024) time.sleep (1) data = numpy.concatenate ((data, new), axis=0) return data
def bramdiskRoach(dl, fpga, timestamp, roach_name): Dada.logMsg(2, dl, "[" + roach_name + "] bramdiskRoach: dumping BRAM"); file_prefix = timestamp + "_" + roach_name # get the current values for pol1 and pol2 pol1, pol2 = bramdumpRoach(dl, fpga, 3) # get the current bit window bit_window = fpga.read_int('reg_output_bitselect') # file to read is bram_file = file_prefix + ".bram" fptr = open(bram_file, "wb") bit_window_bin = struct.pack("I1",bit_window) pol1_binary = struct.pack("512f",*pol1) pol2_binary = struct.pack("512f",*pol2) fptr.write(bit_window_bin) fptr.write(pol1_binary) fptr.write(pol2_binary) fptr.close() return 'ok'
def setComplexGains(dl, fpga, rid, value, bit_window): Dada.logMsg(1, dl, "["+rid+"] setting complex gain levels to="+str(value)+" window="+str(bit_window)) fpga.write_int('reg_output_bitselectR', bit_window) fpga.write_int('reg_output_bitselectC', bit_window) fpga.write_int('reg_coeff_XYI1', value) fpga.write_int('reg_coeff_XYI2', value) fpga.write_int('reg_coeff_XYR1', value) fpga.write_int('reg_coeff_XYR2', value) return ("ok", "")
def getConfig(): config_file = Dada.DADA_ROOT + "/share/mopsr.cfg" config = Dada.readCFGFileIntoDict(config_file) ct_config_file = Dada.DADA_ROOT + "/share/mopsr_cornerturn.cfg" ct_config = Dada.readCFGFileIntoDict(ct_config_file) config.update(ct_config) return config
def accLenRoach(dl, fpga, acc_len, rid): sync_period = 100 * acc_len * 2048 Dada.logMsg(2, dl, "["+rid+"] acc_len " + str(acc_len-1)) fpga.write_int('reg_acclen', acc_len-1) Dada.logMsg(2, dl, "["+rid+"] sync_period " + str(sync_period)) fpga.write_int('reg_sync_period', sync_period) return ("ok", "")
def log(lvl, dlvl, message): message = message.replace("`", "'") if (lvl <= dlvl): time = Dada.getCurrentDadaTimeUS() if args.logfile == None: Dada.logMsg(lvl, dlvl, message) else: fptr = open(args.logfile, "a") if (lvl == -1): fptr.write("[" + time + "] WARN " + message + "\n") elif (lvl == -2): fptr.write("[" + time + "] ERR " + message + "\n") else: fptr.write("[" + time + "] " + message + "\n") fptr.close()
def plotCandDspsr(fil_file, sample, filter, dm): cand_time = (0.000064 * sample) cmd = "dmsmear -f 1382 -b 400 -n 1024 -d " + str(dm) + " -q 2>&1 " p = os.popen(cmd) cand_band_smear = p.readline().strip() p.close() Dada.logMsg(1, DL, "plotCandDspsr: cand_band_smear='" + cand_band_smear + "'") cand_filter_time = (2 ** filter) * 0.000064 cand_smearing = float(cand_band_smear) + float(cand_filter_time) cand_start_time = cand_time - (1.0 * cand_smearing) cand_tot_time = 2.0 * cand_smearing cmd = "dspsr " + fil_file + " -S " + str(cand_start_time) + \ " -b 128" + \ " -T " + str(cand_tot_time) + \ " -c " + str(cand_tot_time) + \ " -D " + str(dm) + \ " -U 8" + \ " 2>&1 | grep unloading | awk '{print $NF}'" # create a temporary working directory workdir = tempfile.mkdtemp() os.chdir(workdir) Dada.logMsg(1, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) response = p.readline().strip() p.close() archive = response + ".ar" count = 10 while ((not os.path.exists(archive)) and count > 0): Dada.logMsg(1, DL, "plotCandDspsr: archive file [" + archive + "] did not exist") time.sleep(1) count = count - 1 binary_data = [] title = "DM=" + str(dm) + " Length=" + str(cand_filter_time*1000) + "ms Epoch=" + str(cand_start_time) cmd = "psrplot -c above:l='" + title + "' -j 'zap chan 0-160' -j 'F 128' -c x:unit=ms -p freq+ ./" + archive + " -D -/PNG"; Dada.logMsg(1, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) binary_data = p.read() p.close() if os.path.exists(archive): os.remove(archive) os.chdir ("/") os.rmdir(workdir) return binary_data
def send_reply (handle, addr, hdr, message): Dada.logMsg(2, DL, "send_reply: addr="+addr[0]+" port="+str(addr[1]) + " message=" +message) raw = struct.pack("8c", hdr[0], hdr[1], hdr[2], hdr[3], hdr[4], hdr[5], hdr[6], hdr[7]) + message Dada.logMsg(3, DL, "send_reply: len(raw)="+str(len(raw))) Dada.logMsg(3, DL, "send_reply: raw="+raw) Dada.logMsg(1, DL, "-> " + message) handle.sendto(raw, addr)
def setLevels (dl, fpga, pol1, pol2, rid): Dada.logMsg(3, dl, "setLevels: levelSetRoach(pol1="+str(pol1)+" pol2="+str(pol2)+")") result, ppqq_response = levelSetRoach(dl, fpga, pol1, pol2, rid) Dada.logMsg(3, dl, "setLevels: " + result + " " + ppqq_response) Dada.logMsg(2, dl, "setLevels: crossLevelSetRoach()") result, xpol_response = crossLevelSetRoach(dl, fpga, rid) Dada.logMsg(3, dl, "setLevels: " + result + " " + xpol_response) return ("ok", ppqq_response + "," + xpol_response)
def connectRoach(dl, rid): roach_cfg = getROACHConfig() roach_ip = roach_cfg["ROACH_" + rid] roach_port = int(roach_cfg["ROACH_PORT"]) connected = False attempts = 0 Dada.logMsg( 2, dl, "[" + rid + "] connectRoach: connecting to " + roach_ip + ":" + str(roach_port)) while (not connected and attempts < 5): Dada.logMsg( 3, dl, "[" + rid + "] connectRoach: connection attempt " + str(attempts) + " for " + roach_ip + ":" + str(roach_port)) fpga = corr.katcp_wrapper.FpgaClient(roach_ip, roach_port) time.sleep(0.1) if (fpga.is_connected()): Dada.logMsg( 3, dl, "[" + rid + "] connectRoach: connected to " + roach_ip + ":" + str(roach_port)) connected = fpga.is_connected() if (not connected): Dada.logMsg( 0, dl, "[" + rid + "] connectRoach: connection to " + roach_ip + " failed, retrying") time.sleep(1.0) attempts += 1 if (not connected): Dada.logMsg(-2, dl, "[" + rid + "] connectRoach: connection failed") return ("fail", 0) return ("ok", fpga)
def plotCandDspsr(fil_file, sample, filter, dm, snr, nchan=0, nbin=0, length=0): cand_time = (0.000064 * sample) cmd = "dmsmear -f 1382 -b 400 -n 1024 -d " + str(dm) + " -q 2>&1 " p = os.popen(cmd) cand_band_smear = p.readline().strip() p.close() Dada.logMsg(2, DL, "plotCandDspsr: cand_band_smear='" + cand_band_smear + "'") cand_filter_time = (2**filter) * 0.000064 cand_smearing = float(cand_band_smear) + float(cand_filter_time) cand_start_time = cand_time - (0.5 * cand_smearing) cand_tot_time = 2.0 * cand_smearing if length != 0: cand_tot_time = length # determine the bin width, based on heimdalls filter width if nbin == 0: bin_width = 0.000064 * (2**filter) nbin = int(cand_tot_time / bin_width) if nbin < 16: nbin = 16 if nbin > 1024: nbin = 1024 cmd = "dspsr " + fil_file + " -S " + str(cand_start_time) + \ " -b " + str(nbin) + \ " -T " + str(cand_tot_time) + \ " -c " + str(cand_tot_time) + \ " -D " + str(dm) + \ " -U 1" + \ " -cepoch start " + \ " 2>&1 | grep unloading | awk '{print $NF}'" # create a temporary working directory workdir = tempfile.mkdtemp() Dada.logMsg(2, DL, "plotCandDspsr: workdir=" + workdir) os.chdir(workdir) Dada.logMsg(2, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) response = p.readline().strip() p.close() archive = response + ".ar" count = 10 while ((not os.path.exists(archive)) and count > 0): Dada.logMsg( 1, DL, "plotCandDspsr: archive file [" + archive + "] did not exist") time.sleep(1) count = count - 1 binary_data = [] if nchan == 0: # determine number of channels based on SNR nchan = int(round(math.pow(float(snr) / 4.0, 2))) if nchan < 2: nchan = 2 nchan_base2 = int(round(math.log(nchan, 2))) nchan = pow(2, nchan_base2) if nchan > 512: nchan = 512 title = "DM=" + str(dm) + " Length=" + str( cand_filter_time * 1000) + "ms Epoch=" + str(cand_start_time) cmd = "psrplot -c above:c='' -j 'zap chan 0-160,335-338,181-183' -c x:unit=ms -O -s " + trans_paths.getBinaryDir( ) + "/frb.style ./" + archive + " -j 'F " + str(nchan) + "' -D -/PNG" Dada.logMsg(2, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) binary_data = p.read() p.close() if os.path.exists(archive): os.remove(archive) os.chdir("/") os.rmdir(workdir) return binary_data
def programRoach(dl, fpga, rid, boffile='default'): roach_cfg = Bpsr.getROACHConfig() roach_bof = roach_cfg["ROACH_BOF"] if (not boffile == 'default'): roach_bof = boffile # program bit stream programmed = False attempts = 0 while (not programmed and attempts < 5): Dada.logMsg(2, dl, "["+rid+"] programming FPGA with " + roach_bof) Dada.logMsg(3, dl, "["+rid+"] programRoach: programming FPGA with " + roach_bof) prog_result = fpga.progdev(roach_bof) if (prog_result): Dada.logMsg(2, dl, "["+rid+"] programRoach: programming done") else: Dada.logMsg(0, dl, "["+rid+"] programRoach: programming FAILED") time.sleep(0.1) try: # try to read from a register #enable = fpga.read_int('enable') #Dada.logMsg(3, dl, "["+rid+"] enable = " + str(enable)) port = fpga.read_int('reg_10GbE_destport0') Dada.logMsg(3, dl, "["+rid+"] reg_10GbE_destport0 = " + str(port)) # try to write to a register #enable = 0 #Dada.logMsg(3, dl, "["+rid+"] enable" + str(enable)) #fpga.write_int('enable', enable) port = 8000 Dada.logMsg(3, dl, "["+rid+"] reg_10GbE_destport0 " + str(port)) fpga.write_int('reg_10GbE_destport0', port) # if we got this far without throwing an exception, we are programmed! programmed = True except: # give it a chance to be ready for commands Dada.logMsg(1, dl, "["+rid+"] exception when trying to read/write") time.sleep(1.0) attempts += 1 if (not programmed): Dada.logMsg(0, dl, "["+rid+"] failed to program FPGA with " + roach_bof) return ("fail", "could not program FPGA with " + roach_bof) return ("ok", "ROACH programmed with " + roach_bof)
def configureRoach(dl, fpga, rid, cfg): roach_cfg = Bpsr.getROACHConfig() roach_beam = roach_cfg["BEAM_"+rid] roach_10gbe_src_ip = Bpsr.convertIPToInteger(roach_cfg["ROACH_10GbE_SRC_"+rid]) roach_10gbe_dest_ip = Bpsr.convertIPToInteger(roach_cfg["ROACH_10GbE_DEST_"+rid]) Dada.logMsg(2, dl, "["+rid+"] configureRoach: " + roach_cfg["ROACH_10GbE_SRC_"+rid] + " -> " + str(roach_10gbe_src_ip)) Dada.logMsg(2, dl, "["+rid+"] configureRoach: " + roach_cfg["ROACH_10GbE_DEST_"+rid] + " -> " + str(roach_10gbe_dest_ip)) # Same port in src and dest roach_10gbe_src_port = int(cfg["PWC_UDP_PORT_"+rid]) roach_10gbe_dest_port = int(cfg["PWC_UDP_PORT_"+rid]) # use a designated private MAC address [02:xx:xx:xx:xx:xx] roach_10gbe_src_mac = (2<<40) + (2<<32) + roach_10gbe_src_ip # hardware device tengbe_device = roach_cfg["ROACH_10GBE_DEVNAME"] # linux device tengbe_tapdev = tengbe_device # start tgtap, which configures the 10Gbe port and begins an ARP process Dada.logMsg(2, dl, "["+rid+"] fpga.tap_start()") fpga.tap_start(tengbe_tapdev,tengbe_device,roach_10gbe_src_mac,roach_10gbe_src_ip,roach_10gbe_src_port) time.sleep(0.5) gbe0_link = bool(fpga.read_int(tengbe_device)) if gbe0_link: Dada.logMsg(2, dl, "["+rid+"] configureRoach: 10GbE device now active") else: Dada.logMsg(-1, dl, "["+rid+"] configureRoach: 10GbE device NOT active") result, response = waitForARP(dl, fpga, tengbe_device, roach_cfg["ROACH_10GbE_DEST_"+rid], rid) if (not result == "ok"): Dada.logMsg(0, dl, "["+rid+"] configureRoach: ARP did not become valid after 60 seconds") return ("fail", fpga) # now configure device properly Dada.logMsg(2, dl, "["+rid+"] reg_ip " + roach_cfg["ROACH_10GbE_DEST_"+rid]) fpga.write_int('reg_ip', roach_10gbe_dest_ip) Dada.logMsg(2, dl, "["+rid+"] reg_10GbE_destport0 " + str(roach_10gbe_dest_port)) fpga.write_int('reg_10GbE_destport0', roach_10gbe_dest_port) Dada.logMsg(1, dl, "["+rid+"] programmed " + roach_beam + ", UDP -> " + roach_cfg["ROACH_10GbE_DEST_"+rid] + ":" + str(roach_10gbe_dest_port)) Dada.logMsg(2, dl, "["+rid+"] configureRoach: returning ok") return ("ok", fpga)
cfg = Bpsr.getConfig() log_file = trans_paths.getControlDir() + "/" + LOGFILE pid_file = trans_paths.getControlDir() + "/" + PIDFILE quit_file = trans_paths.getControlDir() + "/" + QUITFILE if os.path.exists(quit_file): sys.stderr.write("quit file existed at launch: " + quit_file) sys.exit(1) # become a daemon # Dada.daemonize(pid_file, log_file) try: Dada.logMsg(1, DL, "STARTING SCRIPT") quit_event = threading.Event() signal.signal(signal.SIGINT, signal_handler) # start a control thread to handle quit requests control_thread = Dada.controlThread(quit_file, pid_file, quit_event, DL) control_thread.start() Dada.logMsg(2, DL, "main") sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) Dada.logMsg(2, DL, "main: binding to " + LISTEN_HOST + ":" + str(LISTEN_PORT)) sock.bind((LISTEN_HOST, LISTEN_PORT))
def printBandpass(nchan, spectra): for ichan in range(nchan): Dada.logMsg(0, 2, '[' + str(ichan) + '] = ' + str(spectra[ichan]))
def run(self): cfg = self.cfg # os.chdir(cfg["SERVER_STATS_DIR"]) # generate list of current beams beams = [] for i in range(int(roach_cfg["NUM_ROACH"])): beams.append(roach_cfg["BEAM_" + str(i)]) # generate list of resolutions resolutions = ["1024x768", "400x300", "112x84"] Dada.logMsg(1, DL, "plotThread: starting") while (not quit_event.isSet()): # get dir listing of the stats dir directory = cfg["SERVER_STATS_DIR"] extension = ".bram" bram_files = [ file for file in os.listdir(directory) if file.lower().endswith(extension) ] for bram_file in bram_files: Dada.logMsg(2, DL, "plotThread: found " + bram_file) cmd = "hispec_bramplot " + bram_file Dada.logMsg(2, DL, "plotThread: " + cmd) os.system(cmd) os.remove(bram_file) for beam in beams: for res in resolutions: filematch = "*_" + beam + "_" + res + ".png" Dada.logMsg( 3, DL, "plotThread: checking " + os.getcwd() + " for matching " + filematch) filelist = os.listdir(os.getcwd()) filelist.sort(reverse=True) count = 0 for filename in filelist: if (fnmatch.fnmatch(filename, filematch)): count += 1 if (count > 3): Dada.logMsg( 3, DL, "plotThread: cleaning file: " + filename) os.remove(filename) # now sleep for a bit time.sleep(4.0) # end of thread Dada.logMsg(1, DL, "plotThread: exiting")
fil_file = args.fil_file sample = args.sample dm = args.dm filter = args.filter verbose = args.verbose if not os.path.exists(fil_file): sys.exit('ERROR: Filterbank file %s was not found!' % fil_file) proc_type = "dspsr" try: fptr = open(fil_file, 'r') except IOError: Dada.logMsg(1, DL, "main: could not open filterbank file for reading") fil_file = "" else: fptr.close() if len(fil_file) == 0: Dada.logMsg(1, DL, "main: could not find filterbank file") else: binary_data = [] if (proc_type == "dspsr"): Dada.logMsg(2, DL, "main: plotCandDspsr()") binary_data = plotCandDspsr(fil_file, sample, filter, dm) binary_len = len(binary_data) Dada.logMsg(3, DL, "main: sending binary data len="+str(binary_len))
def run(self): self.quit_event = quit_event cond = self.cond lock = self.lock states = self.states results = self.results responses = self.responses cfg = self.cfg try: Dada.logMsg(2, DL, "commandThread: starting") # open a socket to receive commands via socket hostname = cfg["SERVER_HOST"] sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) Dada.logMsg( 2, DL, "commandThread: binding to " + hostname + ":" + cfg["IBOB_MANAGER_PORT"]) sock.bind((hostname, int(cfg["IBOB_MANAGER_PORT"]))) # listen for at most 2 connections at a time (TCS and self) Dada.logMsg(3, DL, "commandThread: sock.listen(2)") sock.listen(2) can_read = [sock] can_write = [] can_error = [] timeout = 1 valid_commands = dict({ "QUIT":QUIT, \ "EXIT":TASK_EXIT, \ "HELP":TASK_HELP, \ "STATE":TASK_STATE, \ "CONFIG":TASK_CONFIG, \ "ARM":TASK_ARM, \ "START_TX":TASK_START_TX, \ "STOP_TX":TASK_STOP_TX, \ "LEVELS":TASK_LEVELS, \ "BRAMPLOT":TASK_BRAMPLOT, \ "BRAMDISK":TASK_BRAMDISK}) # keep listening # while ((not quit_event.isSet()) or (len(can_read) > 1)): while (not quit_event.isSet()): Dada.logMsg( 3, DL, "commandThread: calling select len(can_read)=" + str(len(can_read))) timeout = 1 did_read, did_write, did_error = select.select( can_read, can_write, can_error, timeout) Dada.logMsg( 3, DL, "commandThread: read=" + str(len(did_read)) + " write=" + str(len(did_write)) + " error=" + str(len(did_error))) # if we did_read if (len(did_read) > 0): for handle in did_read: if (handle == sock): (new_conn, addr) = sock.accept() Dada.logMsg( 1, DL, "commandThread: accept connection from " + repr(addr)) # add the accepted connection to can_read can_read.append(new_conn) new_conn.send( "Welcome to the HISPEC Roach Manager\r\n") # an accepted connection must have generated some data else: message = handle.recv(4096) message = message.strip() Dada.logMsg( 3, DL, "commandThread: message='" + message + "'") if (len(message) == 0): Dada.logMsg( 1, DL, "commandThread: closing connection") handle.close() for i, x in enumerate(can_read): if (x == handle): del can_read[i] else: message = message.upper() if ((message == "BRAMPLOT") or (message == "BRAMDISK") or (message == "STATE")): qdl = 2 else: qdl = 1 Dada.logMsg(qdl, DL, "<- " + message) if (message in valid_commands.keys()): command = valid_commands[message] Dada.logMsg( 3, DL, "commandThread: " + message + " was valid, index=" + str(command)) if (command == QUIT): quit_event.set() # remove the server socket from the list of can_reads for i, x in enumerate(can_read): if (x == sock): Dada.logMsg( 2, DL, "commandThread: removed sock from can_read" ) del can_read[i] Dada.logMsg( 2, DL, "commandThread: closing server socket [1]" ) sock.close() sock = [] # request to close the socket elif (command == TASK_EXIT): for i, x in enumerate(can_read): if (x == handle): Dada.logMsg( 2, DL, "commandThread: removed curent handle from can_read" ) del can_read[i] handle.close() handle = [] elif (command == TASK_HELP): handle.send("Available commands:\r\n") handle.send( " help print these commands\r\n" ) handle.send( " exit close current connection\r\n" ) handle.send( " quit stop the server script\r\n" ) handle.send( " config program all roaches\r\n" ) handle.send( " state report state of all roaches\r\n" ) handle.send( " levels perform level setting\r\n" ) handle.send( " arm start 10GbE packets, reset seq no, returning UTC_START\r\n" ) handle.send( " stop stop 10GbE packets\r\n") else: # now process this message Dada.logMsg( 3, DL, "commandThread: lock.acquire()") lock.acquire() Dada.logMsg( 3, DL, "commandThread: lock acquired") for i in range(n_roach): roach_states[i] = command roach_state = command Dada.logMsg( 3, DL, "commandThread: states set to " + message) # all commands should happen as soon as is practical, expect # for the arm, which should ocurr very close to 0.5 seconds # through a second. This command should also return the UTC time # corresponding to the expected start if (command == TASK_ARM): # busy sleep until the next second ticks over curr_time = int(time.time()) next_time = curr_time Dada.logMsg( 2, DL, "commandThread: waiting for 1 second boundary" ) while (curr_time == next_time): next_time = int(time.time()) Dada.logMsg( 2, DL, "commandThread: sleeping 0.5 seconds" ) time.sleep(0.5) utc_start = Dada.getUTCDadaTime(1) Dada.logMsg( 2, DL, "commandThread: UTC_START=" + utc_start) # activate threads Dada.logMsg( 3, DL, "commandThread: cond.notifyAll()") cond.notifyAll() Dada.logMsg( 3, DL, "commandThread: lock.release()") lock.release() # wait for all roaches to finished the command Dada.logMsg( 3, DL, "commandThread: lock.acquire()") lock.acquire() Dada.logMsg( 3, DL, "commandThread: lock acquired") command_result = "" command_response = "" while (roach_state == command): Dada.logMsg( 3, DL, "commandThread: checking all roaches for IDLE" ) n_idle = 0 n_error = 0 n_running = 0 n_ok = 0 n_fail = 0 for i in range(n_roach): Dada.logMsg( 3, DL, "commandThread: testing roach[" + str(i) + "]") # check the states of each roach thread if (roach_states[i] == IDLE): n_idle += 1 # check the return values of this roach Dada.logMsg( 3, DL, "commandThread: roach_results[" + str(i) + "] = " + roach_results[i]) if (roach_results[i] == "ok"): n_ok += 1 else: n_fail += 1 elif (roach_states[i] == ERROR ): Dada.logMsg( -1, DL, "commandThread: roach[" + str(i) + "] thread failed") n_error += 1 else: n_running += 1 # if all roach threads are idle, we are done - extract the results if (n_idle == n_roach): roach_state = IDLE if (n_ok == n_roach): command_result = "ok" else: command_result = "fail" for i in range(n_roach): command_response = command_response + roach_cfg[ "BEAM_" + str(i)] + ":" if (roach_responses[i] != ""): command_response += roach_responses[ i] + " " else: command_response += roach_results[ i] + " " elif (n_error > 0): Dada.logMsg( 2, DL, "commandThread: roach thread error" ) command_result = "fail" command_response = str( n_error ) + " roach threads failed" roach_state = ERROR else: Dada.logMsg( 3, DL, "commandThread: NOT all IDLE, cond.wait()" ) cond.wait() if (command == TASK_ARM): if (command_response != ""): command_response = command_response + "\n" + utc_start else: command_response = utc_start if (command_response != ""): handle.send(command_response + "\r\n") Dada.logMsg( qdl, DL, "-> " + command_response) handle.send(command_result + "\r\n") Dada.logMsg(qdl, DL, "-> " + command_result) Dada.logMsg( 3, DL, "commandThread: lock.release()") lock.release() else: Dada.logMsg( 2, DL, "commandThread: unrecognised command") Dada.logMsg(1, DL, " -> fail") handle.send("fail\r\n") except: Dada.logMsg( -2, DL, "commandThread: exception caught: " + str(sys.exc_info()[0])) print '-' * 60 traceback.print_exc(file=sys.stdout) print '-' * 60 for i, handle in enumerate(can_read): Dada.logMsg(2, DL, "commandThread: closing can_read[" + str(i) + "]") handle.close del can_read[i] if (not sock == []): Dada.logMsg(2, DL, "commandThread: closing server socket [2]") sock.close() Dada.logMsg(2, DL, "commandThread: exiting")
def plotCandDspsr(fil_file, utc_start, sample, filter, dm, snr, nbin, nchan): Dada.logMsg(1, DL, "plotCandDspsr: utc_start =" + utc_start) ddd_time = convertTime(utc_start) Dada.logMsg(1, DL, "plotCandDspsr: ddd_time=" + ddd_time) # cmd = "getMJD " + ddd_time + " |& tail -n 1" # p = os.popen(cmd) # utc_start_mjd = p.readline().strip() # p.close() # Dada.logMsg(1, DL, "main: utc_start_mjd=" + utc_start_mjd ) cand_time = (0.000064 * sample) cmd = "dmsmear -f 1382 -b 400 -n 1024 -d " + str(dm) + " -q 2>&1 " p = os.popen(cmd) cand_band_smear = p.readline().strip() p.close() Dada.logMsg(1, DL, "plotCandDspsr: cand_band_smear=" + str(float(cand_band_smear) * 1000) + " ms") cand_filter_time = (2 ** filter) * 0.000064 Dada.logMsg(1, DL, "plotCandDspsr cand_filter_time=" + str(cand_filter_time * 1000) + " ms") cand_smearing = float(cand_band_smear) + float(cand_filter_time) Dada.logMsg(1, DL, "plotCandDspsr cand_smearing=" + str(cand_smearing * 1000) + " ms") cand_start_time = cand_time - (0.5 * cand_smearing) cand_tot_time = cand_smearing * 2 # determine the bin width, based on heimdalls filter width if nbin == 0: bin_width = 0.000064 * (2 ** (filter-1)) nbin = int(cand_tot_time / bin_width) cmd = "dspsr " + fil_file + " -S " + str(cand_start_time) + \ " -b " + str(nbin) + \ " -T " + str(cand_tot_time) + \ " -c " + str(cand_tot_time) + \ " -D " + str(dm) + \ " -U 1" + \ " -cepoch start" + \ " 2>&1 | grep unloading | awk '{print $NF}'" # create a temporary working directory workdir = tempfile.mkdtemp() os.chdir(workdir) Dada.logMsg(1, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) response = p.readline().strip() p.close() archive = response + ".ar" count = 10 while ((not os.path.exists(archive)) and count > 0): Dada.logMsg(1, DL, "plotCandDspsr: archive file [" + archive + "] did not exist") time.sleep(1) count = count - 1 if nchan == 0: # determine number of channels based on SNR nchan = int(round(math.pow(float(snr)/4.0,2))) if nchan < 2: nchan = 2 nchan_base2 = int(round(math.log(nchan,2))) nchan = pow(2,nchan_base2) if nchan > 512: nchan = 512 Dada.logMsg(1, DL, "plotCandDspsr: snr="+str(snr)+" nchan="+str(nchan)) binary_data = [] title = "DM=" + str(dm) + " Length=" + str(cand_filter_time*1000) + "ms Epoch=" + str(cand_start_time) # cmd = "psrplot -j 'zap chan 0-160' -c y:win=1525:1182 -p freq ./" + archive + " -D -/PNG"; # cmd = "psrplot -J /home/dada/linux_64/bin/zap.psh -j 'zap chan 0-160,335-338' -c x:unit=ms -p freq+ ./" + archive + " -jD -j 'F "+str(nchan)+"' -D -/PNG" cmd = "psrplot -j 'zap chan 0-160,335-338' -O -s /home/dada/linux_64/bin/frb.style ./" + archive + " -j 'F "+str(nchan)+"' -D -/PNG -c above:c='' -c x:unit=ms" Dada.logMsg(1, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) binary_data = p.read() p.close() if os.path.exists(archive): os.remove(archive) os.chdir ("/") os.rmdir(workdir) return binary_data
def findBitWindow(dl, pol1_med, pol2_med, gain1, gain2): bit_window = 0 bitsel_min = [0, 256, 65535, 16777216] bitsel_mid = [64, 8192, 2097152, 536870912] bitsel_max = [255, 65535, 16777215, 4294967295] val = (pol1_med + pol2_med) / 2.0 Dada.logMsg(3, dl, "findBitWindow: max value = "+str(val)) Dada.logMsg(3, dl, "findBitWindow: initial gains ["+str(gain1)+", "+str(gain2)+"]") current_window = 0 desired_window = 0 for i in range(4): # If average (max) value is in the lower half if ((val > bitsel_min[i]) and (val <= bitsel_mid[i])): current_window = i if (i == 0): desired_window = 0 else: desired_window = i-1 # If average (max)n value is in the upper half, simply raise to # the top of this window if ((val > bitsel_mid[i]) and (val <= bitsel_max[i])): current_window = i desired_window = i if (desired_window == 3): desired_window = 2 Dada.logMsg(3, dl, "findBitWindow: current_window="+str(current_window)+" desired_window="+str(desired_window)) if ((pol1_med == 0) or (pol2_med == 0)): pol1_med = 1 pol2_med = 1 # If current gains are too high (2^16) then shift down a window if ((gain1 > 32000) or (gain2 > 32000)): if (desired_window > 0): desired_window -= 1 # If current gains are too low (2^3) then shift down a window if ((gain1 < 8) or (gain2 < 8)): if (desired_window < 3): desired_window += 1 desired_val = ((float((bitsel_max[desired_window]+1)) / 4.0)) Dada.logMsg(3, dl, "findBitWindow: desired_val="+str(desired_val)) gain_factor1 = desired_val / float(pol1_med) gain_factor2 = desired_val / float(pol2_med) Dada.logMsg(3, dl, "findBitWindow: 1 new gains ["+str(gain_factor1)+", "+str(gain_factor2)+"]") gain_factor1 = math.sqrt(gain_factor1) gain_factor2 = math.sqrt(gain_factor2) Dada.logMsg(3, dl, "findBitWindow: 2 new gains ["+str(gain_factor1)+", "+str(gain_factor2)+"]") gain_factor1 *= gain1 gain_factor2 *= gain2 Dada.logMsg(3, dl, "findBitWindow: 3 new gains ["+str(gain_factor1)+", "+str(gain_factor2)+"]") gain1 = int(gain_factor1) gain2 = int(gain_factor2) Dada.logMsg(3, dl, "findBitWindow: gains "+str(gain_factor1)+" -> "+str(gain1)) Dada.logMsg(3, dl, "findBitWindow: gains "+str(gain_factor2)+" -> "+str(gain2)) if (gain1 > 262143): gain1 = 262143 if (gain2 > 262143): gain2 = 262143 return desired_window, gain1, gain2
filter = args.filter snr = args.snr nbin = args.nbin nchan = args.nchan length = args.length verbose = args.verbose if not os.path.exists(fil_file): sys.exit('ERROR: Filterbank file %s was not found!' % fil_file) proc_type = "dspsr" try: fptr = open(fil_file, 'r') except IOError: Dada.logMsg(1, DL, "main: could not open filterbank file for reading") fil_file = "" else: fptr.close() if len(fil_file) == 0: Dada.logMsg(1, DL, "main: could not find filterbank file") else: binary_data = [] if (proc_type == "dspsr"): Dada.logMsg(2, DL, "main: plotCandDspsr()") binary_data = plotCandDspsr(fil_file, sample, filter, dm, snr, nchan, nbin, length) binary_len = len(binary_data) Dada.logMsg(3, DL,
def setGains(dl, fpga, rid, value): Dada.logMsg(1, dl, "["+rid+"] setting gain levels to="+str(value)) fpga.write_int('reg_coeff_pol1', value) fpga.write_int('reg_coeff_pol2', value) return ("ok", "")
def setLevels(dl, fpga, pol0_flag, pol1_flag, rid): n_attempts = 3 # start with sensible first guess? fpga.write_int('reg_output_bitselect', 0) fpga.write_int('reg_coeff_pol1', 4096) fpga.write_int('reg_coeff_pol2', 4096) # intial guess at gain values pol1_coeff = fpga.read_int('reg_coeff_pol1') pol2_coeff = fpga.read_int('reg_coeff_pol2') bit_window = 0 for i in range (n_attempts): fpga.write_int('reg_output_bitselect', bit_window) fpga.write_int('reg_coeff_pol1', pol1_coeff) fpga.write_int('reg_coeff_pol2', pol2_coeff) time.sleep(0.1) Dada.logMsg(2, dl, "["+rid+"] setLevels: setting coeffs ["+str(pol1_coeff)+", "+str(pol2_coeff)+"]") pol1, pol2 = bramdumpRoach(dl, fpga, 1) # do not count the first 150 channels out of 1024 pol1_med = numpy.median( numpy.array(pol1)[75:] ) pol2_med = numpy.median( numpy.array(pol2)[75:] ) Dada.logMsg(2, dl, '['+rid+'] setLevels: pol1_med='+str(pol1_med)+' pol2_med='+str(pol2_med)) # find the right bit window and coeffs bit_window, pol1_coeff, pol2_coeff = findBitWindow(dl, pol1_med, pol2_med, pol1_coeff, pol2_coeff) Dada.logMsg(2, dl, '['+rid+'] setLevels: bit_window='+str(bit_window)+' pol1_coeff='+str(pol1_coeff)+' pol2_coeff='+str(pol2_coeff)) # now get a more sensitive estimate pol1, pol2 = bramdumpRoach(dl, fpga, 16) # do not count the first 150 channels out of 1024 pol1_med = numpy.median( numpy.array(pol1)[75:] ) pol2_med = numpy.median( numpy.array(pol2)[75:] ) Dada.logMsg(2, dl, '['+rid+'] setLevels: pol1_med='+str(pol1_med)+' pol2_med='+str(pol2_med)) # find the right bit window and coeffs bit_window, pol1_coeff, pol2_coeff = findBitWindow(dl, pol1_med, pol2_med, pol1_coeff, pol2_coeff) Dada.logMsg(2, dl, '['+rid+'] setLevels: bit_window='+str(bit_window)+' pol1_coeff='+str(pol1_coeff)+' pol2_coeff='+str(pol2_coeff)) fpga.write_int('reg_output_bitselect', bit_window) fpga.write_int('reg_coeff_pol1', pol1_coeff) fpga.write_int('reg_coeff_pol2', pol2_coeff) Dada.logMsg(2, dl, '['+rid+'] bit_window='+str(bit_window)+' pol1='+str(pol1_coeff)+' pol2='+str(pol2_coeff)) return ("ok", "pol1="+str(pol1_coeff)+",pol2="+str(pol2_coeff))
def getActivePolConfig(beam_name): active_pol_config_file = Dada.DADA_ROOT + "/share/bpsr_active_beams.cfg" active_pol_config = Dada.readCFGFileIntoDict(active_pol_config_file) return active_pol_config["BEAM_" + beam_name + "_p0"] == 'on', \ active_pol_config["BEAM_" + beam_name + "_p1"] == 'on',
def bramplotRoach(dl, fpga, timestamp, roach_name): Dada.logMsg(2, dl, "[" + roach_name + "] bramplotRoach: dumping BRAM"); file_prefix = timestamp + "_" + roach_name # get the current values for pol1 and pol2 pol1, pol2 = bramdumpRoach(dl, fpga, 3) # get the current bit window bit_window = fpga.read_int('reg_output_bitselect') nvals = len(pol1) xaxis = [] pol1_float = [] pol2_float = [] for i in range(nvals): xaxis.append(i) if (pol1[i] > 0): pol1_float.append(math.log(pol1[i],2)) else: pol1_float.append(0) if (pol2[i] > 0): pol2_float.append(math.log(pol2[i],2)) else: pol2_float.append(0) # reverse the elements in the list so the plots match the mon plots # xaxis.reverse() pol1_float.reverse() pol2_float.reverse() ymin = 0 ymax = 32 xmin = 0 xmax = 511 xres_list = [1024, 400, 112] yres_list = [768, 300, 84] pp_list = [True, True, False] Dada.logMsg(2, dl, "[" + roach_name + "] bramplotRoach: starting plot"); for i in range(3): xres = xres_list[i] yres = yres_list[i] pp = pp_list[i] filename = file_prefix + "_" + str(xres) + "x" + str(yres) + ".png" # creates a figure of the specified resolution, white on black fig = createFigure(xres, yres) ax = [] if (pp): ax = fig.add_subplot(1,1,1) else: ax = fig.add_axes((0,0,1,1)) set_foregroundcolor(ax, 'white') set_backgroundcolor(ax, 'black') if (pp): ax.set_title('Pre Bit-Selected Bandpass') ax.set_xlabel('Channel') ax.set_ylabel('Activated Bits') else: ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.grid(False) # plot pol1 as red, pol2 as greeb ax.plot(xaxis, pol1_float, 'r-', label='pol 1') ax.plot(xaxis, pol2_float, 'g-', label='pol 2') if (pp): ax.legend() # print grey frames for the inactive parts of the 32 bit number if (bit_window == 0): ax.axhspan(8, 32, facecolor='grey', alpha=0.75) elif (bit_window == 1): ax.axhspan(0, 8, facecolor='grey', alpha=0.75) ax.axhspan(16, 32, facecolor='grey', alpha=0.75) elif (bit_window == 2): ax.axhspan(0, 16, facecolor='grey', alpha=0.75) ax.axhspan(24, 32, facecolor='grey', alpha=0.75) else: ax.axhspan(0, 24, facecolor='grey', alpha=0.75) # hard set the x,y limits ax.set_xlim((xmin, xmax)) ax.set_ylim((ymin, ymax)) FigureCanvas(fig).print_png(filename) fig.delaxes(ax) Dada.logMsg(2, dl, "[" + roach_name + "] bramplotRoach: plotting complete"); # now cleanup any excess plotting files filematch = "*"+roach_name + "_" + str(xres) + "x" + str(yres) + ".png" Dada.logMsg(3, dl, "bramplotRoach: checking " + os.getcwd() + " for matching " + filematch) filelist = os.listdir(os.getcwd()) filelist.sort(reverse=True) count = 0 for filename in filelist: if (fnmatch.fnmatch(filename, filematch)): count += 1 if (count > 3): Dada.logMsg(3, dl, "bramplotRoach: cleaning file: "+filename) os.remove(filename) Dada.logMsg(2, dl, "[" + roach_name + "] bramplotRoach: cleanup complete"); return "ok"
def getConfig(): config_file = Dada.DADA_ROOT + "/share/hispec.cfg" config = Dada.readCFGFileIntoDict(config_file) return config
def waitForARP(dl, fpga, tengbe_device, ip_addr, rid): # set packet rate to be extremely low [1-2 MB/s] ip_str = "0.0.0.0" ip = Bpsr.convertIPToInteger(ip_str) port = 0 acc_len = 1024 sync_period = 100 * acc_len * 2048 Dada.logMsg(2, dl, "["+rid+"] reg_ip " + ip_str) fpga.write_int('reg_ip', ip) Dada.logMsg(2, dl, "["+rid+"] reg_10GbE_destport0 " + str(port)) fpga.write_int('reg_10GbE_destport0', port) Dada.logMsg(2, dl, "["+rid+"] acc_len " + str(acc_len-1)) fpga.write_int('reg_acclen', acc_len-1) Dada.logMsg(2, dl, "["+rid+"] sync_period " + str(sync_period)) fpga.write_int('reg_sync_period', sync_period) # setup the string to look for in the ARP table parts = ip_addr.split(".") arp_line = "IP: " + parts[0].rjust(3) + "." + parts[1].rjust(3) + "." + parts[2].rjust(3) + "." + parts[3].rjust(3) + ": MAC: FF FF FF FF FF FF " Dada.logMsg(3, dl, "["+rid+"] waitForARP arp_line = " + arp_line) arp_valid = False attempts = 0 while ((not arp_valid) and attempts < 60): arp_table = fpga.return_10gbe_arp_table(tengbe_device) arp_valid = True lines = arp_table.split("\n") for line in lines: Dada.logMsg(3, dl, "["+rid+"] testing line '" + line + "' == '" + arp_line + "'") if (line == arp_line): arp_valid = False if (not arp_valid): Dada.logMsg(2, dl, "["+rid+"] arp not yet valid") time.sleep(1.0) attempts += 1 if (attempts < 60): Dada.logMsg(3, dl, "["+rid+"] ARP now valid") arp_table = fpga.return_10gbe_arp_table(tengbe_device) return ("ok", "") else: return ("fail", "")
def getROACHConfig(): roach_config_file = Dada.DADA_ROOT + "/share/roach.cfg" roach_config = Dada.readCFGFileIntoDict(roach_config_file) return roach_config
n_roach = 0 roach_threads = [] roach_states = [] roach_results = [] roach_responses = [] log_file = cfg["SERVER_LOG_DIR"] + "/" + LOGFILE pid_file = cfg["SERVER_CONTROL_DIR"] + "/" + PIDFILE quit_file = cfg["SERVER_CONTROL_DIR"] + "/" + QUITFILE if os.path.exists(quit_file): sys.stderr.write("quit file existed at launch: " + quit_file) sys.exit(1) # become a daemon Dada.daemonize(pid_file, log_file) try: Dada.logMsg(1, DL, "STARTING SCRIPT") quit_event = threading.Event() signal.signal(signal.SIGINT, signal_handler) # start a control thread to handle quit requests control_thread = Dada.controlThread(quit_file, pid_file, quit_event, DL) control_thread.start() # start a thread for each ROACH board for i in range(int(roach_cfg["NUM_ROACH"])):
def setLevels(dl, fpga, rid): n_attempts = 3 # intial guess at gain values pol1_coeff = fpga.read_int('reg_coeff_pol1') pol2_coeff = fpga.read_int('reg_coeff_pol2') bit_window = 0 for i in range(n_attempts): fpga.write_int('reg_output_bitselect', bit_window) fpga.write_int('reg_coeff_pol1', pol1_coeff) fpga.write_int('reg_coeff_pol2', pol2_coeff) time.sleep(0.1) Dada.logMsg( 2, dl, "[" + rid + "] setLevels: setting coeffs [" + str(pol1_coeff) + ", " + str(pol2_coeff) + "]") pol1, pol2 = bramdumpRoach(dl, fpga, 1) # perform median smoothing on data to remove spikes smoothed_pol1 = median_smooth.smoothList(pol1, 11, 'flat') smoothed_pol2 = median_smooth.smoothList(pol2, 11, 'flat') # get the maximum value in each list, excluding certain channels... pol1_max = calculate_max(smoothed_pol1) pol2_max = calculate_max(smoothed_pol2) Dada.logMsg( 2, dl, '[' + rid + '] setLevels: pol1_max=' + str(pol1_max) + ' pol2_max=' + str(pol2_max)) # find the right bit window and coeffs bit_window, pol1_coeff, pol2_coeff = findBitWindow( dl, pol1_max, pol2_max, pol1_coeff, pol2_coeff) Dada.logMsg( 2, dl, '[' + rid + '] setLevels: bit_window=' + str(bit_window) + ' pol1_coeff=' + str(pol1_coeff) + ' pol2_coeff=' + str(pol2_coeff)) # now get a more sensitive estimate pol1, pol2 = bramdumpRoach(dl, fpga, 16) smoothed_pol1 = median_smooth.smoothList(pol1, 11, 'flat') smoothed_pol2 = median_smooth.smoothList(pol2, 11, 'flat') # get the maximum value in each list, excluding certain channels... pol1_max = calculate_max(smoothed_pol1) pol2_max = calculate_max(smoothed_pol2) Dada.logMsg( 2, dl, '[' + rid + '] setLevels: pol1_max=' + str(pol1_max) + ' pol2_max=' + str(pol2_max)) # find the right bit window and coeffs bit_window, pol1_coeff, pol2_coeff = findBitWindow(dl, pol1_max, pol2_max, pol1_coeff, pol2_coeff) Dada.logMsg( 2, dl, '[' + rid + '] setLevels: bit_window=' + str(bit_window) + ' pol1_coeff=' + str(pol1_coeff) + ' pol2_coeff=' + str(pol2_coeff)) fpga.write_int('reg_output_bitselect', bit_window) fpga.write_int('reg_coeff_pol1', pol1_coeff) fpga.write_int('reg_coeff_pol2', pol2_coeff) Dada.logMsg( 2, dl, '[' + rid + '] bit_window=' + str(bit_window) + ' pol1=' + str(pol1_coeff) + ' pol2=' + str(pol2_coeff)) average_coeff = (pol1_coeff + pol2_coeff) / 2.0 Dada.logMsg(2, dl, '[' + rid + '] setLevels: returning ok, ' + str(average_coeff)) return ("ok", str(average_coeff))
def run(self): rid = str(self.roach_num) ithread = self.roach_num cfg = self.cfg lock = self.lock cond = self.cond states = self.states results = self.results responses = self.responses fpga = [] locked = False acc_len = 25 roach_cfg = Hispec.getROACHConfig() roach_name = roach_cfg["ROACH_" + rid] beam_name = roach_cfg["BEAM_" + rid] # os.chdir(cfg["SERVER_STATS_DIR"]) try: Dada.logMsg(1, DL, "[" + rid + "] roachThread: starting") # acquire lock to wait for commands setup locked = lock.acquire() Dada.logMsg(3, DL, "[" + rid + "] roachThread: lock acquired") while (states[ithread] != QUIT): while (states[ithread] == IDLE): Dada.logMsg( 3, DL, "[" + rid + "] roachThread: waiting for not IDLE") locked = False cond.wait() locked = True if (states[ithread] == QUIT): Dada.logMsg(1, DL, "[" + rid + "] roachThread: quit requested") Hispec.stopTX(DL, fpga) lock.release() locked = False return # we have been given a command to perform (i.e. not QUIT or IDLE) task = states[ithread] Dada.logMsg(3, DL, "[" + rid + "] roachThread: TASK=" + str(task)) Dada.logMsg(3, DL, "[" + rid + "] roachThread: lock.release()") lock.release() locked = False result = "fail" response = "" if (task == TASK_STATE): Dada.logMsg(3, DL, "[" + rid + "] roachThread: state request") if (fpga != []): result = "ok" elif (task == TASK_CONFIG): Dada.logMsg(3, DL, "[" + rid + "] roachThread: perform config") result, fpga = Hispec.configureRoach(DL, acc_len, rid, cfg) if (result != "ok"): Dada.logMsg( -2, DL, "[" + rid + "] roachThread: roach not ready") fpga = [] elif (task == TASK_ARM): Dada.logMsg(3, DL, "[" + rid + "] roachThread: perform arm") result = Hispec.rearm(DL, fpga) elif (task == TASK_START_TX): Dada.logMsg(3, DL, "[" + rid + "] roachThread: perform start tx") result = Hispec.startTX(DL, fpga) elif (task == TASK_STOP_TX): Dada.logMsg(3, DL, "[" + rid + "] roachThread: perform stop tx") result = Hispec.stopTX(DL, fpga) elif (task == TASK_LEVELS): Dada.logMsg( 3, DL, "[" + rid + "] roachThread: perform set levels") if (fpga != []): result, response = Hispec.setLevels(DL, fpga, rid) Dada.logMsg( 2, DL, "[" + rid + "] roachThread: result=" + result + " response=" + response) elif (task == TASK_BRAMPLOT): if (fpga != []): Dada.logMsg( 3, DL, "[" + rid + "] roachThread: perform bramplot") time_str = Dada.getCurrentDadaTime() result = Hispec.bramplotRoach(DL, fpga, time_str, beam_name) else: Dada.logMsg( -1, DL, "[" + rid + "] roachThread: not connected to FPGA") elif (task == TASK_BRAMDISK): if (fpga != []): Dada.logMsg( 3, DL, "[" + rid + "] roachThread: perform bramdisk") time_str = Dada.getCurrentDadaTime() result = Hispec.bramdiskRoach(DL, fpga, time_str, beam_name) else: Dada.logMsg( -1, DL, "[" + rid + "] roachThread: not connected to FPGA") else: Dada.logMsg( 2, DL, "[" + rid + "] roachThread: unrecognised task!!!") # now that task is done, re-acquire lock Dada.logMsg(3, DL, "[" + rid + "] roachThread: lock.acquire()") locked = lock.acquire() Dada.logMsg(3, DL, "[" + rid + "] roachThread: setting state = IDLE") states[ithread] = IDLE results[ithread] = result responses[ithread] = response Dada.logMsg(3, DL, "[" + rid + "] roachThread: cond.notifyAll()") cond.notifyAll() except: print '-' * 60 traceback.print_exc(file=sys.stdout) print '-' * 60 quit_event.set() if (not locked): Dada.logMsg( 0, DL, "[" + rid + "] roachThread: except: lock.acquire()") locked = lock.acquire() Dada.logMsg( 0, DL, "[" + rid + "] roachThread: except: setting state = ERROR") states[ithread] = ERROR results[ithread] = "fail" responses[ ithread] = "exception ocurred in roachThread " + roach_name + ":" + beam_name Hispec.stopTx(DL, fpga) Dada.logMsg(2, DL, "[" + rid + "] roachThread: except: cond.notifyAll()") cond.notifyAll() Dada.logMsg(2, DL, "[" + rid + "] roachThread: except: lock.release()") lock.release() Dada.logMsg(2, DL, "[" + rid + "] roachThread: except: exiting") return # we have been asked to exit the rthread Dada.logMsg(1, DL, "[" + rid + "] roachThread: end of thread") Hispec.stopTx(DL, fpga)
def configureRoach(dl, acc_len, rid, cfg): roach_cfg = getROACHConfig() roach_ip = roach_cfg["ROACH_" + rid] roach_port = int(roach_cfg["ROACH_PORT"]) roach_bof = roach_cfg["ROACH_BOF"] roach_beam = roach_cfg["BEAM_" + rid] pol1_coeff = 16384 pol2_coeff = 16384 bit_window = 0 roach_10gbe_src_ip = convertIPToInteger(roach_cfg["ROACH_10GbE_SRC_" + rid]) roach_10gbe_dest_ip = convertIPToInteger(roach_cfg["ROACH_10GbE_DEST_" + rid]) Dada.logMsg( 3, dl, "[" + rid + "] configureRoach: " + roach_cfg["ROACH_10GbE_SRC_" + rid] + " -> " + str(roach_10gbe_src_ip)) Dada.logMsg( 3, dl, "[" + rid + "] configureRoach: " + roach_cfg["ROACH_10GbE_DEST_" + rid] + " -> " + str(roach_10gbe_dest_ip)) # Same port in src and dest roach_10gbe_src_port = int(cfg["PWC_UDP_PORT_" + rid]) roach_10gbe_dest_port = int(cfg["PWC_UDP_PORT_" + rid]) Dada.logMsg( 1, dl, "[" + rid + "] configureRoach: cfg[PWC_UDP_PORT_" + rid + "]=" + cfg["PWC_UDP_PORT_" + rid]) # use a designated private MAC address [02:xx:xx:xx:xx:xx] roach_10gbe_src_mac = (2 << 40) + (2 << 32) + roach_10gbe_src_ip sync_period = 100 * acc_len * 2048 tengbe_device = roach_cfg["ROACH_10GBE_DEVNAME"] connected = False attempts = 0 Dada.logMsg( 2, dl, "[" + rid + "] configureRoach: connecting to " + roach_ip + ":" + str(roach_port)) # connect to ROACH FPGA while (not connected and attempts < 5): Dada.logMsg( 3, dl, "[" + rid + "] configureRoach: connection attempt " + str(attempts) + " for " + roach_ip + ":" + str(roach_port)) fpga = corr.katcp_wrapper.FpgaClient(roach_ip, roach_port) time.sleep(0.1) if (fpga.is_connected()): Dada.logMsg( 3, dl, "[" + rid + "] configureRoach: connected to " + roach_ip + ":" + str(roach_port)) connected = fpga.is_connected() if (not connected): Dada.logMsg( 0, dl, "[" + rid + "] configureRoach: connection to " + roach_ip + " failed, retrying") time.sleep(1.0) attempts += 1 if (not connected): Dada.logMsg(-2, dl, "[" + rid + "] configureRoach: connection failed") return ("fail", 0) # program bit stream programmed = False attempts = 0 while (not programmed and attempts < 5): Dada.logMsg(2, dl, "[" + rid + "] programming FPGA with " + roach_bof) Dada.logMsg( 3, dl, "[" + rid + "] configureRoach: programming FPGA with " + roach_bof) prog_result = fpga.progdev(roach_bof) if (prog_result): Dada.logMsg(2, dl, "[" + rid + "] configureRoach: programming done") else: Dada.logMsg(0, dl, "[" + rid + "] configureRoach: programming FAILED") time.sleep(0.1) try: # try to read from a register #enable = fpga.read_int('enable') #Dada.logMsg(3, dl, "["+rid+"] enable = " + str(enable)) port = fpga.read_int('reg_10GbE_destport0') Dada.logMsg(3, dl, "[" + rid + "] reg_10GbE_destport0 = " + str(port)) # try to write to a register #enable = 0 #Dada.logMsg(3, dl, "["+rid+"] enable" + str(enable)) #fpga.write_int('enable', enable) port = 8000 Dada.logMsg(3, dl, "[" + rid + "] reg_10GbE_destport0 " + str(port)) fpga.write_int('reg_10GbE_destport0', port) # if we got this far without throwing an exception, we are programmed! programmed = True except: # give it a chance to be ready for commands Dada.logMsg(1, dl, "[" + rid + "] exception when trying to read/write") time.sleep(1.0) attempts += 1 if (not programmed): Dada.logMsg(0, dl, "[" + rid + "] failed to program FPGA") return ("fail", fpga) # old way of ensuring null_ip_str = "0.0.0.0" null_ip = convertIPToInteger(null_ip_str) null_port = 0 null_acc_len = 1024 null_sync_period = 100 * null_acc_len * 2048 Dada.logMsg(2, dl, "[" + rid + "] reg_ip " + null_ip_str) fpga.write_int('reg_ip', null_ip) Dada.logMsg(2, dl, "[" + rid + "] reg_10GbE_destport0 " + str(null_port)) fpga.write_int('reg_10GbE_destport0', null_port) Dada.logMsg(2, dl, "[" + rid + "] acc_len " + str(null_acc_len - 1)) fpga.write_int('reg_acclen', null_acc_len - 1) Dada.logMsg(2, dl, "[" + rid + "] sync_period " + str(null_sync_period)) fpga.write_int('reg_sync_period', null_sync_period) # ensure 10GbE output is disabled # enable = 0 # Dada.logMsg(2, dl, "["+rid+"] enable " + str(enable)) # fpga.write_int('enable', enable) Dada.logMsg(2, dl, "[" + rid + "] reg_coeff_pol1 " + str(pol1_coeff)) fpga.write_int('reg_coeff_pol1', pol1_coeff) Dada.logMsg(2, dl, "[" + rid + "] reg_coeff_pol2 " + str(pol2_coeff)) fpga.write_int('reg_coeff_pol2', pol2_coeff) Dada.logMsg(2, dl, "[" + rid + "] reg_output_bitselect " + str(bit_window)) fpga.write_int('reg_output_bitselect', bit_window) # start tgtap, which configures the 10Gbe port and begins an ARP process Dada.logMsg(2, dl, "[" + rid + "] fpga.tap_start()") fpga.tap_start(tengbe_device, tengbe_device, roach_10gbe_src_mac, roach_10gbe_src_ip, roach_10gbe_src_port) time.sleep(0.5) gbe0_link = bool(fpga.read_int(tengbe_device)) if gbe0_link: Dada.logMsg(2, dl, "[" + rid + "] configureRoach: 10GbE device now active") else: Dada.logMsg(-1, dl, "[" + rid + "] configureRoach: 10GbE device NOT active") # now wait until out destination IP Address has appeared in tgtaps ARP table parts = roach_cfg["ROACH_10GbE_DEST_" + rid].split(".") arp_line = "IP: " + parts[0].rjust(3) + "." + parts[1].rjust( 3) + "." + parts[2].rjust(3) + "." + parts[3].rjust( 3) + ": MAC: FF FF FF FF FF FF " Dada.logMsg(3, dl, "[" + rid + "] arpLine = " + arp_line) arp_valid = False attempts = 0 while ((not arp_valid) and attempts < 60): arp_table = fpga.return_10gbe_arp_table(tengbe_device) arp_valid = True lines = arp_table.split("\n") for line in lines: Dada.logMsg( 3, dl, "[" + rid + "] testing line '" + line + "' == '" + arp_line + "'") if (line == arp_line): arp_valid = False if (not arp_valid): Dada.logMsg(2, dl, "[" + rid + "] arp not yet valid") time.sleep(1.0) attempts += 1 # we have got an IP -> MAC address mapping, and can proceed if (attempts < 60): Dada.logMsg( 2, dl, "[" + rid + "] reg_ip " + roach_cfg["ROACH_10GbE_DEST_" + rid]) fpga.write_int('reg_ip', roach_10gbe_dest_ip) Dada.logMsg( 2, dl, "[" + rid + "] reg_10GbE_destport0 " + str(roach_10gbe_dest_port)) fpga.write_int('reg_10GbE_destport0', roach_10gbe_dest_port) Dada.logMsg(2, dl, "[" + rid + "] acc_len " + str(acc_len - 1)) fpga.write_int('reg_acclen', acc_len - 1) Dada.logMsg(2, dl, "[" + rid + "] sync_period " + str(sync_period)) fpga.write_int('reg_sync_period', sync_period) Dada.logMsg( 1, dl, "[" + rid + "] programmed " + roach_beam + ", UDP -> " + roach_cfg["ROACH_10GbE_DEST_" + rid] + ":" + str(roach_10gbe_dest_port)) Dada.logMsg(2, dl, "[" + rid + "] configureRoach: returning ok") return ("ok", fpga) # the ARP process did not work, fail else: Dada.logMsg(1, dl, "[" + rid + "] arp not valid after 60 seconds") return ("fail", fpga)
#!/usr/bin/env python import corr, time, numpy, struct, sys import Dada, Bpsr, fullpol ############################################################################### # # main # cfg = Bpsr.getConfig() rid = "0" dl = 3 acc_len = 1024 result, fpga = fullpol.initializeRoach(dl, acc_len, rid, cfg) if result == "ok": Dada.logMsg(1, dl, "main: initalizeRoach worked!") else: Dada.logMsg(1, dl, "main: initalizeRoach failed!")
def plotCandDspsr(fil_file, sample, filter, dm, snr, nchan=0, nbin=0): cand_time = (0.000064 * sample) cmd = "dmsmear -f 1382 -b 400 -n 1024 -d " + str(dm) + " -q 2>&1 " p = os.popen(cmd) cand_band_smear = p.readline().strip() p.close() Dada.logMsg(2, DL, "plotCandDspsr: cand_band_smear='" + cand_band_smear + "'") cand_filter_time = (2 ** filter) * 0.000064 cand_smearing = float(cand_band_smear) + float(cand_filter_time) cand_start_time = cand_time - (0.5 * cand_smearing) cand_tot_time = 2.0 * cand_smearing # determine the bin width, based on heimdalls filter width if nbin == 0: bin_width = 0.000064 * (2 ** filter) nbin = int(cand_tot_time / bin_width) if nbin < 16: nbin = 16 cmd = "dspsr " + fil_file + " -S " + str(cand_start_time) + \ " -b " + str(nbin) + \ " -T " + str(cand_tot_time) + \ " -c " + str(cand_tot_time) + \ " -D " + str(dm) + \ " -U 1" + \ " -cepoch start " + \ " 2>&1 | grep unloading | awk '{print $NF}'" # create a temporary working directory workdir = tempfile.mkdtemp() Dada.logMsg(2, DL, "plotCandDspsr: workdir=" + workdir) os.chdir(workdir) Dada.logMsg(2, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) response = p.readline().strip() p.close() archive = response + ".ar" count = 10 while ((not os.path.exists(archive)) and count > 0): Dada.logMsg(1, DL, "plotCandDspsr: archive file [" + archive + "] did not exist") time.sleep(1) count = count - 1 binary_data = [] if nchan == 0: # determine number of channels based on SNR nchan = int(round(math.pow(float(snr)/4.0,2))) if nchan < 2: nchan = 2 nchan_base2 = int(round(math.log(nchan,2))) nchan = pow(2,nchan_base2) if nchan > 512: nchan = 512 title = "DM=" + str(dm) + " Length=" + str(cand_filter_time*1000) + "ms Epoch=" + str(cand_start_time) cmd = "psrplot -c above:c='' -j 'zap chan 0-160,335-338,181-183' -c x:unit=ms -O -s /home/dada/linux_64/bin/frb.style ./" + archive + " -j 'F "+str(nchan)+"' -D -/PNG" Dada.logMsg(2, DL, "plotCandDspsr: " + cmd) p = os.popen(cmd) binary_data = p.read() p.close() if os.path.exists(archive): os.remove(archive) os.chdir ("/") os.rmdir(workdir) return binary_data