meteortools.rmsutils.multiDayRadiant
1# Copyright (C) 2018-2023 Mark McIntyre 2 3import os 4import glob 5import datetime 6try: 7 from Utils.ShowerAssociation import showerAssociation 8 import RMS.ConfigReader as cr 9except Exception: 10 print('RMS not available') 11import argparse 12import shutil 13 14 15def multiDayRadiant(camlist, start, end, outdir=None, shwr=None, datadir=None): 16 """ 17 Create a multi-day and/or multi-camera radiant map for cameras at the same geographic location. 18 19 Arguments: 20 camlist: [list] list of camera IDs eg ['UK0006','UK000F'] 21 start: [string] start date in YYYYMMDD format 22 end: [string] end date in YYYYMMDD format 23 outdir: [string] where to save the file to. Default is current directory 24 shwr: [string] Filter by shower eg PER. Default all showers. 25 datadir: [string] Where to look for the data. Default f:/videos/meteorcam. 26 27 Notes: 28 The function expects data to be stored in RMS folder structures as follows 29 {datadir}/{cameraid}/ConfirmedFiles/{cameraid_date_time_*} 30 31 Each folder must contain an FTPdetectinfo file and a platepars_all file. 32 The first-named folder must contain a valid RMS config file. 33 34 It is assumed that all cameras are at the same location. The output for cameras 35 at different locations has not been tested. 36 37 Output: 38 creates two files in outdir, a PNG containing an all-sky image of the radiants and 39 meteor tracks, and a text file containing the same information 40 41 """ 42 if datadir is None: 43 locfld = os.getenv('LOCALFOLDER', default='f:/videos/meteorcam/fireballs') 44 datadir, _ = os.path.split(locfld) 45 if outdir is None: 46 outdir = '.' 47 print(f'stacking {camlist} for dates {start},{end}, reading from {datadir}, saving to {outdir}') 48 49 sdt = datetime.datetime.strptime(start, '%Y%m%d') 50 edt = datetime.datetime.strptime(end, '%Y%m%d') 51 d = sdt 52 dir_paths = [] 53 while d <= edt: 54 dtstr = d.strftime('%Y%m%d') 55 for cam in camlist: 56 cam = cam.upper() 57 camdir = os.path.join(datadir, cam, 'ConfirmedFiles') 58 dirs = glob.glob1(camdir, f'{cam}_{dtstr}*') 59 if len(dirs) > 0: 60 srcdir = os.path.join(camdir, dirs[0]) 61 ftpdet = os.path.join(srcdir, f'FTPdetectinfo_{dirs[0]}.txt') 62 if os.path.isfile(ftpdet): 63 print(f'using {ftpdet}') 64 dir_paths.append(ftpdet) 65 d = d + datetime.timedelta(days=1) 66 cfgdir, _ = os.path.split(dir_paths[0]) 67 config = cr.loadConfigFromDirectory('.config', cfgdir) 68 69 # file will be created here, need to preserve any existing file then restore afterwards 70 targdir, _ = os.path.split(dir_paths[-1]) 71 prevfiles = glob.glob1(targdir, '*radiants.png') 72 if len(prevfiles) > 0: 73 if os.path.isfile(os.path.join(targdir, prevfiles[0]+'.tmp')): 74 os.remove(os.path.join(targdir, prevfiles[0]+'.tmp')) 75 os.rename(os.path.join(targdir, prevfiles[0]), os.path.join(targdir, prevfiles[0]+'.tmp')) 76 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 77 if len(prevfilestxt) > 0: 78 if os.path.isfile(os.path.join(targdir, prevfilestxt[0]+'.tmp')): 79 os.remove(os.path.join(targdir, prevfilestxt[0]+'.tmp')) 80 os.rename(os.path.join(targdir, prevfilestxt[0]), os.path.join(targdir, prevfilestxt[0]+'.tmp')) 81 82 # Perform shower association 83 associations, shower_counts = showerAssociation(config, dir_paths, 84 shower_code=shwr, show_plot=False, save_plot=True, plot_activity=True, 85 flux_showers=False, color_map='gist_ncar') 86 87 prevfiles = glob.glob1(targdir, '*radiants.png') 88 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 89 newn = prevfiles[0] 90 newntxt = prevfilestxt[0] 91 if shwr is not None: 92 newn = shwr + newn[6:] 93 newntxt = shwr + newntxt[6:] 94 else: 95 newn = "ALL" + newn[6:] 96 newntxt = "ALL" + newntxt[6:] 97 shutil.copyfile(os.path.join(targdir, prevfiles[0]), os.path.join(outdir, newn)) 98 shutil.copyfile(os.path.join(targdir, prevfilestxt[0]), os.path.join(outdir, newntxt)) 99 os.remove(os.path.join(targdir, prevfiles[0])) 100 os.remove(os.path.join(targdir, prevfilestxt[0])) 101 102 prevfiles = glob.glob1(targdir, '*radiants.png') 103 if len(prevfiles) > 0: 104 os.rename(os.path.join(targdir, prevfiles[0])+'.tmp', os.path.join(targdir, prevfiles[0])) 105 106 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 107 if len(prevfilestxt) > 0: 108 os.rename(os.path.join(targdir, prevfilestxt[0])+'.tmp', os.path.join(targdir, prevfilestxt[0])) 109 return 110 111 112if __name__ == '__main__': 113 114 arg_parser = argparse.ArgumentParser(description="Perform multiday/camera radiant mapping.") 115 116 arg_parser.add_argument('cams', metavar='CAMS', nargs='+', type=str, 117 help='List of cameras, comma-separated.') 118 119 arg_parser.add_argument('dates', metavar='DATES', nargs='+', type=str, 120 help='Start and end date, comma-separated in yyyymmdd format.') 121 122 arg_parser.add_argument('-s', '--shower', metavar='SHOWER', type=str, 123 help="Associate just this single shower given its code (e.g. PER, ORI, ETA).") 124 125 arg_parser.add_argument('-o', '--outdir', metavar='OUTDIR', type=str, 126 help="Where to save the output file.") 127 128 # Parse the command line arguments 129 cml_args = arg_parser.parse_args() 130 cams = cml_args.cams[0] 131 if ',' in cams: 132 cams = cams.split(',') 133 else: 134 cams = [cams] 135 136 dates = cml_args.dates[0] 137 if ',' in dates: 138 start, end = dates.split(',') 139 else: 140 start = dates 141 end = start 142 143 shwr = None 144 if cml_args.shower: 145 shwr = cml_args.shower 146 147 outdir = '.' 148 if cml_args.outdir: 149 outdir = cml_args.outdir 150 151 multiDayRadiant(cams, start, end, outdir, shwr)
16def multiDayRadiant(camlist, start, end, outdir=None, shwr=None, datadir=None): 17 """ 18 Create a multi-day and/or multi-camera radiant map for cameras at the same geographic location. 19 20 Arguments: 21 camlist: [list] list of camera IDs eg ['UK0006','UK000F'] 22 start: [string] start date in YYYYMMDD format 23 end: [string] end date in YYYYMMDD format 24 outdir: [string] where to save the file to. Default is current directory 25 shwr: [string] Filter by shower eg PER. Default all showers. 26 datadir: [string] Where to look for the data. Default f:/videos/meteorcam. 27 28 Notes: 29 The function expects data to be stored in RMS folder structures as follows 30 {datadir}/{cameraid}/ConfirmedFiles/{cameraid_date_time_*} 31 32 Each folder must contain an FTPdetectinfo file and a platepars_all file. 33 The first-named folder must contain a valid RMS config file. 34 35 It is assumed that all cameras are at the same location. The output for cameras 36 at different locations has not been tested. 37 38 Output: 39 creates two files in outdir, a PNG containing an all-sky image of the radiants and 40 meteor tracks, and a text file containing the same information 41 42 """ 43 if datadir is None: 44 locfld = os.getenv('LOCALFOLDER', default='f:/videos/meteorcam/fireballs') 45 datadir, _ = os.path.split(locfld) 46 if outdir is None: 47 outdir = '.' 48 print(f'stacking {camlist} for dates {start},{end}, reading from {datadir}, saving to {outdir}') 49 50 sdt = datetime.datetime.strptime(start, '%Y%m%d') 51 edt = datetime.datetime.strptime(end, '%Y%m%d') 52 d = sdt 53 dir_paths = [] 54 while d <= edt: 55 dtstr = d.strftime('%Y%m%d') 56 for cam in camlist: 57 cam = cam.upper() 58 camdir = os.path.join(datadir, cam, 'ConfirmedFiles') 59 dirs = glob.glob1(camdir, f'{cam}_{dtstr}*') 60 if len(dirs) > 0: 61 srcdir = os.path.join(camdir, dirs[0]) 62 ftpdet = os.path.join(srcdir, f'FTPdetectinfo_{dirs[0]}.txt') 63 if os.path.isfile(ftpdet): 64 print(f'using {ftpdet}') 65 dir_paths.append(ftpdet) 66 d = d + datetime.timedelta(days=1) 67 cfgdir, _ = os.path.split(dir_paths[0]) 68 config = cr.loadConfigFromDirectory('.config', cfgdir) 69 70 # file will be created here, need to preserve any existing file then restore afterwards 71 targdir, _ = os.path.split(dir_paths[-1]) 72 prevfiles = glob.glob1(targdir, '*radiants.png') 73 if len(prevfiles) > 0: 74 if os.path.isfile(os.path.join(targdir, prevfiles[0]+'.tmp')): 75 os.remove(os.path.join(targdir, prevfiles[0]+'.tmp')) 76 os.rename(os.path.join(targdir, prevfiles[0]), os.path.join(targdir, prevfiles[0]+'.tmp')) 77 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 78 if len(prevfilestxt) > 0: 79 if os.path.isfile(os.path.join(targdir, prevfilestxt[0]+'.tmp')): 80 os.remove(os.path.join(targdir, prevfilestxt[0]+'.tmp')) 81 os.rename(os.path.join(targdir, prevfilestxt[0]), os.path.join(targdir, prevfilestxt[0]+'.tmp')) 82 83 # Perform shower association 84 associations, shower_counts = showerAssociation(config, dir_paths, 85 shower_code=shwr, show_plot=False, save_plot=True, plot_activity=True, 86 flux_showers=False, color_map='gist_ncar') 87 88 prevfiles = glob.glob1(targdir, '*radiants.png') 89 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 90 newn = prevfiles[0] 91 newntxt = prevfilestxt[0] 92 if shwr is not None: 93 newn = shwr + newn[6:] 94 newntxt = shwr + newntxt[6:] 95 else: 96 newn = "ALL" + newn[6:] 97 newntxt = "ALL" + newntxt[6:] 98 shutil.copyfile(os.path.join(targdir, prevfiles[0]), os.path.join(outdir, newn)) 99 shutil.copyfile(os.path.join(targdir, prevfilestxt[0]), os.path.join(outdir, newntxt)) 100 os.remove(os.path.join(targdir, prevfiles[0])) 101 os.remove(os.path.join(targdir, prevfilestxt[0])) 102 103 prevfiles = glob.glob1(targdir, '*radiants.png') 104 if len(prevfiles) > 0: 105 os.rename(os.path.join(targdir, prevfiles[0])+'.tmp', os.path.join(targdir, prevfiles[0])) 106 107 prevfilestxt = glob.glob1(targdir, '*radiants.txt') 108 if len(prevfilestxt) > 0: 109 os.rename(os.path.join(targdir, prevfilestxt[0])+'.tmp', os.path.join(targdir, prevfilestxt[0])) 110 return
Create a multi-day and/or multi-camera radiant map for cameras at the same geographic location.
Arguments:
camlist: [list] list of camera IDs eg ['UK0006','UK000F']
start: [string] start date in YYYYMMDD format
end: [string] end date in YYYYMMDD format
outdir: [string] where to save the file to. Default is current directory
shwr: [string] Filter by shower eg PER. Default all showers.
datadir: [string] Where to look for the data. Default f:/videos/meteorcam.
Notes:
The function expects data to be stored in RMS folder structures as follows
{datadir}/{cameraid}/ConfirmedFiles/{cameraid_date_time_*}
Each folder must contain an FTPdetectinfo file and a platepars_all file.
The first-named folder must contain a valid RMS config file.
It is assumed that all cameras are at the same location. The output for cameras
at different locations has not been tested.
Output: creates two files in outdir, a PNG containing an all-sky image of the radiants and meteor tracks, and a text file containing the same information