Skip to content

Commit e50be75

Browse files
committed
New lla2ecef and moved plot_rinex to Utils
Also, pyETM now prints the node name and a timestamp to the json file
1 parent 96bd321 commit e50be75

File tree

5 files changed

+127
-71
lines changed

5 files changed

+127
-71
lines changed

.idea/Parallel.GAMIT.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com/GenerateKml.py

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# app
2828
from pgamit import dbConnection, pyDate, pyJobServer, pyOptions, pyStationInfo
2929
from pgamit.pyGamitConfig import GamitConfiguration
30-
from pgamit.Utils import process_stnlist, stationID
30+
from pgamit.Utils import process_stnlist, stationID, plot_rinex_completion
3131

3232
global kml, folder_project, folder_allstns, stnlist
3333

@@ -121,9 +121,7 @@ def description_content(stn, DateS, DateE, count, completion, stn_issues,
121121
<strong>Observation distribution:</strong><br>
122122
</p>
123123
<img src="data:image/png;base64, %s" alt="Available data" />
124-
""" % plot_rinex(cnn,
125-
stn['NetworkCode'],
126-
stn['StationCode'])
124+
""" % plot_rinex_completion(cnn, stn['NetworkCode'], stn['StationCode'])
127125
else:
128126
data_plt = ""
129127

@@ -248,7 +246,7 @@ def generate_kml_stninfo(JobServer, cnn, project, data=False,
248246
pbar = tqdm(
249247
desc=' >> Adding stations', total=len(rs), ncols=80, disable=None)
250248

251-
depfuncs = (plot_station_info_rinex, plot_rinex, stationID)
249+
depfuncs = (plot_station_info_rinex, plot_rinex_completion, stationID)
252250

253251
JobServer.create_cluster(description_content,
254252
depfuncs,
@@ -485,7 +483,7 @@ def generate_kml(cnn, project, data=False):
485483
<strong>Observation distribution:</strong><br>
486484
</p>
487485
<img src="data:image/png;base64, %s" alt="Available data" />
488-
""" % plot_rinex(cnn, stn['NetworkCode'], stn['StationCode'])
486+
""" % plot_rinex_completion(cnn, stn['NetworkCode'], stn['StationCode'])
489487
else:
490488
data_plt = ""
491489

@@ -576,64 +574,5 @@ def plot_station_info_rinex(cnn, NetworkCode, StationCode, stninfo_records):
576574
return figdata_png
577575

578576

579-
def plot_rinex(cnn, NetworkCode, StationCode):
580-
581-
import matplotlib.pyplot as plt
582-
583-
# find the available data
584-
rinex = numpy.array(cnn.query_float("""
585-
SELECT "ObservationYear", "ObservationDOY",
586-
"Completion" FROM rinex_proc WHERE
587-
"NetworkCode" = '%s' AND "StationCode" = '%s'""" % (NetworkCode,
588-
StationCode)))
589-
590-
fig, ax = plt.subplots(figsize=(10, 25))
591-
592-
fig.tight_layout(pad=5)
593-
ax.set_title('RINEX and missing data for %s.%s'
594-
% (NetworkCode, StationCode))
595-
596-
if rinex.size:
597-
# create a continuous vector for missing data
598-
md = numpy.arange(1, 367)
599-
my = numpy.unique(rinex[:, 0])
600-
for yr in my:
601-
ax.plot(numpy.repeat(yr, 366), md, 'o', fillstyle='none',
602-
color='silver', markersize=4, linewidth=0.1)
603-
604-
ax.scatter(rinex[:, 0], rinex[:, 1],
605-
c=['tab:blue' if c >= 0.5 else 'tab:orange'
606-
for c in rinex[:, 2]], s=10, zorder=10)
607-
608-
ax.tick_params(top=True, labeltop=True, labelleft=True,
609-
labelright=True, left=True, right=True)
610-
plt.xticks(numpy.arange(my.min(), my.max()+1, step=1),
611-
rotation='vertical') # Set label locations.
612-
613-
ax.grid(True)
614-
ax.set_axisbelow(True)
615-
plt.ylim([0, 367])
616-
plt.yticks(numpy.arange(0, 368, step=5)) # Set label locations.
617-
618-
ax.set_ylabel('DOYs')
619-
ax.set_xlabel('Years')
620-
621-
figfile = io.BytesIO()
622-
623-
try:
624-
plt.savefig(figfile, format='png')
625-
# plt.show()
626-
figfile.seek(0) # rewind to beginning of file
627-
628-
figdata_png = base64.b64encode(figfile.getvalue()).decode()
629-
except Exception:
630-
# either no rinex or no station info
631-
figdata_png = ''
632-
633-
plt.close()
634-
635-
return figdata_png
636-
637-
638577
if __name__ == '__main__':
639578
main()

pgamit/Utils.py

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import argparse
88
import stat
99
import shutil
10+
import io
11+
import base64
1012
from datetime import datetime
1113
from zlib import crc32 as zlib_crc32
1214
from pathlib import Path
@@ -420,6 +422,35 @@ def ecef2lla(ecefArr):
420422
return lat.ravel(), lon.ravel(), alt.ravel()
421423

422424

425+
def lla2ecef(llaArr):
426+
# convert LLA coordinates to ECEF
427+
# test data : test_coord = [-66.8765400174 23.876539914 999.998386689]
428+
# expected result : 2297292.91, 1016894.94, -5843939.62
429+
430+
llaArr = numpy.atleast_1d(llaArr)
431+
432+
# transpose to work on both vectors and scalars
433+
lat = llaArr.T[0]
434+
lon = llaArr.T[1]
435+
alt = llaArr.T[2]
436+
437+
rad_lat = lat * (numpy.pi / 180.0)
438+
rad_lon = lon * (numpy.pi / 180.0)
439+
440+
# WGS84
441+
a = 6378137.0
442+
finv = 298.257223563
443+
f = 1 / finv
444+
e2 = 1 - (1 - f) * (1 - f)
445+
v = a / numpy.sqrt(1 - e2 * numpy.sin(rad_lat) * numpy.sin(rad_lat))
446+
447+
x = (v + alt) * numpy.cos(rad_lat) * numpy.cos(rad_lon)
448+
y = (v + alt) * numpy.cos(rad_lat) * numpy.sin(rad_lon)
449+
z = (v * (1 - e2) + alt) * numpy.sin(rad_lat)
450+
451+
return numpy.round(x, 4).ravel(), numpy.round(y, 4).ravel(), numpy.round(z, 4).ravel()
452+
453+
423454
def process_date_str(arg, allow_days=False):
424455

425456
rdate = pyDate.Date(datetime=datetime.now())
@@ -915,4 +946,86 @@ def fqdn_parse(fqdn, default_port=None):
915946
fqdn, port = fqdn.split(':')
916947
return fqdn, int(port[1])
917948
else:
918-
return fqdn, default_port
949+
return fqdn, default_port
950+
951+
952+
def plot_rinex_completion(cnn, NetworkCode, StationCode, landscape=False):
953+
954+
import matplotlib.pyplot as plt
955+
956+
# find the available data
957+
rinex = numpy.array(cnn.query_float("""
958+
SELECT "ObservationYear", "ObservationDOY",
959+
"Completion" FROM rinex_proc WHERE
960+
"NetworkCode" = '%s' AND "StationCode" = '%s'""" % (NetworkCode,
961+
StationCode)))
962+
963+
if landscape:
964+
fig, ax = plt.subplots(figsize=(25, 10))
965+
x = 1
966+
y = 0
967+
else:
968+
fig, ax = plt.subplots(figsize=(10, 25))
969+
x = 0
970+
y = 1
971+
972+
fig.tight_layout(pad=5)
973+
ax.set_title('RINEX and missing data for %s.%s'
974+
% (NetworkCode, StationCode))
975+
976+
if rinex.size:
977+
# create a continuous vector for missing data
978+
md = numpy.arange(1, 367)
979+
my = numpy.unique(rinex[:, 0])
980+
for yr in my:
981+
982+
if landscape:
983+
ax.plot(md, numpy.repeat(yr, 366), 'o', fillstyle='none',
984+
color='silver', markersize=4, linewidth=0.1)
985+
else:
986+
ax.plot(numpy.repeat(yr, 366), md, 'o', fillstyle='none',
987+
color='silver', markersize=4, linewidth=0.1)
988+
989+
ax.scatter(rinex[:, x], rinex[:, y],
990+
c=['tab:blue' if c >= 0.5 else 'tab:orange'
991+
for c in rinex[:, 2]], s=10, zorder=10)
992+
993+
ax.tick_params(top=True, labeltop=True, labelleft=True,
994+
labelright=True, left=True, right=True)
995+
if landscape:
996+
plt.yticks(numpy.arange(my.min(), my.max() + 1, step=1)) # Set label locations.
997+
else:
998+
plt.xticks(numpy.arange(my.min(), my.max()+1, step=1),
999+
rotation='vertical') # Set label locations.
1000+
1001+
ax.grid(True)
1002+
ax.set_axisbelow(True)
1003+
1004+
if landscape:
1005+
plt.xlim([0, 367])
1006+
plt.xticks(numpy.arange(0, 368, step=5)) # Set label locations.
1007+
1008+
ax.set_xlabel('DOYs')
1009+
ax.set_ylabel('Years')
1010+
else:
1011+
plt.ylim([0, 367])
1012+
plt.yticks(numpy.arange(0, 368, step=5)) # Set label locations.
1013+
1014+
ax.set_ylabel('DOYs')
1015+
ax.set_xlabel('Years')
1016+
1017+
figfile = io.BytesIO()
1018+
1019+
try:
1020+
plt.savefig(figfile, format='png')
1021+
# plt.show()
1022+
figfile.seek(0) # rewind to beginning of file
1023+
1024+
figdata_png = base64.b64encode(figfile.getvalue()).decode()
1025+
except Exception:
1026+
# either no rinex or no station info
1027+
figdata_png = ''
1028+
1029+
plt.close()
1030+
1031+
return figdata_png

pgamit/pyETM.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import logging
1818
from logging import INFO, ERROR, WARNING, DEBUG, StreamHandler, Formatter
1919
import copy
20+
import platform
2021

2122
from importlib.metadata import version, PackageNotFoundError
2223

@@ -859,8 +860,8 @@ def detect_jumps(self, soln):
859860
N_data = np.column_stack((time_scaled, l[0]))
860861

861862
# Apply DBSCAN clustering with tuned parameters
862-
eps_value = 0.0028 # Adjust as needed to detect prominent clusters
863-
min_samples_value = 15 # value from tests
863+
eps_value = 0.0028 # Adjust as needed to detect prominent clusters
864+
min_samples_value = 15 # value from tests
864865

865866
dbscan = DBSCAN(eps=eps_value, min_samples=min_samples_value)
866867
e_cluster_labels = dbscan.fit_predict(E_data)
@@ -2749,7 +2750,10 @@ def todictionary(self, time_series=False, model=False):
27492750
'ce_y': self.ce_pos[1][0],
27502751
'ce_z': self.ce_pos[2][0],
27512752
't_ref': self.Linear.p.t_ref if self.A is not None else 0.0,
2752-
'Jumps': [to_list(jump.p.toDict()) for jump in self.Jumps.table]
2753+
'Jumps': [to_list(jump.p.toDict()) for jump in self.Jumps.table],
2754+
'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
2755+
'localhost': platform.node(),
2756+
'version': VERSION
27532757
}
27542758

27552759
if self.A is not None:

0 commit comments

Comments
 (0)