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