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
def Lookupdict(filename: Union[pathlib.Path, str]) -> Tuple[dict, dict]:
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.

def ForestGrid( filename: str, Lookupdict: dict) -> Tuple[list[int], list[str], int, int, list[dict[str, Optional[list[int]]]], numpy.ndarray[Any, numpy.dtype[Any]], float]:
 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

def DataGrids( InFolder: str, NCells: int) -> Tuple[numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]]]:
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

def GenerateDat( GFuelType: list, GFuelTypeN: list, Elevation: list, PS: list, SAZ: list, Curing: list, CBD: list, CBH: list, CCF: list, PY: list, FMC: list, InFolder: str) -> pandas.core.frame.DataFrame:
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
def GenDataFile(InFolder: str, Simulator: str) -> None:
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