def run(path, config, scenario_ids, load_demand=False, solve_demand=True, load_supply=False, solve_supply=True, load_error=False, export_results=True, pickle_shapes=True, save_models=True, log_name=None, api_run=False, clear_results=False): global model cfg.initialize_config(path, config, log_name) cfg.geo.log_geo() shape.init_shapes(pickle_shapes) if not scenario_ids: scenario_ids = [os.path.basename(p) for p in glob.glob(os.path.join(cfg.workingdir, '*.json'))] if not scenario_ids: raise ValueError, "No scenarios specified and no .json files found in working directory." # Users may have specified a scenario using the full filename, but for our purposes the 'id' of the scenario # is just the part before the .json scenario_ids = [os.path.splitext(s)[0] for s in scenario_ids] logging.info('Scenario run list: {}'.format(', '.join(scenario_ids))) for scenario_id in scenario_ids: scenario_start_time = time.time() logging.info('Starting scenario {}'.format(scenario_id)) logging.info('Start time {}'.format(str(datetime.datetime.now()).split('.')[0])) if api_run: # FIXME: This will be broken since we changed the scenario list from a list of database ids to a list of # filenames. The API-related code will need to be updated before we can update the server with newer # model code. util.update_status(scenario_id, 3) scenario_name = util.scenario_name(scenario_id) subject = 'Now running: EnergyPathways scenario "%s"' % (scenario_name,) body = 'EnergyPathways is now running your scenario titled "%s". A scenario run generally ' \ 'finishes within a few hours, and you will receive another email when your run is complete. ' \ 'If more than 24 hours pass without you receiving a confirmation email, please log in to ' \ 'https://energypathways.com to check the status of the run. ' \ 'If the run is not complete, please reply to this email and we will investigate.' % (scenario_name,) send_gmail(scenario_id, subject, body) model = load_model(load_demand, load_supply, load_error, scenario_id, api_run) if not load_error: model.run(scenario_id, solve_demand=solve_demand, solve_supply=solve_supply, load_demand=load_demand, load_supply=load_supply, export_results=export_results, save_models=save_models, append_results=False if (scenario_id == scenario_ids[0] and clear_results) else True) if api_run: util.update_status(scenario_id, 4) subject = 'Completed: EnergyPathways scenario "%s"' % (scenario_name,) body = 'EnergyPathways has completed running your scenario titled "%s". ' \ 'Please return to https://energypathways.com to view your results.' % (scenario_name,) send_gmail(scenario_id, subject, body) logging.info('EnergyPATHWAYS run for scenario_id {} successful!'.format(scenario_id)) logging.info('Scenario calculation time {}'.format(str(datetime.timedelta(seconds=time.time() - scenario_start_time)).split('.')[0])) logging.info('Total calculation time {}'.format(str(datetime.timedelta(seconds=time.time() - run_start_time)).split('.')[0])) logging.shutdown() logging.getLogger(None).handlers = [] # necessary to totally flush the logger
def update_api_run_status(status_id): logging.debug("Updating scenario run status in database.") try: global model if model and model.api_run: util.update_status(model.scenario_id, status_id) # This is one of the few times I think a broad except clause is justified; if we've failed to update the run # status in the database at this point we don't really care why, and we don't want it to prevent any other # cleanup code from running. We'll just log it for future troubleshooting. except Exception: logging.exception("Exception caught attempting to write abnormal termination status %i to database." % (status_id,)) logging.debug("Finished updating scenario run status in database.")
def update_api_run_status(status_id): logging.debug("Updating scenario run status in database.") try: global model if model and model.api_run: util.update_status(model.scenario_id, status_id) # This is one of the few times I think a broad except clause is justified; if we've failed to update the run # status in the database at this point we don't really care why, and we don't want it to prevent any other # cleanup code from running. We'll just log it for future troubleshooting. except Exception: logging.exception( "Exception caught attempting to write abnormal termination status %i to database." % (status_id, )) logging.debug("Finished updating scenario run status in database.")
def run(path, config, scenario, load_demand=False, solve_demand=True, load_supply=False, solve_supply=True, load_error=False, export_results=True, pickle_shapes=True, save_models=True, log_name=None, api_run=False, clear_results=False): global model cfg.initialize_config(path, config, log_name) cfg.geo.log_geo() shape.init_shapes(pickle_shapes) scenario_ids = parse_scenario_ids(scenario) logging.info('Scenario_ids run list = {}'.format(scenario_ids)) for scenario_id in scenario_ids: scenario_start_time = time.time() logging.info('Starting scenario_id {}'.format(scenario_id)) if api_run: util.update_status(scenario_id, 3) scenario_name = util.scenario_name(scenario_id) subject = 'Now running: EnergyPathways scenario "%s"' % ( scenario_name, ) body = 'EnergyPathways is now running your scenario titled "%s". A scenario run generally ' \ 'finishes within a few hours, and you will receive another email when your run is complete. ' \ 'If more than 24 hours pass without you receiving a confirmation email, please log in to ' \ 'https://energypathways.com to check the status of the run. ' \ 'If the run is not complete, please reply to this email and we will investigate.' % (scenario_name,) send_gmail(scenario_id, subject, body) model = load_model(load_demand, load_supply, load_error, scenario_id, api_run) if not load_error: model.run( scenario_id, solve_demand=solve_demand, solve_supply=solve_supply, load_demand=load_demand, load_supply=load_supply, export_results=export_results, save_models=save_models, append_results=False if (scenario_id == scenario_ids[0] and clear_results) else True) if api_run: util.update_status(scenario_id, 4) subject = 'Completed: EnergyPathways scenario "%s"' % ( scenario_name, ) body = 'EnergyPathways has completed running your scenario titled "%s". ' \ 'Please return to https://energypathways.com to view your results.' % (scenario_name,) send_gmail(scenario_id, subject, body) logging.info( 'EnergyPATHWAYS run for scenario_id {} successful!'.format( scenario_id)) logging.info( 'Scenario calculation time {} seconds'.format(time.time() - scenario_start_time)) logging.info('Total calculation time {} seconds'.format(time.time() - run_start_time)) logging.shutdown() logging.getLogger(None).handlers = [ ] # necessary to totally flush the logger
def run(path, config, scenario_ids, load_demand=False, solve_demand=True, load_supply=False, solve_supply=True, load_error=False, export_results=True, pickle_shapes=True, save_models=True, log_name=None, api_run=False, clear_results=False): global model cfg.initialize_config(path, config, log_name) cfg.geo.log_geo() shape.init_shapes(pickle_shapes) if not scenario_ids: scenario_ids = [ os.path.basename(p) for p in glob.glob(os.path.join(cfg.workingdir, '*.json')) ] if not scenario_ids: raise ValueError, "No scenarios specified and no .json files found in working directory." # Users may have specified a scenario using the full filename, but for our purposes the 'id' of the scenario # is just the part before the .json scenario_ids = [os.path.splitext(s)[0] for s in scenario_ids] logging.info('Scenario run list: {}'.format(', '.join(scenario_ids))) for scenario_id in scenario_ids: scenario_start_time = time.time() logging.info('Starting scenario {}'.format(scenario_id)) logging.info('Start time {}'.format( str(datetime.datetime.now()).split('.')[0])) if api_run: # FIXME: This will be broken since we changed the scenario list from a list of database ids to a list of # filenames. The API-related code will need to be updated before we can update the server with newer # model code. util.update_status(scenario_id, 3) scenario_name = util.scenario_name(scenario_id) subject = 'Now running: EnergyPathways scenario "%s"' % ( scenario_name, ) body = 'EnergyPathways is now running your scenario titled "%s". A scenario run generally ' \ 'finishes within a few hours, and you will receive another email when your run is complete. ' \ 'If more than 24 hours pass without you receiving a confirmation email, please log in to ' \ 'https://energypathways.com to check the status of the run. ' \ 'If the run is not complete, please reply to this email and we will investigate.' % (scenario_name,) send_gmail(scenario_id, subject, body) model = load_model(load_demand, load_supply, load_error, scenario_id, api_run) if not load_error: model.run( scenario_id, solve_demand=solve_demand, solve_supply=solve_supply, load_demand=load_demand, load_supply=load_supply, export_results=export_results, save_models=save_models, append_results=False if (scenario_id == scenario_ids[0] and clear_results) else True) if api_run: util.update_status(scenario_id, 4) subject = 'Completed: EnergyPathways scenario "%s"' % ( scenario_name, ) body = 'EnergyPathways has completed running your scenario titled "%s". ' \ 'Please return to https://energypathways.com to view your results.' % (scenario_name,) send_gmail(scenario_id, subject, body) logging.info( 'EnergyPATHWAYS run for scenario_id {} successful!'.format( scenario_id)) logging.info('Scenario calculation time {}'.format( str(datetime.timedelta(seconds=time.time() - scenario_start_time)).split('.')[0])) logging.info('Total calculation time {}'.format( str(datetime.timedelta(seconds=time.time() - run_start_time)).split('.')[0])) logging.shutdown() logging.getLogger(None).handlers = [ ] # necessary to totally flush the logger