def generate_indicators(self): self.filepaths = {} for name, (projconfig, batchname, visname, datasourcename, year) in self.indicators.items(): op = OpusProject() op.open(os.path.join(PROJECTCONFIGBASE, projconfig)) bp = BatchProcessor(op) visualizationsconf = get_batch_configuration(project=op, batch_name=batchname, vis_name=visname) bp.set_data(visualizations=visualizationsconf, source_data_name=datasourcename, years=[year, year]) bp.run() visualizations = bp.get_visualizations() # visualizations in batch assert len(visualizations) == 1 vistype, visualizations = visualizations[0] # indicators in visualization assert len(visualizations) == 1 self.filepaths[name] = visualizations[0].get_file_path()
def generate_indicators(self): self.filepaths = {} for name, (projconfig, batchname, visname, datasourcename, year) in self.indicators.items(): op = OpusProject() op.open(os.path.join(PROJECTCONFIGBASE, projconfig)) bp = BatchProcessor(op) visualizationsconf = get_batch_configuration(project = op, batch_name = batchname, vis_name = visname) bp.set_data(visualizations = visualizationsconf, source_data_name = datasourcename, years = [year,year]) bp.run() visualizations = bp.get_visualizations() # visualizations in batch assert len(visualizations) == 1 vistype, visualizations = visualizations[0] # indicators in visualization assert len(visualizations) == 1 self.filepaths[name] = visualizations[0].get_file_path()
class SimulationGuiElement(QWidget, Ui_SimulationGuiElement): def __init__(self, mainwindow, runManager, model, xml_config): QWidget.__init__(self, mainwindow) self.mainwindow = mainwindow self.setupUi(self) self.runManager = runManager self.project = runManager.project self.model = model self.model.guiElement = self self.inGui = False self.logFileKey = 0 self.running = False self.paused = False self.timer = None self.runThread = None self.config = None self.xml_config = xml_config self.config = xml_config.get_run_configuration( str(self.model.modeltorun)) insert_auto_generated_cache_directory_if_needed(self.config) (self.start_year, self.end_year) = self.config['years'] self.tabIcon = QIcon(":/Images/Images/cog.png") self.tabLabel = model.modeltorun self.setup_run_name_line_edit() self.setup_indicator_batch_combobox() # Simulation Progress Tab self.runProgressBarTotal.setProperty("value", QVariant(0)) self.runProgressBarTotal.reset() ### Year Progress Bar self.runProgressBarYear.setProperty("value", QVariant(0)) self.runProgressBarYear.reset() ### Model Progress Bar self.runProgressBarModel.setProperty("value", QVariant(0)) self.runProgressBarModel.reset() self.setupDiagnosticIndicatorTab() self.gb_model_progress.hide() self.spatial_datasets = get_available_spatial_dataset_names( project=self.project) self.diagnostic_go_button.setEnabled(False) def updateConfigAndGuiForRun(self): config = self.xml_config.get_run_configuration( str(self.model.modeltorun)) self.config = config insert_auto_generated_cache_directory_if_needed(config) (self.start_year, self.end_year) = config['years'] #self.summaryYearRangeLabel.setText(QString("Running model from "+str(self.start_year)+" to "+str(self.end_year))) def on_cbYear_stateChanged(self, state): if self.cbYear.isChecked(): self.gb_year_progress.show() self.cbModel.setChecked(False) else: self.gb_year_progress.hide() self.gb_model_progress.hide() def on_cbModel_stateChanged(self, state): if self.cbModel.isChecked(): self.gb_model_progress.show() else: self.setUpdatesEnabled(False) self.gb_model_progress.hide() self.adjustSize() self.setUpdatesEnabled(True) def setupDiagnosticIndicatorTab(self): years = range(self.config["years"][0], self.config["years"][1] + 1) # yearItems is a list of [int, boolean] pairs, where the integer is a year # and the boolean is true if the year has already been added to the drop self.yearItems = [] for year in years: #the second value in the list determines if it is already added to the drop down self.yearItems.append([year, False]) datasets = get_available_dataset_names(self.project) for dataset in datasets: self.diagnostic_dataset_name.addItem(QString(dataset)) self.setup_diagnostic_indicators() self.indicatorResultsTab.removeTab(0) QObject.connect(self.diagnostic_go_button, SIGNAL("released()"), self.on_indicatorBox) QObject.connect(self.diagnostic_dataset_name, SIGNAL("currentIndexChanged(QString)"), self.on_diagnostic_dataset_name_currentIndexChanged) def setup_diagnostic_indicators(self): dataset = str(self.diagnostic_dataset_name.currentText()) indicator_variable_nodes = get_indicator_nodes_per_dataset( self.project) if dataset in indicator_variable_nodes: indicators = indicator_variable_nodes[dataset] else: indicators = [] # indicators = self.xml_helper.get_available_indicator_names(attributes = ['dataset']) self.diagnostic_indicator_name.clear() for indicator in indicators: self.diagnostic_indicator_name.addItem(indicator.tag) # if add_baseyear: # self.diagnostic_year.addItem(str(self.config['base_year'])) def on_diagnostic_dataset_name_currentIndexChanged(self, param): if isinstance(param, int): return #qt sends two signals for the same event; only process one self.setup_diagnostic_indicators() def setup_indicator_batch_combobox(self): self.cboOptionalIndicatorBatch.addItem(QString('(None)')) # Get available batches batch_nodes = get_available_batch_nodes(self.project) for batch_node in batch_nodes: self.cboOptionalIndicatorBatch.addItem(batch_node.get('name')) def setup_run_name_line_edit(self): run_name = 'run_%s' % strftime('%Y_%m_%d_%H_%M', localtime()) self.leRunName.setText(QString(run_name)) def on_indicatorBox(self): indicator_name = str(self.diagnostic_indicator_name.currentText()) dataset_name = self.diagnostic_dataset_name.currentText() indicator_type = str(self.diagnostic_indicator_type.currentText()) year = str(self.diagnostic_year.currentText()) if year == '': return year = int(year) if dataset_name not in self.spatial_datasets and indicator_type == 'map': MessageBox.warning( mainwindow=self.mainwindow, text="That indicator cannot be visualized as a map.", detailed_text=( 'The dataset %s is either not spatial or cannot be ' 'rendered as a grid. If the latter, please try ' 'exporting to an external GIS tool.' % dataset_name)) return cache_directory = self.model.config['cache_directory'] params = {'indicators': [indicator_name]} if indicator_type == 'table': indicator_type = 'tab' params['output_type'] = 'tab' # JLM > commented this out for when implemented animations # else: # indicator_type = 'mapnik_map' visualizations = [(indicator_type, str(dataset_name), params)] self.batch_processor = BatchProcessor(self.project) self.batch_processor.guiElement = self self.batch_processor.set_data(visualizations=visualizations, source_data_name=self.model.run_name, years=[year, year], cache_directory=cache_directory) self.diagnosticThread = OpusGuiThread( parentThread=self.mainwindow, parentGuiElement=self, thread_object=self.batch_processor) # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.diagnosticThread, SIGNAL("runFinished(PyQt_PyObject)"), self.visualizationsCreated) QObject.connect(self.diagnosticThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) self.diagnosticThread.start() def visualizationsCreated(self): all_visualizations = self.batch_processor.get_visualizations() for indicator_type, visualizations in all_visualizations: for visualization in visualizations: if indicator_type == 'mapnik_map': form = ViewImageForm(visualization=visualization) elif indicator_type == 'animated_map': form = ViewAnimationForm(visualization=visualization) else: form = ViewTableForm(visualization=visualization) self.indicatorResultsTab.insertTab(0, form, form.tabIcon, form.tabLabel) def removeElement(self): return self.on_pbnRemoveModel_released() def on_pbnRemoveModel_released(self): # if(self.running == True): success = True if self.runThread: success = self.runThread.cancel() if success: if self.timer: self.timer.stop() self.running = False self.paused = False return success def on_pbnStartModel_released(self): duplicate = False self.diagnostic_go_button.setEnabled(True) if self.running and not self.paused: # Take care of pausing a run success = self.runThread.pause() if success: self.paused = True self.timer.stop() self.pbnStartModel.setText(QString("Resume simulation run...")) elif self.running and self.paused: # Need to resume a paused run success = self.runThread.resume() if success: self.paused = False self.timer.start(1000) self.pbnStartModel.setText(QString("Pause simulation run...")) elif not self.running: run_name = str(self.leRunName.text()) if run_name == '': run_name = None else: run_id = None run_nodes = get_available_run_nodes(self.project) for run_node in run_nodes: existing_run_name = run_node.tag if run_name == existing_run_name: duplicate = True r = run_node.get('run_id') if r is not None: run_id = int(r) break if duplicate: dlg_dup = OverwriteRunDialog(self) if dlg_dup.exec_() == QDialog.Rejected: return delete_simulation_run( self.project, run_node.tag) # todo change to run_node.get('name') # Update the XML self.project.update_xml_config() self.updateConfigAndGuiForRun() # Fire up a new thread and run the model self.pbnStartModel.setText(QString("Pause simulation run...")) # References to the GUI elements for status for this run... self.progressBarTotal = self.runProgressBarTotal self.progressBarYear = self.runProgressBarYear self.progressBarModel = self.runProgressBarModel #self.pbnRemoveModel.setEnabled(False) #self.pbnStartModel.setEnabled(False) # Initializing values self.progressBarTotal.setValue(0) self.progressBarYear.setValue(0) self.progressBarModel.setValue(0) self.progressBarTotal.setRange(0, 0) self.progressBarYear.setRange(0, 0) self.progressBarModel.setRange(0, 0) batch_name = str(self.cboOptionalIndicatorBatch.currentText()) if batch_name == '(None)': batch_name = None self.runThread = RunModelThread(get_mainwindow_instance(), self, batch_name, run_name) if duplicate and run_id is not None: from opus_core.services.run_server.run_manager import RunManager as ServicesRunManager run_manager = ServicesRunManager( ServicesDatabaseConfiguration()) run_manager.delete_everything_for_this_run(run_id=run_id) run_manager.close() # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.runThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread) QObject.connect(self.runThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) # Use this timer to call a function in the thread to check status if the thread is unable # to produce its own signal above self.timer = QTimer() QObject.connect(self.timer, SIGNAL("timeout()"), self.runStatusFromThread) self.timer.start(1000) self.running = True self.paused = False self.runThread.start() else: print "Unexpected state in the model run..." # This is not used currently since the model can not return status... instead we use a timer to # check the status from a log file. def runPingFromThread(self, value): self.progressBar.setValue(value) #print "Ping from thread!" # Called when the model is finished... peg the percentage to 100% and stop the timer. def runFinishedFromThread(self, success): self.progressBarTotal.setValue(100) self.progressBarYear.setValue(100) self.progressBarModel.setValue(100) msg = 'Simulation ran successfully!' if success else 'Simulation failed.' self.summaryCurrentYearValue.setText(QString(msg)) self.summaryCurrentModelValue.setText(QString("Finished")) self.summaryCurrentPieceValue.setText(QString("Finished")) self.timer.stop() # Get the final logfile update after model finishes... self.logFileKey = self.runThread.modelguielement.model._get_current_log( self.logFileKey) self.running = False self.paused = False self.pbnStartModel.setText(QString("Start Simulation Run...")) #get the last year to show up in the diagnostics tab. self.yearItems[-1][1] = True self.diagnostic_year.addItem(QString(str(self.yearItems[-1][0]))) if self.runThread.batch_name is not None: all_visualizations = self.runThread.batch_processor.get_visualizations( ) for indicator_type, visualizations in all_visualizations: form_generator = None print indicator_type if indicator_type == 'mapnik_map' or \ indicator_type == 'matplotlib_chart': form_generator = self.mainwindow.managers[ 'results_manager'].addViewImageIndicator elif indicator_type == 'mapnik_animated_map': form_generator = self.mainwindow.managers[ 'results_manager'].addViewAnimationIndicator elif indicator_type == 'tab': form_generator = self.mainwindow.managers[ 'results_manager'].addViewTableIndicator if form_generator is not None: for visualization in visualizations: form_generator(visualization=visualization, indicator_type=indicator_type) # GUI elements that show progress go here. Note that they have to be set # up first in the constructor of this class, then optionally initialized in # on_pbnStartModel_released(), then calculated and updated here, and finally # when the simulation is done running, finalized values are optionally # defined in runFinishedFromThread (because status.txt doesn't refresh at # end of the simulation. def runStatusFromThread(self): totalProgress = 0 yearProgress = 0 modelProgress = 0 boxTitle = "Simulation run initializing..." # TODO: this is for the old prog bar if self.runThread.modelguielement.model.statusfile is None: boxTitle = "Simulation run initializing..." else: # Compute percent progress for the progress bar. # The statusfile is written by the _write_status_for_gui method # in class ModelSystem in urbansim.model_coordinators.model_system # The file is ascii, with the following format (1 item per line): # current year # total number of models # number of current model that is about to run (starting with 0) # name of current model # total number of pieces of current model (could be 1) # number of current piece # description of current piece (empty string if no description) statusfile = self.runThread.modelguielement.model.statusfile try: f = open(statusfile) lines = f.readlines() f.close() # use float for all numbers to help with percent computation if len(lines) > 0: current_year = float(lines[0]) total_models = float(lines[1]) current_model = float(lines[2]) current_model_names = lines[3] current_model_display_name = current_model_names #current_model_names[0] total_pieces = float(lines[4]) current_piece = float(lines[5]) current_piece_name = lines[6].strip() total_years = float(self.end_year - self.start_year + 1) # For each year, we need to run all of the models. # year_fraction_completed is the fraction completed (ignoring the currently running year) # model_fraction_completed is the additional fraction completed for the current year modelProgress = 100.0 * (current_piece / total_pieces) yearProgress = modelProgress / total_models + 100.0 * ( current_model / total_models) totalProgress = yearProgress / total_years + 100.0 * ( (current_year - self.start_year) / total_years) currentYearString = "(" + str( int((current_year - self.start_year)) + 1) + "/" + str( int(total_years)) + ") " + str(int(current_year)) self.summaryCurrentYearValue.setText( QString(currentYearString)) currentModelString = "(" + str( int(current_model) + 1) + "/" + str(int( total_models)) + ") " + current_model_display_name self.summaryCurrentModelValue.setText( QString(currentModelString)) currentPieceString = "(" + str( int(current_piece) + 1) + "/" + str( int(total_pieces)) + ") " + current_piece_name self.summaryCurrentPieceValue.setText( QString(currentPieceString)) boxTitle = current_model_display_name # detect if a year has been completed for item in self.yearItems: if item[0] < current_year and not item[1]: self.diagnostic_year.addItem(QString(str(item[0]))) item[1] = True #hook into indicator group computation here if (self.progressBarTotal.maximum() == 0): self.progressBarTotal.setRange(0, 100) self.progressBarYear.setRange(0, 100) self.progressBarModel.setRange(0, 100) except IOError: boxTitle = "Simulation run is initializing..." newString = QString(boxTitle) newString.leftJustified(60) # self.simprogressGroupBox.setTitle(newString) self.progressBarTotal.setValue(totalProgress) self.progressBarYear.setValue(yearProgress) self.progressBarModel.setValue(modelProgress) self.logFileKey = self.runThread.modelguielement.model._get_current_log( self.logFileKey) def runErrorFromThread(self, errorMessage): self.running = False self.paused = False self.pbnStartModel.setText(QString("Start Simulation Run...")) MessageBox.warning(mainwindow=self.mainwindow, text="There was a problem running the simulation.", detailed_text=errorMessage)
class SimulationGuiElement(QWidget, Ui_SimulationGuiElement): def __init__(self, mainwindow, runManager, model, xml_config): QWidget.__init__(self, mainwindow) self.mainwindow = mainwindow self.setupUi(self) self.runManager = runManager self.project = runManager.project self.model = model self.model.guiElement = self self.inGui = False self.logFileKey = 0 self.running = False self.paused = False self.timer = None self.runThread = None self.config = None self.xml_config = xml_config self.config = xml_config.get_run_configuration(str(self.model.modeltorun)) insert_auto_generated_cache_directory_if_needed(self.config) (self.start_year, self.end_year) = self.config['years'] self.tabIcon = QIcon(":/Images/Images/cog.png") self.tabLabel = model.modeltorun self.setup_run_name_line_edit() self.setup_indicator_batch_combobox() # Simulation Progress Tab self.runProgressBarTotal.setProperty("value",QVariant(0)) self.runProgressBarTotal.reset() ### Year Progress Bar self.runProgressBarYear.setProperty("value",QVariant(0)) self.runProgressBarYear.reset() ### Model Progress Bar self.runProgressBarModel.setProperty("value",QVariant(0)) self.runProgressBarModel.reset() self.setupDiagnosticIndicatorTab() self.gb_model_progress.hide() self.spatial_datasets = get_available_spatial_dataset_names(project = self.project) self.diagnostic_go_button.setEnabled(False) def updateConfigAndGuiForRun(self): config = self.xml_config.get_run_configuration(str(self.model.modeltorun)) self.config = config insert_auto_generated_cache_directory_if_needed(config) (self.start_year, self.end_year) = config['years'] #self.summaryYearRangeLabel.setText(QString("Running model from "+str(self.start_year)+" to "+str(self.end_year))) def on_cbYear_stateChanged(self, state): if self.cbYear.isChecked(): self.gb_year_progress.show() self.cbModel.setChecked(False) else: self.gb_year_progress.hide() self.gb_model_progress.hide() def on_cbModel_stateChanged(self, state): if self.cbModel.isChecked(): self.gb_model_progress.show() else: self.setUpdatesEnabled(False) self.gb_model_progress.hide() self.adjustSize() self.setUpdatesEnabled(True) def setupDiagnosticIndicatorTab(self): years = range(self.config["years"][0], self.config["years"][1]+1) # yearItems is a list of [int, boolean] pairs, where the integer is a year # and the boolean is true if the year has already been added to the drop self.yearItems = [] for year in years: #the second value in the list determines if it is already added to the drop down self.yearItems.append([year, False]); datasets = get_available_dataset_names(self.project) for dataset in datasets: self.diagnostic_dataset_name.addItem(QString(dataset)) self.setup_diagnostic_indicators() self.indicatorResultsTab.removeTab(0) QObject.connect(self.diagnostic_go_button,SIGNAL("released()"),self.on_indicatorBox) QObject.connect(self.diagnostic_dataset_name, SIGNAL("currentIndexChanged(QString)"), self.on_diagnostic_dataset_name_currentIndexChanged) def setup_diagnostic_indicators(self): dataset = str(self.diagnostic_dataset_name.currentText()) indicator_variable_nodes = get_indicator_nodes_per_dataset(self.project) if dataset in indicator_variable_nodes: indicators = indicator_variable_nodes[dataset] else: indicators = [] # indicators = self.xml_helper.get_available_indicator_names(attributes = ['dataset']) self.diagnostic_indicator_name.clear() for indicator in indicators: self.diagnostic_indicator_name.addItem(indicator.tag) # if add_baseyear: # self.diagnostic_year.addItem(str(self.config['base_year'])) def on_diagnostic_dataset_name_currentIndexChanged(self, param): if isinstance(param, int): return #qt sends two signals for the same event; only process one self.setup_diagnostic_indicators() def setup_indicator_batch_combobox(self): self.cboOptionalIndicatorBatch.addItem(QString('(None)')) # Get available batches batch_nodes = get_available_batch_nodes(self.project) for batch_node in batch_nodes: self.cboOptionalIndicatorBatch.addItem(batch_node.get('name')) def setup_run_name_line_edit(self): run_name = 'run_%s'%strftime('%Y_%m_%d_%H_%M', localtime()) self.leRunName.setText(QString(run_name)) def on_indicatorBox(self): indicator_name = str(self.diagnostic_indicator_name.currentText()) dataset_name = self.diagnostic_dataset_name.currentText() indicator_type = str(self.diagnostic_indicator_type.currentText()) year = str(self.diagnostic_year.currentText()) if year=='': return year = int(year) if dataset_name not in self.spatial_datasets and indicator_type == 'map': MessageBox.warning(mainwindow = self.mainwindow, text = "That indicator cannot be visualized as a map.", detailed_text = ('The dataset %s is either not spatial or cannot be ' 'rendered as a grid. If the latter, please try ' 'exporting to an external GIS tool.'%dataset_name)) return cache_directory = self.model.config['cache_directory'] params = {'indicators':[indicator_name]} if indicator_type == 'table': indicator_type = 'tab' params['output_type'] = 'tab' # JLM > commented this out for when implemented animations # else: # indicator_type = 'mapnik_map' visualizations = [ (indicator_type, str(dataset_name), params) ] self.batch_processor = BatchProcessor(self.project) self.batch_processor.guiElement = self self.batch_processor.set_data( visualizations = visualizations, source_data_name = self.model.run_name, years = [year, year], cache_directory = cache_directory) self.diagnosticThread = OpusGuiThread( parentThread = self.mainwindow, parentGuiElement = self, thread_object = self.batch_processor) # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.diagnosticThread, SIGNAL("runFinished(PyQt_PyObject)"), self.visualizationsCreated) QObject.connect(self.diagnosticThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) self.diagnosticThread.start() def visualizationsCreated(self): all_visualizations = self.batch_processor.get_visualizations() for indicator_type, visualizations in all_visualizations: for visualization in visualizations: if indicator_type == 'mapnik_map': form = ViewImageForm(visualization = visualization) elif indicator_type == 'animated_map': form = ViewAnimationForm(visualization = visualization) else: form = ViewTableForm(visualization = visualization) self.indicatorResultsTab.insertTab(0,form,form.tabIcon,form.tabLabel) def removeElement(self): return self.on_pbnRemoveModel_released() def on_pbnRemoveModel_released(self): # if(self.running == True): success = True if self.runThread: success = self.runThread.cancel() if success: if self.timer: self.timer.stop() self.running = False self.paused = False return success def on_pbnStartModel_released(self): duplicate = False self.diagnostic_go_button.setEnabled(True) if self.running and not self.paused: # Take care of pausing a run success = self.runThread.pause() if success: self.paused = True self.timer.stop() self.pbnStartModel.setText(QString("Resume simulation run...")) elif self.running and self.paused: # Need to resume a paused run success = self.runThread.resume() if success: self.paused = False self.timer.start(1000) self.pbnStartModel.setText(QString("Pause simulation run...")) elif not self.running: run_name = str(self.leRunName.text()) if run_name == '': run_name = None else: run_id = None run_nodes = get_available_run_nodes(self.project) for run_node in run_nodes: existing_run_name = run_node.tag if run_name == existing_run_name: duplicate = True r = run_node.get('run_id') if r is not None: run_id = int(r) break if duplicate: dlg_dup = OverwriteRunDialog(self) if dlg_dup.exec_() == QDialog.Rejected: return delete_simulation_run(self.project, run_node.tag) # todo change to run_node.get('name') # Update the XML self.project.update_xml_config() self.updateConfigAndGuiForRun() # Fire up a new thread and run the model self.pbnStartModel.setText(QString("Pause simulation run...")) # References to the GUI elements for status for this run... self.progressBarTotal = self.runProgressBarTotal self.progressBarYear = self.runProgressBarYear self.progressBarModel = self.runProgressBarModel #self.pbnRemoveModel.setEnabled(False) #self.pbnStartModel.setEnabled(False) # Initializing values self.progressBarTotal.setValue(0) self.progressBarYear.setValue(0) self.progressBarModel.setValue(0) self.progressBarTotal.setRange(0,0) self.progressBarYear.setRange(0,0) self.progressBarModel.setRange(0,0) batch_name = str(self.cboOptionalIndicatorBatch.currentText()) if batch_name == '(None)': batch_name = None self.runThread = RunModelThread(get_mainwindow_instance(), self, batch_name, run_name) if duplicate and run_id is not None: from opus_core.services.run_server.run_manager import RunManager as ServicesRunManager run_manager = ServicesRunManager(ServicesDatabaseConfiguration()) run_manager.delete_everything_for_this_run(run_id = run_id) run_manager.close() # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.runThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread) QObject.connect(self.runThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) # Use this timer to call a function in the thread to check status if the thread is unable # to produce its own signal above self.timer = QTimer() QObject.connect(self.timer, SIGNAL("timeout()"), self.runStatusFromThread) self.timer.start(1000) self.running = True self.paused = False self.runThread.start() else: print "Unexpected state in the model run..." # This is not used currently since the model can not return status... instead we use a timer to # check the status from a log file. def runPingFromThread(self,value): self.progressBar.setValue(value) #print "Ping from thread!" # Called when the model is finished... peg the percentage to 100% and stop the timer. def runFinishedFromThread(self,success): self.progressBarTotal.setValue(100) self.progressBarYear.setValue(100) self.progressBarModel.setValue(100) msg = 'Simulation ran successfully!' if success else 'Simulation failed.' self.summaryCurrentYearValue.setText(QString(msg)) self.summaryCurrentModelValue.setText(QString("Finished")) self.summaryCurrentPieceValue.setText(QString("Finished")) self.timer.stop() # Get the final logfile update after model finishes... self.logFileKey = self.runThread.modelguielement.model._get_current_log(self.logFileKey) self.running = False self.paused = False self.pbnStartModel.setText(QString("Start Simulation Run...")) #get the last year to show up in the diagnostics tab. self.yearItems[-1][1] = True self.diagnostic_year.addItem(QString(str(self.yearItems[-1][0]))) if self.runThread.batch_name is not None: all_visualizations = self.runThread.batch_processor.get_visualizations() for indicator_type, visualizations in all_visualizations: form_generator = None print indicator_type if indicator_type == 'mapnik_map' or \ indicator_type == 'matplotlib_chart': form_generator = self.mainwindow.managers['results_manager'].addViewImageIndicator elif indicator_type == 'mapnik_animated_map': form_generator = self.mainwindow.managers['results_manager'].addViewAnimationIndicator elif indicator_type == 'tab': form_generator = self.mainwindow.managers['results_manager'].addViewTableIndicator if form_generator is not None: for visualization in visualizations: form_generator(visualization = visualization, indicator_type = indicator_type) # GUI elements that show progress go here. Note that they have to be set # up first in the constructor of this class, then optionally initialized in # on_pbnStartModel_released(), then calculated and updated here, and finally # when the simulation is done running, finalized values are optionally # defined in runFinishedFromThread (because status.txt doesn't refresh at # end of the simulation. def runStatusFromThread(self): totalProgress = 0 yearProgress = 0 modelProgress = 0 boxTitle = "Simulation run initializing..." # TODO: this is for the old prog bar if self.runThread.modelguielement.model.statusfile is None: boxTitle = "Simulation run initializing..." else: # Compute percent progress for the progress bar. # The statusfile is written by the _write_status_for_gui method # in class ModelSystem in urbansim.model_coordinators.model_system # The file is ascii, with the following format (1 item per line): # current year # total number of models # number of current model that is about to run (starting with 0) # name of current model # total number of pieces of current model (could be 1) # number of current piece # description of current piece (empty string if no description) statusfile = self.runThread.modelguielement.model.statusfile try: f = open(statusfile) lines = f.readlines() f.close() # use float for all numbers to help with percent computation if len(lines) > 0: current_year = float(lines[0]) total_models = float(lines[1]) current_model = float(lines[2]) current_model_names = lines[3] current_model_display_name = current_model_names#current_model_names[0] total_pieces = float(lines[4]) current_piece = float(lines[5]) current_piece_name = lines[6].strip() total_years = float(self.end_year - self.start_year + 1) # For each year, we need to run all of the models. # year_fraction_completed is the fraction completed (ignoring the currently running year) # model_fraction_completed is the additional fraction completed for the current year modelProgress = 100.0 * (current_piece / total_pieces) yearProgress = modelProgress / total_models + 100.0 * (current_model / total_models) totalProgress = yearProgress / total_years + 100.0 * ((current_year - self.start_year) / total_years) currentYearString = "("+str(int((current_year - self.start_year))+1)+"/"+str(int(total_years))+") "+str(int(current_year)) self.summaryCurrentYearValue.setText(QString(currentYearString)) currentModelString = "("+str(int(current_model)+1)+"/"+str(int(total_models))+") "+current_model_display_name self.summaryCurrentModelValue.setText(QString(currentModelString)) currentPieceString = "("+str(int(current_piece)+1)+"/"+str(int(total_pieces))+") "+current_piece_name self.summaryCurrentPieceValue.setText(QString(currentPieceString)) boxTitle = current_model_display_name # detect if a year has been completed for item in self.yearItems: if item[0] < current_year and not item[1] : self.diagnostic_year.addItem(QString(str(item[0]))) item[1] = True #hook into indicator group computation here if (self.progressBarTotal.maximum() == 0): self.progressBarTotal.setRange(0,100) self.progressBarYear.setRange(0,100) self.progressBarModel.setRange(0,100) except IOError: boxTitle = "Simulation run is initializing..." newString = QString(boxTitle) newString.leftJustified(60) # self.simprogressGroupBox.setTitle(newString) self.progressBarTotal.setValue(totalProgress) self.progressBarYear.setValue(yearProgress) self.progressBarModel.setValue(modelProgress) self.logFileKey = self.runThread.modelguielement.model._get_current_log(self.logFileKey) def runErrorFromThread(self,errorMessage): self.running = False self.paused = False self.pbnStartModel.setText(QString("Start Simulation Run...")) MessageBox.warning(mainwindow = self.mainwindow, text = "There was a problem running the simulation.", detailed_text = errorMessage)
class IndicatorBatchRunForm(QDialog, Ui_runIndicatorBatch): def __init__(self, mainwindow, resultsManagerBase, batch_name = None, run_name = None): QDialog.__init__(self, mainwindow) self.setupUi(self) #mainwindow is an OpusGui self.mainwindow = mainwindow self.resultsManagerBase = resultsManagerBase self.project = resultsManagerBase.project self.available_years_for_simulation_runs = {} self.batch_processor = BatchProcessor(project = self.project) self.batch_processor.guiElement = self self.run_name = run_name self.batch_name = batch_name self._setup_co__years() def _setup_co__years(self): runs = get_simulation_runs(self.project) for run in runs: if run.get('name') == self.run_name: years = get_years_for_simulation_run(project = self.project, simulation_run_node = run) (start,end) = (min(years), max(years)) for i in range(start, end + 1): if i not in years: continue yr = QString(repr(i)) self.co_start_year.addItem(yr) self.co_end_year.addItem(yr) for i in range(1, end - start + 2): yr = QString(repr(i)) self.co_every_year.addItem(yr) def removeElement(self): return True def on_buttonBox_accepted(self): self.buttonBox.setEnabled(False) start_year = int(self.co_start_year.currentText()) end_year = int(self.co_end_year.currentText()) increment = int(self.co_every_year.currentText()) years = range(start_year, end_year + 1, increment) # (visualization_type, dataset_name, vals) visualizations = get_batch_configuration(project = self.project, batch_name = self.batch_name) self.batch_processor.set_data( visualizations = visualizations, source_data_name = self.run_name, years = years) self.runThread = OpusGuiThread( parentThread = self.mainwindow, parentGuiElement = self, thread_object = self.batch_processor) # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.runThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread) QObject.connect(self.runThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) self.runThread.start() # Called when the model is finished... def runFinishedFromThread(self,success): all_visualizations = self.batch_processor.get_visualizations() for indicator_type, visualizations in all_visualizations: if indicator_type == 'mapnik_map' or \ indicator_type == 'matplotlib_chart': form_generator = self.resultsManagerBase.addViewImageIndicator elif indicator_type == 'mapnik_animated_map': form_generator = self.resultsManagerBase.addViewAnimationIndicator elif indicator_type == 'tab': form_generator = self.resultsManagerBase.addViewTableIndicator if form_generator is not None: for visualization in visualizations: form_generator(visualization = visualization, indicator_type = indicator_type) # Get the final logfile update after model finishes... # self.logFileKey = self.batch_processor._get_current_log(self.logFileKey) self.buttonBox.setEnabled(True) self.close() def runErrorFromThread(self,errorMessage): MessageBox.warning(mainwindow = self.mainwindow, text = "There was a problem running the batch.", detailed_text = errorMessage)
class IndicatorBatchRunForm(QDialog, Ui_runIndicatorBatch): def __init__(self, mainwindow, resultsManagerBase, batch_name = None, run_name = None): QDialog.__init__(self, mainwindow) self.setupUi(self) #mainwindow is an OpusGui self.mainwindow = mainwindow self.resultsManagerBase = resultsManagerBase self.project = resultsManagerBase.project self.available_years_for_simulation_runs = {} self.batch_processor = BatchProcessor(project = self.project) self.batch_processor.guiElement = self self.run_name = run_name self.batch_name = batch_name self._setup_co__years() def _setup_co__years(self): years = get_years_for_simulation_run(self.project, run_name=self.run_name) start,end = min(years), max(years) for i in range(start, end + 1): if i not in years: continue yr = QString(repr(i)) self.co_start_year.addItem(yr) self.co_end_year.addItem(yr) for i in range(1, end - start + 2): yr = QString(repr(i)) self.co_every_year.addItem(yr) def removeElement(self): return True def on_buttonBox_accepted(self): self.buttonBox.setEnabled(False) start_year = int(self.co_start_year.currentText()) end_year = int(self.co_end_year.currentText()) increment = int(self.co_every_year.currentText()) years = range(start_year, end_year + 1, increment) # (visualization_type, dataset_name, vals) visualizations = get_batch_configuration(project = self.project, batch_name = self.batch_name) self.batch_processor.set_data( visualizations = visualizations, source_data_name = self.run_name, years = years) self.runThread = OpusGuiThread( parentThread = self.mainwindow, parentGuiElement = self, thread_object = self.batch_processor) # Use this signal from the thread if it is capable of producing its own status signal QObject.connect(self.runThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread) QObject.connect(self.runThread, SIGNAL("runError(PyQt_PyObject)"), self.runErrorFromThread) self.runThread.start() # Called when the model is finished... def runFinishedFromThread(self,success): all_visualizations = self.batch_processor.get_visualizations() for indicator_type, visualizations in all_visualizations: if indicator_type == 'mapnik_map' or \ indicator_type == 'matplotlib_chart': form_generator = self.resultsManagerBase.addViewImageIndicator elif indicator_type == 'mapnik_animated_map': form_generator = self.resultsManagerBase.addViewAnimationIndicator elif indicator_type == 'tab': form_generator = self.resultsManagerBase.addViewTableIndicator if form_generator is not None: for visualization in visualizations: form_generator(visualization = visualization, indicator_type = indicator_type) # Get the final logfile update after model finishes... # self.logFileKey = self.batch_processor._get_current_log(self.logFileKey) self.buttonBox.setEnabled(True) self.close() def runErrorFromThread(self,errorMessage): MessageBox.warning(mainwindow = self.mainwindow, text = "There was a problem running the batch.", detailed_text = errorMessage)