fire2a.managedata
Previous Read Data Prometheus
1#!python3 2""" 3Previous Read Data Prometheus 4""" 5__author__ = "David Palacios Meneses" 6__revision__ = "$Format:%H$" 7 8from pathlib import Path 9from typing import Any, Dict, List, Optional, Tuple, Union 10 11from numpy import dtype 12from numpy import empty as npempty 13from numpy import full as npfull 14from numpy import max as npmax 15from numpy import nan as npnan 16from numpy import ndarray 17from numpy import zeros as npzeros 18from pandas import DataFrame 19 20 21def Lookupdict(filename: Union[Path, str]) -> Tuple[dict, dict]: 22 """Reads lookup_table.csv and creates dictionaries for the fuel types and cells' colors 23 24 Args: 25 filename (string): Path to fuel model lookup_table.csv, format is XXX_lookup_table.csv, e.g: spain_lookup_table.csv 26 27 Returns: 28 dict [int,str]: Dictionary with fuel code number as key and fuel model name as value. 29 dict [int,list [int,int,int,int]]: Dictionary with fuel code number as key and list of colors in rgb as value. 30 """ # fmt:skip 31 32 aux = 1 33 file = open(filename, "r") 34 row = {} 35 colors = {} 36 all = {} 37 38 # Read file and save colors and ftypes dictionaries 39 for line in file: 40 if aux > 1: 41 aux += 1 42 line = line.replace("-", "") 43 line = line.replace("\n", "") 44 line = line.replace("No", "NF") 45 line = line.split(",") 46 47 if line[3][0:3] in ["FM1"]: 48 row[line[0]] = line[3][0:4] 49 elif line[3][0:3] in ["Non", "NFn"]: 50 row[line[0]] = "NF" 51 else: 52 row[line[0]] = line[3][0:3] 53 54 colors[line[0]] = (float(line[4]) / 255.0, float(line[5]) / 255.0, float(line[6]) / 255.0, 1.0) 55 all[line[0]] = line 56 57 if aux == 1: 58 aux += 1 59 60 return row, colors 61 62 63# Tuple[(list, list, int, int, list, list, int)] 64# Tuple[list[Any], list[Any], int, int, list[Any], list[Any], int] 65def ForestGrid( 66 filename: str, Lookupdict: dict 67) -> Tuple[list[int], list[str], int, int, list[dict[str, Optional[list[int]]]], ndarray[Any, dtype[Any]], float]: 68 """Reads fuels.asc file and returns an array with all the cells, and grid dimension nxm 69 70 Args: 71 filename (string): Path to fuel fuel model in ascii format (fuels.asc). 72 Lookupdict (int,str): Dictionary with fuel code number as key and fuel model name as value. 73 74 Returns: 75 list [int]: List of forest grid with fuel code number, where non fuel are represented as 0 76 list [string]: List of forest grid with fuel code name, where non fuel are represented as NF. 77 int: Number of rows of forest grid. 78 int: Number of columns of forest grid. 79 list [dict[str,list[int]]]: List of dictionaries that contains the neighbors of each cell in each compass rose direction 80 list [list[int,int]]: List of lists that stores the x and y coordinate of each cell 81 int: Size of cells in forest grid 82 """ # fmt:skip 83 84 AdjCells = [] 85 North = "N" 86 South = "S" 87 East = "E" 88 West = "W" 89 NorthEast = "NE" 90 NorthWest = "NW" 91 SouthEast = "SE" 92 SouthWest = "SW" 93 94 with open(filename, "r") as f: 95 filelines = f.readlines() 96 97 line = filelines[4].replace("\n", "") 98 parts = line.split() 99 100 if parts[0] != "cellsize": 101 print("line=", line) 102 raise RuntimeError("Expected cellsize on line 5 of " + filename) 103 cellsize = float(parts[1]) 104 105 cells = 0 106 row = 1 107 trows = 0 108 tcols = 0 109 gridcell1 = [] 110 gridcell2 = [] 111 gridcell3 = [] 112 gridcell4 = [] 113 grid = [] 114 grid2 = [] 115 116 # Read the ASCII file with the grid structure 117 for row in range(6, len(filelines)): 118 line = filelines[row] 119 line = line.replace("\n", "") 120 line = " ".join(line.split()) 121 line = line.split(" ") 122 # print(line) 123 124 for c in line: # range(0,len(line)-1): 125 if c not in Lookupdict.keys(): 126 gridcell1.append("NF") 127 gridcell2.append("NF") 128 gridcell3.append(int(0)) 129 gridcell4.append("NF") 130 else: 131 gridcell1.append(c) 132 gridcell2.append(Lookupdict[c]) 133 gridcell3.append(int(c)) 134 gridcell4.append(Lookupdict[c]) 135 tcols = npmax([tcols, len(line)]) 136 137 grid.append(gridcell1) 138 grid2.append(gridcell2) 139 gridcell1 = [] 140 gridcell2 = [] 141 142 # Adjacent list of dictionaries and Cells coordinates 143 CoordCells = npempty([len(grid) * (tcols), 2]).astype(int) 144 n = 1 145 tcols += 1 146 for r in range(0, len(grid)): 147 for c in range(0, tcols - 1): 148 # CoordCells.append([c,len(grid)-r-1]) 149 CoordCells[c + r * (tcols - 1), 0] = c 150 CoordCells[c + r * (tcols - 1), 1] = len(grid) - r - 1 151 152 if len(grid) > 1: 153 154 if r == 0: 155 if c == 0: 156 AdjCells.append( 157 { 158 North: None, 159 NorthEast: None, 160 NorthWest: None, 161 South: [n + tcols - 1], 162 SouthEast: [n + tcols], 163 SouthWest: None, 164 East: [n + 1], 165 West: None, 166 } 167 ) 168 n += 1 169 if c == tcols - 2: 170 AdjCells.append( 171 { 172 North: None, 173 NorthEast: None, 174 NorthWest: None, 175 South: [n + tcols - 1], 176 SouthEast: None, 177 SouthWest: [n + tcols - 2], 178 East: None, 179 West: [n - 1], 180 } 181 ) 182 n += 1 183 if c > 0 and c < tcols - 2: 184 AdjCells.append( 185 { 186 North: None, 187 NorthEast: None, 188 NorthWest: None, 189 South: [n + tcols - 1], 190 SouthEast: [n + tcols], 191 SouthWest: [n + tcols - 2], 192 East: [n + 1], 193 West: [n - 1], 194 } 195 ) 196 n += 1 197 198 if r > 0 and r < len(grid) - 1: 199 if c == 0: 200 AdjCells.append( 201 { 202 North: [n - tcols + 1], 203 NorthEast: [n - tcols + 2], 204 NorthWest: None, 205 South: [n + tcols - 1], 206 SouthEast: [n + tcols], 207 SouthWest: None, 208 East: [n + 1], 209 West: None, 210 } 211 ) 212 n += 1 213 if c == tcols - 2: 214 AdjCells.append( 215 { 216 North: [n - tcols + 1], 217 NorthEast: None, 218 NorthWest: [n - tcols], 219 South: [n + tcols - 1], 220 SouthEast: None, 221 SouthWest: [n + tcols - 2], 222 East: None, 223 West: [n - 1], 224 } 225 ) 226 n += 1 227 if c > 0 and c < tcols - 2: 228 AdjCells.append( 229 { 230 North: [n - tcols + 1], 231 NorthEast: [n - tcols + 2], 232 NorthWest: [n - tcols], 233 South: [n + tcols - 1], 234 SouthEast: [n + tcols], 235 SouthWest: [n + tcols - 2], 236 East: [n + 1], 237 West: [n - 1], 238 } 239 ) 240 n += 1 241 242 if r == len(grid) - 1: 243 if c == 0: 244 AdjCells.append( 245 { 246 North: [n - tcols + 1], 247 NorthEast: [n - tcols + 2], 248 NorthWest: None, 249 South: None, 250 SouthEast: None, 251 SouthWest: None, 252 East: [n + 1], 253 West: None, 254 } 255 ) 256 n += 1 257 258 if c == tcols - 2: 259 AdjCells.append( 260 { 261 North: [n - tcols + 1], 262 NorthEast: None, 263 NorthWest: [n - tcols], 264 South: None, 265 SouthEast: None, 266 SouthWest: None, 267 East: None, 268 West: [n - 1], 269 } 270 ) 271 n += 1 272 273 if c > 0 and c < tcols - 2: 274 AdjCells.append( 275 { 276 North: [n - tcols + 1], 277 NorthEast: [n - tcols + 2], 278 NorthWest: [n - tcols], 279 South: None, 280 SouthEast: None, 281 SouthWest: None, 282 East: [n + 1], 283 West: [n - 1], 284 } 285 ) 286 n += 1 287 288 if len(grid) == 1: 289 if c == 0: 290 AdjCells.append( 291 { 292 North: None, 293 NorthEast: None, 294 NorthWest: None, 295 South: None, 296 SouthEast: None, 297 SouthWest: None, 298 East: [n + 1], 299 West: None, 300 } 301 ) 302 n += 1 303 if c == tcols - 2: 304 AdjCells.append( 305 { 306 North: None, 307 NorthEast: None, 308 NorthWest: None, 309 South: None, 310 SouthEast: None, 311 SouthWest: None, 312 East: None, 313 West: [n - 1], 314 } 315 ) 316 n += 1 317 if c > 0 and c < tcols - 2: 318 AdjCells.append( 319 { 320 North: None, 321 NorthEast: None, 322 NorthWest: None, 323 South: None, 324 SouthEast: None, 325 SouthWest: None, 326 East: [n + 1], 327 West: [n - 1], 328 } 329 ) 330 n += 1 331 332 return gridcell3, gridcell4, len(grid), tcols - 1, AdjCells, CoordCells, cellsize 333 334 335# Tuple[(list, list, list, list, list, list, list, list, list)] 336def DataGrids(InFolder: str, NCells: int) -> Tuple[ 337 ndarray[Any, dtype[Any]], 338 ndarray[Any, dtype[Any]], 339 ndarray[Any, dtype[Any]], 340 ndarray[Any, dtype[Any]], 341 ndarray[Any, dtype[Any]], 342 ndarray[Any, dtype[Any]], 343 ndarray[Any, dtype[Any]], 344 ndarray[Any, dtype[Any]], 345 ndarray[Any, dtype[Any]], 346]: 347 """ 348 Reads *.asc files and returns an array per each ASCII file with the correspondant information per each cell. Currently supports 349 elevation, ascpect, slope, curing, canopy bulk density, crown base height, conifer percent dead fir, probability of ignition and foliar moisture content. 350 351 Args: 352 InFolder (string): Path to data folder. 353 NCells (int): Number of cells in grid. 354 355 Returns: 356 list [float]: List of elevations of each cell 357 list [float]: List of aspect of each cell 358 list [float]: List of slope of each cell 359 list [float]: List of curing degree of each cell 360 list [float]: List of canopy bulk density of each cell 361 list [float]: List of crown base height of each cell 362 list [float]: List of conifer percent dead fir of each cell 363 list [float]: List of ignition probability of each cell 364 list [float]: List of foliar moisture content of each cell 365 """ # fmt:skip 366 p = Path(InFolder) 367 filenames = [ 368 "elevation.asc", 369 "saz.asc", 370 "slope.asc", 371 "cur.asc", 372 "cbd.asc", 373 "cbh.asc", 374 "ccf.asc", 375 "py.asc", 376 "fmc.asc", 377 ] 378 Elevation = npfull(NCells, npnan) 379 SAZ = npfull(NCells, npnan) 380 PS = npfull(NCells, npnan) 381 Curing = npfull(NCells, npnan) 382 CBD = npfull(NCells, npnan) 383 CBH = npfull(NCells, npnan) 384 CCF = npfull(NCells, npnan) 385 PY = npfull(NCells, npnan) 386 FMC = npfull(NCells, npnan) 387 388 for name in filenames: 389 ff = p / name 390 if ff.exists() == True: 391 aux = 0 392 with open(ff, "r") as f: 393 filelines = f.readlines() 394 395 line = filelines[4].replace("\n", "") 396 parts = line.split() 397 398 if parts[0] != "cellsize": 399 print("line=", line) 400 raise RuntimeError("Expected cellsize on line 5 of " + ff) 401 cellsize = float(parts[1]) 402 403 row = 1 404 405 # Read the ASCII file with the grid structure 406 for row in range(6, len(filelines)): 407 line = filelines[row] 408 line = line.replace("\n", "") 409 line = " ".join(line.split()) 410 line = line.split(" ") 411 # print(line) 412 413 for c in line: 414 if name == "elevation.asc": 415 Elevation[aux] = float(c) 416 aux += 1 417 if name == "saz.asc": 418 SAZ[aux] = float(c) 419 aux += 1 420 if name == "slope.asc": 421 PS[aux] = float(c) 422 aux += 1 423 if name == "cbd.asc": 424 CBD[aux] = float(c) 425 aux += 1 426 if name == "cbh.asc": 427 CBH[aux] = float(c) 428 aux += 1 429 if name == "ccf.asc": 430 CCF[aux] = float(c) 431 aux += 1 432 if name == "curing.asc": 433 Curing[aux] = float(c) 434 aux += 1 435 if name == "py.asc": 436 PY[aux] = float(c) 437 aux += 1 438 if name == "fmc.asc": 439 FMC[aux] = float(c) 440 aux += 1 441 442 else: 443 print(" No", name, "file, filling with NaN") 444 445 return Elevation, SAZ, PS, Curing, CBD, CBH, CCF, PY, FMC 446 447 448# Generates the Data.dat file (csv) from all data files (ready for the simulator) 449def GenerateDat( 450 GFuelType: list, 451 GFuelTypeN: list, 452 Elevation: list, 453 PS: list, 454 SAZ: list, 455 Curing: list, 456 CBD: list, 457 CBH: list, 458 CCF: list, 459 PY: list, 460 FMC: list, 461 InFolder: str, 462) -> DataFrame: 463 """ 464 Reads forest information and generates Data.csv file 465 466 Args: 467 GFuelType (list [int]): List of forest grid with fuel code number, where non fuel are represented as 0 468 GFuelTypeN (list [string]): List of forest grid with fuel code name, where non fuel are represented as NF. 469 Elevation (list [float]): List of elevations of each cell 470 PS (list [float]): List of slope of each cell 471 SAZ (list [float]): List of aspect of each cell 472 Curing (list [float]): List of curing degree of each cell 473 CBD (list [float]): List of canopy bulk density of each cell 474 CBH (list [float]): List of crown base height of each cell 475 CCF (list [float]): List of conifer percent dead fir of each cell 476 PY (list [float]): List of ignition probability of each cell 477 FMC (list [float]): List of foliar moisture content of each cell 478 InFolder (string): Path to data folder. 479 480 Returns: 481 482 Dataframe: Dataframe containing information of forest 483 """ # fmt:skip 484 p = Path(InFolder) 485 # DF columns 486 Columns = [ 487 "fueltype", 488 "lat", 489 "lon", 490 "elev", 491 "ws", 492 "waz", 493 "ps", 494 "saz", 495 "cur", 496 "cbd", 497 "cbh", 498 "ccf", 499 "ftypeN", 500 "fmc", 501 "py", 502 ] 503 504 # Dataframe 505 DF = DataFrame(columns=Columns) 506 DF["fueltype"] = [x for x in GFuelType] 507 DF["elev"] = Elevation 508 DF["ps"] = PS 509 DF["saz"] = SAZ 510 DF["cbd"] = CBD 511 DF["cbh"] = CBH 512 DF["ccf"] = CCF 513 DF["py"] = PY 514 DF["fmc"] = FMC 515 DF["lat"] = npzeros(len(GFuelType)) + 51.621244 516 DF["lon"] = npzeros(len(GFuelType)).astype(int) - 115.608378 517 518 # Populate fuel type number 519 DF["ftypeN"] = GFuelTypeN 520 # print(np.asarray(GFuelTypeN).flatten()) 521 522 # Data File 523 filename = p / "Data.csv" 524 DF.to_csv(path_or_buf=filename, index=False, index_label=False, header=True) 525 return DF 526 527 528def GenDataFile(InFolder: str, Simulator: str) -> None: 529 """Main function that reads information available in folder and generates Data.csv file 530 531 Args: 532 InFolder (string): Path to data folder. 533 Simulator (string): Simulator version, currently only supports "K" (for kitral) and "S" (for Scott & Burgan) 534 535 Return: 536 None 537 """ # fmt:skip 538 p = Path(InFolder) 539 if Simulator == "K": 540 FBPlookup = p / "kitral_lookup_table.csv" 541 elif Simulator == "S": 542 FBPlookup = p / "spain_lookup_table.csv" 543 else: # beta version 544 FBPlookup = p / "spain_lookup_table.csv" 545 546 FBPDict, _ = Lookupdict(FBPlookup) 547 548 FGrid = p / "fuels.asc" 549 GFuelTypeN, GFuelType, _, _, _, _, _ = ForestGrid(FGrid, FBPDict) 550 551 NCells = len(GFuelType) 552 Elevation, SAZ, PS, Curing, CBD, CBH, CCF, PY, FMC = DataGrids(InFolder, NCells) 553 GenerateDat(GFuelType, GFuelTypeN, Elevation, PS, SAZ, Curing, CBD, CBH, CCF, PY, FMC, InFolder) 554 555 556if __name__ == "__main__": 557 p = Path("tests") 558 p_fuels = p / "fuels.asc" 559 p_lookup = p / "spain_lookup_table.csv" 560 GenDataFile("tests", "S") 561 # check if generate data exists
22def Lookupdict(filename: Union[Path, str]) -> Tuple[dict, dict]: 23 """Reads lookup_table.csv and creates dictionaries for the fuel types and cells' colors 24 25 Args: 26 filename (string): Path to fuel model lookup_table.csv, format is XXX_lookup_table.csv, e.g: spain_lookup_table.csv 27 28 Returns: 29 dict [int,str]: Dictionary with fuel code number as key and fuel model name as value. 30 dict [int,list [int,int,int,int]]: Dictionary with fuel code number as key and list of colors in rgb as value. 31 """ # fmt:skip 32 33 aux = 1 34 file = open(filename, "r") 35 row = {} 36 colors = {} 37 all = {} 38 39 # Read file and save colors and ftypes dictionaries 40 for line in file: 41 if aux > 1: 42 aux += 1 43 line = line.replace("-", "") 44 line = line.replace("\n", "") 45 line = line.replace("No", "NF") 46 line = line.split(",") 47 48 if line[3][0:3] in ["FM1"]: 49 row[line[0]] = line[3][0:4] 50 elif line[3][0:3] in ["Non", "NFn"]: 51 row[line[0]] = "NF" 52 else: 53 row[line[0]] = line[3][0:3] 54 55 colors[line[0]] = (float(line[4]) / 255.0, float(line[5]) / 255.0, float(line[6]) / 255.0, 1.0) 56 all[line[0]] = line 57 58 if aux == 1: 59 aux += 1 60 61 return row, colors
Reads lookup_table.csv and creates dictionaries for the fuel types and cells' colors
Args: filename (string): Path to fuel model lookup_table.csv, format is XXX_lookup_table.csv, e.g: spain_lookup_table.csv
Returns: dict [int,str]: Dictionary with fuel code number as key and fuel model name as value. dict [int,list [int,int,int,int]]: Dictionary with fuel code number as key and list of colors in rgb as value.
66def ForestGrid( 67 filename: str, Lookupdict: dict 68) -> Tuple[list[int], list[str], int, int, list[dict[str, Optional[list[int]]]], ndarray[Any, dtype[Any]], float]: 69 """Reads fuels.asc file and returns an array with all the cells, and grid dimension nxm 70 71 Args: 72 filename (string): Path to fuel fuel model in ascii format (fuels.asc). 73 Lookupdict (int,str): Dictionary with fuel code number as key and fuel model name as value. 74 75 Returns: 76 list [int]: List of forest grid with fuel code number, where non fuel are represented as 0 77 list [string]: List of forest grid with fuel code name, where non fuel are represented as NF. 78 int: Number of rows of forest grid. 79 int: Number of columns of forest grid. 80 list [dict[str,list[int]]]: List of dictionaries that contains the neighbors of each cell in each compass rose direction 81 list [list[int,int]]: List of lists that stores the x and y coordinate of each cell 82 int: Size of cells in forest grid 83 """ # fmt:skip 84 85 AdjCells = [] 86 North = "N" 87 South = "S" 88 East = "E" 89 West = "W" 90 NorthEast = "NE" 91 NorthWest = "NW" 92 SouthEast = "SE" 93 SouthWest = "SW" 94 95 with open(filename, "r") as f: 96 filelines = f.readlines() 97 98 line = filelines[4].replace("\n", "") 99 parts = line.split() 100 101 if parts[0] != "cellsize": 102 print("line=", line) 103 raise RuntimeError("Expected cellsize on line 5 of " + filename) 104 cellsize = float(parts[1]) 105 106 cells = 0 107 row = 1 108 trows = 0 109 tcols = 0 110 gridcell1 = [] 111 gridcell2 = [] 112 gridcell3 = [] 113 gridcell4 = [] 114 grid = [] 115 grid2 = [] 116 117 # Read the ASCII file with the grid structure 118 for row in range(6, len(filelines)): 119 line = filelines[row] 120 line = line.replace("\n", "") 121 line = " ".join(line.split()) 122 line = line.split(" ") 123 # print(line) 124 125 for c in line: # range(0,len(line)-1): 126 if c not in Lookupdict.keys(): 127 gridcell1.append("NF") 128 gridcell2.append("NF") 129 gridcell3.append(int(0)) 130 gridcell4.append("NF") 131 else: 132 gridcell1.append(c) 133 gridcell2.append(Lookupdict[c]) 134 gridcell3.append(int(c)) 135 gridcell4.append(Lookupdict[c]) 136 tcols = npmax([tcols, len(line)]) 137 138 grid.append(gridcell1) 139 grid2.append(gridcell2) 140 gridcell1 = [] 141 gridcell2 = [] 142 143 # Adjacent list of dictionaries and Cells coordinates 144 CoordCells = npempty([len(grid) * (tcols), 2]).astype(int) 145 n = 1 146 tcols += 1 147 for r in range(0, len(grid)): 148 for c in range(0, tcols - 1): 149 # CoordCells.append([c,len(grid)-r-1]) 150 CoordCells[c + r * (tcols - 1), 0] = c 151 CoordCells[c + r * (tcols - 1), 1] = len(grid) - r - 1 152 153 if len(grid) > 1: 154 155 if r == 0: 156 if c == 0: 157 AdjCells.append( 158 { 159 North: None, 160 NorthEast: None, 161 NorthWest: None, 162 South: [n + tcols - 1], 163 SouthEast: [n + tcols], 164 SouthWest: None, 165 East: [n + 1], 166 West: None, 167 } 168 ) 169 n += 1 170 if c == tcols - 2: 171 AdjCells.append( 172 { 173 North: None, 174 NorthEast: None, 175 NorthWest: None, 176 South: [n + tcols - 1], 177 SouthEast: None, 178 SouthWest: [n + tcols - 2], 179 East: None, 180 West: [n - 1], 181 } 182 ) 183 n += 1 184 if c > 0 and c < tcols - 2: 185 AdjCells.append( 186 { 187 North: None, 188 NorthEast: None, 189 NorthWest: None, 190 South: [n + tcols - 1], 191 SouthEast: [n + tcols], 192 SouthWest: [n + tcols - 2], 193 East: [n + 1], 194 West: [n - 1], 195 } 196 ) 197 n += 1 198 199 if r > 0 and r < len(grid) - 1: 200 if c == 0: 201 AdjCells.append( 202 { 203 North: [n - tcols + 1], 204 NorthEast: [n - tcols + 2], 205 NorthWest: None, 206 South: [n + tcols - 1], 207 SouthEast: [n + tcols], 208 SouthWest: None, 209 East: [n + 1], 210 West: None, 211 } 212 ) 213 n += 1 214 if c == tcols - 2: 215 AdjCells.append( 216 { 217 North: [n - tcols + 1], 218 NorthEast: None, 219 NorthWest: [n - tcols], 220 South: [n + tcols - 1], 221 SouthEast: None, 222 SouthWest: [n + tcols - 2], 223 East: None, 224 West: [n - 1], 225 } 226 ) 227 n += 1 228 if c > 0 and c < tcols - 2: 229 AdjCells.append( 230 { 231 North: [n - tcols + 1], 232 NorthEast: [n - tcols + 2], 233 NorthWest: [n - tcols], 234 South: [n + tcols - 1], 235 SouthEast: [n + tcols], 236 SouthWest: [n + tcols - 2], 237 East: [n + 1], 238 West: [n - 1], 239 } 240 ) 241 n += 1 242 243 if r == len(grid) - 1: 244 if c == 0: 245 AdjCells.append( 246 { 247 North: [n - tcols + 1], 248 NorthEast: [n - tcols + 2], 249 NorthWest: None, 250 South: None, 251 SouthEast: None, 252 SouthWest: None, 253 East: [n + 1], 254 West: None, 255 } 256 ) 257 n += 1 258 259 if c == tcols - 2: 260 AdjCells.append( 261 { 262 North: [n - tcols + 1], 263 NorthEast: None, 264 NorthWest: [n - tcols], 265 South: None, 266 SouthEast: None, 267 SouthWest: None, 268 East: None, 269 West: [n - 1], 270 } 271 ) 272 n += 1 273 274 if c > 0 and c < tcols - 2: 275 AdjCells.append( 276 { 277 North: [n - tcols + 1], 278 NorthEast: [n - tcols + 2], 279 NorthWest: [n - tcols], 280 South: None, 281 SouthEast: None, 282 SouthWest: None, 283 East: [n + 1], 284 West: [n - 1], 285 } 286 ) 287 n += 1 288 289 if len(grid) == 1: 290 if c == 0: 291 AdjCells.append( 292 { 293 North: None, 294 NorthEast: None, 295 NorthWest: None, 296 South: None, 297 SouthEast: None, 298 SouthWest: None, 299 East: [n + 1], 300 West: None, 301 } 302 ) 303 n += 1 304 if c == tcols - 2: 305 AdjCells.append( 306 { 307 North: None, 308 NorthEast: None, 309 NorthWest: None, 310 South: None, 311 SouthEast: None, 312 SouthWest: None, 313 East: None, 314 West: [n - 1], 315 } 316 ) 317 n += 1 318 if c > 0 and c < tcols - 2: 319 AdjCells.append( 320 { 321 North: None, 322 NorthEast: None, 323 NorthWest: None, 324 South: None, 325 SouthEast: None, 326 SouthWest: None, 327 East: [n + 1], 328 West: [n - 1], 329 } 330 ) 331 n += 1 332 333 return gridcell3, gridcell4, len(grid), tcols - 1, AdjCells, CoordCells, cellsize
Reads fuels.asc file and returns an array with all the cells, and grid dimension nxm
Args: filename (string): Path to fuel fuel model in ascii format (fuels.asc). Lookupdict (int,str): Dictionary with fuel code number as key and fuel model name as value.
Returns: list [int]: List of forest grid with fuel code number, where non fuel are represented as 0 list [string]: List of forest grid with fuel code name, where non fuel are represented as NF. int: Number of rows of forest grid. int: Number of columns of forest grid. list [dict[str,list[int]]]: List of dictionaries that contains the neighbors of each cell in each compass rose direction list [list[int,int]]: List of lists that stores the x and y coordinate of each cell int: Size of cells in forest grid
337def DataGrids(InFolder: str, NCells: int) -> Tuple[ 338 ndarray[Any, dtype[Any]], 339 ndarray[Any, dtype[Any]], 340 ndarray[Any, dtype[Any]], 341 ndarray[Any, dtype[Any]], 342 ndarray[Any, dtype[Any]], 343 ndarray[Any, dtype[Any]], 344 ndarray[Any, dtype[Any]], 345 ndarray[Any, dtype[Any]], 346 ndarray[Any, dtype[Any]], 347]: 348 """ 349 Reads *.asc files and returns an array per each ASCII file with the correspondant information per each cell. Currently supports 350 elevation, ascpect, slope, curing, canopy bulk density, crown base height, conifer percent dead fir, probability of ignition and foliar moisture content. 351 352 Args: 353 InFolder (string): Path to data folder. 354 NCells (int): Number of cells in grid. 355 356 Returns: 357 list [float]: List of elevations of each cell 358 list [float]: List of aspect of each cell 359 list [float]: List of slope of each cell 360 list [float]: List of curing degree of each cell 361 list [float]: List of canopy bulk density of each cell 362 list [float]: List of crown base height of each cell 363 list [float]: List of conifer percent dead fir of each cell 364 list [float]: List of ignition probability of each cell 365 list [float]: List of foliar moisture content of each cell 366 """ # fmt:skip 367 p = Path(InFolder) 368 filenames = [ 369 "elevation.asc", 370 "saz.asc", 371 "slope.asc", 372 "cur.asc", 373 "cbd.asc", 374 "cbh.asc", 375 "ccf.asc", 376 "py.asc", 377 "fmc.asc", 378 ] 379 Elevation = npfull(NCells, npnan) 380 SAZ = npfull(NCells, npnan) 381 PS = npfull(NCells, npnan) 382 Curing = npfull(NCells, npnan) 383 CBD = npfull(NCells, npnan) 384 CBH = npfull(NCells, npnan) 385 CCF = npfull(NCells, npnan) 386 PY = npfull(NCells, npnan) 387 FMC = npfull(NCells, npnan) 388 389 for name in filenames: 390 ff = p / name 391 if ff.exists() == True: 392 aux = 0 393 with open(ff, "r") as f: 394 filelines = f.readlines() 395 396 line = filelines[4].replace("\n", "") 397 parts = line.split() 398 399 if parts[0] != "cellsize": 400 print("line=", line) 401 raise RuntimeError("Expected cellsize on line 5 of " + ff) 402 cellsize = float(parts[1]) 403 404 row = 1 405 406 # Read the ASCII file with the grid structure 407 for row in range(6, len(filelines)): 408 line = filelines[row] 409 line = line.replace("\n", "") 410 line = " ".join(line.split()) 411 line = line.split(" ") 412 # print(line) 413 414 for c in line: 415 if name == "elevation.asc": 416 Elevation[aux] = float(c) 417 aux += 1 418 if name == "saz.asc": 419 SAZ[aux] = float(c) 420 aux += 1 421 if name == "slope.asc": 422 PS[aux] = float(c) 423 aux += 1 424 if name == "cbd.asc": 425 CBD[aux] = float(c) 426 aux += 1 427 if name == "cbh.asc": 428 CBH[aux] = float(c) 429 aux += 1 430 if name == "ccf.asc": 431 CCF[aux] = float(c) 432 aux += 1 433 if name == "curing.asc": 434 Curing[aux] = float(c) 435 aux += 1 436 if name == "py.asc": 437 PY[aux] = float(c) 438 aux += 1 439 if name == "fmc.asc": 440 FMC[aux] = float(c) 441 aux += 1 442 443 else: 444 print(" No", name, "file, filling with NaN") 445 446 return Elevation, SAZ, PS, Curing, CBD, CBH, CCF, PY, FMC
Reads *.asc files and returns an array per each ASCII file with the correspondant information per each cell. Currently supports elevation, ascpect, slope, curing, canopy bulk density, crown base height, conifer percent dead fir, probability of ignition and foliar moisture content.
Args: InFolder (string): Path to data folder. NCells (int): Number of cells in grid.
Returns: list [float]: List of elevations of each cell list [float]: List of aspect of each cell list [float]: List of slope of each cell list [float]: List of curing degree of each cell list [float]: List of canopy bulk density of each cell list [float]: List of crown base height of each cell list [float]: List of conifer percent dead fir of each cell list [float]: List of ignition probability of each cell list [float]: List of foliar moisture content of each cell
450def GenerateDat( 451 GFuelType: list, 452 GFuelTypeN: list, 453 Elevation: list, 454 PS: list, 455 SAZ: list, 456 Curing: list, 457 CBD: list, 458 CBH: list, 459 CCF: list, 460 PY: list, 461 FMC: list, 462 InFolder: str, 463) -> DataFrame: 464 """ 465 Reads forest information and generates Data.csv file 466 467 Args: 468 GFuelType (list [int]): List of forest grid with fuel code number, where non fuel are represented as 0 469 GFuelTypeN (list [string]): List of forest grid with fuel code name, where non fuel are represented as NF. 470 Elevation (list [float]): List of elevations of each cell 471 PS (list [float]): List of slope of each cell 472 SAZ (list [float]): List of aspect of each cell 473 Curing (list [float]): List of curing degree of each cell 474 CBD (list [float]): List of canopy bulk density of each cell 475 CBH (list [float]): List of crown base height of each cell 476 CCF (list [float]): List of conifer percent dead fir of each cell 477 PY (list [float]): List of ignition probability of each cell 478 FMC (list [float]): List of foliar moisture content of each cell 479 InFolder (string): Path to data folder. 480 481 Returns: 482 483 Dataframe: Dataframe containing information of forest 484 """ # fmt:skip 485 p = Path(InFolder) 486 # DF columns 487 Columns = [ 488 "fueltype", 489 "lat", 490 "lon", 491 "elev", 492 "ws", 493 "waz", 494 "ps", 495 "saz", 496 "cur", 497 "cbd", 498 "cbh", 499 "ccf", 500 "ftypeN", 501 "fmc", 502 "py", 503 ] 504 505 # Dataframe 506 DF = DataFrame(columns=Columns) 507 DF["fueltype"] = [x for x in GFuelType] 508 DF["elev"] = Elevation 509 DF["ps"] = PS 510 DF["saz"] = SAZ 511 DF["cbd"] = CBD 512 DF["cbh"] = CBH 513 DF["ccf"] = CCF 514 DF["py"] = PY 515 DF["fmc"] = FMC 516 DF["lat"] = npzeros(len(GFuelType)) + 51.621244 517 DF["lon"] = npzeros(len(GFuelType)).astype(int) - 115.608378 518 519 # Populate fuel type number 520 DF["ftypeN"] = GFuelTypeN 521 # print(np.asarray(GFuelTypeN).flatten()) 522 523 # Data File 524 filename = p / "Data.csv" 525 DF.to_csv(path_or_buf=filename, index=False, index_label=False, header=True) 526 return DF
Reads forest information and generates Data.csv file
Args: GFuelType (list [int]): List of forest grid with fuel code number, where non fuel are represented as 0 GFuelTypeN (list [string]): List of forest grid with fuel code name, where non fuel are represented as NF. Elevation (list [float]): List of elevations of each cell PS (list [float]): List of slope of each cell SAZ (list [float]): List of aspect of each cell Curing (list [float]): List of curing degree of each cell CBD (list [float]): List of canopy bulk density of each cell CBH (list [float]): List of crown base height of each cell CCF (list [float]): List of conifer percent dead fir of each cell PY (list [float]): List of ignition probability of each cell FMC (list [float]): List of foliar moisture content of each cell InFolder (string): Path to data folder.
Returns:
Dataframe: Dataframe containing information of forest
529def GenDataFile(InFolder: str, Simulator: str) -> None: 530 """Main function that reads information available in folder and generates Data.csv file 531 532 Args: 533 InFolder (string): Path to data folder. 534 Simulator (string): Simulator version, currently only supports "K" (for kitral) and "S" (for Scott & Burgan) 535 536 Return: 537 None 538 """ # fmt:skip 539 p = Path(InFolder) 540 if Simulator == "K": 541 FBPlookup = p / "kitral_lookup_table.csv" 542 elif Simulator == "S": 543 FBPlookup = p / "spain_lookup_table.csv" 544 else: # beta version 545 FBPlookup = p / "spain_lookup_table.csv" 546 547 FBPDict, _ = Lookupdict(FBPlookup) 548 549 FGrid = p / "fuels.asc" 550 GFuelTypeN, GFuelType, _, _, _, _, _ = ForestGrid(FGrid, FBPDict) 551 552 NCells = len(GFuelType) 553 Elevation, SAZ, PS, Curing, CBD, CBH, CCF, PY, FMC = DataGrids(InFolder, NCells) 554 GenerateDat(GFuelType, GFuelTypeN, Elevation, PS, SAZ, Curing, CBD, CBH, CCF, PY, FMC, InFolder)
Main function that reads information available in folder and generates Data.csv file
Args: InFolder (string): Path to data folder. Simulator (string): Simulator version, currently only supports "K" (for kitral) and "S" (for Scott & Burgan)
Return: None