class BeamformerBackend(Backend): #class BeamformerBackend(VegasBackend): """A class which implements the FLAG Beamformer functionality. and which communicates with the roach and with the HPC programs via shared memory. BeamformerBackend(theBank, theMode, theRoach = None, theValon = None) Where: * *theBank:* Instance of specific bank configuration data BankData. * *theMode:* Instance of specific mode configuration data ModeData. * *theRoach:* Instance of katcp_wrapper * *theValon:* instance of ValonKATCP * *unit_test:* Set to true to unit test. Will not attempt to talk to roach, shared memory, etc. """ def __init__(self, theBank, theMode, theRoach, theValon, hpc_macs, unit_test=False, instance_id=None): """ Creates an instance of BeamformerBackend """ self.roach_simulator = True print "BFBE: ROACH SIMULATOR MODE" self.name = theMode.backend_name.lower() self.current_mode = theMode.name self.bank_name = theBank.name.upper() # Read in the additional parameters from the configuration file #config_file = './dibas.conf' config_file = os.getenv("DIBAS_DIR") + '/etc/config/dibas.conf' dibas_parser = DibasParser(dibas_conf_file=config_file) dibas_info = dibas_parser.get_dibas_info() self.roaches = [] self.configures_roaches = False self.RD = None self.pkt_gen = dibas_info['pkt_gen'] roach_names = dibas_info['roaches'] if theBank.name == dibas_info['isDoctor']: self.RD = RoachDoctor(roach_host_list=roach_names, dibas_info=dibas_info) self.configures_roaches = True self.roaches = self.RD.get_roaches() #self.RD.configure(fft_shift=0xffffffff, quan_gain=0x00000014) self.RD.configure(simulator=self.roach_simulator) self.read_parameters(theBank, theMode) # init the super, clear shmem and init shmem Backend.__init__(self, theBank, theMode, theRoach, theValon, hpc_macs, unit_test) self.clear_shared_memory() self.status = FlagPole(instance_id=self.instance) # Set some default parameter values self.requested_weight_file = '' self.weifile_new = '' self.requested_channel = 0 self.requested_integration_time = 1.0 self.fits_writer_process = None # Add additional dealer-controlled parameters self.params["int_length"] = self.setIntegrationTime self.params["weight_file"] = self.setNewWeightFilename self.params["channel_select"] = self.setChannel # TODO: will we need use roach_kvpairs if self.mode.roach_kvpairs: self.write_registers(**self.mode.roach_kvpairs) # TODO: will we need to use reset_roach - this is defined in diabs.conf, a sequence of commands to execute #self.reset_roach() self.prepare() # super class backend says this is backend dependent and I dont think our backend needs this #self.clear_switching_states() #self.add_switching_state(1.0, blank = False, cal = False, sig_ref_1 = False) self.start_hpc() self.fits_writer_program = self.fits_writer_program_bf self.start_fits_writer() def setIntegrationTime(self, int_time): """ Sets the integration time for each integration. """ self.requested_integration_time = int_time def setNewWeightFilename(self, weights): """ Sets the file containing the weights Assumes the file is submited as "weight_file_name.ext", The function will then separate the name and extension in order to append the bank letter at the end of the file and then reapply the extension such that the file is now "weight_file_name[LETTER].ext" """ flist = weights.split('.') name = flist[0] ext = flist[1] f = name + (self.bank_name[-1]).upper() + "." + ext self.requested_weight_file = f def setChannel(self, channel): """ This method is available to the user to select a block of 5 contiguous coarse channels for fine filter bank processing. @param channel - int - [0,4] 0 --> channels 0-4 1 --> channels 5-9 2 --> channels 10-14 3 --> channels 15-19 4 --> channels 20-24 If the selected channels is outside the range [0,4] prints an error to the user and retains the current channel select value. """ if channel >= 0 and channel <= 4: self.requested_channel = channel else: print( "ERROR: Invalid channel selection. Valid values are in the range [0,4]." ) print("\tUsing %i as the selected channel." % self.requested_channel) return def selectFilteredChannels(self, channel): """ This method is very similar to setChannel It's purpose is to select channels that are to be filtered via rfi mitigation processing (v1.0) currently it implements the same thing as the setChannel interface. The goal, however, is to allow any subset of channels to be selected (contiguous or not) since rfi appears at any band and can be wide, narrow or split among many different channels... """ if channel >= 0 and channel <= 4: self.requested_channel = channel else: print( "ERROR: Invalid channel selection. Valid values are in the range [0,4]." ) print("\tUsing %i as the selected channel" % self.requested_channel) return def earliest_start(self): # Get the current time now = datetime.utcnow() # Add the needed arming time to get earliest possible start time earliest_start = self.round_second_up(now) + self.mode.needed_arm_delay return earliest_start def read_parameters(self, theBank, theMode): # Quick little process to convert IP addresses from raw integer values int2ip = lambda n: '.'.join( [str(n >> (i << 3) & 0xFF) for i in range(0, 4)[::-1]]) bank = theBank.name mode = theMode.name dibas_dir = os.getenv( 'DIBAS_DIR') # Should always succeed since player started up # Create a quick ConfigParser to parse the extra information in dibas.conf config = ConfigParser.ConfigParser() filename = dibas_dir + '/etc/config/dibas.conf' config.readfp(open(filename)) # Extract the XID self.xid = config.getint(bank, 'xid') # Extract the Hashpipe instance number self.instance = config.getint(bank, 'instance') # Extract the GPU device index self.gpudev = config.getint(bank, 'gpudev') # Extract the list of cpu cores on which to run the threads self.cpus = config.get(bank, 'cpus') self.core = [ int(x) for x in self.cpus.split(',') if x.strip().isdigit() ] if mode.lower() == "flag_rtbf_mode": self.weightdir = config.get(mode, "WEIGHTD") if mode.lower() == "flag_pfb_mode" or mode.lower( ) == "flag_pfbcorr_mode": self.coeffdir = config.get(mode, "COEFFDIR") # Get the 10 GbE BINDHOST and BINDPORT for this player self.bindhost = int2ip(theBank.dest_ip) self.bindport = theBank.dest_port # Get the FITS writer process name self.fits_writer_program_bf = config.get(mode, 'fits_process') # Get sim3 flag self.sim3 = config.getint(mode, 'sim3') def start(self, starttime=None): """ Method that arms the ROACH boards and starts the acquisition process in flag_gpu Overloads the start method in VegasBackend.py """ # Check to see if a scan is already running... if self.scan_running: print "BFBE: Scan already running..." return (False, "Scan already started.") # Process the starttime argument if starttime: if type(starttime) == tuple or type( starttime) == list: # Type check starttime = datetime(*starttime) # Convert to datetime object if type( starttime ) != datetime: # If not a datetime object by here, throw exception raise Exception( "starttime must be a datetime object or datetime compatible tuple or list." ) # Make the starttime be on the next 1-second boundary starttime = self.round_second_up(starttime) now = datetime.utcnow() earliest_start = self.earliest_start() # Check to see if the required arming time puts us past the desired start time if starttime < earliest_start: # BAD-- desired time too close to be ready in time raise Exception( "Not enough time to arm ROACHs. Start: %s, earliest possible start: %s" % (str(starttime), str(earliest_start))) else: starttime = earliest_start # Set the start time in the system self.start_time = starttime # Convert datetime to seconds from start of epoch t = calendar.timegm(starttime.timetuple()) # Convert seconds to day-month julian date startDMJD = self.secs_2_dmjd(t) tstamp = starttime.strftime("%Y_%m_%d_%H:%M:%S") # Write the start time/scan length to shared memory for the FITS writer # Write day-month julian date and scan length to shared memory # Note that self.scan_length can be modified, for example, by using # dealer.set_param(scan_length=2.0) # If not set prior to running start(), this will default to 30.0 self.write_status(STRTDMJD=str(startDMJD), SCANLEN=str(self.scan_length)) self.write_status(TSTAMP=str(tstamp)) print "BFBE: TSTAMP ", str(tstamp) # Write the integration length to shared memory self.write_status(REQSTI=str(self.requested_integration_time)) # MCB -- Modified the write_status function to allow writing int/str/bool need to type cast the value as in input. # Set weight flag to default value of 0 #self.write_status(WFLAG=str(0)) #self.write_status(WFLAG=0) self.write_status(WFLAG=False) # Write the beamformer weight filename to shared memory self.write_status(BWEIFILE=str(self.requested_weight_file)) # Write the nchunk to shared memory print "BFBE: Writing CHANSEL=%d" % (self.requested_channel) self.write_status(CHANSEL=str(self.requested_channel)) self.weifile_old = self.weifile_new self.weifile_new = self.get_status('BWEIFILE') if self.weifile_old is self.weifile_new: print "BFBE: Weight file name unchanged." #self.write_status(WFLAG=str(0)) #self.write_status(WFLAG=0) self.write_status(WFLAG=False) else: print "BFBE: Weight file name changed." #self.write_status(WFLAG=str(1)) #self.write_status(WFLAG=1) self.write_status(WFLAG=True) # Print out this information print "BFBE: ", now, starttime # Check if everything is up and running if self.hpc_process is None: print "BFBE: HPC process not running... Starting HPC process..." self.start_hpc() if self.fits_writer_process is None: print "BFBE: Fits writer not running... Starting Fits writer process..." self.start_fits_writer() # Send start commands to HPC and FITS writer processes # NOTE: this does not start any timers or set any time stamps # this only forces the processes to move from IDLE states to ACQUIRE states self.hpc_cmd('START') self.fits_writer_cmd('START') # Let arming time occur immediately after penultimate 1 PPS arm_time = starttime - timedelta( microseconds=900000) # starttime - 0.9 seconds # Get current time to compare against now = datetime.utcnow() # Check to see if we are too late to arm if now > arm_time: self.hpc_cmd('STOP') self.fits_writer_cmd('STOP') raise Exception( "BFBE: start():: deadline missed, arm time is in the past.") # Get amount of waiting time tdelta = arm_time - now # Set the sleep time sleep_time = tdelta.seconds + tdelta.microseconds / 1e6 print "BFBE: Sleeping for %f seconds..." % (sleep_time) time.sleep(sleep_time) # Wake up and get to work! # We should be within a second of the specified start time self.arm_roach() # Begin watchdog timer countdown self.scan_running = True # Write... something to shared memory for some reason... #self.write_status(ACCBLKOU='-') # End function so new commands can be processed if necessary return (True, "BFBE: Successfully started ROACH for starttime=%s" % (str(self.start_time))) def startin(self, inSecs, durSecs): """ This method retains the 'interactive dealer' ability to issue a start from within a specified time and the duration of the scan. """ self.scan_length = durSecs dt = datetime.utcnow() dt.replace(second=0) dt.replace(microsecond=0) dt += timedelta(seconds=inSecs) self.start(starttime=dt) def start_old(self, inSecs, durSecs): """ Start a scan in inSecs for durSecs long Now deprecated (Richard Black), use def start(self, starttime) instead """ # our fake GPU simulator needs to know the start time of the scan # and it's duration, so we need to write it to status shared mem. def secs_2_dmjd(secs): dmjd = (secs / 86400) + 40587 return dmjd + ((secs % 86400) / 86400.) inSecs = inSecs if inSecs is not None else 5 durSecs = durSecs if durSecs is not None else 5 print "self.scan_length= %f" % (self.scan_length) self.scan_length = durSecs print "self.scan_length after = %f" % (self.scan_length) # TBF: we've done our stuff w/ DMJD, but our start is a utc datetime obj now = time.time() startDMJD = secs_2_dmjd(int(now + inSecs)) # NOTE: SCANLEN can also be set w/ player.set_param(scan_length=#) self.write_status(STRTDMJD=str(startDMJD), SCANLEN=str(durSecs)) self.write_status(REQSTI=str(self.requested_integration_time)) self.write_status(BWEIFILE=str(self.requested_weight_file)) self.write_status(CHANSEL=str(self.requested_channel)) self.weifile_old = self.weifile_new self.weifile_new = self.get_status('BWEIFILE') if self.weifile_old is self.weifile_new: print "Weight file name unchanged." # MCB -- Modified the write_status function to allow writing int/str/bool need to type cast the value as in input. #self.write_status(WFLAG=str(0)) #self.write_status(WFLAG=int(0)) self.write_status(WFLAG=False) else: print "Weight file name changed." #self.write_status(WFLAG=str(1)) #self.write_status(WFLAG=int(1)) self.write_status(WFLAG=True) dt = datetime.utcnow() dt.replace(second=0) dt.replace(microsecond=0) dt += timedelta(seconds=inSecs) BeamformerBackend.start(self, starttime=dt) #print "In Vegas Backend!!!!!!!!!!!!!!!!!!!!!!!!!!!" #print "Vegas self.scan_length after = %f" % (self.scan_length) #VegasBackend.start(self, starttime = dt) #print "Vegas self.scan_length after = %f" % (self.scan_length) #print "Out of Vegas Backend!!!!!!!!!!!!!!!!!!!!!" # prepare() for this class calls the base class prepare then does # the bare minimum required just for this backend, and then writes # to hardware, HPC, shared memory, etc. def prepare(self): """ This command writes calculated values to the hardware and status memory. This command should be run prior to the first scan to properly setup the hardware. The sequence of commands to set up a measurement is thus typically:: be.set_param(...) be.set_param(...) ... be.set_param(...) be.prepare() """ # Dont really want to call vegas (Beamformers current super) prepare method should call the Backend parent # class at a minimum however I am not sure we use it in flag. So to do this we need to get rid of the # vegas dependency # super(BeamformerBackend, self).prepare() self.write_status(BANKNAM=self.bank_name[-1]) bblock = False # perform bit/byte lock if bblock: if self.roaches: # Connect and turn noise on nb.connect() nb.send_recv('ps0') time.sleep(2) self.arm_roach() nb.set_rf_switch('NS') time.sleep(15) # bit lock for roach in self.roaches: self.RD.bit_lock(fpga=roach) nb.set_rf_switch('TT') time.sleep(15) # byte lock for roach in self.roaches: self.RD.byte_lock(fpga=roach, check=False) # # check byte lock # for roach in self.roaches: # self.RD.byte_lock(fpga=roach, check=True) # # turn noise source off nb.set_rf_switch('OFF') # turn blades off? #nb.send_recv('ps1') nb.NB.close() # Talk to outside things: status memory, HPC programs, roach if self.bank is not None: self.write_status(**self.status_mem_local) else: for i in self.status_mem_local.keys(): print "%s = %s" % (i, self.status_mem_local[i]) if self.roach: self.write_registers(**self.roach_registers_local) # _set_state_table_keywords() overrides the parent version, but # should call the parent version first thing, as it will build on # what the parent function does. Since the parent class prepare() # calls this, no need to call this from this Backend's prepare. def _set_state_table_keywords(self): """ Gather status sets here Not yet sure what to place here... """ super(BeamformerBackend, self)._set_state_table_keywords() self.set_status(BW_MODE="high") self.set_status(OBS_MODE="HBW") def set_instance_id(self, instance_id): self.instance_id = instance_id def start_hpc(self): """ Beamformer mode's are hashpipe plugins that require special handling: * are not in the dibas install area * need to pass on the instance id """ if self.test_mode: return self.stop_hpc() # Get hashpipe command (specified by configuration file) hpc_program = self.mode.hpc_program if hpc_program is None: raise Exception( "Configuration error: no field hpc_program specified in " "MODE section of %s " % (self.current_mode)) # Create command to start process process_list = [] # process_list = "sudo nice -n -20 sudo -u rablack".split() process_list = process_list + hpc_program.split() # Add flags specified by configuration file if self.mode.hpc_program_flags: process_list = process_list + self.mode.hpc_program_flags.split() # Add Instance ID inst_str = "-I " + str(self.instance) process_list = process_list + inst_str.split() # Add BINDHOST host_str = "-o BINDHOST=" + str(self.bindhost) process_list = process_list + host_str.split() # Add BINDPORT port_str = "-o BINDPORT=" + str(self.bindport) process_list = process_list + port_str.split() # Add XID xid_str = "-o XID=" + str(self.xid) process_list = process_list + xid_str.split() # Add GPUDEV gpu_str = "-o GPUDEV=" + str(self.gpudev) process_list = process_list + gpu_str.split() # Add DATADIR dir_str = "-o DATADIR=" + str(self.datadir) process_list = process_list + dir_str.split() # Add PROJID proj_str = "-o PROJID=TMP" #proj_str = "-o PROJID=." process_list = process_list + proj_str.split() # Add MODENAME mode_name = "-o MODENAME=" + str(self.current_mode) process_list = process_list + mode_name.split() # Mode-specific thread layout if self.name == "hi_correlator": # Add mode specifier for FITS writers mode_str = "-o COVMODE=HI" process_list = process_list + mode_str.split() # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_correlator_thread" % (self.core[2]) # thread4 = "-c %d flag_corsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() # process_list = process_list + thread4.split() elif self.name == "cal_correlator": # Add mode specifier for FITS writers mode_str = "-o COVMODE=PAF_CAL" process_list = process_list + mode_str.split() # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_correlator_thread" % (self.core[2]) thread4 = "-c %d flag_corsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() process_list = process_list + thread4.split() elif self.name == "correlator_save": # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_correlator_thread" % (self.core[2]) #thread4 = "-c %d flag_corsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() #process_list = process_list + thread4.split() if self.name == "frb_correlator": # Add mode specifier for FITS writers mode_str = "-o COVMODE=FRB" process_list = process_list + mode_str.split() # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_frb_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_frb_correlator_thread" % (self.core[2]) thread4 = "-c %d flag_frb_corsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() #process_list = process_list + thread4.split() elif self.name == "pulsar_beamformer": # Set weight directory weightdir_str = "-o WEIGHTD=" + str(self.weightdir) process_list = process_list + weightdir_str.split() # Add threads # GPU Transpose plugin thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_transpose_beamform_thread" % (self.core[2]) # # CPU Transpose plugin w/ trasponse thread assigned across cores. # thread1 = "-c %d flag_net_thread" % (self.core[0]) # thread2 = "-c %d flag_transpose_thread" % (self.core[1]) # if not (self.instance % 2): # thread2 = "-c %d flag_transpose_thread" % (self.core[1]) # else: # thread2 = "-c %d flag_transpose_thread" % (self.core[3]) # thread3 = "-c %d flag_beamform_thread" % (self.core[2]) # Save thread #thread4 = "-c %d flag_beamsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() #process_list = process_list + thread3.split() #process_list = process_list + thread4.split() elif self.name == "flag_total_power": # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_power_thread" % (self.core[2]) thread4 = "-c %d flag_powersave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() process_list = process_list + thread4.split() elif self.name == "flag_bx_mode": # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_bx_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_bx_thread" % (self.core[2]) #thread4 = "-c %d flag_bx_save_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() #process_list = process_list + thread4.split() elif self.name == "flag_pfb": # Set COEFFDIR coeffdir_str = "-o COEFFDIR=" + str(self.coeffdir) process_list = process_list + coeffdir_str.split() # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_pfb_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_pfb_thread" % (self.core[2]) thread4 = "-c %d flag_pfbsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() process_list = process_list + thread4.split() elif self.name == "flag_pfb_corr": # Set COEFFDIR coeffdir_str = "-o COEFFDIR=" + str(self.coeffdir) process_list = process_list + coeffdir_str.split() # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_pfb_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_pfb_thread" % (self.core[2]) thread4 = "-c %d flag_pfb_correlator_thread" % (self.core[3]) thread5 = "-c %d flag_pfb_corsave_thread" % (self.core[1]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() process_list = process_list + thread4.split() process_list = process_list + thread5.split() elif self.name == "flag_xrfi_corr": # Add threads thread1 = "-c %d flag_net_thread" % (self.core[0]) thread2 = "-c %d flag_xrfi_transpose_thread" % (self.core[1]) thread3 = "-c %d flag_xrfi_correlator_thread" % (self.core[2]) thread4 = "-c %d flag_xrfi_corsave_thread" % (self.core[3]) process_list = process_list + thread1.split() process_list = process_list + thread2.split() process_list = process_list + thread3.split() process_list = process_list + thread4.split() print ' '.join(process_list) self.hpc_process = subprocess.Popen(process_list, stdin=subprocess.PIPE) # Logic to ensure that the process is indeed finished starting time.sleep(10) def stop(self): """ Stops a scan and the FITS writer. Immediately restart FITS writer for the next scan """ if not self.scan_running: return (False, "BFBE: No scan running!") if self.scan_running: self.hpc_cmd('stop') self.fits_writer_cmd('stop') self.scan_running = False self.write_status(DISKSTAT='-') # stop data flow from roaches if self.configures_roaches: for roach in self.roaches: print "BFBE: Stop data flow for roach %s" % roach.host roach.write_int('pkt_stop', 1) time.sleep(.1) roach.write_int('pkt_stop', 0) self.start_fits_writer() def clear_shared_memory(self): """ Clears status shared memory. This was originally done in player.py in set_mode(). It has been commented out. Looking through the various parent classes, Vegas, Guppi and Backend, the shared memory status and setups have been different and there doesn't seem to be one way to deal with shared memory. If there is a universal command to be used this could be done in player. Otherwise the backends should do this. """ # Clear shared memory segments command = "hashpipe_clean_shmem -I %d" % (self.instance) ps_clean = subprocess.Popen(command.split()) ps_clean.wait() ###################################################### # FITS writer functions ###################################################### # Create a simple helper function def secs_2_dmjd(self, secs): dmjd = (secs / 86400) + 40587 return dmjd + ((secs % 86400) / 86400.) def fits_writer_cmd(self, cmd): """ Opens the named pipe to the fits_writer_cmd program, sends 'cmd', and closes the pipe. Takes care not to block on an unconnected fifo. """ if self.test_mode: return if self.fits_writer_process is None: raise Exception("Fits writer program has not been started") fh = self.fits_writer_process.stdin.fileno() os.write(fh, cmd + '\n') return True def start_fits_writer(self): """ start_fits_writer() Starts the fits writer program running. Stops any previously running instance. For the beamformer, we have to pass on the instance id. """ if self.test_mode: return self.stop_fits_writer() cmd = self.dibas_dir + '/exec/x86_64-linux/' + self.fits_writer_program cmd += " -i %d" % self.instance if self.name == 'hi_correlator': cmd += " -m s" if self.name == 'flag_pfb_corr': cmd += " -m s" # if self.name == 'flag_xrfi_corr': # cmd += " -m s" if self.name == 'cal_correlator': cmd += " -m c" if self.name == 'frb_correlator': cmd += " -m f" if self.name == 'pulsar_beamformer': cmd += " -m p" print "BFBE: Command to fits writer >> %s" % cmd process_list = shlex.split(cmd) self.fits_writer_process = subprocess.Popen(process_list, stdin=subprocess.PIPE) def stop_fits_writer(self): """ stop_fits_writer() Stops the fits writer program and make it exit. To stop an observation use 'stop()' instead. @author Mark Ruzindana """ if self.test_mode: return if self.fits_writer_process is None: return False # Nothing to do try: # First ask nicely self.fits_writer_process.communicate("quit\n") time.sleep(1) # Kill if necessary if self.fits_writer_process.poll() == None: # still running, try once more self.fits_writer_process.terminate() time.sleep(1) if self.fits_writer_process.poll() is not None: killed = True else: self.fits_writer_process.kill() killed = True else: killed = False # this was commented out??? if something with fits breaks check here self.fits_writer_process = None except OSError, e: print "While killing child process:", e killed = False finally:
def __init__(self, theBank, theMode, theRoach, theValon, hpc_macs, unit_test=False, instance_id=None): """ Creates an instance of BeamformerBackend """ self.roach_simulator = True print "BFBE: ROACH SIMULATOR MODE" self.name = theMode.backend_name.lower() self.current_mode = theMode.name self.bank_name = theBank.name.upper() # Read in the additional parameters from the configuration file #config_file = './dibas.conf' config_file = os.getenv("DIBAS_DIR") + '/etc/config/dibas.conf' dibas_parser = DibasParser(dibas_conf_file=config_file) dibas_info = dibas_parser.get_dibas_info() self.roaches = [] self.configures_roaches = False self.RD = None self.pkt_gen = dibas_info['pkt_gen'] roach_names = dibas_info['roaches'] if theBank.name == dibas_info['isDoctor']: self.RD = RoachDoctor(roach_host_list=roach_names, dibas_info=dibas_info) self.configures_roaches = True self.roaches = self.RD.get_roaches() #self.RD.configure(fft_shift=0xffffffff, quan_gain=0x00000014) self.RD.configure(simulator=self.roach_simulator) self.read_parameters(theBank, theMode) # init the super, clear shmem and init shmem Backend.__init__(self, theBank, theMode, theRoach, theValon, hpc_macs, unit_test) self.clear_shared_memory() self.status = FlagPole(instance_id=self.instance) # Set some default parameter values self.requested_weight_file = '' self.weifile_new = '' self.requested_channel = 0 self.requested_integration_time = 1.0 self.fits_writer_process = None # Add additional dealer-controlled parameters self.params["int_length"] = self.setIntegrationTime self.params["weight_file"] = self.setNewWeightFilename self.params["channel_select"] = self.setChannel # TODO: will we need use roach_kvpairs if self.mode.roach_kvpairs: self.write_registers(**self.mode.roach_kvpairs) # TODO: will we need to use reset_roach - this is defined in diabs.conf, a sequence of commands to execute #self.reset_roach() self.prepare() # super class backend says this is backend dependent and I dont think our backend needs this #self.clear_switching_states() #self.add_switching_state(1.0, blank = False, cal = False, sig_ref_1 = False) self.start_hpc() self.fits_writer_program = self.fits_writer_program_bf self.start_fits_writer()
import os from f_engine_config.RoachDoctor import RoachDoctor from config.DibasParser import DibasParser config_file = os.getenv("DIBAS_DIR") + '/etc/config/dibas.conf' dibas_parser = DibasParser(dibas_conf_file=config_file) dibas_info = dibas_parser.get_dibas_info() roach_names = dibas_info['roaches'] RD = RoachDoctor(roach_host_list=roach_names, dibas_info=dibas_info) roaches = RD.get_roaches() #num = [0, 2, 4, 6, 8, 10, 12, 14] num = [0, 2, 4, 6, 8, 10] for roach in roaches: i = 7 #i=5 for xid in num: #print "idx=%d, xid=%d" % (xid, i) roach.write_int('part2_x_id' + str(xid), i) i = i + 1