##// END OF EJS Templates
Danny Scipión -
r1346:a455424d10b0 merge
parent child
Show More
@@ -5,4 +5,4 try:
5 5 except:
6 6 pass
7 7
8 __version__ = '3.0.0b5'
8 __version__ = '3.0.0b6'
@@ -907,12 +907,10 class PlotterData(object):
907 907 MAXNUMX = 200
908 908 MAXNUMY = 200
909 909
910 def __init__(self, code, throttle_value, exp_code, localtime=True, buffering=True, snr=False):
910 def __init__(self, code, exp_code, localtime=True):
911 911
912 912 self.key = code
913 self.throttle = throttle_value
914 913 self.exp_code = exp_code
915 self.buffering = buffering
916 914 self.ready = False
917 915 self.flagNoData = False
918 916 self.localtime = localtime
@@ -920,46 +918,24 class PlotterData(object):
920 918 self.meta = {}
921 919 self.__heights = []
922 920
923 if 'snr' in code:
924 self.plottypes = ['snr']
925 elif code == 'spc':
926 self.plottypes = ['spc', 'noise', 'rti']
927 elif code == 'cspc':
928 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
929 elif code == 'rti':
930 self.plottypes = ['noise', 'rti']
931 else:
932 self.plottypes = [code]
933
934 if 'snr' not in self.plottypes and snr:
935 self.plottypes.append('snr')
936
937 for plot in self.plottypes:
938 self.data[plot] = {}
939
940 921 def __str__(self):
941 922 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
942 923 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
943 924
944 925 def __len__(self):
945 return len(self.data[self.key])
926 return len(self.data)
946 927
947 928 def __getitem__(self, key):
948
949 if key not in self.data:
950 raise KeyError(log.error('Missing key: {}'.format(key)))
951 if 'spc' in key or not self.buffering:
952 ret = self.data[key][self.tm]
953 elif 'scope' in key:
954 ret = numpy.array(self.data[key][float(self.tm)])
955 else:
956 ret = numpy.array([self.data[key][x] for x in self.times])
929 if isinstance(key, int):
930 return self.data[self.times[key]]
931 elif isinstance(key, str):
932 ret = numpy.array([self.data[x][key] for x in self.times])
957 933 if ret.ndim > 1:
958 934 ret = numpy.swapaxes(ret, 0, 1)
959 935 return ret
960 936
961 937 def __contains__(self, key):
962 return key in self.data
938 return key in self.data[self.min_time]
963 939
964 940 def setup(self):
965 941 '''
@@ -971,125 +947,25 class PlotterData(object):
971 947 self.data = {}
972 948 self.__heights = []
973 949 self.__all_heights = set()
974 for plot in self.plottypes:
975 if 'snr' in plot:
976 plot = 'snr'
977 elif 'spc_moments' == plot:
978 plot = 'moments'
979 self.data[plot] = {}
980
981 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
982 self.data['noise'] = {}
983 self.data['rti'] = {}
984 if 'noise' not in self.plottypes:
985 self.plottypes.append('noise')
986 if 'rti' not in self.plottypes:
987 self.plottypes.append('rti')
988 950
989 951 def shape(self, key):
990 952 '''
991 953 Get the shape of the one-element data for the given key
992 954 '''
993 955
994 if len(self.data[key]):
995 if 'spc' in key or not self.buffering:
996 return self.data[key].shape
997 return self.data[key][self.times[0]].shape
956 if len(self.data[self.min_time][key]):
957 return self.data[self.min_time][key].shape
998 958 return (0,)
999 959
1000 def update(self, dataOut, tm):
960 def update(self, data, tm, meta={}):
1001 961 '''
1002 962 Update data object with new dataOut
1003 963 '''
1004 964
1005 self.profileIndex = dataOut.profileIndex
1006 self.tm = tm
1007 self.type = dataOut.type
1008 self.parameters = getattr(dataOut, 'parameters', [])
1009
1010 if hasattr(dataOut, 'meta'):
1011 self.meta.update(dataOut.meta)
1012
1013 if hasattr(dataOut, 'pairsList'):
1014 self.pairs = dataOut.pairsList
1015
1016 self.interval = dataOut.timeInterval
1017 if True in ['spc' in ptype for ptype in self.plottypes]:
1018 self.xrange = (dataOut.getFreqRange(1)/1000.,
1019 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1020 self.__heights.append(dataOut.heightList)
1021 self.__all_heights.update(dataOut.heightList)
1022
1023 for plot in self.plottypes:
1024 if plot in ('spc', 'spc_moments', 'spc_cut'):
1025 z = dataOut.data_spc/dataOut.normFactor
1026 buffer = 10*numpy.log10(z)
1027 if plot == 'cspc':
1028 buffer = (dataOut.data_spc, dataOut.data_cspc)
1029 if plot == 'noise':
1030 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1031 if plot in ('rti', 'spcprofile'):
1032 buffer = dataOut.getPower()
1033 if plot == 'snr_db':
1034 buffer = dataOut.data_SNR
1035 if plot == 'snr':
1036 buffer = 10*numpy.log10(dataOut.data_SNR)
1037 if plot == 'dop':
1038 buffer = dataOut.data_DOP
1039 if plot == 'pow':
1040 buffer = 10*numpy.log10(dataOut.data_POW)
1041 if plot == 'width':
1042 buffer = dataOut.data_WIDTH
1043 if plot == 'coh':
1044 buffer = dataOut.getCoherence()
1045 if plot == 'phase':
1046 buffer = dataOut.getCoherence(phase=True)
1047 if plot == 'output':
1048 buffer = dataOut.data_output
1049 if plot == 'param':
1050 buffer = dataOut.data_param
1051 if plot == 'scope':
1052 buffer = dataOut.data
1053 self.flagDataAsBlock = dataOut.flagDataAsBlock
1054 self.nProfiles = dataOut.nProfiles
1055 if plot == 'pp_power':
1056 buffer = dataOut.dataPP_POWER
1057 self.flagDataAsBlock = dataOut.flagDataAsBlock
1058 self.nProfiles = dataOut.nProfiles
1059 if plot == 'pp_signal':
1060 buffer = dataOut.dataPP_POW
1061 self.flagDataAsBlock = dataOut.flagDataAsBlock
1062 self.nProfiles = dataOut.nProfiles
1063 if plot == 'pp_velocity':
1064 buffer = dataOut.dataPP_DOP
1065 self.flagDataAsBlock = dataOut.flagDataAsBlock
1066 self.nProfiles = dataOut.nProfiles
1067 if plot == 'pp_specwidth':
1068 buffer = dataOut.dataPP_WIDTH
1069 self.flagDataAsBlock = dataOut.flagDataAsBlock
1070 self.nProfiles = dataOut.nProfiles
1071
1072 if plot == 'spc':
1073 self.data['spc'][tm] = buffer
1074 elif plot == 'cspc':
1075 self.data['cspc'][tm] = buffer
1076 elif plot == 'spc_moments':
1077 self.data['spc'][tm] = buffer
1078 self.data['moments'][tm] = dataOut.moments
1079 else:
1080 if self.buffering:
1081 self.data[plot][tm] = buffer
1082 else:
1083 self.data[plot][tm] = buffer
1084
1085 if dataOut.channelList is None:
1086 self.channels = range(buffer.shape[0])
1087 else:
1088 self.channels = dataOut.channelList
965 self.data[tm] = data
1089 966
1090 if buffer is None:
1091 self.flagNoData = True
1092 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
967 for key, value in meta.items():
968 setattr(self, key, value)
1093 969
1094 970 def normalize_heights(self):
1095 971 '''
@@ -1119,18 +995,21 class PlotterData(object):
1119 995 Convert data to json
1120 996 '''
1121 997
1122 dy = int(self.heights.size/self.MAXNUMY) + 1
1123 if self.key in ('spc', 'cspc'):
1124 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
998 meta = {}
999 meta['xrange'] = []
1000 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1001 tmp = self.data[tm][self.key]
1002 shape = tmp.shape
1003 if len(shape) == 2:
1004 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1005 elif len(shape) == 3:
1006 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1125 1007 data = self.roundFloats(
1126 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1127 else:
1128 if self.key is 'noise':
1129 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1008 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1009 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1130 1010 else:
1131 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1011 data = self.roundFloats(self.data[tm][self.key].tolist())
1132 1012
1133 meta = {}
1134 1013 ret = {
1135 1014 'plot': plot_name,
1136 1015 'code': self.exp_code,
@@ -1140,12 +1019,7 class PlotterData(object):
1140 1019 meta['type'] = plot_type
1141 1020 meta['interval'] = float(self.interval)
1142 1021 meta['localtime'] = self.localtime
1143 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1144 if 'spc' in self.data or 'cspc' in self.data:
1145 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1146 else:
1147 meta['xrange'] = []
1148
1022 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1149 1023 meta.update(self.meta)
1150 1024 ret['metadata'] = meta
1151 1025 return json.dumps(ret)
@@ -1156,10 +1030,9 class PlotterData(object):
1156 1030 Return the list of times of the current data
1157 1031 '''
1158 1032
1159 ret = numpy.array([t for t in self.data[self.key]])
1160 if self:
1033 ret = [t for t in self.data]
1161 1034 ret.sort()
1162 return ret
1035 return numpy.array(ret)
1163 1036
1164 1037 @property
1165 1038 def min_time(self):
@@ -1177,13 +1050,13 class PlotterData(object):
1177 1050
1178 1051 return self.times[-1]
1179 1052
1180 @property
1181 def heights(self):
1182 '''
1183 Return the list of heights of the current data
1184 '''
1053 # @property
1054 # def heights(self):
1055 # '''
1056 # Return the list of heights of the current data
1057 # '''
1185 1058
1186 return numpy.array(self.__heights[-1])
1059 # return numpy.array(self.__heights[-1])
1187 1060
1188 1061 @staticmethod
1189 1062 def roundFloats(obj):
@@ -302,7 +302,7 class RadarControllerHeader(Header):
302 302 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
303 303 numTaus=0, line6Function=0, line5Function=0, fClock=None,
304 304 prePulseBefore=0, prePulseAfter=0,
305 codeType=0, nCode=0, nBaud=0, code=None,
305 codeType=0, nCode=0, nBaud=0, code=[],
306 306 flip1=0, flip2=0):
307 307
308 308 # self.size = 116
@@ -12,7 +12,7 import zmq
12 12 import time
13 13 import numpy
14 14 import datetime
15 from multiprocessing import Queue
15 from collections import deque
16 16 from functools import wraps
17 17 from threading import Thread
18 18 import matplotlib
@@ -22,7 +22,7 if 'BACKEND' in os.environ:
22 22 elif 'linux' in sys.platform:
23 23 matplotlib.use("TkAgg")
24 24 elif 'darwin' in sys.platform:
25 matplotlib.use('WxAgg')
25 matplotlib.use('MacOSX')
26 26 else:
27 27 from schainpy.utils import log
28 28 log.warning('Using default Backend="Agg"', 'INFO')
@@ -83,7 +83,6 def figpause(interval):
83 83 pass
84 84 return
85 85
86
87 86 def popup(message):
88 87 '''
89 88 '''
@@ -186,7 +185,7 class Plot(Operation):
186 185 self.sender_time = 0
187 186 self.data = None
188 187 self.firsttime = True
189 self.sender_queue = Queue(maxsize=60)
188 self.sender_queue = deque(maxlen=10)
190 189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
191 190
192 191 def __fmtTime(self, x, pos):
@@ -230,6 +229,7 class Plot(Operation):
230 229 self.yscale = kwargs.get('yscale', None)
231 230 self.xlabel = kwargs.get('xlabel', None)
232 231 self.attr_time = kwargs.get('attr_time', 'utctime')
232 self.attr_data = kwargs.get('attr_data', 'data_param')
233 233 self.decimation = kwargs.get('decimation', None)
234 234 self.showSNR = kwargs.get('showSNR', False)
235 235 self.oneFigure = kwargs.get('oneFigure', True)
@@ -251,8 +251,8 class Plot(Operation):
251 251 self.tag = kwargs.get('tag', '')
252 252 self.height_index = kwargs.get('height_index', None)
253 253 self.__throttle_plot = apply_throttle(self.throttle)
254 self.data = PlotterData(
255 self.CODE, self.throttle, self.exp_code, self.localtime, self.buffering, snr=self.showSNR)
254 code = self.attr_data if self.attr_data else self.CODE
255 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
256 256
257 257 if self.server:
258 258 if not self.server.startswith('tcp://'):
@@ -385,8 +385,8 class Plot(Operation):
385 385 xmax = self.tmin + self.xrange*60*60
386 386 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
387 387 ax.xaxis.set_major_locator(LinearLocator(9))
388 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
389 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
388 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
389 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
390 390 ax.set_facecolor(self.bgcolor)
391 391 if self.xscale:
392 392 ax.xaxis.set_major_formatter(FuncFormatter(
@@ -478,14 +478,28 class Plot(Operation):
478 478 if self.server:
479 479 self.send_to_server()
480 480
481 def __update(self, dataOut, timestamp):
482 '''
483 '''
484
485 metadata = {
486 'yrange': dataOut.heightList,
487 'interval': dataOut.timeInterval,
488 'channels': dataOut.channelList
489 }
490
491 data, meta = self.update(dataOut)
492 metadata.update(meta)
493 self.data.update(data, timestamp, metadata)
494
481 495 def save_figure(self, n):
482 496 '''
483 497 '''
484 498
485 if (self.data.tm - self.save_time) <= self.save_period:
499 if (self.data.max_time - self.save_time) <= self.save_period:
486 500 return
487 501
488 self.save_time = self.data.tm
502 self.save_time = self.data.max_time
489 503
490 504 fig = self.figures[n]
491 505
@@ -520,11 +534,15 class Plot(Operation):
520 534 '''
521 535 '''
522 536
523 interval = self.data.tm - self.sender_time
537 if self.exp_code == None:
538 log.warning('Missing `exp_code` skipping sending to server...')
539
540 last_time = self.data.max_time
541 interval = last_time - self.sender_time
524 542 if interval < self.sender_period:
525 543 return
526 544
527 self.sender_time = self.data.tm
545 self.sender_time = last_time
528 546
529 547 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
530 548 for attr in attrs:
@@ -541,27 +559,21 class Plot(Operation):
541 559 self.data.meta['colormap'] = 'Viridis'
542 560 self.data.meta['interval'] = int(interval)
543 561
544 try:
545 self.sender_queue.put(self.data.tm, block=False)
546 except:
547 tm = self.sender_queue.get()
548 self.sender_queue.put(self.data.tm)
562 self.sender_queue.append(last_time)
549 563
550 564 while True:
551 if self.sender_queue.empty():
552 break
553 tm = self.sender_queue.get()
554 565 try:
566 tm = self.sender_queue.popleft()
567 except IndexError:
568 break
555 569 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
556 except:
557 continue
558 570 self.socket.send_string(msg)
559 socks = dict(self.poll.poll(5000))
571 socks = dict(self.poll.poll(2000))
560 572 if socks.get(self.socket) == zmq.POLLIN:
561 573 reply = self.socket.recv_string()
562 574 if reply == 'ok':
563 575 log.log("Response from server ok", self.name)
564 time.sleep(0.2)
576 time.sleep(0.1)
565 577 continue
566 578 else:
567 579 log.warning(
@@ -569,11 +581,10 class Plot(Operation):
569 581 else:
570 582 log.warning(
571 583 "No response from server, retrying...", self.name)
572 self.sender_queue.put(self.data.tm)
584 self.sender_queue.appendleft(tm)
573 585 self.socket.setsockopt(zmq.LINGER, 0)
574 586 self.socket.close()
575 587 self.poll.unregister(self.socket)
576 time.sleep(0.1)
577 588 self.socket = self.context.socket(zmq.REQ)
578 589 self.socket.connect(self.server)
579 590 self.poll.register(self.socket, zmq.POLLIN)
@@ -595,10 +606,22 class Plot(Operation):
595 606
596 607 def plot(self):
597 608 '''
598 Must be defined in the child class
609 Must be defined in the child class, the actual plotting method
599 610 '''
600 611 raise NotImplementedError
601 612
613 def update(self, dataOut):
614 '''
615 Must be defined in the child class, update self.data with new data
616 '''
617
618 data = {
619 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
620 }
621 meta = {}
622
623 return data, meta
624
602 625 def run(self, dataOut, **kwargs):
603 626 '''
604 627 Main plotting routine
@@ -630,7 +653,7 class Plot(Operation):
630 653 self.data.setup()
631 654 self.clear_figures()
632 655
633 self.data.update(dataOut, tm)
656 self.__update(dataOut, tm)
634 657
635 658 if self.isPlotConfig is False:
636 659 self.__setup_plot()
@@ -658,7 +681,7 class Plot(Operation):
658 681 def close(self):
659 682
660 683 if self.data and not self.data.flagNoData:
661 self.save_time = self.data.tm
684 self.save_time = self.data.max_time
662 685 self.__plot()
663 686 if self.data and not self.data.flagNoData and self.pause:
664 687 figpause(10)
@@ -1,342 +1,101
1 '''
2 Created on Jul 9, 2014
3
4 @author: roj-idl71
5 '''
6 import os
7 import datetime
8 import numpy
9
10 from schainpy.model.graphics.jroplot_base import Plot
11
12
13 class SpectraHeisScope(Plot):
14
15
16 isConfig = None
17 __nsubplots = None
18
19 WIDTHPROF = None
20 HEIGHTPROF = None
21 PREFIX = 'spc'
22
23 def __init__(self):#, **kwargs):
24
25 Plot.__init__(self)#, **kwargs)
26 self.isConfig = False
27 self.__nsubplots = 1
28
29 self.WIDTH = 230
30 self.HEIGHT = 250
31 self.WIDTHPROF = 120
32 self.HEIGHTPROF = 0
33 self.counter_imagwr = 0
34
35 self.PLOT_CODE = SPEC_CODE
36
37 def getSubplots(self):
38
39 ncol = int(numpy.sqrt(self.nplots)+0.9)
40 nrow = int(self.nplots*1./ncol + 0.9)
41
42 return nrow, ncol
43
44 def setup(self, id, nplots, wintitle, show):
45
46 showprofile = False
47 self.__showprofile = showprofile
48 self.nplots = nplots
49
50 ncolspan = 1
51 colspan = 1
52 if showprofile:
53 ncolspan = 3
54 colspan = 2
55 self.__nsubplots = 2
56
57 self.createFigure(id = id,
58 wintitle = wintitle,
59 widthplot = self.WIDTH + self.WIDTHPROF,
60 heightplot = self.HEIGHT + self.HEIGHTPROF,
61 show = show)
62
63 nrow, ncol = self.getSubplots()
64
65 counter = 0
66 for y in range(nrow):
67 for x in range(ncol):
68
69 if counter >= self.nplots:
70 break
71
72 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
73
74 if showprofile:
75 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
76
77 counter += 1
78
79
80 def run(self, dataOut, id, wintitle="", channelList=None,
81 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
82 figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
83 server=None, folder=None, username=None, password=None,
84 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
3 #
4 # Distributed under the terms of the BSD 3-clause license.
5 """Classes to plo Specra Heis data
85 6
86 7 """
87 8
88 Input:
89 dataOut :
90 id :
91 wintitle :
92 channelList :
93 xmin : None,
94 xmax : None,
95 ymin : None,
96 ymax : None,
97 """
98
99 if dataOut.flagNoData:
100 return dataOut
101
102 if dataOut.realtime:
103 if not(isRealtime(utcdatatime = dataOut.utctime)):
104 print('Skipping this plot function')
105 return
106
107 if channelList == None:
108 channelIndexList = dataOut.channelIndexList
109 else:
110 channelIndexList = []
111 for channel in channelList:
112 if channel not in dataOut.channelList:
113 raise ValueError("Channel %d is not in dataOut.channelList")
114 channelIndexList.append(dataOut.channelList.index(channel))
115
116 # x = dataOut.heightList
117 c = 3E8
118 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
119 #deberia cambiar para el caso de 1Mhz y 100KHz
120 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
121 #para 1Mhz descomentar la siguiente linea
122 #x= x/(10000.0)
123 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
124 # y = y.real
125 factor = dataOut.normFactor
126 data = dataOut.data_spc / factor
127 datadB = 10.*numpy.log10(data)
128 y = datadB
129
130 #thisDatetime = dataOut.datatime
131 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
132 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
133 xlabel = ""
134 #para 1Mhz descomentar la siguiente linea
135 #xlabel = "Frequency x 10000"
136 ylabel = "Intensity (dB)"
137
138 if not self.isConfig:
139 nplots = len(channelIndexList)
140
141 self.setup(id=id,
142 nplots=nplots,
143 wintitle=wintitle,
144 show=show)
145
146 if xmin == None: xmin = numpy.nanmin(x)
147 if xmax == None: xmax = numpy.nanmax(x)
148 if ymin == None: ymin = numpy.nanmin(y)
149 if ymax == None: ymax = numpy.nanmax(y)
150
151 self.FTP_WEI = ftp_wei
152 self.EXP_CODE = exp_code
153 self.SUB_EXP_CODE = sub_exp_code
154 self.PLOT_POS = plot_pos
155
156 self.isConfig = True
157
158 self.setWinTitle(title)
159
160 for i in range(len(self.axesList)):
161 ychannel = y[i,:]
162 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
163 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[channelIndexList[i]], numpy.max(ychannel), str_datetime)
164 axes = self.axesList[i]
165 axes.pline(x, ychannel,
166 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
167 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
168
169
170 self.draw()
171
172 self.save(figpath=figpath,
173 figfile=figfile,
174 save=save,
175 ftp=ftp,
176 wr_period=wr_period,
177 thisDatetime=thisDatetime)
178
179 return dataOut
180
181
182 class RTIfromSpectraHeis(Plot):
183
184 isConfig = None
185 __nsubplots = None
186
187 PREFIX = 'rtinoise'
188
189 def __init__(self):#, **kwargs):
190 Plot.__init__(self)#, **kwargs)
191 self.timerange = 24*60*60
192 self.isConfig = False
193 self.__nsubplots = 1
194
195 self.WIDTH = 820
196 self.HEIGHT = 200
197 self.WIDTHPROF = 120
198 self.HEIGHTPROF = 0
199 self.counter_imagwr = 0
200 self.xdata = None
201 self.ydata = None
202 self.figfile = None
203
204 self.PLOT_CODE = RTI_CODE
205
206 def getSubplots(self):
207
208 ncol = 1
209 nrow = 1
210
211 return nrow, ncol
9 import numpy
212 10
213 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
11 from schainpy.model.graphics.jroplot_base import Plot, plt
214 12
215 self.__showprofile = showprofile
216 self.nplots = nplots
217 13
218 ncolspan = 7
219 colspan = 6
220 self.__nsubplots = 2
14 class SpectraHeisPlot(Plot):
221 15
222 self.createFigure(id = id,
223 wintitle = wintitle,
224 widthplot = self.WIDTH+self.WIDTHPROF,
225 heightplot = self.HEIGHT+self.HEIGHTPROF,
226 show = show)
16 CODE = 'spc_heis'
227 17
228 nrow, ncol = self.getSubplots()
18 def setup(self):
229 19
230 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
20 self.nplots = len(self.data.channels)
21 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
22 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
23 self.height = 2.6 * self.nrows
24 self.width = 3.5 * self.ncols
25 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.95, 'bottom': 0.08})
26 self.ylabel = 'Intensity [dB]'
27 self.xlabel = 'Frequency [KHz]'
28 self.colorbar = False
231 29
30 def update(self, dataOut):
232 31
233 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
234 xmin=None, xmax=None, ymin=None, ymax=None,
235 timerange=None,
236 save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
237 server=None, folder=None, username=None, password=None,
238 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
32 data = {}
33 meta = {}
34 spc = 10*numpy.log10(dataOut.data_spc / dataOut.normFactor)
35 data['spc_heis'] = spc
239 36
240 if dataOut.flagNoData:
241 return dataOut
37 return data, meta
242 38
39 def plot(self):
243 40
244 if channelList == None:
245 channelIndexList = dataOut.channelIndexList
246 channelList = dataOut.channelList
41 c = 3E8
42 deltaHeight = self.data.yrange[1] - self.data.yrange[0]
43 x = numpy.arange(-1*len(self.data.yrange)/2., len(self.data.yrange)/2.)*(c/(2*deltaHeight*len(self.data.yrange)*1000))
44 self.y = self.data[-1]['spc_heis']
45 self.titles = []
46
47 for n, ax in enumerate(self.axes):
48 ychannel = self.y[n,:]
49 if ax.firsttime:
50 self.xmin = min(x) if self.xmin is None else self.xmin
51 self.xmax = max(x) if self.xmax is None else self.xmax
52 ax.plt = ax.plot(x, ychannel, lw=1, color='b')[0]
247 53 else:
248 channelIndexList = []
249 for channel in channelList:
250 if channel not in dataOut.channelList:
251 raise ValueError("Channel %d is not in dataOut.channelList")
252 channelIndexList.append(dataOut.channelList.index(channel))
253
254 if timerange != None:
255 self.timerange = timerange
256
257 x = dataOut.getTimeRange()
258 y = dataOut.heightList
259
260 factor = dataOut.normFactor
261 data = dataOut.data_spc / factor
262 data = numpy.average(data,axis=1)
263 datadB = 10*numpy.log10(data)
264
265 # factor = dataOut.normFactor
266 # noise = dataOut.getNoise()/factor
267 # noisedB = 10*numpy.log10(noise)
268
269 #thisDatetime = dataOut.datatime
270 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
271 title = wintitle + " RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
272 xlabel = "Local Time"
273 ylabel = "Intensity (dB)"
54 ax.plt.set_data(x, ychannel)
274 55
275 if not self.isConfig:
56 self.titles.append("Channel {}: {:4.2f}dB".format(n, numpy.max(ychannel)))
276 57
277 nplots = 1
278 58
279 self.setup(id=id,
280 nplots=nplots,
281 wintitle=wintitle,
282 showprofile=showprofile,
283 show=show)
59 class RTIHeisPlot(Plot):
284 60
285 self.tmin, self.tmax = self.getTimeLim(x, xmin, xmax)
61 CODE = 'rti_heis'
286 62
287 if ymin == None: ymin = numpy.nanmin(datadB)
288 if ymax == None: ymax = numpy.nanmax(datadB)
63 def setup(self):
289 64
290 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
291 self.isConfig = True
292 self.figfile = figfile
293 self.xdata = numpy.array([])
294 self.ydata = numpy.array([])
65 self.xaxis = 'time'
66 self.ncols = 1
67 self.nrows = 1
68 self.nplots = 1
69 self.ylabel = 'Intensity [dB]'
70 self.xlabel = 'Time'
71 self.titles = ['RTI']
72 self.colorbar = False
73 self.height = 4
74 self.plots_adjust.update({'right': 0.85 })
295 75
296 self.FTP_WEI = ftp_wei
297 self.EXP_CODE = exp_code
298 self.SUB_EXP_CODE = sub_exp_code
299 self.PLOT_POS = plot_pos
76 def update(self, dataOut):
300 77
301 self.setWinTitle(title)
78 data = {}
79 meta = {}
80 spc = dataOut.data_spc / dataOut.normFactor
81 spc = 10*numpy.log10(numpy.average(spc, axis=1))
82 data['rti_heis'] = spc
302 83
84 return data, meta
303 85
304 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
305 title = "RTI - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
86 def plot(self):
306 87
307 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
308 axes = self.axesList[0]
88 x = self.data.times
89 Y = self.data['rti_heis']
309 90
310 self.xdata = numpy.hstack((self.xdata, x[0:1]))
311
312 if len(self.ydata)==0:
313 self.ydata = datadB[channelIndexList].reshape(-1,1)
91 if self.axes[0].firsttime:
92 self.ymin = numpy.nanmin(Y) - 5 if self.ymin == None else self.ymin
93 self.ymax = numpy.nanmax(Y) + 5 if self.ymax == None else self.ymax
94 for ch in self.data.channels:
95 y = Y[ch]
96 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
97 plt.legend(bbox_to_anchor=(1.18, 1.0))
314 98 else:
315 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
316
317
318 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
319 xmin=self.tmin, xmax=self.tmax, ymin=ymin, ymax=ymax,
320 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
321 XAxisAsTime=True
322 )
323
324 self.draw()
325
326 update_figfile = False
327
328 if dataOut.ltctime >= self.tmax:
329 self.counter_imagwr = wr_period
330 self.isConfig = False
331 update_figfile = True
332
333 self.save(figpath=figpath,
334 figfile=figfile,
335 save=save,
336 ftp=ftp,
337 wr_period=wr_period,
338 thisDatetime=thisDatetime,
339 update_figfile=update_figfile)
340
341
342 return dataOut No newline at end of file
99 for ch in self.data.channels:
100 y = Y[ch]
101 self.axes[0].lines[ch].set_data(x, y)
@@ -47,6 +47,13 class SnrPlot(RTIPlot):
47 47 CODE = 'snr'
48 48 colormap = 'jet'
49 49
50 def update(self, dataOut):
51
52 data = {
53 'snr': 10*numpy.log10(dataOut.data_snr)
54 }
55
56 return data, {}
50 57
51 58 class DopplerPlot(RTIPlot):
52 59 '''
@@ -56,6 +63,13 class DopplerPlot(RTIPlot):
56 63 CODE = 'dop'
57 64 colormap = 'jet'
58 65
66 def update(self, dataOut):
67
68 data = {
69 'dop': 10*numpy.log10(dataOut.data_dop)
70 }
71
72 return data, {}
59 73
60 74 class PowerPlot(RTIPlot):
61 75 '''
@@ -65,6 +79,13 class PowerPlot(RTIPlot):
65 79 CODE = 'pow'
66 80 colormap = 'jet'
67 81
82 def update(self, dataOut):
83
84 data = {
85 'pow': 10*numpy.log10(dataOut.data_pow)
86 }
87
88 return data, {}
68 89
69 90 class SpectralWidthPlot(RTIPlot):
70 91 '''
@@ -74,6 +95,13 class SpectralWidthPlot(RTIPlot):
74 95 CODE = 'width'
75 96 colormap = 'jet'
76 97
98 def update(self, dataOut):
99
100 data = {
101 'width': dataOut.data_width
102 }
103
104 return data, {}
77 105
78 106 class SkyMapPlot(Plot):
79 107 '''
@@ -123,45 +151,45 class SkyMapPlot(Plot):
123 151 self.titles[0] = title
124 152
125 153
126 class ParametersPlot(RTIPlot):
154 class GenericRTIPlot(Plot):
127 155 '''
128 Plot for data_param object
156 Plot for data_xxxx object
129 157 '''
130 158
131 159 CODE = 'param'
132 colormap = 'seismic'
160 colormap = 'viridis'
161 plot_type = 'pcolorbuffer'
133 162
134 163 def setup(self):
135 164 self.xaxis = 'time'
136 165 self.ncols = 1
137 self.nrows = self.data.shape(self.CODE)[0]
166 self.nrows = self.data.shape(self.attr_data)[0]
138 167 self.nplots = self.nrows
139 168 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
140 169
141 170 if not self.xlabel:
142 171 self.xlabel = 'Time'
143 172
144 if self.showSNR:
145 self.nrows += 1
146 self.nplots += 1
147
148 173 self.ylabel = 'Height [km]'
149 174 if not self.titles:
150 175 self.titles = self.data.parameters \
151 176 if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)]
152 if self.showSNR:
153 self.titles.append('SNR')
177
178 def update(self, dataOut):
179
180 data = {
181 self.attr_data : getattr(dataOut, self.attr_data)
182 }
183
184 meta = {}
185
186 return data, meta
154 187
155 188 def plot(self):
156 self.data.normalize_heights()
189 # self.data.normalize_heights()
157 190 self.x = self.data.times
158 self.y = self.data.heights
159 if self.showSNR:
160 self.z = numpy.concatenate(
161 (self.data[self.CODE], self.data['snr'])
162 )
163 else:
164 self.z = self.data[self.CODE]
191 self.y = self.data.yrange
192 self.z = self.data[self.attr_data]
165 193
166 194 self.z = numpy.ma.masked_invalid(self.z)
167 195
@@ -197,15 +225,6 class ParametersPlot(RTIPlot):
197 225 )
198 226
199 227
200 class OutputPlot(ParametersPlot):
201 '''
202 Plot data_output object
203 '''
204
205 CODE = 'output'
206 colormap = 'seismic'
207
208
209 228 class PolarMapPlot(Plot):
210 229 '''
211 230 Plot for weather radar
@@ -251,14 +270,14 class PolarMapPlot(Plot):
251 270 zeniths = numpy.linspace(
252 271 0, self.data.meta['max_range'], data.shape[1])
253 272 if self.mode == 'E':
254 azimuths = -numpy.radians(self.data.heights)+numpy.pi/2
273 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
255 274 r, theta = numpy.meshgrid(zeniths, azimuths)
256 275 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
257 276 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
258 277 x = km2deg(x) + self.lon
259 278 y = km2deg(y) + self.lat
260 279 else:
261 azimuths = numpy.radians(self.data.heights)
280 azimuths = numpy.radians(self.data.yrange)
262 281 r, theta = numpy.meshgrid(zeniths, azimuths)
263 282 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
264 283 self.y = zeniths
@@ -1,15 +1,15
1 '''
2 Created on Jul 9, 2014
3 Modified on May 10, 2020
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
3 #
4 # Distributed under the terms of the BSD 3-clause license.
5 """Classes to plot Spectra data
4 6
5 @author: Juan C. Espinoza
6 '''
7 """
7 8
8 9 import os
9 import datetime
10 10 import numpy
11 11
12 from schainpy.model.graphics.jroplot_base import Plot, plt
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 13
14 14
15 15 class SpectraPlot(Plot):
@@ -20,6 +20,7 class SpectraPlot(Plot):
20 20 CODE = 'spc'
21 21 colormap = 'jet'
22 22 plot_type = 'pcolor'
23 buffering = False
23 24
24 25 def setup(self):
25 26 self.nplots = len(self.data.channels)
@@ -34,6 +35,20 class SpectraPlot(Plot):
34 35 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
35 36 self.ylabel = 'Range [km]'
36 37
38 def update(self, dataOut):
39
40 data = {}
41 meta = {}
42 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
43 data['spc'] = spc
44 data['rti'] = dataOut.getPower()
45 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
46 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
47 if self.CODE == 'spc_moments':
48 data['moments'] = dataOut.moments
49
50 return data, meta
51
37 52 def plot(self):
38 53 if self.xaxis == "frequency":
39 54 x = self.data.xrange[0]
@@ -51,14 +66,16 class SpectraPlot(Plot):
51 66
52 67 self.titles = []
53 68
54 y = self.data.heights
69 y = self.data.yrange
55 70 self.y = y
56 z = self.data['spc']
71
72 data = self.data[-1]
73 z = data['spc']
57 74
58 75 for n, ax in enumerate(self.axes):
59 noise = self.data['noise'][n][-1]
76 noise = data['noise'][n]
60 77 if self.CODE == 'spc_moments':
61 mean = self.data['moments'][n, :, 1, :][-1]
78 mean = data['moments'][n, 2]
62 79 if ax.firsttime:
63 80 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
64 81 self.xmin = self.xmin if self.xmin else -self.xmax
@@ -72,7 +89,7 class SpectraPlot(Plot):
72 89
73 90 if self.showprofile:
74 91 ax.plt_profile = self.pf_axes[n].plot(
75 self.data['rti'][n][-1], y)[0]
92 data['rti'][n], y)[0]
76 93 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
77 94 color="k", linestyle="dashed", lw=1)[0]
78 95 if self.CODE == 'spc_moments':
@@ -80,7 +97,7 class SpectraPlot(Plot):
80 97 else:
81 98 ax.plt.set_array(z[n].T.ravel())
82 99 if self.showprofile:
83 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
100 ax.plt_profile.set_data(data['rti'][n], y)
84 101 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
85 102 if self.CODE == 'spc_moments':
86 103 ax.plt_mean.set_data(mean, y)
@@ -100,14 +117,37 class CrossSpectraPlot(Plot):
100 117 def setup(self):
101 118
102 119 self.ncols = 4
103 self.nrows = len(self.data.pairs)
104 self.nplots = self.nrows * 4
120 self.nplots = len(self.data.pairs) * 2
121 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
105 122 self.width = 3.1 * self.ncols
106 123 self.height = 2.6 * self.nrows
107 124 self.ylabel = 'Range [km]'
108 125 self.showprofile = False
109 126 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
110 127
128 def update(self, dataOut):
129
130 data = {}
131 meta = {}
132
133 spc = dataOut.data_spc
134 cspc = dataOut.data_cspc
135 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
136 meta['pairs'] = dataOut.pairsList
137
138 tmp = []
139
140 for n, pair in enumerate(meta['pairs']):
141 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
142 coh = numpy.abs(out)
143 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
144 tmp.append(coh)
145 tmp.append(phase)
146
147 data['cspc'] = numpy.array(tmp)
148
149 return data, meta
150
111 151 def plot(self):
112 152
113 153 if self.xaxis == "frequency":
@@ -122,46 +162,17 class CrossSpectraPlot(Plot):
122 162
123 163 self.titles = []
124 164
125 y = self.data.heights
165 y = self.data.yrange
126 166 self.y = y
127 nspc = self.data['spc']
128 spc = self.data['cspc'][0]
129 cspc = self.data['cspc'][1]
130 167
131 for n in range(self.nrows):
132 noise = self.data['noise'][:,-1]
133 pair = self.data.pairs[n]
134 ax = self.axes[4 * n]
135 if ax.firsttime:
136 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
137 self.xmin = self.xmin if self.xmin else -self.xmax
138 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
139 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
140 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
141 vmin=self.zmin,
142 vmax=self.zmax,
143 cmap=plt.get_cmap(self.colormap)
144 )
145 else:
146 ax.plt.set_array(nspc[pair[0]].T.ravel())
147 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
168 data = self.data[-1]
169 cspc = data['cspc']
148 170
149 ax = self.axes[4 * n + 1]
150 if ax.firsttime:
151 ax.plt = ax.pcolormesh(x , y, nspc[pair[1]].T,
152 vmin=self.zmin,
153 vmax=self.zmax,
154 cmap=plt.get_cmap(self.colormap)
155 )
156 else:
157 ax.plt.set_array(nspc[pair[1]].T.ravel())
158 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
159
160 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
161 coh = numpy.abs(out)
162 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
163
164 ax = self.axes[4 * n + 2]
171 for n in range(len(self.data.pairs)):
172 pair = self.data.pairs[n]
173 coh = cspc[n*2]
174 phase = cspc[n*2+1]
175 ax = self.axes[2 * n]
165 176 if ax.firsttime:
166 177 ax.plt = ax.pcolormesh(x, y, coh.T,
167 178 vmin=0,
@@ -173,7 +184,7 class CrossSpectraPlot(Plot):
173 184 self.titles.append(
174 185 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
175 186
176 ax = self.axes[4 * n + 3]
187 ax = self.axes[2 * n + 1]
177 188 if ax.firsttime:
178 189 ax.plt = ax.pcolormesh(x, y, phase.T,
179 190 vmin=-180,
@@ -206,9 +217,18 class RTIPlot(Plot):
206 217 self.titles = ['{} Channel {}'.format(
207 218 self.CODE.upper(), x) for x in range(self.nrows)]
208 219
220 def update(self, dataOut):
221
222 data = {}
223 meta = {}
224 data['rti'] = dataOut.getPower()
225 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
226
227 return data, meta
228
209 229 def plot(self):
210 230 self.x = self.data.times
211 self.y = self.data.heights
231 self.y = self.data.yrange
212 232 self.z = self.data[self.CODE]
213 233 self.z = numpy.ma.masked_invalid(self.z)
214 234
@@ -220,6 +240,7 class RTIPlot(Plot):
220 240 for n, ax in enumerate(self.axes):
221 241 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
222 242 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
243 data = self.data[-1]
223 244 if ax.firsttime:
224 245 ax.plt = ax.pcolormesh(x, y, z[n].T,
225 246 vmin=self.zmin,
@@ -228,8 +249,8 class RTIPlot(Plot):
228 249 )
229 250 if self.showprofile:
230 251 ax.plot_profile = self.pf_axes[n].plot(
231 self.data['rti'][n][-1], self.y)[0]
232 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
252 data['rti'][n], self.y)[0]
253 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
233 254 color="k", linestyle="dashed", lw=1)[0]
234 255 else:
235 256 ax.collections.remove(ax.collections[0])
@@ -239,9 +260,9 class RTIPlot(Plot):
239 260 cmap=plt.get_cmap(self.colormap)
240 261 )
241 262 if self.showprofile:
242 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
263 ax.plot_profile.set_data(data['rti'][n], self.y)
243 264 ax.plot_noise.set_data(numpy.repeat(
244 self.data['noise'][n][-1], len(self.y)), self.y)
265 data['noise'][n], len(self.y)), self.y)
245 266
246 267
247 268 class CoherencePlot(RTIPlot):
@@ -268,6 +289,14 class CoherencePlot(RTIPlot):
268 289 self.titles = [
269 290 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
270 291
292 def update(self, dataOut):
293
294 data = {}
295 meta = {}
296 data['coh'] = dataOut.getCoherence()
297 meta['pairs'] = dataOut.pairsList
298
299 return data, meta
271 300
272 301 class PhasePlot(CoherencePlot):
273 302 '''
@@ -277,6 +306,14 class PhasePlot(CoherencePlot):
277 306 CODE = 'phase'
278 307 colormap = 'seismic'
279 308
309 def update(self, dataOut):
310
311 data = {}
312 meta = {}
313 data['phase'] = dataOut.getCoherence(phase=True)
314 meta['pairs'] = dataOut.pairsList
315
316 return data, meta
280 317
281 318 class NoisePlot(Plot):
282 319 '''
@@ -286,7 +323,6 class NoisePlot(Plot):
286 323 CODE = 'noise'
287 324 plot_type = 'scatterbuffer'
288 325
289
290 326 def setup(self):
291 327 self.xaxis = 'time'
292 328 self.ncols = 1
@@ -296,33 +332,41 class NoisePlot(Plot):
296 332 self.xlabel = 'Time'
297 333 self.titles = ['Noise']
298 334 self.colorbar = False
335 self.plots_adjust.update({'right': 0.85 })
336
337 def update(self, dataOut):
338
339 data = {}
340 meta = {}
341 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
342 meta['yrange'] = numpy.array([])
343
344 return data, meta
299 345
300 346 def plot(self):
301 347
302 348 x = self.data.times
303 349 xmin = self.data.min_time
304 350 xmax = xmin + self.xrange * 60 * 60
305 Y = self.data[self.CODE]
351 Y = self.data['noise']
306 352
307 353 if self.axes[0].firsttime:
354 self.ymin = numpy.nanmin(Y) - 5
355 self.ymax = numpy.nanmax(Y) + 5
308 356 for ch in self.data.channels:
309 357 y = Y[ch]
310 358 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
311 plt.legend()
359 plt.legend(bbox_to_anchor=(1.18, 1.0))
312 360 else:
313 361 for ch in self.data.channels:
314 362 y = Y[ch]
315 363 self.axes[0].lines[ch].set_data(x, y)
316 364
317 self.ymin = numpy.nanmin(Y) - 5
318 self.ymax = numpy.nanmax(Y) + 5
319
320 365
321 366 class PowerProfilePlot(Plot):
322 367
323 CODE = 'spcprofile'
368 CODE = 'pow_profile'
324 369 plot_type = 'scatter'
325 buffering = False
326 370
327 371 def setup(self):
328 372
@@ -336,12 +380,20 class PowerProfilePlot(Plot):
336 380 self.titles = ['Power Profile']
337 381 self.colorbar = False
338 382
383 def update(self, dataOut):
384
385 data = {}
386 meta = {}
387 data[self.CODE] = dataOut.getPower()
388
389 return data, meta
390
339 391 def plot(self):
340 392
341 y = self.data.heights
393 y = self.data.yrange
342 394 self.y = y
343 395
344 x = self.data['spcprofile']
396 x = self.data[-1][self.CODE]
345 397
346 398 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
347 399 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
@@ -372,6 +424,16 class SpectraCutPlot(Plot):
372 424 self.colorbar = False
373 425 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
374 426
427 def update(self, dataOut):
428
429 data = {}
430 meta = {}
431 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
432 data['spc'] = spc
433 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
434
435 return data, meta
436
375 437 def plot(self):
376 438 if self.xaxis == "frequency":
377 439 x = self.data.xrange[0][1:]
@@ -385,9 +447,8 class SpectraCutPlot(Plot):
385 447
386 448 self.titles = []
387 449
388 y = self.data.heights
389 #self.y = y
390 z = self.data['spc_cut']
450 y = self.data.yrange
451 z = self.data[-1]['spc']
391 452
392 453 if self.height_index:
393 454 index = numpy.array(self.height_index)
@@ -31,6 +31,27 class ScopePlot(Plot):
31 31 self.width = 6
32 32 self.height = 4
33 33
34 def update(self, dataOut):
35
36 data = {}
37 meta = {
38 'nProfiles': dataOut.nProfiles,
39 'flagDataAsBlock': dataOut.flagDataAsBlock,
40 'profileIndex': dataOut.profileIndex,
41 }
42 if self.CODE == 'scope':
43 data[self.CODE] = dataOut.data
44 elif self.CODE == 'pp_power':
45 data[self.CODE] = dataOut.dataPP_POWER
46 elif self.CODE == 'pp_signal':
47 data[self.CODE] = dataOut.dataPP_POW
48 elif self.CODE == 'pp_velocity':
49 data[self.CODE] = dataOut.dataPP_DOP
50 elif self.CODE == 'pp_specwidth':
51 data[self.CODE] = dataOut.dataPP_WIDTH
52
53 return data, meta
54
34 55 def plot_iq(self, x, y, channelIndexList, thisDatetime, wintitle):
35 56
36 57 yreal = y[channelIndexList,:].real
@@ -41,15 +62,14 class ScopePlot(Plot):
41 62
42 63 self.y = yreal
43 64 self.x = x
44 self.xmin = min(x)
45 self.xmax = max(x)
46
47 65
48 66 self.titles[0] = title
49 67
50 68 for i,ax in enumerate(self.axes):
51 69 title = "Channel %d" %(i)
52 70 if ax.firsttime:
71 self.xmin = min(x)
72 self.xmax = max(x)
53 73 ax.plt_r = ax.plot(x, yreal[i,:], color='b')[0]
54 74 ax.plt_i = ax.plot(x, yimag[i,:], color='r')[0]
55 75 else:
@@ -61,24 +81,22 class ScopePlot(Plot):
61 81 yreal = y.real
62 82 yreal = 10*numpy.log10(yreal)
63 83 self.y = yreal
64 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y"))
84 title = wintitle + " Power: %s" %(thisDatetime.strftime("%d-%b-%Y"))
65 85 self.xlabel = "Range (Km)"
66 self.ylabel = "Intensity"
67 self.xmin = min(x)
68 self.xmax = max(x)
86 self.ylabel = "Intensity [dB]"
69 87
70 88
71 89 self.titles[0] = title
72 90
73 91 for i,ax in enumerate(self.axes):
74 92 title = "Channel %d" %(i)
75
76 93 ychannel = yreal[i,:]
77 94
78 95 if ax.firsttime:
96 self.xmin = min(x)
97 self.xmax = max(x)
79 98 ax.plt_r = ax.plot(x, ychannel)[0]
80 99 else:
81 #pass
82 100 ax.plt_r.set_data(x, ychannel)
83 101
84 102 def plot_weatherpower(self, x, y, channelIndexList, thisDatetime, wintitle):
@@ -153,16 +171,8 class ScopePlot(Plot):
153 171 channels = self.data.channels
154 172
155 173 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1])
156 if self.CODE == "pp_power":
157 scope = self.data['pp_power']
158 elif self.CODE == "pp_signal":
159 scope = self.data["pp_signal"]
160 elif self.CODE == "pp_velocity":
161 scope = self.data["pp_velocity"]
162 elif self.CODE == "pp_specwidth":
163 scope = self.data["pp_specwidth"]
164 else:
165 scope =self.data["scope"]
174
175 scope = self.data[-1][self.CODE]
166 176
167 177 if self.data.flagDataAsBlock:
168 178
@@ -171,7 +181,7 class ScopePlot(Plot):
171 181 wintitle1 = " [Profile = %d] " %i
172 182 if self.CODE =="scope":
173 183 if self.type == "power":
174 self.plot_power(self.data.heights,
184 self.plot_power(self.data.yrange,
175 185 scope[:,i,:],
176 186 channels,
177 187 thisDatetime,
@@ -179,21 +189,21 class ScopePlot(Plot):
179 189 )
180 190
181 191 if self.type == "iq":
182 self.plot_iq(self.data.heights,
192 self.plot_iq(self.data.yrange,
183 193 scope[:,i,:],
184 194 channels,
185 195 thisDatetime,
186 196 wintitle1
187 197 )
188 198 if self.CODE=="pp_power":
189 self.plot_weatherpower(self.data.heights,
199 self.plot_weatherpower(self.data.yrange,
190 200 scope[:,i,:],
191 201 channels,
192 202 thisDatetime,
193 203 wintitle
194 204 )
195 205 if self.CODE=="pp_signal":
196 self.plot_weatherpower(self.data.heights,
206 self.plot_weatherpower(self.data.yrange,
197 207 scope[:,i,:],
198 208 channels,
199 209 thisDatetime,
@@ -201,14 +211,14 class ScopePlot(Plot):
201 211 )
202 212 if self.CODE=="pp_velocity":
203 213 self.plot_weathervelocity(scope[:,i,:],
204 self.data.heights,
214 self.data.yrange,
205 215 channels,
206 216 thisDatetime,
207 217 wintitle
208 218 )
209 219 if self.CODE=="pp_spcwidth":
210 220 self.plot_weatherspecwidth(scope[:,i,:],
211 self.data.heights,
221 self.data.yrange,
212 222 channels,
213 223 thisDatetime,
214 224 wintitle
@@ -217,7 +227,7 class ScopePlot(Plot):
217 227 wintitle = " [Profile = %d] " %self.data.profileIndex
218 228 if self.CODE== "scope":
219 229 if self.type == "power":
220 self.plot_power(self.data.heights,
230 self.plot_power(self.data.yrange,
221 231 scope,
222 232 channels,
223 233 thisDatetime,
@@ -225,21 +235,21 class ScopePlot(Plot):
225 235 )
226 236
227 237 if self.type == "iq":
228 self.plot_iq(self.data.heights,
238 self.plot_iq(self.data.yrange,
229 239 scope,
230 240 channels,
231 241 thisDatetime,
232 242 wintitle
233 243 )
234 244 if self.CODE=="pp_power":
235 self.plot_weatherpower(self.data.heights,
245 self.plot_weatherpower(self.data.yrange,
236 246 scope,
237 247 channels,
238 248 thisDatetime,
239 249 wintitle
240 250 )
241 251 if self.CODE=="pp_signal":
242 self.plot_weatherpower(self.data.heights,
252 self.plot_weatherpower(self.data.yrange,
243 253 scope,
244 254 channels,
245 255 thisDatetime,
@@ -247,21 +257,20 class ScopePlot(Plot):
247 257 )
248 258 if self.CODE=="pp_velocity":
249 259 self.plot_weathervelocity(scope,
250 self.data.heights,
260 self.data.yrange,
251 261 channels,
252 262 thisDatetime,
253 263 wintitle
254 264 )
255 265 if self.CODE=="pp_specwidth":
256 266 self.plot_weatherspecwidth(scope,
257 self.data.heights,
267 self.data.yrange,
258 268 channels,
259 269 thisDatetime,
260 270 wintitle
261 271 )
262 272
263 273
264
265 274 class PulsepairPowerPlot(ScopePlot):
266 275 '''
267 276 Plot for P= S+N
@@ -269,7 +278,6 class PulsepairPowerPlot(ScopePlot):
269 278
270 279 CODE = 'pp_power'
271 280 plot_type = 'scatter'
272 buffering = False
273 281
274 282 class PulsepairVelocityPlot(ScopePlot):
275 283 '''
@@ -277,7 +285,6 class PulsepairVelocityPlot(ScopePlot):
277 285 '''
278 286 CODE = 'pp_velocity'
279 287 plot_type = 'scatter'
280 buffering = False
281 288
282 289 class PulsepairSpecwidthPlot(ScopePlot):
283 290 '''
@@ -285,7 +292,6 class PulsepairSpecwidthPlot(ScopePlot):
285 292 '''
286 293 CODE = 'pp_specwidth'
287 294 plot_type = 'scatter'
288 buffering = False
289 295
290 296 class PulsepairSignalPlot(ScopePlot):
291 297 '''
@@ -294,4 +300,3 class PulsepairSignalPlot(ScopePlot):
294 300
295 301 CODE = 'pp_signal'
296 302 plot_type = 'scatter'
297 buffering = False
@@ -304,7 +304,7 class BLTRParamReader(Reader, ProcessingUnit):
304 304 Storing data from databuffer to dataOut object
305 305 '''
306 306
307 self.dataOut.data_SNR = self.snr
307 self.dataOut.data_snr = self.snr
308 308 self.dataOut.height = self.height
309 309 self.dataOut.data = self.buffer
310 310 self.dataOut.utctimeInit = self.time
@@ -618,6 +618,7 class HDFWriter(Operation):
618 618 for ds in self.ds:
619 619 ds.resize(self.blockIndex, axis=0)
620 620
621 if self.fp:
621 622 self.fp.flush()
622 623 self.fp.close()
623 624
@@ -313,7 +313,7 class JULIAParamReader(JRODataReader, ProcessingUnit):
313 313 Storing data from databuffer to dataOut object
314 314 '''
315 315
316 self.dataOut.data_SNR = self.buffer[4].reshape(1, -1)
316 self.dataOut.data_snr = self.buffer[4].reshape(1, -1)
317 317 self.dataOut.heightList = self.heights
318 318 self.dataOut.data_param = self.buffer[0:4,]
319 319 self.dataOut.utctimeInit = self.time
@@ -25,7 +25,7 class BLTRParametersProc(ProcessingUnit):
25 25 self.dataOut.nchannels - Number of channels
26 26 self.dataOut.nranges - Number of ranges
27 27
28 self.dataOut.data_SNR - SNR array
28 self.dataOut.data_snr - SNR array
29 29 self.dataOut.data_output - Zonal, Vertical and Meridional velocity array
30 30 self.dataOut.height - Height array (km)
31 31 self.dataOut.time - Time array (seconds)
@@ -67,10 +67,10 class BLTRParametersProc(ProcessingUnit):
67 67
68 68 self.dataOut.data_param = self.dataOut.data[mode]
69 69 self.dataOut.heightList = self.dataOut.height[0]
70 self.dataOut.data_SNR = self.dataOut.data_SNR[mode]
70 self.dataOut.data_snr = self.dataOut.data_snr[mode]
71 71
72 72 if snr_threshold is not None:
73 SNRavg = numpy.average(self.dataOut.data_SNR, axis=0)
73 SNRavg = numpy.average(self.dataOut.data_snr, axis=0)
74 74 SNRavgdB = 10*numpy.log10(SNRavg)
75 75 for i in range(3):
76 76 self.dataOut.data_param[i][SNRavgdB <= snr_threshold] = numpy.nan
@@ -174,7 +174,7 class ParametersProc(ProcessingUnit):
174 174
175 175 self.dataOut.abscissaList = self.dataIn.lagRange
176 176 self.dataOut.noise = self.dataIn.noise
177 self.dataOut.data_SNR = self.dataIn.SNR
177 self.dataOut.data_snr = self.dataIn.SNR
178 178 self.dataOut.flagNoData = False
179 179 self.dataOut.nAvg = self.dataIn.nAvg
180 180
@@ -840,9 +840,9 class FullSpectralAnalysis(Operation):
840 840 data_SNR=numpy.zeros([nProfiles])
841 841 noise = dataOut.noise
842 842
843 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
843 dataOut.data_snr = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
844 844
845 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
845 dataOut.data_snr[numpy.where( dataOut.data_snr <0 )] = 1e-20
846 846
847 847
848 848 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
@@ -851,7 +851,7 class FullSpectralAnalysis(Operation):
851 851 velocityY=[]
852 852 velocityV=[]
853 853
854 dbSNR = 10*numpy.log10(dataOut.data_SNR)
854 dbSNR = 10*numpy.log10(dataOut.data_snr)
855 855 dbSNR = numpy.average(dbSNR,0)
856 856
857 857 '''***********************************************WIND ESTIMATION**************************************'''
@@ -1290,7 +1290,7 class SpectralMoments(Operation):
1290 1290
1291 1291 Affected:
1292 1292 self.dataOut.moments : Parameters per channel
1293 self.dataOut.data_SNR : SNR per channel
1293 self.dataOut.data_snr : SNR per channel
1294 1294
1295 1295 '''
1296 1296
@@ -1306,10 +1306,10 class SpectralMoments(Operation):
1306 1306 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1307 1307
1308 1308 dataOut.moments = data_param[:,1:,:]
1309 dataOut.data_SNR = data_param[:,0]
1310 dataOut.data_POW = data_param[:,1]
1311 dataOut.data_DOP = data_param[:,2]
1312 dataOut.data_WIDTH = data_param[:,3]
1309 dataOut.data_snr = data_param[:,0]
1310 dataOut.data_pow = data_param[:,1]
1311 dataOut.data_dop = data_param[:,2]
1312 dataOut.data_width = data_param[:,3]
1313 1313
1314 1314 return dataOut
1315 1315
@@ -1436,7 +1436,7 class SALags(Operation):
1436 1436 self.dataOut.abscissaList
1437 1437 self.dataOut.noise
1438 1438 self.dataOut.normFactor
1439 self.dataOut.data_SNR
1439 self.dataOut.data_snr
1440 1440 self.dataOut.groupList
1441 1441 self.dataOut.nChannels
1442 1442
@@ -1455,7 +1455,7 class SALags(Operation):
1455 1455 nHeights = dataOut.nHeights
1456 1456 absc = dataOut.abscissaList
1457 1457 noise = dataOut.noise
1458 SNR = dataOut.data_SNR
1458 SNR = dataOut.data_snr
1459 1459 nChannels = dataOut.nChannels
1460 1460 # pairsList = dataOut.groupList
1461 1461 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
@@ -1570,7 +1570,7 class SpectralFitting(Operation):
1570 1570 listChannels = groupArray.reshape((groupArray.size))
1571 1571 listChannels.sort()
1572 1572 noise = self.dataIn.getNoise()
1573 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1573 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1574 1574
1575 1575 for i in range(nGroups):
1576 1576 coord = groupArray[i,:]
@@ -2222,7 +2222,7 class WindProfiler(Operation):
2222 2222 absc = dataOut.abscissaList[:-1]
2223 2223 # noise = dataOut.noise
2224 2224 heightList = dataOut.heightList
2225 SNR = dataOut.data_SNR
2225 SNR = dataOut.data_snr
2226 2226
2227 2227 if technique == 'DBS':
2228 2228
@@ -2230,7 +2230,7 class WindProfiler(Operation):
2230 2230 kwargs['heightList'] = heightList
2231 2231 kwargs['SNR'] = SNR
2232 2232
2233 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2233 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2234 2234 dataOut.utctimeInit = dataOut.utctime
2235 2235 dataOut.outputInterval = dataOut.paramInterval
2236 2236
@@ -2424,7 +2424,7 class EWDriftsEstimation(Operation):
2424 2424 def run(self, dataOut, zenith, zenithCorrection):
2425 2425 heiRang = dataOut.heightList
2426 2426 velRadial = dataOut.data_param[:,3,:]
2427 SNR = dataOut.data_SNR
2427 SNR = dataOut.data_snr
2428 2428
2429 2429 zenith = numpy.array(zenith)
2430 2430 zenith -= zenithCorrection
@@ -2445,7 +2445,7 class EWDriftsEstimation(Operation):
2445 2445
2446 2446 dataOut.heightList = heiRang1
2447 2447 dataOut.data_output = winds
2448 dataOut.data_SNR = SNR1
2448 dataOut.data_snr = SNR1
2449 2449
2450 2450 dataOut.utctimeInit = dataOut.utctime
2451 2451 dataOut.outputInterval = dataOut.timeInterval
@@ -874,3 +874,25 class IncohInt(Operation):
874 874 dataOut.flagNoData = False
875 875
876 876 return dataOut
877
878 class dopplerFlip(Operation):
879
880 def run(self, dataOut):
881 # arreglo 1: (num_chan, num_profiles, num_heights)
882 self.dataOut = dataOut
883 # JULIA-oblicua, indice 2
884 # arreglo 2: (num_profiles, num_heights)
885 jspectra = self.dataOut.data_spc[2]
886 jspectra_tmp = numpy.zeros(jspectra.shape)
887 num_profiles = jspectra.shape[0]
888 freq_dc = int(num_profiles / 2)
889 # Flip con for
890 for j in range(num_profiles):
891 jspectra_tmp[num_profiles-j-1]= jspectra[j]
892 # Intercambio perfil de DC con perfil inmediato anterior
893 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
894 jspectra_tmp[freq_dc]= jspectra[freq_dc]
895 # canal modificado es re-escrito en el arreglo de canales
896 self.dataOut.data_spc[2] = jspectra_tmp
897
898 return self.dataOut No newline at end of file
@@ -146,7 +146,7 class selectChannels(Operation):
146 146
147 147 class selectHeights(Operation):
148 148
149 def run(self, dataOut, minHei=None, maxHei=None):
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 150 """
151 151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 152 minHei <= height <= maxHei
@@ -164,11 +164,7 class selectHeights(Operation):
164 164
165 165 self.dataOut = dataOut
166 166
167 if minHei == None:
168 minHei = self.dataOut.heightList[0]
169
170 if maxHei == None:
171 maxHei = self.dataOut.heightList[-1]
167 if minHei and maxHei:
172 168
173 169 if (minHei < self.dataOut.heightList[0]):
174 170 minHei = self.dataOut.heightList[0]
General Comments 0
You need to be logged in to leave comments. Login now