class getMERRA2(QtWidgets.QDialog): procStart = QtCore.pyqtSignal(str) statusmsg = QtCore.pyqtSignal() def get_config(self): self.config = configparser.RawConfigParser() self.config_file = self.ini_file self.config.read(self.config_file) try: self.help = self.config.get('Files', 'help') except: self.help = 'help.html' self.restorewindows = False try: rw = self.config.get('Windows', 'restorewindows') if rw.lower() in ['true', 'yes', 'on']: self.restorewindows = True except: pass self.zoom = 0.8 try: self.zoom = float(self.config.get('View', 'zoom_rate')) if self.zoom > 1: self.zoom = 1 / self.zoom if self.zoom > 0.95: self.zoom = 0.95 elif self.zoom < 0.75: self.zoom = 0.75 except: pass self.wait_days = 42 try: self.wait_days = int(self.config.get('getmerra2', 'wait_days')) except: pass def __init__(self, help='help.html', ini_file='getfiles.ini', parent=None): super(getMERRA2, self).__init__(parent) self.help = help self.ini_file = ini_file self.get_config() self.ignore = False self.worldwindow = None ok = False if sys.platform == 'win32' or sys.platform == 'cygwin': try: netrc = '~\\.netrc'.replace('~', os.environ['HOME']) except: netrc = '' else: netrc = '~/.netrc'.replace('~', os.path.expanduser('~')) if netrc != '' and os.path.exists(netrc): ok = True if not ok: netrcmsg = '.netrc file missing.\n(' + netrc + ')\nDo you want create one?' if sys.platform == 'win32' or sys.platform == 'cygwin': netrcmsg += '\nYou will need to reinvoke getmerra2.' reply = QtWidgets.QMessageBox.question(self, 'SIREN - getmerra2 - No .netrc file', netrcmsg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: self.create_netrc() self.northSpin = QtWidgets.QDoubleSpinBox() self.northSpin.setDecimals(3) self.northSpin.setSingleStep(.5) self.northSpin.setRange(-85.06, 85.06) self.northSpin.setObjectName('north') self.westSpin = QtWidgets.QDoubleSpinBox() self.westSpin.setDecimals(3) self.westSpin.setSingleStep(.5) self.westSpin.setRange(-180, 180) self.westSpin.setObjectName('west') self.southSpin = QtWidgets.QDoubleSpinBox() self.southSpin.setDecimals(3) self.southSpin.setSingleStep(.5) self.southSpin.setRange(-85.06, 85.06) self.southSpin.setObjectName('south') self.eastSpin = QtWidgets.QDoubleSpinBox() self.eastSpin.setDecimals(3) self.eastSpin.setSingleStep(.5) self.eastSpin.setRange(-180, 180) self.eastSpin.setObjectName('east') self.latSpin = QtWidgets.QDoubleSpinBox() self.latSpin.setDecimals(3) self.latSpin.setSingleStep(.5) self.latSpin.setRange(-84.56, 84.56) self.latSpin.setObjectName('lat') self.lonSpin = QtWidgets.QDoubleSpinBox() self.lonSpin.setDecimals(3) self.lonSpin.setSingleStep(.5) self.lonSpin.setRange(-179.687, 179.687) self.lonSpin.setObjectName('lon') self.latwSpin = QtWidgets.QDoubleSpinBox() self.latwSpin.setDecimals(3) self.latwSpin.setSingleStep(.5) self.latwSpin.setRange(0, 170.12) self.latwSpin.setObjectName('latw') self.lonwSpin = QtWidgets.QDoubleSpinBox() self.lonwSpin.setDecimals(3) self.lonwSpin.setSingleStep(.5) self.lonwSpin.setRange(0, 360) self.lonwSpin.setObjectName('lonw') if len(sys.argv) > 1: his_config_file = sys.argv[1] his_config = configparser.RawConfigParser() his_config.read(his_config_file) try: mapp = his_config.get('Map', 'map_choice') except: mapp = '' try: upper_left = his_config.get('Map', 'upper_left' + mapp).split(',') self.northSpin.setValue(float(upper_left[0].strip())) self.westSpin.setValue(float(upper_left[1].strip())) lower_right = his_config.get('Map', 'lower_right' + mapp).split(',') self.southSpin.setValue(float(lower_right[0].strip())) self.eastSpin.setValue(float(lower_right[1].strip())) except: try: lower_left = his_config.get('Map', 'lower_left' + mapp).split(',') upper_right = his_config.get('Map', 'upper_right' + mapp).split(',') self.northSpin.setValue(float(upper_right[0].strip())) self.westSpin.setValue(float(lower_left[1].strip())) self.southSpin.setValue(float(lower_left[0].strip())) self.eastSpin.setValue(float(upper_right[1].strip())) except: pass self.northSpin.valueChanged.connect(self.showArea) self.westSpin.valueChanged.connect(self.showArea) self.southSpin.valueChanged.connect(self.showArea) self.eastSpin.valueChanged.connect(self.showArea) self.latSpin.valueChanged.connect(self.showArea) self.lonSpin.valueChanged.connect(self.showArea) self.latwSpin.valueChanged.connect(self.showArea) self.lonwSpin.valueChanged.connect(self.showArea) self.grid = QtWidgets.QGridLayout() self.grid.addWidget(QtWidgets.QLabel('Area of Interest:'), 0, 0) area = QtWidgets.QPushButton('Choose area via Map', self) self.grid.addWidget(area, 0, 1, 1, 2) area.clicked.connect(self.areaClicked) self.grid.addWidget(QtWidgets.QLabel('Upper left:'), 1, 0, 1, 1) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(QtWidgets.QLabel('North'), 2, 0) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.northSpin, 2, 1) self.grid.addWidget(QtWidgets.QLabel('West'), 3, 0) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.westSpin, 3, 1) self.grid.addWidget(QtWidgets.QLabel('Lower right:'), 1, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(QtWidgets.QLabel('South'), 2, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.southSpin, 2, 3) self.grid.addWidget(QtWidgets.QLabel('East'), 3, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.eastSpin, 3, 3) self.grid.addWidget(QtWidgets.QLabel('Centre:'), 1, 4) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(QtWidgets.QLabel('Lat.'), 2, 4) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.latSpin, 2, 5) self.grid.addWidget(QtWidgets.QLabel('Lon.'), 3, 4) self.grid.itemAt(self.grid.count() - 1).setAlignment(QtCore.Qt.AlignRight) self.grid.addWidget(self.lonSpin, 3, 5) self.grid.addWidget(QtWidgets.QLabel('Degrees'), 1, 6) self.grid.addWidget(self.latwSpin, 2, 6) self.grid.addWidget(self.lonwSpin, 3, 6) self.grid.addWidget(QtWidgets.QLabel('Approx. area:'), 4, 0) self.approx_area = QtWidgets.QLabel('') self.grid.addWidget(self.approx_area, 4, 1) self.grid.addWidget(QtWidgets.QLabel('MERRA-2 dimensions:'), 4, 2) self.merra_cells = QtWidgets.QLabel('') self.grid.addWidget(self.merra_cells, 4, 3, 1, 2) self.grid.addWidget(QtWidgets.QLabel('Start date:'), 5, 0) self.strt_date = QtWidgets.QDateEdit(self) self.strt_date.setDate(QtCore.QDate.currentDate().addDays(-self.wait_days)) self.strt_date.setCalendarPopup(True) self.strt_date.setMinimumDate(QtCore.QDate(1980, 1, 1)) self.strt_date.setMaximumDate(QtCore.QDate.currentDate().addDays(-self.wait_days)) self.grid.addWidget(self.strt_date, 5, 1) self.grid.addWidget(QtWidgets.QLabel('End date:'), 6, 0) self.end_date = QtWidgets.QDateEdit(self) self.end_date.setDate(QtCore.QDate.currentDate().addDays(-self.wait_days)) self.end_date.setCalendarPopup(True) self.end_date.setMinimumDate(QtCore.QDate(1980,1,1)) self.end_date.setMaximumDate(QtCore.QDate.currentDate()) self.grid.addWidget(self.end_date, 6, 1) self.grid.addWidget(QtWidgets.QLabel('Copy folder down:'), 7, 0) self.checkbox = QtWidgets.QCheckBox() self.checkbox.setCheckState(QtCore.Qt.Checked) self.grid.addWidget(self.checkbox, 7, 1) self.grid.addWidget(QtWidgets.QLabel('If checked will copy solar folder changes down'), 7, 2, 1, 3) cur_dir = os.getcwd() self.dir_labels = ['Solar', 'Wind'] datasets = [] self.collections = [] for typ in self.dir_labels: datasets.append(self.config.get('getmerra2', typ.lower() + '_collection') + ' (Parameters: ' + \ self.config.get('getmerra2', typ.lower() + '_variables') + ')') self.collections.append(self.config.get('getmerra2', typ.lower() + '_collection')) self.dirs = [None, None, None] for i in range(2): self.grid.addWidget(QtWidgets.QLabel(self.dir_labels[i] + ' files:'), 8 + i * 2, 0) self.grid.addWidget(QtWidgets.QLabel(datasets[i]), 8 + i * 2, 1, 1, 5) self.grid.addWidget(QtWidgets.QLabel(' Target Folder:'), 9 + i * 2, 0) self.dirs[i] = ClickableQLabel() try: self.dirs[i].setText(self.config.get('Files', self.dir_labels[i].lower() + '_files').replace('$USER$', getUser())) except: self.dirs[i].setText(cur_dir) self.dirs[i].setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.dirs[i].clicked.connect(self.dirChanged) self.grid.addWidget(self.dirs[i], 9 + i * 2, 1, 1, 8) self.log = QtWidgets.QLabel('') msg_palette = QtGui.QPalette() msg_palette.setColor(QtGui.QPalette.Foreground, QtCore.Qt.red) self.log.setPalette(msg_palette) self.grid.addWidget(self.log, 12, 1, 2, 4) sw = self.northSpin.minimumSizeHint().width() dw = self.strt_date.minimumSizeHint().width() if sw > dw: # fix for wide QDoubleSpinBox width in Windows self.northSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.westSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.southSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.eastSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.latSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.lonSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.latwSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) self.lonwSpin.setMinimumWidth(self.strt_date.minimumSizeHint().width()) buttongrid = QtWidgets.QGridLayout() quit = QtWidgets.QPushButton('Done', self) buttongrid.addWidget(quit, 0, 0) quit.clicked.connect(self.quitClicked) QtWidgets.QShortcut(QtGui.QKeySequence('q'), self, self.quitClicked) QtWidgets.QShortcut(QtGui.QKeySequence('x'), self, self.quitClicked) solar = QtWidgets.QPushButton('Get Solar', self) buttongrid.addWidget(solar, 0, 1) solar.clicked.connect(self.getClicked) wind = QtWidgets.QPushButton('Get Wind', self) buttongrid.addWidget(wind, 0, 2) wind.clicked.connect(self.getClicked) check = QtWidgets.QPushButton('Check Solar', self) buttongrid.addWidget(check, 0, 3) check.clicked.connect(self.checkClicked) check = QtWidgets.QPushButton('Check Wind', self) buttongrid.addWidget(check, 0, 4) check.clicked.connect(self.checkClicked) help = QtWidgets.QPushButton('Help', self) buttongrid.addWidget(help, 0, 5) help.clicked.connect(self.helpClicked) QtWidgets.QShortcut(QtGui.QKeySequence('F1'), self, self.helpClicked) frame = QtWidgets.QFrame() frame.setLayout(self.grid) self.scroll = QtWidgets.QScrollArea() self.scroll.setWidgetResizable(True) self.scroll.setWidget(frame) self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.scroll) frame2 = QtWidgets.QFrame() frame2.setLayout(buttongrid) self.layout.addWidget(frame2) self.setWindowTitle('SIREN - getmerra2 (' + fileVersion() + ') - Get MERRA-2 data') self.setWindowIcon(QtGui.QIcon('sen_icon32.ico')) self.resize(int(self.sizeHint().width()* 1.5), int(self.sizeHint().height() * 1.07)) self.updated = False self.show() def dirChanged(self): for i in range(2): if self.dirs[i].hasFocus(): break curdir = self.dirs[i].text() newdir = QtWidgets.QFileDialog.getExistingDirectory(self, 'Choose ' + self.dir_labels[i] + ' Folder', curdir, QtWidgets.QFileDialog.ShowDirsOnly) if newdir != '': self.dirs[i].setText(newdir) if self.checkbox.isChecked(): if i == 0: self.dirs[1].setText(newdir) self.updated = True def helpClicked(self): dialog = displayobject.AnObject(QtWidgets.QDialog(), self.help, title='Help for getting MERRA-2 data (' + fileVersion() + ')', section='getmerra2') dialog.exec_() def exit(self): self.close() def closeEvent(self, event): try: self.mySubwindow.close() except: pass event.accept() @QtCore.pyqtSlot(list, str) def maparea(self, rectangle, approx_area=None): if type(rectangle) is str: if rectangle == 'goodbye': self.worldwindow = None return elif type(rectangle[0]) is str: if rectangle[0] == 'goodbye': self.worldwindow = None return self.ignore = True self.northSpin.setValue(rectangle[0].y()) self.westSpin.setValue(rectangle[0].x()) self.southSpin.setValue(rectangle[1].y()) self.eastSpin.setValue(rectangle[1].x()) self.ignore = False self.approx_area.setText(approx_area) merra_dims = worldwindow.merra_cells(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value()) self.merra_cells.setText(merra_dims) def areaClicked(self): if self.worldwindow is None: scene = worldwindow.WorldScene() self.worldwindow = worldwindow.WorldWindow(self, scene) self.worldwindow.view.tellarea.connect(self.maparea) self.worldwindow.show() self.showArea('init') def showArea(self, event): if self.ignore: return if self.sender().objectName() == 'north' or self.sender().objectName() == 'south': self.ignore = True if self.southSpin.value() > self.northSpin.value(): y = self.northSpin.value() self.northSpin.setValue(self.southSpin.value()) self.southSpin.setValue(y) self.latwSpin.setValue(self.northSpin.value() - self.southSpin.value()) self.latSpin.setValue(self.northSpin.value() - (self.northSpin.value() - self.southSpin.value()) / 2.) self.ignore = False elif self.sender().objectName() == 'east' or self.sender().objectName() == 'west': self.ignore = True if self.eastSpin.value() < self.westSpin.value(): x = self.westSpin.value() self.westSpin.setValue(self.eastSpin.value()) self.eastSpin.setValue(x) self.lonwSpin.setValue(self.eastSpin.value() - self.westSpin.value()) self.lonwSpin.setValue(self.eastSpin.value() - (self.eastSpin.value() - self.westSpin.value()) / 2.) self.ignore = False elif self.sender().objectName() == 'lat': self.ignore = True if self.latwSpin.value() == 0: self.latwSpin.setValue(1.) self.northSpin.setValue(self.latSpin.value() + self.latwSpin.value() / 2) self.southSpin.setValue(self.latSpin.value() - self.latwSpin.value() / 2) self.ignore = False elif self.sender().objectName() == 'lon': self.ignore = True if self.lonwSpin.value() == 0: self.lonwSpin.setValue(1.5) self.eastSpin.setValue(self.lonSpin.value() + self.lonwSpin.value() / 2) self.westSpin.setValue(self.lonSpin.value() - self.lonwSpin.value() / 2) self.ignore = False elif self.sender().objectName() == 'latw': self.ignore = True self.northSpin.setValue(self.latSpin.value() + self.latwSpin.value() / 2) self.southSpin.setValue(self.latSpin.value() - self.latwSpin.value() / 2) self.ignore = False elif self.sender().objectName() == 'lonw': self.ignore = True self.eastSpin.setValue(self.lonSpin.value() + self.lonwSpin.value() / 2) self.westSpin.setValue(self.lonSpin.value() - self.lonwSpin.value() / 2) self.ignore = False merra_dims = worldwindow.merra_cells(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value()) self.merra_cells.setText(merra_dims) if self.worldwindow is None: return approx_area = self.worldwindow.view.drawRect([QtCore.QPointF(self.westSpin.value(), self.northSpin.value()), QtCore.QPointF(self.eastSpin.value(), self.southSpin.value())]) self.approx_area.setText(approx_area) if event != 'init': self.worldwindow.view.statusmsg.emit(approx_area + ' ' + merra_dims) def quitClicked(self): if self.updated: updates = {} lines = [] for i in range(2): lines.append(self.dir_labels[i].lower() + '_files=' + \ self.dirs[i].text().replace(getUser(), '$USER$')) updates['Files'] = lines SaveIni(updates, ini_file=self.config_file) self.close() def checkClicked(self): def get_range(top): self.chk_folders.append(top) ndx = len(self.chk_folders) - 1 self.chk_src_key.append([]) self.chk_src_dte.append([]) fils = sorted(os.listdir(top)) for fil in fils: if os.path.isdir(top + '/' + fil): if fil.isdigit() and len(fil) == 4: get_range(top + '/' + fil) elif fil.find('MERRA') >= 0: if fil[-6:] == '.gz.nc': # ignore unzipped continue ndy = 0 #value[1] j = fil.find(self.chk_collection) l = len(self.chk_collection) if j > 0: fil_key = fil[:j + l + 1] + fil[j + l + 9:] if fil_key not in self.chk_src_key[-1]: self.chk_src_key[-1].append(fil_key) self.chk_src_dte[-1].append([]) self.chk_src_dte[-1][-1].append(fil[j + l + 1: j + l + 9]) else: k = self.chk_src_key[-1].index(fil_key) self.chk_src_dte[-1][k].append(fil[j + l + 1: j + l + 9]) del fils if self.sender().text() == 'Check Solar': chk_key = 'solar' ndx = 0 elif self.sender().text() == 'Check Wind': chk_key = 'wind' ndx = 1 self.log.setText('') self.chk_collection = self.collections[ndx] check = checkFiles(chk_key, self.dirs[ndx].text(), ini_file=self.ini_file, collection=self.chk_collection) if len(check) > 1: # ok self.ignore = True self.southSpin.setValue(check[4]) self.northSpin.setValue(check[3]) self.latwSpin.setValue(self.northSpin.value() - self.southSpin.value()) self.latSpin.setValue(self.northSpin.value() - (self.northSpin.value() - self.southSpin.value()) / 2.) self.westSpin.setValue(check[5]) self.eastSpin.setValue(check[6]) self.lonwSpin.setValue(self.eastSpin.value() - self.westSpin.value()) self.lonSpin.setValue(self.eastSpin.value() - (self.eastSpin.value() - self.westSpin.value()) / 2.) self.strt_date.setDate(check[1]) self.end_date.setDate(datetime.datetime.now() - datetime.timedelta(days=self.wait_days)) if self.end_date.date() < self.strt_date.date(): self.end_date.setDate(self.strt_date.date()) self.ignore = False merra_dims = worldwindow.merra_cells(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value()) self.merra_cells.setText(merra_dims) self.log.setText(check[0]) if self.worldwindow is None: return approx_area = self.worldwindow.view.drawRect([QtCore.QPointF(self.westSpin.value(), self.northSpin.value()), QtCore.QPointF(self.eastSpin.value(), self.southSpin.value())]) self.approx_area.setText(approx_area) self.worldwindow.view.statusmsg.emit(approx_area + ' ' + merra_dims) def getClicked(self): lat_rnge = self.northSpin.value() - self.southSpin.value() lon_rnge = self.eastSpin.value() - self.westSpin.value() if lat_rnge < 1 or lon_rnge < 1.25: self.log.setText('Area too small. Range must be at least 1 degree Lat x 1.25 Lon') return if self.sender().text() == 'Get Solar': me = 'solar' elif self.sender().text() == 'Get Wind': me = 'wind' date1 = datetime.date(int(self.strt_date.date().year()), int(self.strt_date.date().month()), int(self.strt_date.date().day())) date2 = datetime.date(int(self.end_date.date().year()), int(self.end_date.date().month()), int(self.end_date.date().day())) i = self.dir_labels.index(me.title()) tgt_dir = self.dirs[i].text() wgot = invokeWget(self.ini_file, me, date1, date2, self.southSpin.value(), self.northSpin.value(), self.westSpin.value(), self.eastSpin.value(), tgt_dir, True) self.log.setText(wgot) return def create_netrc(self): self.mySubwindow = subwindow() grid = QtWidgets.QGridLayout() grid.addWidget(QtWidgets.QLabel('Enter details for URS Registration'), 0, 0, 1, 2) r = 1 if sys.platform == 'win32' or sys.platform == 'cygwin': try: self.home_dir = os.environ['HOME'] except: self.home_dir = os.getcwd() grid.addWidget(QtWidgets.QLabel('HOME directory:'), 1, 0) self.home = ClickableQLabel() self.home.setText(self.home_dir) self.home.setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.home.clicked.connect(self.ursdirChanged) grid.addWidget(self.home, 1, 1, 1, 3) r = 2 grid.addWidget(QtWidgets.QLabel('URS Userid:'), r, 0) self.urs_id = QtWidgets.QLineEdit('') grid.addWidget(self.urs_id, r, 1) grid.addWidget(QtWidgets.QLabel('URS Password:'******'') grid.addWidget(self.urs_pwd, r + 1, 1) netrc_button = QtWidgets.QPushButton('Create .netrc file', self.mySubwindow) netrc_button.clicked.connect(self.createnetrc) grid.addWidget(netrc_button, r + 2, 0) self.mySubwindow.setLayout(grid) self.mySubwindow.exec_() def ursdirChanged(self): curdir = self.home.text() newdir = QtWidgets.QFileDialog.getExistingDirectory(self, 'Choose .netrc Folder', curdir, QtWidgets.QFileDialog.ShowDirsOnly) if newdir != '': self.home.setText(newdir) self.home_dir = newdir def createnetrc(self): if sys.platform == 'win32' or sys.platform == 'cygwin': env_var = 'HOME' os.system('SETX {0} "{1}"'.format(env_var, self.home_dir)) netrc = self.home_dir + '\\.netrc' else: netrc = '~/.netrc'.replace('~', os.path.expanduser('~')) netrc_string = 'machine urs.earthdata.nasa.gov login %s password %s' % (self.urs_id.text(), self.urs_pwd.text()) fou = open(netrc, 'wb') fou.write(netrc_string.encode()) fou.close() self.mySubwindow.close() if sys.platform == 'win32' or sys.platform == 'cygwin': self.close()
class getMap(QtWidgets.QWidget): statusmsg = QtCore.pyqtSignal() def deg2num(self, lat_deg, lon_deg): if lat_deg > 85: ld = 85. elif lat_deg < -85: ld = -85. else: ld = lat_deg lat_rad = math.radians(ld) n = self.world_width xtile = (lon_deg + 180.0) / 360.0 * n try: ytile = (1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n except: ytile = 0 return (xtile, ytile) def __init__(self, help='help.html'): super(getMap, self).__init__() self.help = help self.ignore = False self.worldwindow = None self.northSpin = QtWidgets.QDoubleSpinBox() self.northSpin.setDecimals(3) self.northSpin.setSingleStep(.5) self.northSpin.setRange(-85.06, 85.06) self.westSpin = QtWidgets.QDoubleSpinBox() self.westSpin.setDecimals(3) self.westSpin.setSingleStep(.5) self.westSpin.setRange(-180, 180) self.southSpin = QtWidgets.QDoubleSpinBox() self.southSpin.setDecimals(3) self.southSpin.setSingleStep(.5) self.southSpin.setRange(-85.06, 85.06) self.eastSpin = QtWidgets.QDoubleSpinBox() self.eastSpin.setDecimals(3) self.eastSpin.setSingleStep(.5) self.eastSpin.setRange(-180, 180) if len(sys.argv) > 1: his_config_file = sys.argv[1] his_config = configparser.RawConfigParser() his_config.read(his_config_file) try: mapp = his_config.get('Map', 'map_choice') except: mapp = '' try: upper_left = his_config.get('Map', 'upper_left' + mapp).split(',') self.northSpin.setValue(float(upper_left[0].strip())) self.westSpin.setValue(float(upper_left[1].strip())) lower_right = his_config.get('Map', 'lower_right' + mapp).split(',') self.southSpin.setValue(float(lower_right[0].strip())) self.eastSpin.setValue(float(lower_right[1].strip())) except: try: lower_left = his_config.get('Map', 'lower_left' + mapp).split(',') upper_right = his_config.get('Map', 'upper_right' + mapp).split(',') self.northSpin.setValue(float(upper_right[0].strip())) self.westSpin.setValue(float(lower_left[1].strip())) self.southSpin.setValue(float(lower_left[0].strip())) self.eastSpin.setValue(float(upper_right[1].strip())) except: pass self.northSpin.valueChanged.connect(self.showArea) self.westSpin.valueChanged.connect(self.showArea) self.southSpin.valueChanged.connect(self.showArea) self.eastSpin.valueChanged.connect(self.showArea) self.grid = QtWidgets.QGridLayout() self.grid.addWidget(QtWidgets.QLabel('Area of Interest:'), 0, 0) area = QtWidgets.QPushButton('Choose area via Map', self) self.grid.addWidget(area, 0, 1, 1, 2) area.clicked.connect(self.areaClicked) self.grid.addWidget(QtWidgets.QLabel('Upper left:'), 1, 0) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(QtWidgets.QLabel(' North'), 2, 0) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(self.northSpin, 2, 1) self.grid.addWidget(QtWidgets.QLabel(' West'), 3, 0) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(self.westSpin, 3, 1) self.grid.addWidget(QtWidgets.QLabel('Lower right:'), 1, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(QtWidgets.QLabel(' South'), 2, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(self.southSpin, 2, 3) self.grid.addWidget(QtWidgets.QLabel(' East'), 3, 2) self.grid.itemAt(self.grid.count() - 1).setAlignment( QtCore.Qt.AlignRight) self.grid.addWidget(self.eastSpin, 3, 3) self.grid.addWidget(QtWidgets.QLabel('Approx. area:'), 4, 0) self.approx_area = QtWidgets.QLabel('') self.grid.addWidget(self.approx_area, 4, 1, 1, 2) zoom = QtWidgets.QLabel('Map Scale (Zoom):') self.zoomSpin = QtWidgets.QSpinBox() self.zoomSpin.setValue(6) config_file = 'getfiles.ini' config = configparser.RawConfigParser() config.read(config_file) try: maxz = int(config.get('getmap', 'max_zoom')) except: maxz = 11 self.zoomSpin.setRange(0, maxz) self.zoomSpin.valueChanged[str].connect(self.zoomChanged) self.zoomScale = QtWidgets.QLabel('(' + scale[6] + ')') self.grid.addWidget(zoom, 5, 0) self.grid.addWidget(self.zoomSpin, 5, 1) self.grid.addWidget(self.zoomScale, 5, 2, 1, 2) self.grid.addWidget(QtWidgets.QLabel('URL template:'), 6, 0) self.urltemplate = QtWidgets.QLineEdit() config_file = 'getfiles.ini' config = configparser.RawConfigParser() config.read(config_file) try: url = his_config.get('getmap', 'url_template') except: url = 'https://[abc].tile.openstreetmap.org/zoom/x/y.png' self.urltemplate.setText(url) self.grid.addWidget(self.urltemplate, 6, 1, 1, 5) self.grid.addWidget(QtWidgets.QLabel('Image Width:'), 7, 0) self.widthSpin = QtWidgets.QSpinBox() self.widthSpin.setSingleStep(50) self.widthSpin.setRange(50, 3840) self.widthSpin.setValue(400) self.grid.addWidget(self.widthSpin, 7, 1) hlabel = QtWidgets.QLabel('Image Height: ') hlabel.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.grid.addWidget(hlabel, 7, 2) self.heightSpin = QtWidgets.QSpinBox() self.heightSpin.setSingleStep(50) self.heightSpin.setRange(50, 3840) self.heightSpin.setValue(200) self.grid.addWidget(self.heightSpin, 7, 3) adate = QtWidgets.QDateEdit() dw = adate.minimumSizeHint().width() sw = self.northSpin.minimumSizeHint().width() if sw > dw: # fix for wide QDoubleSpinBox width in Windows self.northSpin.setMinimumWidth(adate.minimumSizeHint().width()) self.westSpin.setMinimumWidth(adate.minimumSizeHint().width()) self.southSpin.setMinimumWidth(adate.minimumSizeHint().width()) self.eastSpin.setMinimumWidth(adate.minimumSizeHint().width()) sw = self.heightSpin.minimumSizeHint().width() if sw > dw: # fix for wide QSpinBox width in Windows self.zoomSpin.setMinimumWidth(adate.minimumSizeHint().width()) self.widthSpin.setMinimumWidth(adate.minimumSizeHint().width()) self.heightSpin.setMinimumWidth(adate.minimumSizeHint().width()) del adate self.grid.addWidget(QtWidgets.QLabel('Image File name:'), 8, 0) cur_dir = os.getcwd() self.filename = ClickableQLabel() self.filename.setStyleSheet( "background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;" ) self.filename.setText(cur_dir + '/untitled.png') self.filename.clicked.connect(self.fileChanged) self.grid.addWidget(self.filename, 8, 1, 1, 5) self.grid.addWidget(QtWidgets.QLabel('Properties:'), 9, 0) self.properties = QtWidgets.QPlainTextEdit() self.properties.setMaximumHeight( int(self.northSpin.sizeHint().height() * 4.5)) self.properties.setReadOnly(True) self.grid.addWidget(self.properties, 9, 1, 3, 5) self.log = QtWidgets.QLabel() self.grid.addWidget(self.log, 14, 1, 3, 5) self.progressbar = QtWidgets.QProgressBar() self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) self.progressbar.setValue(0) self.progressbar.setStyleSheet('QProgressBar {border: 1px solid grey; border-radius: 2px; text-align: center;}' \ + 'QProgressBar::chunk { background-color: #6891c6;}') self.grid.addWidget(self.progressbar, 17, 1, 1, 5) self.progressbar.setHidden(True) self.progresslabel = QtWidgets.QLabel('') self.grid.addWidget(self.progresslabel, 17, 1, 1, 4) self.progresslabel.setHidden(True) quit = QtWidgets.QPushButton('Quit', self) self.grid.addWidget(quit, 18, 0) quit.clicked.connect(self.quitClicked) QtWidgets.QShortcut(QtGui.QKeySequence('q'), self, self.quitClicked) query = QtWidgets.QPushButton('Query Map', self) wdth = query.fontMetrics().boundingRect(query.text()).width() + 9 self.grid.addWidget(query, 18, 1) query.clicked.connect(self.queryClicked) make = QtWidgets.QPushButton('Get Map', self) make.setMaximumWidth(wdth) self.grid.addWidget(make, 18, 2) make.clicked.connect(self.makeClicked) mapquest = QtWidgets.QPushButton('MapQuest', self) mapquest.setMaximumWidth(wdth) self.grid.addWidget(mapquest, 18, 3) mapquest.clicked.connect(self.mapquestClicked) help = QtWidgets.QPushButton('Help', self) help.setMaximumWidth(wdth) self.grid.addWidget(help, 18, 4) help.clicked.connect(self.helpClicked) QtWidgets.QShortcut(QtGui.QKeySequence('F1'), self, self.helpClicked) frame = QtWidgets.QFrame() frame.setLayout(self.grid) self.scroll = QtWidgets.QScrollArea() self.scroll.setWidgetResizable(True) self.scroll.setWidget(frame) self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.scroll) # self.resize(self.width() + int(self.world_width * .7), self.height() + int(self.world_height * .7)) self.setWindowTitle('SIREN - getmap (' + fileVersion() + ") - Make Map from OSM or MapQuest") self.setWindowIcon(QtGui.QIcon('sen_icon32.ico')) self.center() self.resize(int(self.sizeHint().width() * 1.5), int(self.sizeHint().height() * 1.3)) self.show() def center(self): frameGm = self.frameGeometry() screen = QtWidgets.QApplication.desktop().screenNumber( QtWidgets.QApplication.desktop().cursor().pos()) centerPoint = QtWidgets.QApplication.desktop().availableGeometry( screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def zoomChanged(self, val): self.zoomScale.setText('(' + scale[int(val)] + ')') self.zoomScale.adjustSize() def fileChanged(self): self.filename.setText( QtWidgets.QFileDialog.getSaveFileName( self, 'Save Image File', self.filename.text(), 'Images (*.jpeg *.jpg *.png)')[0]) if self.filename.text() != '': i = self.filename.text().rfind('.') if i < 0: self.filename.setText(self.filename.text() + '.png') def helpClicked(self): dialog = displayobject.AnObject(QtWidgets.QDialog(), self.help, title='Help for getmap (' + fileVersion() + ')', section='map') dialog.exec_() def quitClicked(self): self.close() def queryClicked(self): if self.northSpin.value() < self.southSpin.value(): l = self.northSpin.value() self.northSpin.setValue(self.southSpin.value()) self.southSpin.setValue(l) if self.eastSpin.value() < self.westSpin.value(): l = self.eastSpin.value() self.eastSpin.setValue(self.westSpin.value()) self.westSpin.setValue(l) mapp = retrieveMap(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value(), '?', self.zoomSpin.value(), url=self.urltemplate.text(), caller=self) self.properties.setPlainText(mapp.getProperties()) self.log.setText(mapp.getLog()) def makeClicked(self): self.progressbar.setHidden(False) self.progresslabel.setText('') self.progresslabel.setHidden(False) mapp = retrieveMap(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value(), self.filename.text(), zoom=self.zoomSpin.value(), url=self.urltemplate.text(), caller=self) self.progressbar.setValue(0) self.progressbar.setHidden(True) self.progresslabel.setHidden(True) self.properties.setPlainText(mapp.getProperties()) self.log.setText(mapp.getLog()) def mapquestClicked(self): self.progressbar.setHidden(False) self.progresslabel.setText('') self.progresslabel.setHidden(False) mapp = retrieveMap(self.northSpin.value(), self.westSpin.value(), self.southSpin.value(), self.eastSpin.value(), self.filename.text(), width=self.widthSpin.value(), height=self.heightSpin.value(), caller=self) self.progressbar.setValue(0) self.progressbar.setHidden(True) self.progresslabel.setHidden(True) self.properties.setPlainText(mapp.getProperties()) self.log.setText(mapp.getLog()) @QtCore.pyqtSlot(list, str) def maparea(self, rectangle, approx_area=None): if type(rectangle) is str: if rectangle == 'goodbye': self.worldwindow = None return elif type(rectangle[0]) is str: if rectangle[0] == 'goodbye': self.worldwindow = None return self.ignore = True self.northSpin.setValue(rectangle[0].y()) self.westSpin.setValue(rectangle[0].x()) self.southSpin.setValue(rectangle[1].y()) self.eastSpin.setValue(rectangle[1].x()) self.ignore = False self.approx_area.setText(approx_area) def areaClicked(self): if self.worldwindow is None: scene = worldwindow.WorldScene() self.worldwindow = worldwindow.WorldWindow(self, scene) self.worldwindow.view.tellarea.connect(self.maparea) self.worldwindow.show() self.showArea('init') def showArea(self, event): if self.ignore: return if self.sender() == self.southSpin or self.sender() == self.eastSpin: if self.southSpin.value() > self.northSpin.value(): y = self.northSpin.value() self.northSpin.setValue(self.southSpin.value()) self.southSpin.setValue(y) if self.eastSpin.value() < self.westSpin.value(): x = self.westSpin.value() self.westSpin.setValue(self.eastSpin.value()) self.eastSpin.setValue(x) if self.worldwindow is None: return approx_area = self.worldwindow.view.drawRect([ QtCore.QPointF(self.westSpin.value(), self.northSpin.value()), QtCore.QPointF(self.eastSpin.value(), self.southSpin.value()) ]) self.approx_area.setText(approx_area) if event != 'init': self.worldwindow.view.statusmsg.emit(approx_area)
class getParms(QtWidgets.QWidget): def __init__(self, help='help.html'): super(getParms, self).__init__() self.help = help self.initUI() def initUI(self): config = configparser.RawConfigParser() if len(sys.argv) > 1: config_file = sys.argv[1] else: config_file = getModelFile('SIREN.ini') config.read(config_file) try: self.base_year = config.get('Base', 'year') except: self.base_year = '2012' self.parents = [] try: self.parents = getParents(config.items('Parents')) except: pass try: self.solarfiles = config.get('Files', 'solar_files') for key, value in self.parents: self.solarfiles = self.solarfiles.replace(key, value) self.solarfiles = self.solarfiles.replace('$USER$', getUser()) self.solarfiles = self.solarfiles.replace('$YEAR$', self.base_year) except: self.solarfiles = '' try: self.solarindex = config.get('Files', 'solar_index') for key, value in self.parents: self.solarindex = self.solarindex.replace(key, value) self.solarindex = self.solarindex.replace('$USER$', getUser()) self.solarindex = self.solarindex.replace('$YEAR$', self.base_year) except: self.solarindex = '' if self.solarindex == '': self.solarindex = self.solarfiles + '/solar_index.xls' try: self.windfiles = config.get('Files', 'wind_files') for key, value in self.parents: self.windfiles = self.windfiles.replace(key, value) self.windfiles = self.windfiles.replace('$USER$', getUser()) self.windfiles = self.windfiles.replace('$YEAR$', self.base_year) except: self.windfiles = '' try: self.windindex = config.get('Files', 'wind_index') for key, value in self.parents: self.windindex = self.windindex.replace(key, value) self.windindex = self.windindex.replace('$USER$', getUser()) self.windindex = self.windindex.replace('$YEAR$', self.base_year) except: self.windindex = '' if self.windindex == '': self.windindex = self.windfiles + '/wind_index.xls' self.grid = QtWidgets.QGridLayout() self.grid.addWidget(QtWidgets.QLabel('Solar Folder:'), 1, 0) self.ssource = ClickableQLabel() self.ssource.setText(self.solarfiles) self.ssource.setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.ssource.clicked.connect(self.sdirChanged) self.grid.addWidget(self.ssource, 1, 1, 1, 4) self.grid.addWidget(QtWidgets.QLabel('Solar Index:'), 2, 0) self.starget = ClickableQLabel() self.starget.setText(self.solarindex) self.starget.setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.starget.clicked.connect(self.stgtChanged) self.grid.addWidget(self.starget, 2, 1, 1, 4) self.grid.addWidget(QtWidgets.QLabel('Wind Folder:'), 3, 0) self.wsource = ClickableQLabel() self.wsource.setText(self.windfiles) self.wsource.setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.wsource.clicked.connect(self.wdirChanged) self.grid.addWidget(self.wsource, 3, 1, 1, 4) self.grid.addWidget(QtWidgets.QLabel('Wind Index:'), 4, 0) self.wtarget = ClickableQLabel() self.wtarget.setText(self.windindex) self.wtarget.setStyleSheet("background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;") self.wtarget.clicked.connect(self.wtgtChanged) self.grid.addWidget(self.wtarget, 4, 1, 1, 4) self.grid.addWidget(QtWidgets.QLabel('Properties:'), 5, 0) self.properties = QtWidgets.QLineEdit() self.properties.setReadOnly(True) self.grid.addWidget(self.properties, 5, 1, 1, 4) self.log = QtWidgets.QLabel(' ') self.grid.addWidget(self.log, 6, 1, 1, 4) quit = QtWidgets.QPushButton('Quit', self) self.grid.addWidget(quit, 7, 0) quit.clicked.connect(self.quitClicked) QtWidgets.QShortcut(QtGui.QKeySequence('q'), self, self.quitClicked) dosolar = QtWidgets.QPushButton('Produce Solar Index', self) wdth = dosolar.fontMetrics().boundingRect(dosolar.text()).width() + 9 dosolar.setMaximumWidth(wdth) self.grid.addWidget(dosolar, 7, 1) dosolar.clicked.connect(self.dosolarClicked) dowind = QtWidgets.QPushButton('Produce Wind Index', self) dowind.setMaximumWidth(wdth) self.grid.addWidget(dowind, 7, 2) dowind.clicked.connect(self.dowindClicked) help = QtWidgets.QPushButton('Help', self) help.setMaximumWidth(wdth) self.grid.addWidget(help, 7, 3) help.clicked.connect(self.helpClicked) QtWidgets.QShortcut(QtGui.QKeySequence('F1'), self, self.helpClicked) self.grid.setColumnStretch(3, 5) frame = QtWidgets.QFrame() frame.setLayout(self.grid) self.scroll = QtWidgets.QScrollArea() self.scroll.setWidgetResizable(True) self.scroll.setWidget(frame) self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.scroll) self.setWindowTitle('SIREN - indexweather (' + fileVersion() + ') - Make resource grid file') self.setWindowIcon(QtGui.QIcon('sen_icon32.ico')) self.center() self.resize(int(self.sizeHint().width()* 1.07), int(self.sizeHint().height() * 1.07)) self.show() def center(self): frameGm = self.frameGeometry() screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos()) centerPoint = QtWidgets.QApplication.desktop().availableGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def sdirChanged(self): curdir = self.ssource.text() newdir = str(QtWidgets.QFileDialog.getExistingDirectory(self, 'Choose Solar Folder', curdir, QtWidgets.QFileDialog.ShowDirsOnly)) if newdir != '': self.ssource.setText(newdir) def wdirChanged(self): curdir = self.wsource.text() newdir = str(QtWidgets.QFileDialog.getExistingDirectory(self, 'Choose Wind Folder', curdir, QtWidgets.QFileDialog.ShowDirsOnly)) if newdir != '': self.wsource.setText(newdir) def stgtChanged(self): curtgt = self.starget.text() newtgt = QtWidgets.QFileDialog.getSaveFileName(self, 'Choose Solar Index', curtgt, 'XLS Files (*.xls)')[0] if newtgt != '': self.starget.setText(newtgt) def wtgtChanged(self): curtgt = self.starget.text() newtgt = QtWidgets.QFileDialog.getSaveFileName(self, 'Choose Wind Index', curtgt, 'XLS Files (*.xls)')[0] if newtgt != '': self.wtarget.setText(newtgt) def helpClicked(self): dialog = displayobject.AnObject(QtWidgets.QDialog(), self.help, title='Help for indexweather (' + fileVersion() + ')', section='index') dialog.exec_() def quitClicked(self): self.close() def dosolarClicked(self): solar = makeIndex('Solar', str(self.ssource.text()), str(self.starget.text())) self.log.setText(solar.getLog()) prop = 'solar_index=' + str(self.starget.text()) self.properties.setText(prop) def dowindClicked(self): wind = makeIndex('Wind', str(self.wsource.text()), str(self.wtarget.text())) self.log.setText(wind.getLog()) prop = 'wind_index=' + str(self.wtarget.text()) self.properties.setText(prop)
class FlexiPlot(QtWidgets.QWidget): def __init__(self, help='help.html'): super(FlexiPlot, self).__init__() self.help = help config = configparser.RawConfigParser() if len(sys.argv) > 1: self.config_file = sys.argv[1] else: self.config_file = getModelFile('flexiplot.ini') config.read(self.config_file) if not config.has_section('Flexiplot'): # new file set windows section self.restorewindows = True else: self.restorewindows = False try: rw = config.get('Windows', 'restorewindows') if rw.lower() in ['true', 'yes', 'on']: self.restorewindows = True except: pass parents = [] self.colours = {} try: parents = getParents(config.items('Parents')) except: pass try: base_year = config.get('Base', 'year') except: base_year = '2012' try: scenario_prefix = config.get('Files', 'scenario_prefix') except: scenario_prefix = '' try: self.scenarios = config.get('Files', 'scenarios') if scenario_prefix != '': self.scenarios += '/' + scenario_prefix for key, value in parents: self.scenarios = self.scenarios.replace(key, value) self.scenarios = self.scenarios.replace('$USER$', getUser()) self.scenarios = self.scenarios.replace('$YEAR$', base_year) self.scenarios = self.scenarios[:self.scenarios.rfind('/') + 1] if self.scenarios[:3] == '../': ups = self.scenarios.split('../') me = os.getcwd().split(os.sep) me = me[:-(len(ups) - 1)] me.append(ups[-1]) self.scenarios = '/'.join(me) except: self.scenarios = '' try: colours = config.items('Plot Colors') for item, colour in colours: itm = item.replace('_', ' ') self.colours[itm] = colour except: pass ifile = '' isheet = '' columns = [] self.setup = [False, False] self.details = True self.book = None self.rows = None self.leapyear = False iper = '<none>' imax = 0 self.alpha = 0.25 self.title_font = 'size=x-large' #'size=15' self.label_font = '' #'size=x-large' self.legend_font = '' #'size=x-large' self.ticks_font = '' #'size=large' self.constrained_layout = False self.series = [] self.xvalues = [] self.palette = True self.history = None self.max_files = 10 ifiles = self.get_flex_config() if len(ifiles) > 0: if self.history is None: self.history = sorted(ifiles.keys(), reverse=True) while ifile == '' and len(self.history) > 0: try: ifile = ifiles[self.history[0]] except: self.history.pop(0) matplotlib.rcParams['savefig.directory'] = os.getcwd() self.grid = QtWidgets.QGridLayout() self.updated = False self.colours_updated = False self.log = QtWidgets.QLabel('') rw = 0 self.grid.addWidget(QtWidgets.QLabel('Recent Files:'), rw, 0) self.files = QtWidgets.QComboBox() if ifile != '': self.popfileslist(ifile, ifiles) self.grid.addWidget(self.files, rw, 1, 1, 5) rw += 1 self.grid.addWidget(QtWidgets.QLabel('File:'), rw, 0) self.file = ClickableQLabel() self.file.setStyleSheet( "background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;" ) self.file.setText('') self.grid.addWidget(self.file, rw, 1, 1, 5) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Sheet:'), rw, 0) self.sheet = QtWidgets.QComboBox() self.grid.addWidget(self.sheet, rw, 1, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Title:'), rw, 0) self.title = QtWidgets.QLineEdit('') self.grid.addWidget(self.title, rw, 1, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Series:'), rw, 0) self.seriesi = CustomCombo() for series in self.series: self.seriesi.addItem(series) self.seriesi.setEditable(True) self.grid.addWidget(self.seriesi, rw, 1, 1, 2) self.grid.addWidget( QtWidgets.QLabel( '(Cells for Series Categories; A1:B2 or r1,c1,r2,c2 format)'), rw, 3, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Series Label:'), rw, 0) self.ylabel = QtWidgets.QLineEdit('') self.grid.addWidget(self.ylabel, rw, 1, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('X Values:'), rw, 0) self.xvaluesi = CustomCombo() for xvalues in self.xvalues: self.xvaluesi.addItem(xvalues) self.xvaluesi.setEditable(True) self.grid.addWidget(self.xvaluesi, rw, 1, 1, 2) self.grid.addWidget( QtWidgets.QLabel( '(Cells for X values; A1:B2 or r1,c1,r2,c2 format)'), rw, 3, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('X Label:'), rw, 0) self.xlabel = QtWidgets.QLineEdit('') self.grid.addWidget(self.xlabel, rw, 1, 1, 2) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Maximum:'), rw, 0) self.maxSpin = QtWidgets.QSpinBox() self.maxSpin.setRange(0, 100000) self.maxSpin.setSingleStep(500) self.grid.addWidget(self.maxSpin, rw, 1) self.grid.addWidget( QtWidgets.QLabel( '(Handy if you want to produce a series of plots)'), rw, 3, 1, 3) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Type of Plot:'), rw, 0) plots = ['Bar Chart', 'Cumulative', 'Linegraph', 'Step Plot'] self.plottype = QtWidgets.QComboBox() for plot in plots: self.plottype.addItem(plot) self.grid.addWidget(self.plottype, rw, 1) #, 1, 2) self.grid.addWidget( QtWidgets.QLabel('(Type of plot - stacked except for Linegraph)'), rw, 3, 1, 3) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Percentage:'), rw, 0) self.percentage = QtWidgets.QCheckBox() self.percentage.setCheckState(QtCore.Qt.Unchecked) self.grid.addWidget(self.percentage, rw, 1) #, 1, 2) self.grid.addWidget( QtWidgets.QLabel('(Check for percentage distribution)'), rw, 3, 1, 3) rw += 1 self.grid.addWidget(QtWidgets.QLabel('Show Grid:'), rw, 0) grids = ['Both', 'Horizontal', 'Vertical', 'None'] self.gridtype = QtWidgets.QComboBox() for grid in grids: self.gridtype.addItem(grid) self.grid.addWidget(self.gridtype, rw, 1) #, 1, 2) self.grid.addWidget(QtWidgets.QLabel('(Choose gridlines)'), rw, 3, 1, 3) rw += 1 self.grid.addWidget( QtWidgets.QLabel('Column Order:\n(move to right\nto exclude)'), rw, 0) self.order = ListWidget(self) self.grid.addWidget(self.order, rw, 1, 1, 2) self.ignore = ListWidget(self) self.grid.addWidget(self.ignore, rw, 3, 1, 2) self.grid.addWidget(QtWidgets.QLabel(' '), rw, 5) if ifile != '': self.get_file_config(self.history[0]) self.files.currentIndexChanged.connect(self.filesChanged) self.file.clicked.connect(self.fileChanged) # self.seriesi.textChanged.connect(self.seriesChanged) self.seriesi.activated[str].connect(self.seriesChanged) self.seriesi.currentIndexChanged.connect(self.seriesChanged) self.xvaluesi.activated[str].connect(self.xvaluesChanged) self.xvaluesi.currentIndexChanged.connect(self.xvaluesChanged) # self.xvalues.textChanged.connect(self.somethingChanged) self.files.currentIndexChanged.connect(self.seriesChanged) self.sheet.currentIndexChanged.connect(self.sheetChanged) self.title.textChanged.connect(self.somethingChanged) self.maxSpin.valueChanged.connect(self.somethingChanged) self.plottype.currentIndexChanged.connect(self.somethingChanged) self.gridtype.currentIndexChanged.connect(self.somethingChanged) self.percentage.stateChanged.connect(self.somethingChanged) self.order.itemSelectionChanged.connect(self.somethingChanged) rw += 1 msg_palette = QtGui.QPalette() msg_palette.setColor(QtGui.QPalette.Foreground, QtCore.Qt.red) self.log.setPalette(msg_palette) self.grid.addWidget(self.log, rw, 1, 1, 4) rw += 1 done = QtWidgets.QPushButton('Done', self) self.grid.addWidget(done, rw, 0) done.clicked.connect(self.doneClicked) QtWidgets.QShortcut(QtGui.QKeySequence('q'), self, self.doneClicked) pp = QtWidgets.QPushButton('Plot', self) self.grid.addWidget(pp, rw, 1) pp.clicked.connect(self.ppClicked) QtWidgets.QShortcut(QtGui.QKeySequence('p'), self, self.ppClicked) cb = QtWidgets.QPushButton('Colours', self) self.grid.addWidget(cb, rw, 2) cb.clicked.connect(self.editColours) ep = QtWidgets.QPushButton('Preferences', self) self.grid.addWidget(ep, rw, 3) ep.clicked.connect(self.editIniFile) help = QtWidgets.QPushButton('Help', self) self.grid.addWidget(help, rw, 4) help.clicked.connect(self.helpClicked) QtWidgets.QShortcut(QtGui.QKeySequence('F1'), self, self.helpClicked) frame = QtWidgets.QFrame() frame.setLayout(self.grid) self.scroll = QtWidgets.QScrollArea() self.scroll.setWidgetResizable(True) self.scroll.setWidget(frame) self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.scroll) self.setWindowTitle('SIREN - flexiplot (' + fileVersion() + ') - FlexiPlot') self.setWindowIcon(QtGui.QIcon('sen_icon32.ico')) if self.restorewindows: try: rw = config.get('Windows', 'flexiplot_size').split(',') self.resize(int(rw[0]), int(rw[1])) mp = config.get('Windows', 'flexiplot_pos').split(',') self.move(int(mp[0]), int(mp[1])) except: pass else: self.center() self.resize(int(self.sizeHint().width() * 1.2), int(self.sizeHint().height() * 1.2)) self.log.setText('Preferences file: ' + self.config_file) self.show() def center(self): frameGm = self.frameGeometry() screen = QtWidgets.QApplication.desktop().screenNumber( QtWidgets.QApplication.desktop().cursor().pos()) centerPoint = QtWidgets.QApplication.desktop().availableGeometry( screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def get_flex_config(self): ifiles = {} self.constrained_layout = False self.palette = True self.sparse_ticks = [] self.random_colours = True config = configparser.RawConfigParser() config.read(self.config_file) try: # get defaults and list of files if any items = config.items('Flexiplot') for key, value in items: if key == 'alpha': try: self.alpha = float(value) except: pass elif key == 'constrained_layout': if value.lower() in ['true', 'yes', 'on']: self.constrained_layout = True elif key == 'file_history': self.history = value.split(',') elif key == 'file_choices': self.max_files = int(value) elif key[:4] == 'file': ifiles[key[4:]] = value.replace('$USER$', getUser()) elif key == 'label_font': self.label_font = value elif key == 'legend_font': self.legend_font = value elif key == 'palette': if value.lower() in ['false', 'no', 'off']: self.palette = False elif key == 'random_colours' or key == 'random_colors': if value.lower() in ['false', 'no', 'off']: self.random_colours = False elif key == 'sparse_ticks': try: self.sparse_ticks = [int(value)] except: if value.lower() in ['true', 'yes', 'on']: self.sparse_ticks = True else: if value.find(':') > 0: self.sparse_ticks = value.split(':') else: self.sparse_ticks = value.split(',') elif key == 'ticks_font': self.ticks_font = value elif key == 'title_font': self.title_font = value except: pass return ifiles def get_file_config(self, choice=''): ifile = '' ignore = True config = configparser.RawConfigParser() config.read(self.config_file) columns = [] isheet = '' try: # get list of files if any self.maxSpin.setValue(0) self.gridtype.setCurrentIndex(0) self.percentage.setCheckState(QtCore.Qt.Unchecked) items = config.items('Flexiplot') for key, value in items: if key == 'columns' + choice: columns = charSplit(value) elif key == 'file' + choice: ifile = value.replace('$USER$', getUser()) elif key == 'grid' + choice: self.gridtype.setCurrentIndex( self.gridtype.findText(value)) elif key == 'percentage' + choice: if value.lower() in ['true', 'yes', 'on']: self.percentage.setCheckState(QtCore.Qt.Checked) else: self.percentage.setCheckState(QtCore.Qt.Unchecked) elif key == 'plot' + choice: self.plottype.setCurrentIndex( self.plottype.findText(value)) elif key == 'series' + choice: self.seriesi.clear() self.series = charSplit(value) for series in self.series: self.seriesi.addItem(series) elif key == 'maximum' + choice: try: self.maxSpin.setValue(int(value)) except: self.maxSpin.setValue(0) elif key == 'sheet' + choice: isheet = value elif key == 'title' + choice: self.title.setText(value) elif key == 'xlabel' + choice: self.xlabel.setText(value) elif key == 'xvalues' + choice: self.xvaluesi.clear() self.xvalues = charSplit(value) for xvalues in self.xvalues: self.xvaluesi.addItem(xvalues) elif key == 'ylabel' + choice: self.ylabel.setText(value) except: pass self.columns = [] if ifile != '': if self.book is not None: pxl.free_resources() self.book = None self.file.setText(ifile) if os.path.exists(ifile): self.setSheet(ifile, isheet) else: self.setSheet(self.scenarios + ifile, isheet) self.setColumns(isheet, columns=columns) for column in self.columns: self.check_colour(column, config, add=False) ignore = False def popfileslist(self, ifile, ifiles=None): self.setup[1] = True if ifiles is None: ifiles = {} for i in range(self.files.count()): ifiles[self.history[i]] = self.files.itemText(i) if self.history is None: self.history = [''] ifiles = {'': ifile} else: for i in range(len(self.history)): if ifile == ifiles[self.history[i]]: self.history.insert( 0, self.history.pop(i)) # make this entry first break else: # find new entry if len(self.history) >= self.max_files: self.history.insert( 0, self.history.pop(-1)) # make last entry first else: hist = sorted(self.history) if hist[0] != '': ent = '' else: for i in range(1, len(hist)): if str(i) != hist[i]: ent = str(i) break else: ent = str(i + 1) self.history.insert(0, ent) ifiles[self.history[0]] = ifile self.files.clear() for i in range(len(self.history)): try: self.files.addItem(ifiles[self.history[i]]) except: pass self.files.setCurrentIndex(0) self.setup[1] = False def fileChanged(self): self.log.setText('') if os.path.exists(self.file.text()): curfile = self.file.text() else: curfile = self.scenarios + self.file.text() newfile = QtWidgets.QFileDialog.getOpenFileName( self, 'Open file', curfile)[0] if newfile != '': if self.book is not None: pxl.free_resources() self.book = None isheet = self.sheet.currentText() self.setSheet(newfile, isheet) if newfile[:len(self.scenarios)] == self.scenarios: self.file.setText(newfile[len(self.scenarios):]) else: self.file.setText(newfile) self.popfileslist(self.file.text()) self.setup[1] = False self.updated = True def filesChanged(self): if self.setup[1]: return self.setup[0] = True self.log.setText('') self.saveConfig() self.get_file_config(self.history[self.files.currentIndex()]) self.popfileslist(self.files.currentText()) self.log.setText('File "loaded"') self.setup[0] = False def somethingChanged(self): if not self.setup[0]: self.updated = True def setSheet(self, ifile, isheet): if self.book is None: try: self.book = pxl.get_book(file_name=ifile) except: self.log.setText("Can't open file - " + ifile) return ndx = 0 self.sheet.clear() j = -1 for sht in self.book.sheet_names(): j += 1 self.sheet.addItem(sht) if sht == isheet: ndx = j self.sheet.setCurrentIndex(ndx) def sheetChanged(self): self.log.setText('') if self.book is None: self.book = pxl.get_book(file_name=ifile) isheet = self.sheet.currentText() if isheet not in self.book.sheet_names(): self.log.setText("Can't find sheet - " + isheet) return self.setColumns(isheet) self.updated = True def seriesChanged(self): self.log.setText('') series = self.seriesi.currentText() self.series = [series] for i in range(self.seriesi.count()): if self.seriesi.itemText(i) != series: self.series.append(self.seriesi.itemText(i)) self.setColumns(self.sheet.currentText()) self.updated = True def xvaluesChanged(self): self.log.setText('') xvalues = self.xvaluesi.currentText() self.xvalues = [xvalues] for i in range(self.xvaluesi.count()): if self.xvaluesi.itemText(i) != xvalues: self.xvalues.append(self.xvaluesi.itemText(i)) self.updated = True def setColumns(self, isheet, columns=[]): try: ws = getattr(self.book, isheet.replace(' ', '_')) except: self.log.setText("Can't find sheet - " + isheet) return self.columns = [] oldcolumns = [] for col in range(self.order.count()): oldcolumns.append(self.order.item(col).text()) self.order.clear() self.ignore.clear() try: roco = get_range(self.series[0]) except: return if roco is None: return for row in range(roco[0], roco[2] + 1): for col in range(roco[1], roco[3] + 1): try: column = str(ws[row, col]).replace('\n', ' ') except: continue self.columns.append(column) # need order of columns if column in oldcolumns and column not in columns: columns.append(column) if column in columns: pass else: self.ignore.addItem(column) try: self.ignore.item(self.ignore.count() - 1) \ .setBackground(QtGui.QColor(self.colours[column.lower()])) except: pass for column in columns: if column in self.columns: self.order.addItem(column) try: self.order.item(self.order.count() - 1) \ .setBackground(QtGui.QColor(self.colours[column.lower()])) except: pass self.updated = True def helpClicked(self): dialog = displayobject.AnObject(QtWidgets.QDialog(), self.help, title='Help for flexiplot (' + fileVersion() + ')', section='flexiplot') dialog.exec_() def doneClicked(self): if self.book is not None: pxl.free_resources() if not self.updated and not self.colours_updated: self.close() self.saveConfig() self.close() def closeEvent(self, event): if self.restorewindows: updates = {} lines = [] add = int((self.frameSize().width() - self.size().width()) / 2) # need to account for border lines.append( 'flexiplot_pos=%s,%s' % (str(self.pos().x() + add), str(self.pos().y() + add))) lines.append('flexiplot_size=%s,%s' % (str(self.width()), str(self.height()))) updates['Windows'] = lines SaveIni(updates, ini_file=self.config_file) event.accept() def editIniFile(self): curfldr = self.file.text()[:self.file.text().rfind('/')] dialr = EditSect('Flexiplot', curfldr, ini_file=self.config_file) ifiles = self.get_flex_config() def saveConfig(self): updates = {} if self.updated: config = configparser.RawConfigParser() config.read(self.config_file) try: choice = self.history[0] except: choice = '' save_file = self.file.text().replace(getUser(), '$USER$') try: self.max_files = int(config.get('Flexiplot', 'file_choices')) except: pass lines = [] fix_history = [] try: if len(self.history) > 0: check_history = [] line = '' for i in range(len(self.history)): itm = self.history[i] if self.files.itemText(i) in check_history: fix_history.append([i, itm]) else: check_history.append(self.files.itemText(i)) line += itm + ',' line = line[:-1] lines.append('file_history=' + line) except: pass cols = 'columns' + choice + '=' for col in range(self.order.count()): try: if self.order.item(col).text().index(',') >= 0: try: if self.order.item(col).text().index("'") >= 0: qte = '"' except: qte = "'" except: qte = '' cols += qte + self.order.item(col).text() + qte + ',' if cols[-1] != '=': cols = cols[:-1] lines.append(cols) lines.append('file' + choice + '=' + self.file.text().replace(getUser(), '$USER$')) lines.append('grid' + choice + '=' + self.gridtype.currentText()) lines.append('maximum' + choice + '=') if self.maxSpin.value() != 0: lines[-1] = lines[-1] + str(self.maxSpin.value()) lines.append('percentage' + choice + '=') if self.percentage.isChecked(): lines[-1] = lines[-1] + 'True' lines.append('plot' + choice + '=' + self.plottype.currentText()) lines.append('sheet' + choice + '=' + self.sheet.currentText()) line = 'series' + choice + '=' for series in self.series: if series.find(',') >= 0: line += "'" + series + "'," else: line += series + ',' lines.append(line[:-1]) lines.append('title' + choice + '=' + self.title.text()) lines.append('xlabel' + choice + '=' + self.xlabel.text()) line = 'xvalues' + choice + '=' for xvalues in self.xvalues: if xvalues.find(',') >= 0: line += "'" + xvalues + "'," else: line += xvalues + ',' lines.append(line[:-1]) lines.append('ylabel' + choice + '=' + self.ylabel.text()) props = [ 'columns', 'file', 'grid', 'maximum', 'percentage', 'plot', 'sheet', 'series', 'title', 'xlabel', 'xvalues', 'ylabel' ] for i in range(len(fix_history) - 1, -1, -1): self.files.removeItem(fix_history[i][0]) self.history.pop(fix_history[i][0]) for prop in props: lines.append(prop + fix_history[i][1] + '=') updates['Flexiplot'] = lines if self.restorewindows and not config.has_section( 'Windows'): # new file set windows section updates['Windows'] = ['restorewindows=True'] if self.colours_updated: lines = [] for key, value in self.colours.items(): if value != '': lines.append(key.replace(' ', '_') + '=' + value) updates['Plot Colors'] = lines SaveIni(updates, ini_file=self.config_file) self.updated = False self.colours_updated = False def editColours(self, color=False): # if they've selected some items I'll create a palette of colours for them palette = [] if self.palette: for item in self.order.selectedItems(): palette.append(item.text()) for item in self.ignore.selectedItems(): palette.append(item.text()) dialr = Colours(section='Plot Colors', ini_file=self.config_file, add_colour=color, palette=palette, underscore=True) dialr.exec_() self.colours = {} config = configparser.RawConfigParser() config.read(self.config_file) try: colours = config.items('Plot Colors') for item, colour in colours: itm = item.replace('_', ' ') self.colours[itm] = colour except: pass for c in range(self.order.count()): col = self.order.item(c).text() try: self.order.item(c).setBackground( QtGui.QColor(self.colours[col.lower()])) except: pass for c in range(self.ignore.count()): col = self.ignore.item(c).text() try: self.ignore.item(c).setBackground( QtGui.QColor(self.colours[col.lower()])) except: pass def check_colour(self, colour, config, add=True): colr = colour.lower() if colr in self.colours.keys(): return True elif self.random_colours: # new approach to generate random colour if not in [Plot Colors] r = lambda: random.randint(0, 255) new_colr = '#%02X%02X%02X' % (r(), r(), r()) self.colours[colr] = new_colr return True # previous approach may ask for new colours to be stored in .ini file colr2 = colr.replace('_', ' ') if config is not None: try: amap = config.get('Map', 'map_choice') tgt_colr = config.get('Colors' + amap, colr2) self.colours[colr] = tgt_colr self.colours_updated = True return True except: pass try: tgt_colr = config.get('Colors', colr2) self.colours[colr] = tgt_colr self.colours_updated = True return True except: pass if not add: return False self.editColours(color=colour) if colr not in self.colours.keys(): self.log.setText('No colour for ' + colour) return False return True if not add: return False self.editColours(color=colour) if colr not in self.colours.keys(): self.log.setText('No colour for ' + colour) return False return True def ppClicked(self): if self.book is None: self.log.setText('Error accessing Workbook.') return if self.order.count() == 0: self.log.setText('Nothing to plot.') return isheet = self.sheet.currentText() if isheet == '': self.log.setText('Sheet not set.') return if len(sys.argv) > 1: config_file = sys.argv[1] config = configparser.RawConfigParser() config.read(self.config_file) else: config = None for c in range(self.order.count()): if not self.check_colour(self.order.item(c).text(), config): return del config self.log.setText('') i = self.file.text().rfind('/') if i > 0: matplotlib.rcParams['savefig.directory'] = self.file.text()[:i + 1] else: matplotlib.rcParams['savefig.directory'] = self.scenarios ws = getattr(self.book, isheet.replace(' ', '_')) x = [] xlabels = [] rocox = get_range(self.xvalues[0]) # print(rocox) data_in_cols = True if rocox[1] == rocox[3]: pass elif rocox[0] == rocox[2]: data_in_cols = False else: print('Assume in columns') ctr = 0 if data_in_cols: if rocox[2] >= ws.number_of_rows(): rocox[2] = ws.number_of_rows() - 1 for row in range(rocox[0], rocox[2] + 1): x.append(ctr) ctr += 1 try: xlabels.append(str(int(ws[row, rocox[1]]))) except: xlabels.append(ws[row, rocox[1]]) else: if rocox[3] >= ws.number_of_columns(): rocox[3] = ws.number_of_columns() - 1 for col in range(rocox[1], rocox[3] + 1): x.append(ctr) ctr += 1 try: xlabels.append(str(int(ws[rocox[0], col]))) except: xlabels.append(ws[rocox[0], col]) data = [] label = [] miny = 0 maxy = 0 titl = self.title.text() #.replace('$YEAR$', str(year)) titl = titl.replace('$MTH$', '') titl = titl.replace('$MONTH$', '') titl = titl.replace(' ', '') titl = titl.replace('Diurnal ', '') titl = titl.replace('Diurnal', '') titl = titl.replace('$SHEET$', isheet) roco = get_range(self.series[0]) for c in range(self.order.count() - 1, -1, -1): try: column = self.order.item(c).text() ndx = self.columns.index(column) if data_in_cols: col = roco[1] + ndx else: row = roco[0] + ndx except: continue data.append([]) label.append(column) if data_in_cols: for row in range(rocox[0], rocox[2] + 1): if ws[row, col] == '': data[-1].append(0.) else: data[-1].append(ws[row, col]) miny = min(miny, data[-1][-1]) maxy = max(maxy, data[-1][-1]) else: for col in range(rocox[1], rocox[3] + 1): if ws[row, col] == '': data[-1].append(0.) else: data[-1].append(ws[row, col]) miny = min(miny, data[-1][-1]) maxy = max(maxy, data[-1][-1]) if self.gridtype.currentText() == 'Both': gridtype = 'both' elif self.gridtype.currentText() == 'Horizontal': gridtype = 'y' elif self.gridtype.currentText() == 'Vertical': gridtype = 'x' else: gridtype = '' figname = self.plottype.currentText().lower().replace( ' ', '') # + str(year)) fig = plt.figure(figname, constrained_layout=self.constrained_layout) if gridtype != '': plt.grid(axis=gridtype) graph = fig.add_subplot(111) plt.title(titl, fontdict=font_props(self.title_font)) if self.plottype.currentText() in ['Cumulative', 'Step Plot']: if self.plottype.currentText() == 'Cumulative': step = None else: step = 'pre' if self.percentage.isChecked(): miny = 0 totals = [0.] * len(x) bottoms = [0.] * len(x) values = [0.] * len(x) for c in range(len(data)): for h in range(len(data[c])): totals[h] = totals[h] + data[c][h] for h in range(len(data[0])): values[h] = data[0][h] / totals[h] * 100. graph.fill_between(x, 0, values, label=label[0], color=self.colours[label[0].lower()], step=step) for c in range(1, len(data)): for h in range(len(data[c])): bottoms[h] = values[h] values[h] = values[h] + data[c][h] / totals[h] * 100. graph.fill_between(x, bottoms, values, label=label[c], color=self.colours[label[c].lower()], step=step) maxy = 100 else: graph.fill_between(x, miny, data[0], label=label[0], color=self.colours[label[0].lower()], step=step) for c in range(1, len(data)): for h in range(len(data[c])): data[c][h] = data[c][h] + data[c - 1][h] maxy = max(maxy, data[c][h]) graph.fill_between(x, data[c - 1], data[c], label=label[c], color=self.colours[label[c].lower()], step=step) top = data[0][:] for d in range(1, len(data)): for h in range(len(top)): top[h] = max(top[h], data[d][h]) if self.plottype.currentText() == 'Cumulative': graph.plot(x, top, color='white') else: graph.step(x, top, color='white') if self.maxSpin.value() > 0: maxy = self.maxSpin.value() else: try: rndup = pow(10, round(log10(maxy * 1.5) - 1)) / 2 maxy = ceil(maxy / rndup) * rndup except: pass elif self.plottype.currentText() == 'Bar Chart': if self.percentage.isChecked(): miny = 0 totals = [0.] * len(x) bottoms = [0.] * len(x) values = [0.] * len(x) for c in range(len(data)): for h in range(len(data[c])): totals[h] = totals[h] + data[c][h] for h in range(len(data[0])): values[h] = data[0][h] / totals[h] * 100. graph.bar(x, values, label=label[0], color=self.colours[label[0].lower()]) for c in range(1, len(data)): for h in range(len(data[c])): bottoms[h] = bottoms[h] + values[h] values[h] = data[c][h] / totals[h] * 100. graph.bar(x, values, bottom=bottoms, label=label[c], color=self.colours[label[c].lower()]) maxy = 100 else: graph.bar(x, data[0], label=label[0], color=self.colours[label[0].lower()]) bottoms = [0.] * len(x) for c in range(1, len(data)): for h in range(len(data[c])): bottoms[h] = bottoms[h] + data[c - 1][h] maxy = max(maxy, data[c][h] + bottoms[h]) graph.bar(x, data[c], bottom=bottoms, label=label[c], color=self.colours[label[c].lower()]) if self.maxSpin.value() > 0: maxy = self.maxSpin.value() else: try: rndup = pow(10, round(log10(maxy * 1.5) - 1)) / 2 maxy = ceil(maxy / rndup) * rndup except: pass else: #Linegraph for c in range(len(data)): mx = max(data[c]) maxy = max(maxy, mx) graph.plot(x, data[c], linewidth=2.0, label=label[c], color=self.colours[label[c].lower()]) if self.maxSpin.value() > 0: maxy = self.maxSpin.value() else: try: rndup = pow(10, round(log10(maxy * 1.5) - 1)) / 2 maxy = ceil(maxy / rndup) * rndup except: pass leg_font = font_props(self.legend_font, fontdict=False) graph.legend(bbox_to_anchor=[0.5, -0.1], loc='center', ncol=(len(data) + 2), prop=leg_font) plt.ylim([miny, maxy]) plt.xlim([0, len(x) - 1]) if self.sparse_ticks or len(self.sparse_ticks) > 0: # if self.plottype.currentText() == 'Linegraph' and len(x) > 24: tick_labels = [str(xlabels[0])] xticks = [0] if self.sparse_ticks and isinstance(self.sparse_ticks, bool): for l in range(1, len(xlabels)): if xlabels[l] != tick_labels[-1]: xticks.append(l) tick_labels.append(xlabels[l]) elif len(self.sparse_ticks) == 1: for l in range(self.sparse_ticks[0] + 1, len(xlabels), self.sparse_ticks[0]): xticks.append(l) tick_labels.append(xlabels[l]) else: try: fr = int(self.sparse_ticks[0]) - 1 to = int(self.sparse_ticks[1]) except: fr = 0 to = 3 for l in range(1, len(xlabels)): if str(xlabels[l])[fr:to] != tick_labels[-1][fr:to]: xticks.append(l) tick_labels.append(xlabels[l]) xticks.append(len(xlabels) - 1) tick_labels.append(xlabels[-1]) plt.xticks(xticks) graph.set_xticklabels(tick_labels, rotation='vertical', fontdict=font_props(self.ticks_font)) else: plt.xticks(x, xlabels) graph.set_xticklabels(xlabels, rotation='vertical', fontdict=font_props(self.ticks_font)) graph.set_xlabel(self.xlabel.text(), fontdict=font_props(self.label_font)) graph.set_ylabel(self.ylabel.text(), fontdict=font_props(self.label_font)) yticks = graph.get_yticklabels() graph.set_yticklabels(yticks, fontdict=font_props(self.ticks_font)) if self.percentage.isChecked(): formatter = plt.FuncFormatter(lambda y, pos: '{:.0f}%'.format(y)) else: formatter = plt.FuncFormatter(lambda y, pos: '{:,.0f}'.format(y)) graph.yaxis.set_major_formatter(formatter) zp = ZoomPanX(yformat=formatter) f = zp.zoom_pan(graph, base_scale=1.2, dropone=True) # enable scrollable zoom plt.show() del zp
class getParms(QtWidgets.QWidget): def __init__(self, help='help.html'): super(getParms, self).__init__() self.help = help self.initUI() def initUI(self): config = configparser.RawConfigParser() if len(sys.argv) > 1: config_file = sys.argv[1] else: config_file = getModelFile('SIREN.ini') config.read(config_file) try: self.base_year = config.get('Base', 'year') except: self.base_year = '2012' self.yrndx = -1 this_year = time.strftime('%Y') try: self.years = [] years = config.get('Base', 'years') bits = years.split(',') for i in range(len(bits)): rngs = bits[i].split('-') if len(rngs) > 1: for j in range(int(rngs[0].strip()), int(rngs[1].strip()) + 1): if str(j) == self.base_year: self.yrndx = len(self.years) self.years.append(str(j)) else: if rngs[0].strip() == self.base_year: self.yrndx = len(self.years) self.years.append(rngs[0].strip()) if this_year not in self.years: self.years.append(this_year) except: if self.base_year != this_year: self.years = [self.base_year, this_year] else: self.years = self.base_year self.yrndx = 0 if self.yrndx < 0: self.yrndx = len(self.years) self.years.append(self.base_year) parents = [] try: parents = getParents(config.items('Parents')) except: pass self.grid_stations = '' try: fac_file = config.get('Files', 'grid_stations') for key, value in parents: fac_file = fac_file.replace(key, value) fac_file = fac_file.replace('$USER$', getUser()) fac_file = fac_file.replace('$YEAR$', self.base_year) self.grid_stations = fac_file except: pass self.load_file = '' try: fac_file = config.get('Files', 'load') for key, value in parents: fac_file = fac_file.replace(key, value) fac_file = fac_file.replace('$USER$', getUser()) fac_file = fac_file.replace('$YEAR$', self.base_year) self.load_file = fac_file except: pass my_config = configparser.RawConfigParser() my_config_file = 'getfiles.ini' my_config.read(my_config_file) try: aemo_facilities = my_config.get('updateswis', 'aemo_facilities') except: aemo_facilities = '/datafiles/facilities/facilities.csv' try: aemo_load = my_config.get('updateswis', 'aemo_load') except: aemo_load = '/datafiles/load-summary/load-summary-$YEAR$.csv' aemo_load = aemo_load.replace('$YEAR$', self.base_year) try: aemo_url = my_config.get('updateswis', 'aemo_url') except: aemo_url = 'data.wa.aemo.com.au' self.grid = QtWidgets.QGridLayout() self.grid.addWidget(QtWidgets.QLabel('Host site:'), 0, 0) self.host = QtWidgets.QLineEdit() self.host.setText(aemo_url) self.grid.addWidget(self.host, 0, 1, 1, 2) self.grid.addWidget(QtWidgets.QLabel('Existing Stations (Facilities)'), 1, 0, 1, 2) self.grid.addWidget(QtWidgets.QLabel('File location:'), 2, 0) self.url = QtWidgets.QLineEdit() self.url.setText(aemo_facilities) self.grid.addWidget(self.url, 2, 1, 1, 2) self.grid.addWidget(QtWidgets.QLabel('Target file:'), 3, 0) self.target = ClickableQLabel() self.target.setText(self.grid_stations) self.target.setStyleSheet( "background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;" ) self.target.clicked.connect(self.tgtChanged) self.grid.addWidget(self.target, 3, 1, 1, 4) self.grid.addWidget(QtWidgets.QLabel('Excel file:'), 4, 0) self.excel = ClickableQLabel() self.excel.setText('') self.excel.setStyleSheet( "background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;" ) self.excel.clicked.connect(self.excelChanged) self.grid.addWidget(self.excel, 4, 1, 1, 3) self.grid.addWidget(QtWidgets.QLabel('Keep deleted:'), 5, 0) self.keepbox = QtWidgets.QCheckBox() self.keepbox.setCheckState(QtCore.Qt.Checked) self.grid.addWidget(self.keepbox, 5, 1) self.grid.addWidget( QtWidgets.QLabel('If checked will retain deleted facilities'), 5, 2, 1, 3) self.grid.addWidget(QtWidgets.QLabel('System Load'), 6, 0) self.grid.addWidget(QtWidgets.QLabel('Year:'), 7, 0) self.yearCombo = QtWidgets.QComboBox() for i in range(len(self.years)): self.yearCombo.addItem(self.years[i]) self.yearCombo.setCurrentIndex(self.yrndx) self.yearCombo.currentIndexChanged[str].connect(self.yearChanged) self.grid.addWidget(self.yearCombo, 7, 1) self.grid.addWidget(QtWidgets.QLabel('Wrap to prior year:'), 8, 0) self.wrapbox = QtWidgets.QCheckBox() self.wrapbox.setCheckState(QtCore.Qt.Checked) self.grid.addWidget(self.wrapbox, 8, 1) self.grid.addWidget( QtWidgets.QLabel('If checked will wrap back to prior year'), 8, 2, 1, 3) self.grid.addWidget(QtWidgets.QLabel('Load file location:'), 9, 0) self.lurl = QtWidgets.QLineEdit() self.lurl.setText(aemo_load) self.grid.addWidget(self.lurl, 9, 1, 1, 3) self.grid.addWidget(QtWidgets.QLabel('Target load file:'), 10, 0) self.targetl = ClickableQLabel() self.targetl.setText(self.load_file) self.targetl.setStyleSheet( "background-color: white; border: 1px inset grey; min-height: 22px; border-radius: 4px;" ) self.targetl.clicked.connect(self.tgtlChanged) self.grid.addWidget(self.targetl, 10, 1, 1, 4) self.log = QtWidgets.QLabel(' ') self.grid.addWidget(self.log, 11, 1, 1, 3) quit = QtWidgets.QPushButton('Quit', self) wdth = quit.fontMetrics().boundingRect(quit.text()).width() + 29 self.grid.addWidget(quit, 12, 0) quit.clicked.connect(self.quitClicked) QtWidgets.QShortcut(QtGui.QKeySequence('q'), self, self.quitClicked) dofile = QtWidgets.QPushButton('Update Existing Stations', self) self.grid.addWidget(dofile, 12, 1) dofile.clicked.connect(self.dofileClicked) dofilel = QtWidgets.QPushButton('Update Load file', self) self.grid.addWidget(dofilel, 12, 2) dofilel.clicked.connect(self.dofilelClicked) help = QtWidgets.QPushButton('Help', self) help.setMaximumWidth(wdth) self.grid.addWidget(help, 12, 3) help.clicked.connect(self.helpClicked) QtWidgets.QShortcut(QtGui.QKeySequence('F1'), self, self.helpClicked) self.grid.setColumnStretch(3, 5) frame = QtWidgets.QFrame() frame.setLayout(self.grid) self.scroll = QtWidgets.QScrollArea() self.scroll.setWidgetResizable(True) self.scroll.setWidget(frame) self.layout = QtWidgets.QVBoxLayout(self) self.layout.addWidget(self.scroll) self.setWindowTitle('SIREN - updateswis (' + fileVersion() + ') - Update SWIS Data') self.setWindowIcon(QtGui.QIcon('sen_icon32.ico')) self.center() self.resize(int(self.sizeHint().width() * 1.07), int(self.sizeHint().height() * 1.07)) self.show() def center(self): frameGm = self.frameGeometry() screen = QtWidgets.QApplication.desktop().screenNumber( QtWidgets.QApplication.desktop().cursor().pos()) centerPoint = QtWidgets.QApplication.desktop().availableGeometry( screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) def tgtChanged(self): curtgt = self.target.text() newtgt = QtWidgets.QFileDialog.getSaveFileName(self, 'Choose Target file', curtgt)[0] if newtgt != '': self.target.setText(newtgt) def tgtlChanged(self): curtgt = self.targetl.text() newtgt = QtWidgets.QFileDialog.getSaveFileName( self, 'Choose Target Load file', curtgt)[0] if newtgt != '': self.targetl.setText(newtgt) def excelChanged(self): curtgt = self.excel.text() newtgt = QtWidgets.QFileDialog.getSaveFileName(self, 'Choose Excel File', curtgt)[0] if newtgt != '': self.excel.setText(newtgt) def yearChanged(self, val): year = self.yearCombo.currentText() if year != self.years[self.yrndx]: lurl = self.lurl.text() i = lurl.find(self.years[self.yrndx]) while i >= 0: lurl = lurl[:i] + year + lurl[i + len(self.years[self.yrndx]):] i = lurl.find(self.years[self.yrndx]) self.lurl.setText(lurl) targetl = self.targetl.text() i = targetl.find(self.years[self.yrndx]) while i >= 0: targetl = targetl[:i] + year + targetl[ i + len(self.years[self.yrndx]):] i = targetl.find(self.years[self.yrndx]) self.targetl.setText(targetl) self.yrndx = self.years.index(year) def helpClicked(self): dialog = displayobject.AnObject(QtWidgets.QDialog(), self.help, title='Help for updateswis (' + fileVersion() + ')', section='updateswis') dialog.exec_() def quitClicked(self): self.close() def dofileClicked(self): resource = makeFile(self.host.text(), self.url.text(), self.target.text(), self.excel.text(), self.keepbox.isChecked()) log = resource.getLog() self.log.setText(log) def dofilelClicked(self): if self.wrapbox.isChecked(): wrap = True else: wrap = False resource = makeLoadFile(self.host.text(), self.lurl.text(), self.targetl.text(), self.yearCombo.currentText(), wrap) log = resource.getLog() self.log.setText(log)