def __init__( self, my_qra: str = "PK05je", filename: str = "/Users/tim/Library/Application Support/WSJT-X/ALL_WSPR.TXT", tz="Asia/Manila", ): """ Initialize the class. :param filename: Filename of the Log file :param tz: The Timezone of your location. """ self.filename = filename self.my_qra = my_qra self.band = HamBand() self.tz = tz self.qso = [] self.process() self.tod = TimeOfDay()
def __init__( self, my_qra: str = "PK05je", filename: str = "/Users/tim/Data/ft8.dat", tz="Asia/Manila", ): """ Initialize the class. :param filename: Filename of the Log file :param tz: The Timezone of your location. """ self.filename = filename self.my_qra = my_qra self.band = HamBand() self.tz = tz self.qso = [] self.process() self.tod = TimeOfDay()
def process(self): """ My log file looks something like this ... 200210_002000 18.105 Tx WSPR 0 0.0 1547 <DU3/M0FGC> PK04LO 37 200210_002000 18.105 Tx WSPR 0 0.0 1547 <DU3/M0FGC> PK04LO 37 200210 0024 3 -22 0.24 18.1060640 KR6LA CN90 37 -3 2 0 1 379 0 200210 0024 2 -25 0.11 18.1061200 VK2JFP QF58 23 1 4 0 1 38 0 200210 0024 2 -23 -0.74 18.1061936 VK4EKA QG62 30 0 4 0 1 200 0 200210 0028 2 -26 -0.70 18.1061938 VK4EKA QG62 30 0 10 0 1 10 0 200212 0336 2 -23 0.37 14.0971782 VK3GYH QF21 40 0 3 0 1 105 0 200212 0340 4 -14 -0.27 14.0970291 P29ZL QI23 33 0 1 0 1 435 0 200212 0340 3 -23 -4.07 14.0970701 BH1NSN OM89 23 0 1 0 1 334 0 200212 0342 2 -27 0.15 14.0971009 BI1EIH ON80 27 0 6 0 1 -30 0 :return: """ maidenhead = Locator() band = HamBand() with open(self.filename, "rt") as log_file: for line in log_file: parts = line.split() if len(parts) == 15: # Ignore the Tx Lines try: whn_noutc = datetime.strptime( f"20{parts[0]}{parts[1]}", "%Y%m%d%H%M" ) whn = whn_noutc.replace(tzinfo=pytz.UTC) aprox_lat, aprox_lon = Locator.locator_to_latlong( parts[7] + "LM" ) self.qso.append( WsjXQso( when=whn, timeofday="unk", # ToDO timeofday band=self.band.khz_to_m(1000.0 * float(parts[5])), call=parts[6], grid=parts[7] + "LM", lat=aprox_lat, lon=aprox_lon, ) ) except ValueError as ve: print(f"{str(ve)} problem with {parts[0]}{parts[1]}")
def setUp(self) -> None: self.test_band = HamBand()
class TestCalcLocator(TestCase): def setUp(self) -> None: self.test_band = HamBand() def test_contest(self): self.assertEqual(self.test_band.contest, [80, 40, 20, 15, 10]) def test_khz_to_meters(self): self.assertEqual(self.test_band.khz_to_m(1850.3), 160) self.assertEqual(self.test_band.khz_to_m(3621.2), 80) self.assertEqual(self.test_band.khz_to_m(7021.2), 40) self.assertEqual(self.test_band.khz_to_m(10121.2), 30) self.assertEqual(self.test_band.khz_to_m(14021.2), 20) self.assertEqual(self.test_band.khz_to_m(18088.9999), 18) self.assertEqual(self.test_band.khz_to_m(21030.543), 15) self.assertEqual(self.test_band.khz_to_m(24895.1), 12) self.assertEqual(self.test_band.khz_to_m(28010.7), 10) def test_index(self): self.assertEqual(self.test_band.index(160), 0) self.assertEqual(self.test_band.index(80), 1) self.assertEqual(self.test_band.index(60), 2) self.assertEqual(self.test_band.index(40), 3) self.assertEqual(self.test_band.index(30), 4) self.assertEqual(self.test_band.index(20), 5) self.assertEqual(self.test_band.index(18), 6) self.assertEqual(self.test_band.index(15), 7) self.assertEqual(self.test_band.index(12), 8) self.assertEqual(self.test_band.index(10), 9)
class LogRead: def __init__( self, my_qra: str = "PK05je", filename: str = "/Users/tim/Library/Application Support/WSJT-X/ALL_WSPR.TXT", tz="Asia/Manila", ): """ Initialize the class. :param filename: Filename of the Log file :param tz: The Timezone of your location. """ self.filename = filename self.my_qra = my_qra self.band = HamBand() self.tz = tz self.qso = [] self.process() self.tod = TimeOfDay() def process(self): """ My log file looks something like this ... 200210_002000 18.105 Tx WSPR 0 0.0 1547 <DU3/M0FGC> PK04LO 37 200210_002000 18.105 Tx WSPR 0 0.0 1547 <DU3/M0FGC> PK04LO 37 200210 0024 3 -22 0.24 18.1060640 KR6LA CN90 37 -3 2 0 1 379 0 200210 0024 2 -25 0.11 18.1061200 VK2JFP QF58 23 1 4 0 1 38 0 200210 0024 2 -23 -0.74 18.1061936 VK4EKA QG62 30 0 4 0 1 200 0 200210 0028 2 -26 -0.70 18.1061938 VK4EKA QG62 30 0 10 0 1 10 0 200212 0336 2 -23 0.37 14.0971782 VK3GYH QF21 40 0 3 0 1 105 0 200212 0340 4 -14 -0.27 14.0970291 P29ZL QI23 33 0 1 0 1 435 0 200212 0340 3 -23 -4.07 14.0970701 BH1NSN OM89 23 0 1 0 1 334 0 200212 0342 2 -27 0.15 14.0971009 BI1EIH ON80 27 0 6 0 1 -30 0 :return: """ maidenhead = Locator() band = HamBand() with open(self.filename, "rt") as log_file: for line in log_file: parts = line.split() if len(parts) == 15: # Ignore the Tx Lines try: whn_noutc = datetime.strptime( f"20{parts[0]}{parts[1]}", "%Y%m%d%H%M" ) whn = whn_noutc.replace(tzinfo=pytz.UTC) aprox_lat, aprox_lon = Locator.locator_to_latlong( parts[7] + "LM" ) self.qso.append( WsjXQso( when=whn, timeofday="unk", # ToDO timeofday band=self.band.khz_to_m(1000.0 * float(parts[5])), call=parts[6], grid=parts[7] + "LM", lat=aprox_lat, lon=aprox_lon, ) ) except ValueError as ve: print(f"{str(ve)} problem with {parts[0]}{parts[1]}") def dump(self): pprint(self.qso) def dump_geo(self): my_lat, my_lon = Locator.locator_to_latlong(self.my_qra) return FeatureCollection( [ LineString( [(my_lon, my_lat), (q.lon, q.lat)], properties={"band": q.band, "call": q.call, "when": q.when.hour}, ) for q in self.qso ] ) def dump_geo_to_file(self, filename: str = "MySpots.json"): with open(filename, "wt") as geoJsonFile: json.dump(self.dump_geo(), geoJsonFile)
def process(self): """ My log file looks something like this ... We only Want lines with the QRA on them... the others are responding to other QSOs 200221 000030 11.0 -3 0.18 14074352 JH7OTG QM08 200221 000030 7.5 -4 0.08 14075982 JA6BXA PM52 200221 000030 8.7 -5 0.00 18101824 BH4IGO 200221 000045 11.5 -5 0.20 14074760 JA8ECS QN03 200221 000100 5.7 -5 0.20 7075672 BG5GLV PL09 200221 000115 12.2 0 0.00 7075745 YB5HPT OI09 200221 000115 5.6 -12 -0.62 10137410 JP3SHI 200221 000130 9.8 1 -0.03 7074414 XV1X OK33 200221 000130 3.0 -8 -0.06 7075581 DV3CEP PK05 200221 000145 3.3 -7 -0.02 7076183 YF5TKN OJ20 200221 000215 14.3 -4 -0.05 7075135 YD4URY OI25 :return: """ maidenhead = Locator() band = HamBand() with open(self.filename, "rt") as log_file: for line in log_file: parts = line.split() bearing_short_path = 0 distance_short_path_km = 0.0 if len(parts) == 8: # Ignore the Tx Lines try: whn_noutc = datetime.strptime( f"20{parts[0]}{parts[1]}", "%Y%m%d%H%M%S" ) whn = whn_noutc.replace(tzinfo=pytz.UTC) aprox_lat, aprox_lon = Locator.locator_to_latlong( parts[7] + "LM" ) bearing_short_path = maidenhead.calculate_heading( self.my_qra, parts[7] + "LM" ) distance_short_path_km = maidenhead.calculate_distance_km( self.my_qra, parts[7] + "LM" ) # # Hack for Leaflet.js # As I am close to the Pacific .... It plots Ph to US via Europe # THis is called the " antimeridian artifacts" # So if I have a longitude < -15 (Ireland, North Africa) I make it postive if aprox_lon < -15.0: aprox_lon += 360.0 self.qso.append( ft8Qso( when=whn, # ToDO timeofday timeofday="unk", band=self.band.khz_to_m(float(parts[5]) / 1000.0), call=parts[6], grid=parts[7] + "LM", lat=aprox_lat, lon=aprox_lon, heading_sp=bearing_short_path, distance_sp_km=distance_short_path_km, ) ) except ValueError as ve: print(f"{str(ve)} problem with {parts[0]}{parts[1]}")
class LogRead: def __init__( self, my_qra: str = "PK05je", filename: str = "/Users/tim/Data/ft8.dat", tz="Asia/Manila", ): """ Initialize the class. :param filename: Filename of the Log file :param tz: The Timezone of your location. """ self.filename = filename self.my_qra = my_qra self.band = HamBand() self.tz = tz self.qso = [] self.process() self.tod = TimeOfDay() def process(self): """ My log file looks something like this ... We only Want lines with the QRA on them... the others are responding to other QSOs 200221 000030 11.0 -3 0.18 14074352 JH7OTG QM08 200221 000030 7.5 -4 0.08 14075982 JA6BXA PM52 200221 000030 8.7 -5 0.00 18101824 BH4IGO 200221 000045 11.5 -5 0.20 14074760 JA8ECS QN03 200221 000100 5.7 -5 0.20 7075672 BG5GLV PL09 200221 000115 12.2 0 0.00 7075745 YB5HPT OI09 200221 000115 5.6 -12 -0.62 10137410 JP3SHI 200221 000130 9.8 1 -0.03 7074414 XV1X OK33 200221 000130 3.0 -8 -0.06 7075581 DV3CEP PK05 200221 000145 3.3 -7 -0.02 7076183 YF5TKN OJ20 200221 000215 14.3 -4 -0.05 7075135 YD4URY OI25 :return: """ maidenhead = Locator() band = HamBand() with open(self.filename, "rt") as log_file: for line in log_file: parts = line.split() bearing_short_path = 0 distance_short_path_km = 0.0 if len(parts) == 8: # Ignore the Tx Lines try: whn_noutc = datetime.strptime( f"20{parts[0]}{parts[1]}", "%Y%m%d%H%M%S" ) whn = whn_noutc.replace(tzinfo=pytz.UTC) aprox_lat, aprox_lon = Locator.locator_to_latlong( parts[7] + "LM" ) bearing_short_path = maidenhead.calculate_heading( self.my_qra, parts[7] + "LM" ) distance_short_path_km = maidenhead.calculate_distance_km( self.my_qra, parts[7] + "LM" ) # # Hack for Leaflet.js # As I am close to the Pacific .... It plots Ph to US via Europe # THis is called the " antimeridian artifacts" # So if I have a longitude < -15 (Ireland, North Africa) I make it postive if aprox_lon < -15.0: aprox_lon += 360.0 self.qso.append( ft8Qso( when=whn, # ToDO timeofday timeofday="unk", band=self.band.khz_to_m(float(parts[5]) / 1000.0), call=parts[6], grid=parts[7] + "LM", lat=aprox_lat, lon=aprox_lon, heading_sp=bearing_short_path, distance_sp_km=distance_short_path_km, ) ) except ValueError as ve: print(f"{str(ve)} problem with {parts[0]}{parts[1]}") def dump(self): pprint(self.qso) def dump_geo(self): my_lat, my_lon = Locator.locator_to_latlong(self.my_qra) return FeatureCollection( [ LineString( [(my_lon, my_lat), (q.lon, q.lat)], properties={ "band": q.band, "call": q.call, "when": q.when.hour, "distance": q.distance_sp_km, "heading": q.heading_sp, }, ) for q in self.qso ] ) def dump_data(self): """ Output data in a flat format for csv, pandas etc :return: """ my_lat, my_lon = Locator.locator_to_latlong(self.my_qra) return [ { "my_lat": my_lat, "my_lon": my_lon, "their_lat": q.lat, "their_lon": q.lon, "bearing": q.heading_sp, "distance": q.distance_sp_km, "band": q.band, "call": q.call, "when": q.when.hour, } for q in self.qso ] def dump_geojson_to_file(self, filename: str = "Myft8Spots.json"): with open(filename, "wt") as geoJsonFile: json.dump(self.dump_geo(), geoJsonFile) def dump_data_to_pickle(self, filename: str = "Myft8Spots.pkl"): with open(filename, "wb") as pickle_file: pickle.dump(self.dump_geo(), pickle_file)