def dump_spectral_density(self): assert self.devtype == DEVTYPE_4PORT data = struct.pack(">HHHH", 2, 2, 2, 2) data = self.run_cmd("SCAN-SPEC-DENSITY", data=data, instance=0b1111) nports = struct.unpack(">H", data[0:2])[0] data = data[2:] print("FSCAN: Port Count: {}".format(nports)) port = 1 while data: npoints = struct.unpack(">H", data[:2])[0] data = data[2:] spoints = struct.unpack(">" + str(npoints * 3) + "h", data[:6 * npoints]) upoints = struct.unpack(">" + str(npoints * 3) + "H", data[:6 * npoints]) data = data[6 * npoints:] print("SPDENSE PORT {} points {}".format(port, npoints)) with open("sd-{}.csv".format(port), "w") as f: for freq, avgpower, maxpower in zip(upoints[::3], spoints[1::3], spoints[2::3]): avgpower = Power(avgpower / 100) + Gain(20) maxpower = Power(maxpower / 100) + Gain(20) freq = (1900000 + freq) / 10 print("SPDENSE PORT {}: FRQ: {}\tWVL: " "{}\t Avg Pwr: {}\tMax Pwr: {}".format( port, freq, frequency_to_wavelen_precise(freq), avgpower, maxpower)) f.write("{}\t{}\t{}\n".format(freq, avgpower, maxpower)) port += 1
def get_itu_scan(self, hires): assert self.devtype == DEVTYPE_TFOCM hival = 2 if hires else 1 data = self.run_cmd("FULL-ITU-SCAN", struct.pack(">H", hival)) if hires: size = 512 # XXX this is probably msw lsw of channel wavelen words = unpack_unsigned(data[:size]) it = iter(words) uints = [(((msw & 0xFFFF) << 16) + (lsw & 0xFFFF)) for msw, lsw in zip(it, it)] frequency = [ wavelen_to_frequency(float(x) / 1000.0) if x > 0 else 0 for x in uints ] # frequency = [ float(x) / 1000.0 if x > 0 else 0 for x in uints ] else: size = 256 # frequency = [ wavelen_to_frequency(((x / 100.0) + 1500) if x > 0 else 0 for x in unpack_unsigned(data[:size]) ] frequency = [ wavelen_to_frequency((float(x) / 100.0) + 1500.0) for x in unpack_unsigned(data[:size]) ] # frequency = [ (float(x) / 100.0) + 1500.0 for x in unpack_unsigned(data[:size]) ] # frequency = unpack_unsigned(data[:size]) data = data[size:] presence = unpack_unsigned(data[:256]) data = data[256:] if hires: power = [Power(x / 100) for x in unpack_signed(data[:256])] else: power = [Power(x / 10) for x in unpack_signed(data[:256])] return zip(frequency, presence, power)
def get_itu_power_scan(self, hires): assert self.devtype == DEVTYPE_TFOCM hival = 2 if hires else 1 data = self.run_cmd("FULL-ITU-POWER-SCAN", struct.pack(">H", hival)) if hires: power = [Power(x / 100) for x in unpack_signed(data[:256])] else: power = [Power(x / 10) for x in unpack_signed(data[:256])] # XXX Are the start and stop frequency or the interval affected by the user settings? # or always constant b/c it's the ITU variant of the commands return zip( range(TFOCM_DEFAULT_START_FREQ, TFOCM_DEFAULT_STOP_FREQ + 1, 50), power)
def dump_channel_scan(self): assert self.devtype == DEVTYPE_4PORT data = struct.pack(">HHHH", 2, 2, 2, 2) data = self.run_cmd("FULL-12-CH-SCAN", data=data, instance=0b1111) nports = struct.unpack(">H", data[0:2])[0] data = data[2:] print("FSCAN: Port Count: {}".format(nports)) port = 1 while data: nchan = struct.unpack(">H", data[:2])[0] data = data[2:] print("FSCAN PORT {} Channel count {}".format(port, nchan)) chandata = data[:nchan * 3 * 2] data = data[nchan * 3 * 2:] spoints = struct.unpack(">" + str(nchan * 3) + "h", chandata) upoints = struct.unpack(">" + str(nchan * 3) + "H", chandata) with open("fpcs-{}.csv".format(port), "w") as f: for freq, power, present in zip(upoints[::3], spoints[1::3], upoints[2::3]): power = Power(power / 100) + Gain(20) freq = (1900000 + freq) / 10 if True or power > Power(-25): print("FSCAN PORT {} CHFRQ: {}\tPWR: {}\tPRES: {}". format(port, freq, power, present)) f.write("{}\t{}\n".format(freq, power)) npoints = struct.unpack(">H", data[:2])[0] data = data[2:] pdata = data[:npoints * 2] data = data[2 * npoints:] spoints = struct.unpack(">" + str(npoints) + "h", pdata) # print("FSCAN PORT {} points {}".format(port, npoints)) # for idx, power in enumerate(spoints): # power = Power(power / 100) + Gain(20) # if power > Power(-30): # print("FSCAN PORT {}: SLICE IDX: {}\tPWR: {}".format(port, # idx, # power)) port += 1
def get_wavelen_power(self, wavelen): "Get power level of a wavelen in nanometers (non-int ok)" assert self.devtype == DEVTYPE_TFOCM val = int(wavelen * 1000) msw = (val >> 16) & 0xFFFF lsw = (val & 0xFFFF) data = self.run_cmd("GET-SINGLE-POWER", struct.pack(">HHHH", 2, msw, lsw, 2)) power = Power(unpack_signed(data)[0] / 100) return power
def get_freq_power(self, freq): "Get power level of a frequency in GHz" assert self.devtype == DEVTYPE_TFOCM val = int(frequency_to_wavelen_precise(int(freq)) * 1000) msw = (val >> 16) & 0xFFFF lsw = (val & 0xFFFF) # This seems to ignore our resolution request and always returns low data = self.run_cmd("GET-SINGLE-POWER", struct.pack(">HHHH", 1, msw, lsw, 2)) power = Power(unpack_signed(data)[0] / 10) return power
def get_full_125_scan(self, instance=0b1111): assert self.devtype == DEVTYPE_4PORT data = self.run_cmd("FULL-12-SCAN", instance=instance) nports = struct.unpack(">H", data[0:2])[0] data = data[2:] if self.debug: logger.debug("FSCAN125x625: Port Count: %s", str(nports)) result = [] for port in instance_to_ports(instance): npoints = struct.unpack(">H", data[:2])[0] data = data[2:] if npoints != 839: raise ValueError( "Too man points %d (not 839) in 12.5x6.25 scan", npoints) spoints = struct.unpack(">" + str(npoints) + "h", data[:2 * npoints]) data = data[2 * npoints:] if self.debug: logger.debug("FSCAN125x625 PORT %d points %d", port, npoints) rpoints = [] # Start of scan range freq = 191000 for power in spoints: rpoints.append((freq, Power(power / 100) + Gain(20))) freq += 6.25 lrpoints = len(rpoints) if npoints != lrpoints: raise ValueError( "Returned points {} different from expected {}".format( lrpoints, npoints)) result.append((port, rpoints)) if data: raise ValueError("Extra data form OCM of len: {}".format( len(data))) return result
def get_full_scan(self, instance=0b1111): assert self.devtype == DEVTYPE_4PORT data = self.run_cmd("FULL-SPECTRUM-SCAN", instance=instance) nports = struct.unpack(">H", data[0:2])[0] data = data[2:] if self.debug: logger.debug("FSCAN: Port Count: %d", nports) result = [] for port in instance_to_ports(instance): npoints = struct.unpack(">H", data[:2])[0] data = data[2:] spoints, upoints = unpack_signed_unsigned(data[:4 * npoints]) data = data[4 * npoints:] if self.debug: logger.debug("FSCAN PORT %s points %d", port, npoints) rpoints = [] for freq, power in zip(upoints[::2], spoints[1::2]): power = Power(power / 100) + Gain(20) # Tap is 1% so add 20dB freq = 1900000 + freq rpoints.append((freq, power)) lrpoints = len(rpoints) if npoints != lrpoints: raise ValueError( "Returned points {} different from expected {}".format( lrpoints, npoints)) result.append((port, rpoints)) # Want better error here. if data: raise ValueError("Extra data form OCM of len: {}".format( len(data))) return result