Newer
Older
""" FireGdf_sfs
Module for creating geojson summary for temporal evolution of each single fire
(large active fires up to the present time step)
Large fires are fires with area > falim
List of geojson types
---------------------
* fperim(''): fire basic attributes and perimeter geometry
* fline('FL'): active fire line geometry
* NFP('NFP'): new fire pixels
List of functions
-----------------
* make_fire_history
* merge_fires
* save_gdf_1fire
* save_gdf_trng
Modules required
----------------
* FireObj
* FireIO
* FireConsts
"""
warnings.simplefilter(action='ignore', category=FutureWarning)
# Use a logger to record console output
from FireLog import logger
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def getdd(layer):
''' Get attributes names and formats for different gpkg layers
'''
# # attributes name and data types (in addition to geometries)
if layer == "perimeter":
dd = {
"n_pixels": "int", # number of total pixels
"n_newpixels": "int", # number of new pixels
"farea": "float", # fire size
"fperim": "float", # fire perimeter length
"flinelen": "float", # active fire front line length
"duration": "float", # fire duration
"pixden": "float", # fire pixel density
"meanFRP": "float", # mean FRP of the new fire pixels
"t": "datetime64",
}
elif layer == "fireline":
dd = {
"t": "datetime64",
}
elif layer == "newfirepix":
dd = {
"t": "datetime64",
}
elif layer == "nfplist":
dd = {
"x": "float",
"y": "float",
"frp": "float",
"DS": "float",
"DT": "float",
"ampm": "str",
"datetime": "datetime64",
"sat": "str",
}
return dd
def find_largefires(allfires, falim=4):
""" Given an allfires object, extract large fires to be used for single fire
recording. Only active fires or sleepers are considered.
Parameters
----------
allfires : Allfires obj
the allfires object at a given time step
falim : float
the area threshold (km) for large fire
Returns
-------
large_ids : list
the list of large fire IDs
"""
large_ids = [
fid
for fid in (allfires.fids_active + allfires.fids_sleeper)
if allfires.fires[fid].farea > falim
]
def find_mergefires_ct(allfires, fid):
""" Find fires that are merged to fire (fid) at time t and started before t
allfires : Allfires obj
the allfires object at a given time step
fid : int
the target fire ID
t : tuple (y,m,d,ampm)
the target merging time
Returns
-------
fids_m : list
the list of fire IDs that are merged to fire (fid) at time t
t = allfires.t
# fids_m = list(sorted([h[0] for h in allfires.heritages if
# ((allfires.fires[h[0]].t_ed == t) & (allfires.fires[h[0]].t_st != t)
# & (h[1] == fid))]))
fids_m = []
for h in allfires.heritages:
if h[1] == fid:
f_m = allfires.fires[h[0]]
if (f_m.t_ed == t) & (f_m.t_st != t):
fids_m.append(h[0])
def merge_fires(gdf_1d, fid, t, sfkeys):
""" merge fire perimeters of all fires with the same merge id
gdf : geopandas DataFrame
the gdf containing all entries that should be merged
fid: the mergeid of the fire
Returns
-------
gdf_diss : geopandas DataFrame
the gdf containing a merged geometry and summary stats
gdf_1d["mergeid"] = fid
gdf_diss = gdf_1d.dissolve(by="mergeid")
# gdf_sf.loc[t_m,'geometry'] = gdf_sf.loc[t_m,'geometry'].union(gs_t_m['geometry'])
if "n_pixels" in sfkeys:
gdf_diss.loc[fid, "n_pixels"] = sum(gdf_1d.n_pixels)
if "n_newpixels" in sfkeys:
gdf_diss.loc[fid, "n_newpixels"] = sum(gdf_1d.n_newpixels)
if "farea" in sfkeys:
gdf_diss.loc[fid, "farea"] = sum(gdf_1d.farea)
if "fperim" in sfkeys:
gdf_diss.loc[fid, "fperim"] = sum(gdf_1d.fperim)
if "flinelen" in sfkeys:
gdf_diss.loc[fid, "flinelen"] = sum(gdf_1d.flinelen)
if "t" in sfkeys:
gdf_diss.loc[fid, "t"] = FireTime.t2dt(t)
if ("pixden" in sfkeys) & ("farea" in sfkeys):
gdf_1d = gdf_1d.assign(
pixweigh=gdf_1d["pixden"] * gdf_1d["farea"]
) ## IS THIS CORRECT?
gdf_diss.loc[fid, "pixden"] = sum(gdf_1d.pixweigh) / sum(gdf_1d.farea)
if ("meanFRP" in sfkeys) & ("n_pixels" in sfkeys):
gdf_1d = gdf_1d.assign(FRPweigh=gdf_1d["meanFRP"] * gdf_1d["n_pixels"])
gdf_diss.loc[fid, "meanFRP"] = sum(gdf_1d.FRPweigh) / sum(gdf_1d.n_pixels)
gdf_diss = gdf_diss.reset_index().drop(columns="mergeid")
def make_sf(t, regnm, layer, fids_m, fid):
""" At a given time step, create single row DataFrame for a target fire fid
- read snapshot gpkg files for the time step (t, regnm, layer)
- extract records (sfkeys) for target fire and fires merged to it (fids_m)
- merge the extracted records
- create gdf ready for making single fire time series
t : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' of time
regnm : str
the study region name (used for reading previous day's data)
fids_m : list
the list of fire IDs needed to merge (1-element list is ok)
sfkeys : list
the attributes (geometry excluded) used for making single fire time series
gdf_1d : Geopandas DataFrame
the 1-row gdf for the single fire
import FireIO, FireTime
import pandas as pd
import geopandas as gpd
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
dd = getdd(layer)
sfkeys = list(dd.keys())
# extract rows for fires merged to the target fire
gdf = FireIO.load_gpkgobj(
t, regnm, layer=layer
) # read daily gdf: active and sleeper only
# extract rows with fireID in fids_m only
if gdf is None:
return None
idx = [i for i in fids_m if i in list(gdf.index)]
if len(idx) == 0: # if no rows satistying condition, return None
return None
gdf_1d = gdf.loc[idx] # extract all fires merged to fid
gdf_1d = gdf_1d[
sfkeys + ["geometry"]
] # drop some columns not used in single fire gpkg
gdf_1d = gdf_1d.reset_index().drop(columns="fireID")
# if there are multiple rows (fires), merge them
if len(gdf_1d) > 1:
gdf_1d = merge_fires(gdf_1d, fid, t, sfkeys)
# # make sure the fireID is correct (this is needed to merge all fires)
# gdf_1d['fireID'] = fid
# # change index to date; maybe no need to drop FireID?
# gdf_1d.index = [FireTime.t2dt(t)]
return gdf_1d
def make_sf_nfplist(allfires, t, regnm, fids):
""" At a given time step, create single row DataFrame for all newly detected
pixels associated with fires fids.
Parameters
----------
t : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' of time
regnm : str
the study region name (used for reading previous day's data)
fids : list
the list of fire IDs needed to merge (1-element list is ok)
sfkeys : list
the attributes (geometry excluded) used for making single fire time series
Returns
-------
gdf_1d : Geopandas DataFrame
the 1-row gdf for the single fire
"""
import FireIO, FireTime
import pandas as pd
import geopandas as gpd
from FireConsts import epsg
dd = getdd('nfplist')
sfkeys = list(dd.keys())
allfires = FireIO.load_fobj(t, regnm, activeonly=False)
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# record all nfps for all fires with fids to make nfplist at t
gdf_1d = None
for fid in fids:
if fid in allfires.fids_valid: # only record newpixels for valid fires
f = allfires.fires[fid]
plist = []
for p in f.newpixels:
p_attrs = []
for k in sfkeys:
p_attrs.append(getattr(p, k))
plist.append(p_attrs)
if len(plist) > 0:
df = pd.DataFrame(plist)
df.columns = sfkeys
gdf_1f = gpd.GeoDataFrame(
df,
crs="epsg:" + str(epsg),
geometry=gpd.points_from_xy(df.x, df.y),
)
# also add t variable (detection 12-hourly time step)
gdf_1f['t'] = FireTime.t2dt(t)
if gdf_1d is None:
gdf_1d = gdf_1f
else:
gdf_1d = gdf_1d.append(gdf_1f)
def make_sfts_1f(allfires,f, fid, fids_m, regnm, layer="perimeter"):
""" create the single large fire gpkg file at time t.
In this approximate approach, the snapshots for fid between t_st and t_ed are
extracted and concategated. In addition, the snapshots for fires merged to
this fire (with heritage target as fid) are also added (except for the t_ed
when the fire with fid already contains the contributions from these merged
fires).
Parameters
----------
allfires : Allfires obj
the allfires object at a given time step
fid : int
the target fire ID
regnm : str
the study region name (used for reading previous day's data)
Returns
-------
gdf_all : Geopandas DataFrame
the full time series gdf for the single fire
endloop = False # flag to control the ending of the loop
t = list(f.t_st) # t is the time (year,month,day,ampm) for each step
gdf_1d = make_sf_nfplist(allfires, t, regnm, fids_m+[fid])
gdf_1d = make_sf(t, regnm, layer, fids_m+[fid], fid)
# append daily row to gdf_all
# if FireTime.t_dif(t, f.t_st) == 0:
if (gdf_1d is not None):
if (gdf_all is None):
gdf_all = gdf_1d
else:
gdf_all = gdf_all.append(gdf_1d, ignore_index=True)
# - if t reaches ted, set endloop to True to stop the loop
endloop = True
# - update t with the next time stamp
def update_sfts_1f(allfires, allfires_pt, fid, regnm, layer="perimeter"):
""" update the single large fire gpkg file at time t
allfires : Allfires obj
the allfires object at a given time step
the target fire ID
regnm : str
the study region name (used for reading previous day's data)
Returns
-------
gdf_all : Geopandas DataFrame
the full time series gdf for the single fire
import FireTime, FireIO
import geopandas as gpd
# the target single large fire and target time
f = allfires.fires[fid]
t = allfires.t
# try to read small fire file at previous time step (gdf_sf_pt)
gdf_sf_pt = FireIO.load_gpkgsfs(t_pt, fid, regnm, layer=layer)
# if no gdf_sf_pt, create historical time series using the make_sfts_1f()
# if the running is fast enough, no need to use the code in the 'else' part...
# find all fires merged to this fire at any time step
fids_m = list(sorted([h[0] for h in allfires.heritages if h[1] == fid]))
gdf_all = make_sfts_1f(allfires,f,fid, fids_m, regnm, layer=layer)
# when gdf_sf_pt is present, to save time, read it and add fires just merged at t
else:
# use gdf_sf_pt as basis, and only need to add changes at t and newly merged fires
gdf_all = gdf_sf_pt
# find all fires merged to this fire at present time step
# loop over all merged fires and add to gdf_all
for fid_m in fids_m:
# create historical time series of all newly merged fires at t_pt
# using the same approach as the case of gdf_sf_pt==None
f_pt = allfires_pt.fires[fid_m]
fids_mm = list(sorted([h[0] for h in allfires_pt.heritages if h[1] == fid_m]))
gdf_all_m = make_sfts_1f(allfires_pt,f_pt, fid_m, fids_mm, regnm, layer=layer)
gdf_all = gdf_all.append(gdf_all_m, ignore_index=True)
# also add current fire record at present time time step (for fid at t only)
gdf_ct = make_sf_nfplist(allfires, t, regnm, [fid])
else:
gdf_ct = make_sf(t, regnm, layer, [fid], fid)
# for k,tp in dd.items():
# gdf_ct[k] = gdf_ct[k].astype(tp)
if gdf_all is None:
print('Warning gdf_all is None. Returning...')
return gdf_all
if layer == 'nfplist':
gdf_all['t'] = gdf_all['t'].astype('datetime64')
# gdf_all = gdf_all.reset_index()
return gdf_all
def save_sfts_all(queue: multiprocessing.Queue, t, regnm, layers=["perimeter", "fireline", "newfirepix", "nfplist"]):
"""Wrapper to create and save gpkg files at a time step for all large fires
t : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' of time
regnm : str
region name
allfires = FireIO.load_fobj(t, regnm, activeonly=False)
t_pt = FireTime.t_nb(t, nb="previous")
# read allfires object at previous time step
allfires_pt = FireIO.load_fobj(t_pt, regnm, activeonly=False)
# loop over all fires, and create/save gpkg files for each single fire
queue.put([allfires, allfires_pt, fid, regnm, layers])
logger.info(f'Time sending to queue for timestep {t} with multiproc: {(tend-tstart)/60.} minutes')
def worker_save_sfts_1f(queue: multiprocessing.Queue):
"""pop off the queue and call `save_sfts_1f`
:param queue:
:return:
"""
while True:
payload = queue.get()
# check for poison pill
if payload is None:
break
# unpack
allfires, allfires_pt, fid, regnm, layers = payload
logger.info(f'[ WORKER {os.getpid()} ]: writing out LF={fid}')
save_sfts_1f(allfires, allfires_pt, fid, regnm, layers)
def save_sfts_1f(allfires, allfires_pt, fid, regnm, layers=["perimeter", "fireline", "newfirepix", "nfplist"]):
"""Wrapper to create and save gpkg files at a time step for all large fires
Parameters
----------
t : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' of time
regnm : str
region name
"""
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
logger.info(f'Generating LF data for fid {fid}')
tstart = time.time()
f = allfires.fires[fid]
if "perimeter" in layers:
tstart = time.time()
gdf_fperim = update_sfts_1f(allfires, allfires_pt, fid, regnm, layer="perimeter")
tend = time.time()
logger.info(f"{(tend-tstart)/60.} minutes used for updating perimeter layer.")
tstart = time.time()
FireIO.save_gpkgsfs(allfires.t, fid, regnm, gdf_fperim=gdf_fperim)
tend = time.time()
logger.info(f"{(tend-tstart)/60.} minutes used for I/O data perimeter layer.")
if "fireline" in layers:
gdf_fline = update_sfts_1f(allfires,allfires_pt, fid, regnm, layer="fireline")
FireIO.save_gpkgsfs(allfires.t, fid, regnm, gdf_fline=gdf_fline)
if "newfirepix" in layers:
gdf_nfp = update_sfts_1f(allfires,allfires_pt, fid, regnm, layer="newfirepix")
FireIO.save_gpkgsfs(allfires.t, fid, regnm, gdf_nfp=gdf_nfp)
if "nfplist" in layers:
gdf_nfplist = update_sfts_1f(allfires,allfires_pt, fid, regnm, layer="nfplist")
FireIO.save_gpkgsfs(allfires.t, fid, regnm, gdf_nfplist=gdf_nfplist)
tend = time.time()
logger.info(f"{(tend-tstart)/60.} minutes used to save Largefire data for fid {fid}.")
def save_sfts_trng(
tst, ted, regnm, layers=["perimeter", "fireline", "newfirepix", "nfplist"]
):
"""Wrapper to create and save all gpkg files for a time period
Parameters
----------
tst : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' at start time
ted : tuple, (int,int,int,str)
the year, month, day and 'AM'|'PM' at end time
regnm : str
region name
# loop over all days during the period
endloop = False # flag to control the ending olf the loop
t = list(tst) # t is the time (year,month,day,ampm) for each step
p = multiprocessing.Process(target=worker_save_sfts_1f, args=(queue,))
p.start()
workers.append(p)
logger.info('Single fire saving: '+str(t))
tstart = time.time()
try:
save_sfts_all(queue, t, regnm, layers=layers)
except Exception as exc:
logger.exception(exc)
tend = time.time()
logger.info(f"{(tend-tstart)/60.} minutes used to save Largefire data for this time.")
endloop = True
# - update t with the next time stamp
# wait all writer workers
for p in workers:
p.join()
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
def combine_sfts(regnm,yr,addFRAP=False):
''' Combine all large fire time series to a gpkg data, with the option to add fire name from FRAP data
used for a large region
Parameters
----------
regnm : str
the name of the region
yr : int
year
addFRAP : bool
if set to true, add fire name/id from FRAP database (require FRAP data and AT_FRAP function)
'''
import FireIO, os
from AT import AT_FRAP
import geopandas as gpd
from glob import glob
import pandas as pd
from FireTime import dt_dif
strdir = FireIO.get_gpkgsfs_dir(yr,regnm)
if addFRAP:
vFRAP = AT_FRAP.getFRAPyr(yr)
if vFRAP is not None:
vFRAP.geometry = vFRAP.geometry.buffer(0)
# get a list of all fids
fids = []
for f in glob(strdir+'/*.gpkg'):
fid = int(os.path.basename(f).split('.')[0].split('_')[0][1:])
fids.append(fid)
# loop over all fids
gdf_perim_all, gdf_fline_all, gdf_nfp_all, gdf_nfplist_all = None, None, None, None
for fid in set(fids):
print(fid,end=',')
# for each fire, find the last gpkg file
fnmlast = sorted(glob(strdir+'/F'+str(fid)+'_*.gpkg'))[-1]
# read the data (four layers)
gdf_perim = FireIO.gpd_read_file(fnmlast,layer='perimeter').to_crs(epsg=4326)
gdf_fline = FireIO.gpd_read_file(fnmlast,layer='fireline').to_crs(epsg=4326)
gdf_nfp = FireIO.gpd_read_file(fnmlast,layer='newfirepix').to_crs(epsg=4326)
gdf_nfplist = FireIO.gpd_read_file(fnmlast,layer='nfplist').to_crs(epsg=4326)
# add fire ID to the gdf
gdf_perim['FireID'] = fid
gdf_fline['FireID'] = fid
gdf_nfp['FireID'] = fid
gdf_nfplist['FireID'] = fid
# add duration to fline, nfp, and nfplist
t0 = pd.to_datetime(gdf_perim.iloc[0].t)
gdf_fline['duration'] = pd.to_datetime(gdf_fline['t']).apply(lambda x: dt_dif(x,t0))
gdf_nfp['duration'] = pd.to_datetime(gdf_nfp['t']).apply(lambda x: dt_dif(x,t0))
gdf_nfplist['duration'] = pd.to_datetime(gdf_nfplist['t']).apply(lambda x: dt_dif(x,t0))
# add FRAP fire name and id
if addFRAP:
if vFRAP is not None:
gFEDS = gdf_perim.iloc[-1].geometry
FRAPid,FRAPfnm = AT_FRAP.get_FRAPidfnm_from_geometry(vFRAP,gFEDS,fid)
if FRAPid is not None:
gdf_perim['FRAPid'] = FRAPid
gdf_perim['FRAPfnm'] = FRAPfnm
gdf_fline['FRAPid'] = FRAPid
gdf_fline['FRAPfnm'] = FRAPfnm
gdf_nfp['FRAPid'] = FRAPid
gdf_nfp['FRAPfnm'] = FRAPfnm
gdf_nfplist['FRAPid'] = FRAPid
gdf_nfplist['FRAPfnm'] = FRAPfnm
else:
gdf_perim['FRAPid'] = -1
gdf_perim['FRAPfnm'] = ''
gdf_fline['FRAPid'] = -1
gdf_fline['FRAPfnm'] = ''
gdf_nfp['FRAPid'] = -1
gdf_nfp['FRAPfnm'] = ''
gdf_nfplist['FRAPid'] = -1
gdf_nfplist['FRAPfnm'] = ''
# combine all fids
if (gdf_perim_all is None):
gdf_perim_all = gdf_perim
gdf_fline_all = gdf_fline
gdf_nfp_all = gdf_nfp
gdf_nfplist_all = gdf_nfplist
else:
gdf_perim_all = gdf_perim_all.append(gdf_perim,ignore_index=True)
gdf_fline_all = gdf_fline_all.append(gdf_fline,ignore_index=True)
gdf_nfp_all = gdf_nfp_all.append(gdf_nfp,ignore_index=True)
gdf_nfplist_all = gdf_nfplist_all.append(gdf_nfplist,ignore_index=True)
# drop x and y columns for nfplist
gdf_nfplist_all = gdf_nfplist_all.drop(columns=['x','y'])
# save combined gdfs
fnmout = os.path.join(strdir,'largefires.gpkg')
gdf_perim_all.to_file(fnmout, driver="GPKG", layer="perimeter")
gdf_fline_all.to_file(fnmout, driver="GPKG", layer="fireline")
gdf_nfp_all.to_file(fnmout, driver="GPKG", layer="newfirepix")
gdf_nfplist_all.to_file(fnmout, driver="GPKG", layer="nfplist")
# return gdf_perim_all, gdf_fline_all, gdf_nfp_all, gdf_nfplist_all
def convert_sfts(regnm,yr,fids):
''' Convert a large fire time series to a gpkg data; usually used to process a single fire run
Parameters
----------
regnm : str
the name of the region
yr : int
year
fids : list of int
fire ids
'''
import FireIO, os
from AT import AT_FRAP
import geopandas as gpd
from glob import glob
import pandas as pd
from FireTime import dt_dif
strdir = FireIO.get_gpkgsfs_dir(yr,regnm)
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
# loop over all fids
gdf_perim_all, gdf_fline_all, gdf_nfp_all, gdf_nfplist_all = None, None, None, None
for fid in set(fids):
print(fid,end=',')
# for each fire, find the last gpkg file
fnmlast = sorted(glob(strdir+'/F'+str(fid)+'_*.gpkg'))[-1]
# read the data (four layers)
gdf_perim = FireIO.gpd_read_file(fnmlast,layer='perimeter').to_crs(epsg=4326)
gdf_fline = FireIO.gpd_read_file(fnmlast,layer='fireline').to_crs(epsg=4326)
gdf_nfp = FireIO.gpd_read_file(fnmlast,layer='newfirepix').to_crs(epsg=4326)
gdf_nfplist = FireIO.gpd_read_file(fnmlast,layer='nfplist').to_crs(epsg=4326)
# add fire ID to the gdf
gdf_perim['FireID'] = fid
gdf_fline['FireID'] = fid
gdf_nfp['FireID'] = fid
gdf_nfplist['FireID'] = fid
# add duration to fline, nfp, and nfplist
t0 = pd.to_datetime(gdf_perim.iloc[0].t)
gdf_fline['duration'] = pd.to_datetime(gdf_fline['t']).apply(lambda x: dt_dif(x,t0))
gdf_nfp['duration'] = pd.to_datetime(gdf_nfp['t']).apply(lambda x: dt_dif(x,t0))
gdf_nfplist['duration'] = pd.to_datetime(gdf_nfplist['t']).apply(lambda x: dt_dif(x,t0))
# combine all fids
if (gdf_perim_all is None):
gdf_perim_all = gdf_perim
gdf_fline_all = gdf_fline
gdf_nfp_all = gdf_nfp
gdf_nfplist_all = gdf_nfplist
else:
gdf_perim_all = gdf_perim_all.append(gdf_perim,ignore_index=True)
gdf_fline_all = gdf_fline_all.append(gdf_fline,ignore_index=True)
gdf_nfp_all = gdf_nfp_all.append(gdf_nfp,ignore_index=True)
gdf_nfplist_all = gdf_nfplist_all.append(gdf_nfplist,ignore_index=True)
# drop x and y columns for nfplist
gdf_nfplist_all = gdf_nfplist_all.drop(columns=['x','y'])
# save combined gdfs
fnmout = os.path.join(strdir,'largefires.gpkg')
gdf_perim_all.to_file(fnmout, driver="GPKG", layer="perimeter")
gdf_fline_all.to_file(fnmout, driver="GPKG", layer="fireline")
gdf_nfp_all.to_file(fnmout, driver="GPKG", layer="newfirepix")
gdf_nfplist_all.to_file(fnmout, driver="GPKG", layer="nfplist")
""" The main code to record time series of geojson data for a fire
"""
t1 = time.time()
# set the start and end time
save_sfts_trng(tst, ted, regnm="Creek")