def phase4(spread_coeff, z, excld, delta, slope, slope_weights, og): TimerUtility.start_timer('spr_phase4') nrows = IGrid.nrows ncols = IGrid.ncols neighbor_options = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)] # Loop over the interior pixels looking for urban from which to perform organic growth for row in range(1, nrows - 1): for col in range(1, ncols - 1): offset = row * ncols + col # Is this an urban pixel and do we pass the random spread coefficient test? if z[offset] > 0 and Random.get_int(0, 100) < spread_coeff: # Examine the eight cell neighbors # Spread at random if at least 2 are urban # Pixel itself must be urban (3) urb_count = Spread.count_neighbor(z, row, col) if 2 <= urb_count < 8: x_neigh, y_neigh = Random.get_element(neighbor_options) row_neighbor = row + x_neigh col_neighbor = col + y_neigh success, og = Spread.urbanize(row_neighbor, col_neighbor, z, delta, slope, excld, slope_weights, UGMDefines.PHASE4G, og) TimerUtility.stop_timer('spr_phase4') return og
def phase1n3(diffusion_coeff, breed_coeff, z, delta, slope, excld, slope_weights, sng, sdc): TimerUtility.start_timer("spr_phase1n3") diffusion_value = Spread.calculate_diffusion_value(diffusion_coeff) nrows = IGrid.nrows ncols = IGrid.ncols for k in range(1 + int(diffusion_value)): # get a random row and col index i = Random.get_int(0, nrows - 1) j = Random.get_int(0, ncols - 1) # check if it is an interior point if 0 < i < nrows - 1 and 0 < j < ncols - 1: success, sng = Spread.urbanize(i, j, z, delta, slope, excld, slope_weights, UGMDefines.PHASE1G, sng) if success and Random.get_int(0, 100) < breed_coeff: count = 0 max_tries = 8 for tries in range(max_tries): urbanized, sdc, i_neigh, j_neigh = Spread.urbanize_neighbor( i, j, z, delta, slope, excld, slope_weights, UGMDefines.PHASE3G, sdc) if urbanized: count += 1 if count == UGMDefines.MIN_NGHBR_TO_SPREAD: break TimerUtility.stop_timer('spr_phase1n3') return sng, sdc
def monte_carlo(cumulate, land1): log_it = Scenario.get_scen_value("logging") z = PGrid.get_z() total_pixels = IGrid.get_total_pixels() num_monte_carlo = int( Scenario.get_scen_value("monte_carlo_iterations")) for imc in range(num_monte_carlo): Processing.set_current_monte(imc) '''print("--------Saved-------") print(Coeff.get_saved_diffusion()) print(Coeff.get_saved_spread()) print(Coeff.get_saved_breed()) print(Coeff.get_saved_slope_resistance()) print(Coeff.get_saved_road_gravity()) print("--------------------")''' # Reset the Parameters Coeff.set_current_diffusion(Coeff.get_saved_diffusion()) Coeff.set_current_spread(Coeff.get_saved_spread()) Coeff.set_current_breed(Coeff.get_saved_breed()) Coeff.set_current_slope_resistance( Coeff.get_saved_slope_resistance()) Coeff.set_current_road_gravity(Coeff.get_saved_road_gravity()) if log_it and Scenario.get_scen_value("log_initial_coefficients"): Coeff.log_current() # Run Simulation Stats.init_urbanization_attempts() TimerUtility.start_timer('grw_growth') Grow.grow(z, land1) TimerUtility.stop_timer('grw_growth') if log_it and Scenario.get_scen_value("log_urbanization_attempts"): Stats.log_urbanization_attempts() # Update Cumulate Grid for i in range(total_pixels): if z.gridData[i] > 0: cumulate.gridData[i] += 1 # Update Annual Land Class Probabilities if Processing.get_processing_type( ) == Globals.mode_enum["predict"]: LandClass.update_annual_prob(land1.gridData, total_pixels) # Normalize Cumulative Urban Image for i in range(total_pixels): cumulate.gridData[i] = (100 * cumulate.gridData[i]) / num_monte_carlo
def deltatron(new_indices, landuse_classes, class_indices, deltatron, urban_land, land_out, slope, drive, class_slope, ftransition): TimerUtility.start_timer('delta_deltatron') phase1_land = Deltatron.phase1(drive, urban_land.gridData, slope.gridData, deltatron.gridData, landuse_classes, class_indices, new_indices, class_slope, ftransition) phase2_land = Deltatron.phase2(urban_land.gridData, phase1_land, deltatron.gridData, landuse_classes, new_indices, ftransition) for i in range(len(phase2_land)): land_out.gridData[i] = phase2_land[i] TimerUtility.stop_timer('delta_deltatron')
def read_gif(grid, filename, grid_nrows, grid_ncols): TimerUtility.start_timer('gdif_ReadGIF') im = Image.open(filename).convert('RGB') ncols, nrows = im.size # print(f"{ncols} {nrows} == {grid_ncols} {grid_nrows}") if ncols != grid_ncols or nrows != grid_nrows: print( f"{filename}: {ncols} x {nrows} image does not match expected size {grid_ncols}x{nrows}" ) raise Exception max_pixel = -1 min_pixel = 300 test_file = open(f"{Scenario.get_scen_value('output_dir')}ReadingRoad", "w") for j in range(grid_ncols): for i in range(grid_nrows): red, green, blue = im.getpixel((j, i)) # red, green, blue = Gdif.__hex_to_rgb(pixel_val) # Check that the image is a true grayscale image if red == green and red == blue: index = i * grid_ncols + j grid.gridData[index] = red test_file.write(f"{red}\n") if red > max_pixel: max_pixel = red if red < min_pixel: min_pixel = red else: print( f'File is not a true gray scale image -> {red} {green} {blue}' ) test_file.close() im.close() grid.max = max_pixel grid.min = min_pixel TimerUtility.stop_timer('gdif_ReadGIF')
def write_gif(grid, colortable, fname, date, grid_nrows, grid_ncols): date_color = Scenario.get_scen_value("date_color") TimerUtility.start_timer('gdif_WriteGIF') if Scenario.get_scen_value("logging") and Scenario.get_scen_value( "log_writes"): Logger.log(f"Writing GIF {fname}") Logger.log(f"colortable name={colortable.name} date={date}") Logger.log(f"rows={grid_nrows} cols={grid_ncols}") Logger.log(f"date color index = {date_color}") ImageIO._date_y = grid_nrows - 16 file = open(fname, 'w') im = Image.new('RGB', (grid_ncols, grid_nrows)) index = 0 for i in range(grid_nrows): for j in range(grid_ncols): offset = i * grid_ncols + j color_component = grid.gridData[offset] color_component = int(color_component) color = colortable.color[color_component] im.putpixel((j, i), color) index += 1 if date is not None: d = ImageDraw.Draw(im) hex_color = date_color[2:] (r, g, b) = tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) d.text((ImageIO._date_x, ImageIO._date_y), date, fill=(r, g, b)) im.save(fname) im.close() file.close() TimerUtility.stop_timer('gdif_WriteGIF')
def driver(): TimerUtility.start_timer('drv_driver') name = "_cumcolor_urban_" output_dir = Scenario.get_scen_value("output_dir") landuse_flag = len(Scenario.get_scen_value("landuse_data_file")) > 0 nrows = IGrid.nrows ncols = IGrid.ncols total_pixels = IGrid.get_total_pixels() z_cumulate = PGrid.get_cumulate() sim_landuse = PGrid.get_land1() # Create Annual Landuse Probability File if Processing.get_processing_type() == Globals.mode_enum["predict"]: if landuse_flag: LandClass.init_annual_prob(total_pixels) # Monte Carlo Simulation Driver.monte_carlo(z_cumulate, sim_landuse) if Processing.get_processing_type() == Globals.mode_enum["predict"]: # Output Urban Images if IGrid.using_gif: filename = f"{output_dir}cumulate_urban.gif" else: filename = f"{output_dir}cumulate_urban.tif" IGrid.echo_meta(f"{output_dir}cumulate_urban.tfw", "urban") colortable = Color.get_grayscale_table() ImageIO.write_gif(z_cumulate, colortable, filename, "", nrows, ncols) Utilities.write_z_prob_grid(z_cumulate.gridData, name) if landuse_flag: cum_prob, cum_uncert = LandClass.build_prob_image(total_pixels) #print(cum_prob) # Output Cumulative Prob Image if IGrid.using_gif: filename = f"{output_dir}cumcolor_landuse.gif" else: filename = f"{output_dir}cumcolor_landuse.tif" IGrid.echo_meta(f"{output_dir}cumcolor_landuse.tfw", "landuse") cum_prob_grid = IGrid.wrap_list(cum_prob) ImageIO.write_gif(cum_prob_grid, Color.get_landuse_table(), filename, "", nrows, ncols) # Output Cumulative Uncertainty Image if IGrid.using_gif: filename = f"{output_dir}uncertainty.landuse.gif" else: filename = f"{output_dir}uncertainty.landuse.tif" IGrid.echo_meta(f"{output_dir}uncertainty.landuse.tfw", "landuse") cum_uncert_grid = IGrid.wrap_list(cum_uncert) ImageIO.write_gif(cum_uncert_grid, Color.get_grayscale_table(), filename, "", nrows, ncols) if not landuse_flag or Processing.get_processing_type( ) == Globals.mode_enum['predict']: fmatch = 0.0 else: landuse1 = IGrid.igrid.get_landuse_igrid(1) fmatch = Driver.fmatch(sim_landuse, landuse1, landuse_flag, total_pixels) Stats.analyze(fmatch) TimerUtility.stop_timer('drv_driver')
def phase5(road_gravity, diffusion_coeff, breed_coeff, z, delta, slope, excld, roads, slope_weights, rt): TimerUtility.start_timer('spr_phase5') nrows = IGrid.nrows ncols = IGrid.ncols total_pixels = nrows * ncols # Determine the total growth count and save the row and col locations of the new growth growth_tracker = [] growth_count = 0 for i in range(total_pixels): if delta[i] > 0: growth_tracker.append((int(i / ncols), i % ncols)) growth_count += 1 # Phase 5: Road Trips # If there is new growth, begin processing road trips if growth_count > 0: for i in range(1 + int(breed_coeff)): """Determine the Max Index into the Global_Road_Seach_Incices Array for road_gravity of 1 we have 8 values for road_gravity of 2 we have 16 values for road_gravity of 3 we have 24 values and so on... if we need to cover N road_gravity values, then the total number of indexed values woud be 8 + 16 + 24 + ... + (8*N) = 8 *(1+2+3+...+N) = 8*(N(1+N))/2 """ int_road_gravity = Spread.get_road_gravity_val(road_gravity) max_search_index = 4 * (int_road_gravity * (1 + int_road_gravity)) max_search_index = max(max_search_index, nrows) max_search_index = max(max_search_index, ncols) # Randomly select a growth pixel to start search for road growth_row, growth_col = Random.get_element(growth_tracker) # Search for road about this growth point road_found, i_road_start, j_road_start = Spread.road_search( growth_row, growth_col, max_search_index, roads) # If there is a road found, then walk along it i_road_end = 0 j_road_end = 0 spread = False if road_found: #print(roads) spread, i_road_end, j_road_end = Spread.road_walk( i_road_start, j_road_start, roads, diffusion_coeff) if spread: urbanized, rt, i_neigh, j_neigh = Spread.urbanize_neighbor( i_road_end, j_road_end, z, delta, slope, excld, slope_weights, UGMDefines.PHASE5G, rt) if urbanized: max_tries = 3 for tries in range(3): urbanized, rt, i_neigh_neigh, j_neigh_neigh = Spread.urbanize_neighbor( i_neigh, j_neigh, z, delta, slope, excld, slope_weights, UGMDefines.PHASE5G, rt) TimerUtility.stop_timer('spr_phase5') return rt
def spread(z, avg_slope): TimerUtility.start_timer('spr_spread') sng = 0 sdc = 0 og = 0 rt = 0 nrows = IGrid.nrows ncols = IGrid.ncols total_pixels = nrows * ncols road_gravity = Coeff.get_current_road_gravity() diffusion = Coeff.get_current_diffusion() breed = Coeff.get_current_breed() spread = Coeff.get_current_spread() excld = IGrid.igrid.get_excld_grid() roads = IGrid.igrid.get_road_grid_by_year( Processing.get_current_year()) slope = IGrid.igrid.get_slope_grid() nrows = IGrid.nrows ncols = IGrid.ncols # Zero the growth array for this time period delta = [0] * (nrows * ncols) # Get slope rates slope_weights = Spread.get_slope_weights() # Phase 1N3 - Spontaneous Neighborhood Growth and Spreading sng, sdc = Spread.phase1n3(diffusion, breed, z.gridData, delta, slope, excld, slope_weights, sng, sdc) # Phase 4 - Organic Growth og = Spread.phase4(spread, z.gridData, excld, delta, slope, slope_weights, og) # Phase 5 - Road Influence Growth rt = Spread.phase5(road_gravity, diffusion, breed, z.gridData, delta, slope, excld, roads, slope_weights, rt) Utilities.condition_gt_gif(delta, UGMDefines.PHASE5G, delta, 0) Utilities.condition_ge_gif(excld, 100, delta, 0) # Now place growth array into current array num_growth_pix = 0 avg_slope = 0.0 for i in range(total_pixels): if z.gridData[i] == 0 and delta[i] > 0: # New growth being placed into array avg_slope += slope[i] z.gridData[i] = delta[i] num_growth_pix += 1 pop = 0 for pixels in z.gridData: if pixels >= UGMDefines.PHASE0G: pop += 1 if num_growth_pix == 0: avg_slope = 0.0 else: avg_slope /= num_growth_pix TimerUtility.stop_timer('spr_spread') return avg_slope, num_growth_pix, sng, sdc, og, rt, pop
def main(): TimerUtility.start_timer('total_time') valid_modes = ["predict", "restart", "test", "calibrate"] Globals.mype = 0 Globals.npes = 1 packing = False restart_run = 0 # Parse command line if len(sys.argv) != 3: __print_usage(sys.argv[0]) sys.exit(1) if len(sys.argv) != 3 or sys.argv[1] not in valid_modes: __print_usage(sys.argv[0]) sys.exit(1) Processing.set_processing_type(Globals.mode_enum[sys.argv[1]]) if Processing.get_processing_type() == Globals.mode_enum['restart']: Processing.set_restart_flag(True) Scenario.init(sys.argv[2], Processing.get_restart_flag()) try: log_it = Scenario.get_scen_value("logging") random_seed = Scenario.get_scen_value("random_seed") Random.set_seed(random_seed) landuse_class_info = Scenario.get_scen_value("landuse_class_info") LandClass.num_landclasses = len(landuse_class_info) # filling in the class array in Land_Class for i, landuse_class in enumerate(landuse_class_info): # num, class_id, name, idx, hexColor landuse_class_meta = LanduseMeta(landuse_class.grayscale, landuse_class.type, landuse_class.name, i, landuse_class.color[2:]) LandClass.landuse_classes.append(landuse_class_meta) # Set up Coefficients if sys.argv[1] == 'restart': if log_it: print("Implement log here") diffusion, breed, spread, slope_resistance, road_gravity, random_seed, restart_run = \ Input.read_restart_file(Scenario.get_scen_value("output_dir")) Processing.set_current_run(restart_run) else: Processing.set_current_run(0) Coeff.set_start_coeff( Scenario.get_scen_value("calibration_diffusion_start"), Scenario.get_scen_value("calibration_spread_start"), Scenario.get_scen_value("calibration_breed_start"), Scenario.get_scen_value("calibration_slope_start"), Scenario.get_scen_value("calibration_road_start")) Coeff.set_stop_coeff( Scenario.get_scen_value("calibration_diffusion_stop"), Scenario.get_scen_value("calibration_spread_stop"), Scenario.get_scen_value("calibration_breed_stop"), Scenario.get_scen_value("calibration_slope_stop"), Scenario.get_scen_value("calibration_road_stop")) Coeff.set_step_coeff( Scenario.get_scen_value("calibration_diffusion_step"), Scenario.get_scen_value("calibration_spread_step"), Scenario.get_scen_value("calibration_breed_step"), Scenario.get_scen_value("calibration_slope_step"), Scenario.get_scen_value("calibration_road_step")) Coeff.set_best_fit_coeff( Scenario.get_scen_value("prediction_diffusion_best_fit"), Scenario.get_scen_value("prediction_spread_best_fit"), Scenario.get_scen_value("prediction_breed_best_fit"), Scenario.get_scen_value("prediction_slope_best_fit"), Scenario.get_scen_value("prediction_road_best_fit")) # Initial IGrid IGrid.init(packing, Processing.get_processing_type()) ''' Skipped memory and logging stuff for now, don't know if I'll need it If there is a problem, I can go back and implement ''' # Initialize Landuse if len(Scenario.get_scen_value("landuse_data_file")) > 0: LandClass.init() if Scenario.get_scen_value("log_landclass_summary"): if log_it: # this is where we would log Logger.log("Test log") # Initialize Colortables Color.init(IGrid.ncols) # Read and validate input IGrid.read_input_files(packing, Scenario.get_scen_value("echo_image_files"), Scenario.get_scen_value("output_dir")) IGrid.validate_grids(log_it) # Normalize Roads IGrid.normalize_roads() landuse_flag = len(Scenario.get_scen_value("landuse_data_file")) != 0 IGrid.verify_inputs(log_it, landuse_flag) # Initialize PGRID Grids PGrid.init(IGrid.get_total_pixels()) if log_it and Scenario.get_scen_value("log_colortables"): Color.log_colors() # Count the Number of Runs Processing.set_total_runs() Processing.set_last_monte( int(Scenario.get_scen_value("monte_carlo_iterations")) - 1) if log_it: if Processing.get_processing_type( ) == Globals.mode_enum["calibrate"]: Logger.log( f"Total Number of Runs = {Processing.get_total_runs()}") # Compute Transition Matrix if len(Scenario.get_scen_value("landuse_data_file")) > 0: Transition.create_matrix() if log_it and Scenario.get_scen_value("log_transition_matrix"): Transition.log_transition() # Compute the Base Statistics against which the calibration will take place Stats.set_base_stats() if log_it and Scenario.get_scen_value("log_base_statistics"): Stats.log_base_stats() if log_it and Scenario.get_scen_value("log_debug"): IGrid.debug("main.py") Processing.set_num_runs_exec_this_cpu(0) if Processing.get_current_run() == 0 and Globals.mype == 0: output_dir = Scenario.get_scen_value("output_dir") if Processing.get_processing_type( ) != Globals.mode_enum["predict"]: filename = f"{output_dir}control_stats.log" Stats.create_control_file(filename) if Scenario.get_scen_value("write_std_dev_file"): filename = f"{output_dir}std_dev.log" Stats.create_stats_val_file(filename) if Scenario.get_scen_value("write_avg_file"): filename = f"{output_dir}avg.log" Stats.create_stats_val_file(filename) if Scenario.get_scen_value("write_coeff_file"): output_dir = Scenario.get_scen_value("output_dir") filename = f"{output_dir}coeff.log" Coeff.create_coeff_file(filename, True) if Processing.get_processing_type() == Globals.mode_enum["predict"]: # Prediction Runs Processing.set_stop_year( Scenario.get_scen_value("prediction_stop_date")) Coeff.set_current_coeff(Coeff.get_best_diffusion(), Coeff.get_best_spread(), Coeff.get_best_breed(), Coeff.get_best_slope_resistance(), Coeff.get_best_road_gravity()) if Globals.mype == 0: Driver.driver() Processing.increment_num_runs_exec_this_cpu() # Timing stuff if log_it and int(Scenario.get_scen_value('log_timings')) > 1: TimerUtility.log_timers() else: # Calibration and Test Runs Processing.set_stop_year( IGrid.igrid.get_urban_year(IGrid.igrid.get_num_urban() - 1)) output_dir = Scenario.get_scen_value('output_dir') d_start, d_step, d_stop = Coeff.get_start_step_stop_diffusion() for diffusion_coeff in range(d_start, d_stop + 1, d_step): b_start, b_step, b_stop = Coeff.get_start_step_stop_breed() for breed_coeff in range(b_start, b_stop + 1, b_step): s_start, s_step, s_stop = Coeff.get_start_step_stop_spread( ) for spread_coeff in range(s_start, s_stop + 1, s_step): sr_start, sr_step, sr_stop = Coeff.get_start_step_stop_slope_resistance( ) for slope_resist_coeff in range( sr_start, sr_stop + 1, sr_step): rg_start, rg_step, rg_stop = Coeff.get_start_step_stop_road_gravity( ) for road_grav_coeff in range( rg_start, rg_stop + 1, rg_step): filename = f"{output_dir}{UGMDefines.RESTART_FILE}{Globals.mype}" Output.write_restart_data( filename, diffusion_coeff, breed_coeff, spread_coeff, slope_resist_coeff, road_grav_coeff, Scenario.get_scen_value('random_seed'), restart_run) restart_run += 1 Coeff.set_current_coeff( diffusion_coeff, spread_coeff, breed_coeff, slope_resist_coeff, road_grav_coeff) Driver.driver() Processing.increment_num_runs_exec_this_cpu() # Timing Logs if log_it and int( Scenario.get_scen_value( 'log_timings')) > 1: TimerUtility.log_timers() Processing.increment_current_run() if Processing.get_processing_type( ) == Globals.mode_enum['test']: TimerUtility.stop_timer('total_time') if log_it and int( Scenario.get_scen_value( 'log_timings')) > 0: TimerUtility.log_timers() Logger.close() sys.exit(0) # Stop timer TimerUtility.stop_timer('total_time') if log_it and int(Scenario.get_scen_value('log_timings')) > 0: TimerUtility.log_timers() # Close Logger Logger.close() except KeyError as err: traceback.print_exc() print("{0} is not set. Please set it in your scenario file".format( str(err).upper())) Logger.log("Something went wrong") Logger.close() sys.exit(1) except FileNotFoundError as err: traceback.print_exc() print(err) Logger.log("Something went wrong") Logger.close() sys.exit(1) except Exception: traceback.print_exc() Logger.log("Something went wrong") Logger.close() sys.exit(1)
def phase1(drive, urban_land, slope, deltatron, landuse_classes, class_indices, new_indices, class_slope, ftransition): TimerUtility.start_timer('delta_phase1') nrows = IGrid.nrows ncols = IGrid.ncols phase1_land = [] # Copy input land grid into output land grid for urban in urban_land: phase1_land.append(urban) # Try to make Transitions for tries in range(drive): # Select a transition pixel to e center of spreading cluster offset, i_center, j_center = Deltatron.get_rand_landuse_offset() index = new_indices[urban_land[offset]] while not landuse_classes[index].trans: offset, i_center, j_center = Deltatron.get_rand_landuse_offset( ) index = new_indices[urban_land[offset]] # Randomly choose new landuse number new_landuse = Deltatron.get_new_landuse(class_indices, landuse_classes, slope[offset], class_slope) # Test transition probability for new cluster new_i = new_indices[urban_land[offset]] new_j = new_indices[new_landuse] trans_offset = new_i * LandClass.get_num_landclasses() + new_j if Random.get_float() < ftransition[trans_offset]: # Transition the center pixel phase1_land[offset] = new_landuse deltatron[offset] = 1 # Try building up cluster around this center pixel i = i_center j = j_center for regions in range(UGMDefines.REGION_SIZE): # Occasionally Reset to center of cluster random_int = Random.get_int(0, 7) if random_int == 7: i = i_center j = j_center # Get a neighbor i, j = Utilities.get_neighbor(i, j) if 0 <= i < nrows and 0 <= j < ncols: # Test new pixel against transition probability offset = i * ncols + j # print(f"{len(urban_land)} | {i} {j} -> {offset}") urban_index = urban_land[offset] new_i = new_indices[urban_index] new_j = new_indices[new_landuse] trans_offset = new_i * LandClass.get_num_landclasses( ) + new_j if Random.get_float() < ftransition[trans_offset]: # If the immediate pixel is allowed to transition, then change it index = new_indices[urban_land[offset]] if landuse_classes[index].trans: phase1_land[offset] = new_landuse deltatron[offset] = 1 # Try to transition a neighboring pixel i, j = Utilities.get_neighbor(i, j) if 0 <= i < nrows and 0 <= j < ncols: offset = i * ncols + j index = new_indices[urban_land[offset]] if landuse_classes[index].trans: phase1_land[offset] = new_landuse deltatron[offset] = 1 TimerUtility.stop_timer('delta_phase1') return phase1_land
def phase2(urban_land, phase1_land, deltatron, landuse_classes, new_indices, ftransition): TimerUtility.start_timer('delta_phase2') nrows = IGrid.nrows ncols = IGrid.ncols phase2_land = [] # Copy current land to phase2_land for pixel in phase1_land: phase2_land.append(pixel) # For each interior point for i in range(1, nrows - 1): for j in range(1, ncols - 1): offset = i * ncols + j index = new_indices[phase1_land[offset]] if landuse_classes[index].trans and deltatron[offset] == 0: """ I,J is a Transitional Pixel which was not transitioned within the last min_years_between_transitions years; count its neighbors which have transitioned in previous year (IE Deltatron == 2) """ deltatron_neighbors = Deltatron.count_neighbor( deltatron, i, j) random_int = 1 + Random.get_int(0, 1) if deltatron_neighbors >= random_int: max_tries = 16 for tries in range(max_tries): i_neigh, j_neigh = Utilities.get_neighbor(i, j) offset_neigh = i_neigh * ncols + j_neigh index = new_indices[phase1_land[offset_neigh]] if deltatron[offset_neigh] == 2 and landuse_classes[ index]: trans_i = new_indices[phase2_land[offset]] trans_j = new_indices[urban_land[offset_neigh]] offset_trans = trans_i * LandClass.get_num_landclasses( ) + trans_j if Random.get_float( ) < ftransition[offset_trans]: phase2_land[offset] = urban_land[ offset_neigh] deltatron[offset] = 1 break if Scenario.get_scen_value('view_deltatron_aging'): if IGrid.using_gif: filename = f"{Scenario.get_scen_value('output_dir')}deltatron_{Processing.get_current_run()}_" \ f"{Processing.get_current_monte()}_{Processing.get_current_year()}.gif" else: filename = f"{Scenario.get_scen_value('output_dir')}deltatron_{Processing.get_current_run()}_" \ f"{Processing.get_current_monte()}_{Processing.get_current_year()}.tif" date = f"{Processing.get_current_year()}" ImageIO.write_gif(deltatron, Color.get_deltatron_table(), filename, date, nrows, ncols) # Age the Deltatrons for i in range(nrows * ncols): if deltatron[i] > 0: deltatron[i] += 1 # Kill old deltatrons Utilities.condition_gt_gif(deltatron, UGMDefines.MIN_YEARS_BETWEEN_TRANSITIONS, deltatron, 0) TimerUtility.stop_timer("delta_phase2") return phase2_land