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)
def multiDayRadiant(camlist, start, end, outdir=None, shwr=None, datadir=None):
 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