def set_delarea(self, *args): ''' Set deletion area ''' # Turning DELAREA on if the given area exists: if areafilter.hasArea(args[0]): self.areaname = args[0] self.active = True # Initialize geovector previds sets for geoname, geovec in geovector.geovecs.items(): for limname in lims: key = geoname + limname self.previds[key] = set() self.geovecs[geoname] = np.array([geovec.gsmin, \ geovec.gsmax, geovec.trkmin, geovec.trkmax, geovec.vsmin, geovec.vsmax]) return True, f'Deletion area is set to {args[0]}' # Turning DELAREA off: if args[0][:2] == 'OF': # Deactivate delarea self.active = False self.name = '' return True, f'Deletion area is switched OFF' # Incorrect arguments: return False, 'Incorrect arguments for DELAREA function!'
def setArea(self, *args): ''' Set Experiment Area. Aicraft leaving the experiment area are deleted. Input can be exisiting shape name, or a box with optional altitude constrainsts.''' # if all args are empty, then print out the current area status if len(args) == 0: return True, "Area is currently " + ("ON" if self.active else "OFF") + \ "\nCurrent Area name is: " + str(self.name) # start by checking if the first argument is a string -> then it is an area name if isinstance(args[0], str) and len(args) == 1: if areafilter.hasArea(args[0]): # switch on Area, set it to the shape name self.name = args[0] self.active = True return True, "Area is set to " + str(self.name) elif args[0] == 'OFF' or args[0] == 'OF': # switch off the area areafilter.deleteArea(self.name) self.active = False self.name = None return True, "Area is switched OFF" else: # shape name is unknown return False, "Shapename unknown. Please create shapename first or shapename is misspelled!" # if first argument is a float -> then make a box with the arguments elif (isinstance(args[0], float) or isinstance(args[0], int)) and 4 <= len(args) <= 6: self.active = True self.name = 'DELAREA' areafilter.defineArea(self.name, 'BOX', args[:4], args[4:]) return True, "Area is ON. Area name is: " + str(self.name) else: return False, "Incorrect arguments" + \ "\nAREA Shapename/OFF or\n Area lat,lon,lat,lon,[top,bottom]"
def sectorcount(sw, name=''): if sw == 'LIST': if len(sectors) == 0: return True, 'No registered sectors available' else: return True, 'Registered sectors:', str.join(', ', sectors) elif sw == 'ADD': # Add new sector to list. if name in sectors: return True, 'Sector %s already registered.' % name elif areafilter.hasArea(name): # Add new area to the sector list, and add an initial inside count of traffic sectors.append(name) inside = areafilter.checkInside(name, traf.lat, traf.lon, traf.alt) previnside.append(set(np.array(traf.id)[inside])) return True, 'Added %s to sector list.' % name else: return False, "No area found with name '%s', create it first with one of the shape commands" % name else: # Remove area from sector list if name in sectors: idx = sectors.index(name) sectors.pop(idx) previnside.pop(idx) return True, 'Removed %s from sector list.' % name else: return False, "No sector registered with name '%s'." % name
def sectorcount(sw, name=''): if sw == 'LIST': if len(sectors) == 0: return True, 'No registered sectors available' else: return True, 'Registered sectors:', str.join(', ', sectors) elif sw == 'ADD': # Add new sector to list. if name in sectors: return True, 'Sector %s already registered.' % name elif areafilter.hasArea(name): # Add new area to the sector list, and add an initial inside count of traffic sectors.append(name) inside = areafilter.checkInside(name, traf.lat, traf.lon, traf.alt) previnside.append(set(np.array(traf.id)[inside])) return True, 'Added %s to sector list.' % name else: return False, "No area found with name '%s', create it first with one of the shape commands" % name else: # Remove area from sector list if name in sectors: idx = sectors.index(name) sectors.pop(idx) previnside.pop(idx) return True, 'Removed %s from sector list.' % name else: return False, "No sector registered with name '%s'." % name
def stackio(self, cmd: 'txt', name: 'txt' = ''): ''' Calculate a set of metrics within specified sectors. ''' print('BLAAA', cmd, name) if cmd == 'LIST': if not self.sectors: return True, 'No registered sectors available' return True, 'Registered sectors:', str.join(', ', self.sectors) elif cmd == 'ADDSECTOR': if name == 'ALL': for areaname in areafilter.basic_shapes.keys(): self.stackio('ADDSECTOR', areaname) # Add new sector to list. elif name in self.sectors: return False, 'Sector %s already registered.' % name elif areafilter.hasArea(name): if not self.sectors: self.fconv = open( 'output/' + stack.get_scenname() + 'convergence.csv', 'w') self.fsd = open( 'output/' + stack.get_scenname() + 'density.csv', 'w') self.feff = open( 'output/' + stack.get_scenname() + 'efficiency.csv', 'w') # Create the plot if this is the first sector plotter.plot('metrics.metrics.sectorsd', dt=2.5, title='Static Density', xlabel='Time', ylabel='Aircraft count', fig=1) plotter.plot('metrics.metrics.sectorconv', dt=2.5, title='Summed Pairwise Convergence', xlabel='Time', ylabel='Convergence', fig=2) self.effplot = plotter.Plot('metrics.metrics.sectoreff', title='Route Efficiency', plot_type='boxplot', xlabel='Sector', ylabel='Efficiency', fig=3) # Add new area to the sector list, and add an initial inside count of traffic self.sectors.append(name) self.acinside.append(SectorData()) plotter.legend(self.sectors, 1) return True, 'Added %s to sector list.' % name else: return False, "No area found with name '%s', create it first with one of the shape commands" % name else: # Remove area from sector list if name in self.sectors: idx = self.sectors.index(name) self.sectors.pop(idx) return True, 'Removed %s from sector list.' % name return False, "No sector registered with name '%s'." % name
def applygeovec(): # Apply each geovector for vec in geovecs: areaname = vec[0] if areafilter.hasArea(areaname): swinside = areafilter.checkInside(areaname, traf.lat, traf.lon, traf.alt) gsmin, gsmax, trkmin, trkmax, vsmin, vsmax = vec[1:] # -----Ground speed limiting # For now assume no wind: so use tas as gs if gsmin: casmin = vtas2cas(np.ones(traf.ntraf) * gsmin, traf.alt) usemin = traf.selspd < casmin traf.selspd[swinside & usemin] = casmin[swinside & usemin] if gsmax: casmax = vtas2cas(np.ones(traf.ntraf) * gsmax, traf.alt) usemax = traf.selspd > casmax traf.selspd[swinside & usemax] = casmax[swinside & usemax] #------ Limit Track(so hdg) # Max track interval is 180 degrees to avoid ambiguity of what is inside the interval if trkmin and trkmax: # Use degto180 to avodi problems for e.g interval [350,30] usemin = swinside & (degto180(traf.trk - trkmin) < 0 ) # Left of minimum usemax = swinside & (degto180(traf.trk - trkmax) > 0 ) # Right of maximum #print(usemin,usemax) traf.ap.trk[swinside & usemin] = trkmin traf.ap.trk[swinside & usemax] = trkmax # -----Ground speed limiting # For now assume no wind: so use tas as gs if vsmin: traf.selvs[swinside & (traf.vs < vsmin)] = vsmin # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs < vsmin)] = traf.alt[swinside & (traf.vs < vsmin)] + \ np.sign(vsmin)*200.*ft if vsmax: traf.selvs[swinside & (traf.vs > vsmax)] = vsmax # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs > vsmax)] = traf.alt[swinside & (traf.vs > vsmax)] + \ np.sign(vsmax)*200.*ft return
def color(self, name, r, g, b): ''' Set custom color for aircraft or shape. ''' if areafilter.hasArea(name): idx = self.objname.index(name) self.objcolor[idx] = (r, g, b) else: return False, 'No object found with name ' + name self.redrawradbg = True # redraw background return True
def color(self, name, r, g, b): ''' Set custom color for aircraft or shape. ''' if areafilter.hasArea(name): idx = self.objname.index(name) self.objcolor[idx] = (r, g, b) else: return False, 'No object found with name ' + name self.redrawradbg = True # redraw background return True
def set_area(self, *args): """ Set Experiment Area. Aircraft leaving this experiment area raise an error. Input can be existing shape name, or a box with optional altitude constraints. """ # Set both exp_area and del_area to the same size. curname = self.exp_area msgname = 'Experiment area' # If no args, print current area state. if not args: return True, f'{msgname} is currently ON (name={curname})' if self.active else \ f'{msgname} is currently OFF' # If the first argument is a string, it is an area name. if isinstance(args[0], str) and len(args) == 1: if areafilter.hasArea(args[0]): # Switch on area, set it to the shape name. self.exp_area = args[0] self.active = True # Initiate the loggers. self.flst_log.start(prefix=self.log_prefix) self.conf_log.start(prefix=self.log_prefix) self.flst_log.write(flst_vars) self.conf_log.write(conf_vars) return True, f'{msgname} is set to {args[0]}' elif args[0][:2] == 'OF': # Switch off the area and reset the logger. self.close_log() return True, f'{msgname} is switched OFF\nLogs are closed' elif args[0][:2] == 'ON': if not curname: return False, 'No area defined.' else: self.active = True return True, f'{msgname} switched ON (name={curname})' else: # Shape name is unknown. return False, 'Shapename unknown. ' + \ 'Please create shapename first or shapename is misspelled!' # If first argument is a float, make a box with the arguments. if isinstance(args[0], (float, int)) and 4 <= len(args) <= 6: self.active = True self.exp_area = 'EXPAREA' areafilter.defineArea('EXPAREA', 'BOX', args[:4], *args[4:]) # Initiate the loggers. self.flst_log.start(prefix=self.log_prefix) self.conf_log.start(prefix=self.log_prefix) self.flst_log.write(flst_vars) self.conf_log.write(conf_vars) return True, f'{msgname} is ON. Area name is: {self.exp_area}' else: return False, 'Incorrect arguments\n' + \ 'AREA Shapename/OFF or\n Area lat,lon,lat,lon,[top,bottom]'
def applygeovec(): # Apply each geovector for vec in geovecs: areaname = vec[0] if areafilter.hasArea(areaname): swinside = areafilter.checkInside(areaname, traf.lat, traf.lon, traf.alt) gsmin,gsmax,trkmin,trkmax,vsmin,vsmax = vec[1:] # -----Ground speed limiting # For now assume no wind: so use tas as gs if gsmin: casmin = vtas2cas(np.ones(traf.ntraf)*gsmin,traf.alt) usemin = traf.selspd<casmin traf.selspd[swinside & usemin] = casmin[swinside & usemin] if gsmax: casmax = vtas2cas(np.ones(traf.ntraf)*gsmax,traf.alt) usemax = traf.selspd > casmax traf.selspd[swinside & usemax] = casmax[swinside & usemax] #------ Limit Track(so hdg) # Max track interval is 180 degrees to avoid ambiguity of what is inside the interval if trkmin and trkmax: # Use degto180 to avodi problems for e.g interval [350,30] usemin = swinside & (degto180(traf.trk - trkmin)<0) # Left of minimum usemax = swinside & (degto180(traf.trk - trkmax)>0) # Right of maximum #print(usemin,usemax) traf.ap.trk[swinside & usemin] = trkmin traf.ap.trk[swinside & usemax] = trkmax # -----Ground speed limiting # For now assume no wind: so use tas as gs if vsmin: traf.selvs[swinside & (traf.vs<vsmin)] = vsmin # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs < vsmin)] = traf.alt[swinside & (traf.vs < vsmin)] + \ np.sign(vsmin)*200.*ft if vsmax: traf.selvs[swinside & (traf.vs > vsmax)] = vsmax # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs > vsmax)] = traf.alt[swinside & (traf.vs > vsmax)] + \ np.sign(vsmax)*200.*ft return
def set_area(self, *args, exparea=False): ''' Set Experiment Area. Aircraft leaving the experiment area are deleted. Input can be existing shape name, or a box with optional altitude constraints.''' curname = self.exparea if exparea else self.delarea msgname = 'Experiment area' if exparea else 'Deletion area' # if all args are empty, then print out the current area status if not args: return True, f'{msgname} is currently ON (name={curname})' if self.active else \ f'{msgname} is currently OFF' # start by checking if the first argument is a string -> then it is an area name if isinstance(args[0], str) and len(args) == 1: if areafilter.hasArea(args[0]): # switch on Area, set it to the shape name if exparea: self.exparea = args[0] else: self.delarea = args[0] self.active = True self.flst.start() self.conflog.start() return True, f'{msgname} is set to {args[0]}' if args[0][:2] == 'OF': # switch off the area and reset the logger self.active = False return True, f'{msgname} is switched OFF' if args[0][:2] == 'ON': if not self.name: return False, 'No area defined.' else: self.active = True return True, f'{msgname} switched ON (name={curname})' # shape name is unknown return False, 'Shapename unknown. ' + \ 'Please create shapename first or shapename is misspelled!' # if first argument is a float -> then make a box with the arguments if isinstance(args[0], (float, int)) and 4 <= len(args) <= 6: self.active = True if exparea: self.exparea = 'EXPAREA' areafilter.defineArea('EXPAREA', 'BOX', args[:4], *args[4:]) else: self.delarea = 'DELAREA' areafilter.defineArea('DELAREA', 'BOX', args[:4], *args[4:]) self.flst.start() self.conflog.start() return True, f'{msgname} is ON. Area name is: {"EXP" if exparea else "DEL"}AREA' return False, 'Incorrect arguments' + \ '\nAREA Shapename/OFF or\n Area lat,lon,lat,lon,[top,bottom]'
def color(self, name, r, g, b): ''' Set custom color for aircraft or shape. ''' data = dict(color=(r, g, b)) if name in bs.traf.id: data['acid'] = name self.custacclr[name] = (r, g, b) elif areafilter.hasArea(name): data['polyid'] = name areafilter.areas[name].raw['color'] = (r, g, b) else: return False, 'No object found with name ' + name bs.net.send_event(b'COLOR', data) return True
def color(self, name, r, g, b): ''' Set custom color for aircraft or shape. ''' data = dict(color=(r, g, b)) if name in bs.traf.groups: groupmask = bs.traf.groups.groups[name] data['groupid'] = groupmask self.custgrclr[groupmask] = (r, g, b) elif name in bs.traf.id: data['acid'] = name self.custacclr[name] = (r, g, b) elif areafilter.hasArea(name): data['polyid'] = name areafilter.basic_shapes[name].raw['color'] = (r, g, b) else: return False, 'No object found with name ' + name bs.net.send_event(b'COLOR', data, target=[b'*']) return True
def color(self, name, r, g, b): ''' Set custom color for aircraft or shape. ''' data = dict(color=(r, g, b)) if name in bs.traf.groups: groupmask = bs.traf.groups.groups[name] data['groupid'] = groupmask self.custgrclr[groupmask] = (r, g, b) elif name in bs.traf.id: data['acid'] = name self.custacclr[name] = (r, g, b) elif areafilter.hasArea(name): data['polyid'] = name areafilter.areas[name].raw['color'] = (r, g, b) else: return False, 'No object found with name ' + name bs.sim.send_event(b'COLOR', data) return True
def stackio(self, cmd, name): if cmd == 'LIST': if not self.sectors: return True, 'No registered sectors available' else: return True, 'Registered sectors:', str.join(', ', self.sectors) elif cmd == 'ADDSECTOR': if name == 'ALL': for name in areafilter.areas.keys(): self.stackio('ADDSECTOR', name) # Add new sector to list. elif name in self.sectors: return False, 'Sector %s already registered.' % name elif areafilter.hasArea(name): if not self.sectors: self.fconv = open('output/convergence.csv', 'w') self.fsd = open('output/density.csv', 'w') self.feff = open('output/efficiency.csv', 'w') # Create the plot if this is the first sector plotter.plot('metrics.metrics.sectorsd', dt=2.5, title='Static Density', xlabel='Time', ylabel='Aircraft count', fig=1) plotter.plot('metrics.metrics.sectorconv', dt=2.5, title='Summed Pairwise Convergence', xlabel='Time', ylabel='Convergence', fig=2) self.effplot = plotter.Plot('metrics.metrics.sectoreff', title='Route Efficiency', plot_type='boxplot', xlabel='Sector', ylabel='Efficiency', fig=3) # Add new area to the sector list, and add an initial inside count of traffic self.sectors.append(name) self.acinside.append(SectorData()) plotter.legend(self.sectors, 1) return True, 'Added %s to sector list.' % name else: return False, "No area found with name '%s', create it first with one of the shape commands" % name else: # Remove area from sector list if name in self.sectors: idx = self.sectors.index(name) self.sectors.pop(idx) return True, 'Removed %s from sector list.' % name else: return False, "No sector registered with name '%s'." % name
def group(self, groupname='', *args): '''Add aircraft to group, list aircraft in group, or list existing groups.''' # Return list of groups if no groupname is given if not groupname: if not self.groups: return True, 'There are currently no traffic groups defined.' else: return True, 'Defined traffic groups:\n' + ', '.join( self.groups) if len(self.groups) >= 64: return False, 'Maximum number of 64 groups reached' if groupname not in self.groups: if not args: return False, 'Group {} doesn\'t exist'.format(groupname) # Get first unused group mask for i in range(64): groupmask = (1 << i) if not self.allmasks & groupmask: self.allmasks |= groupmask self.groups[groupname] = groupmask break elif not args: acnames = np.array(bs.traf.id)[self.listgroup(groupname)] return True, 'Aircraft in group {}:\n{}'.format( groupname, ', '.join(acnames)) # Add aircraft to group if areafilter.hasArea(args[0]): inside = areafilter.checkInside(args[0], bs.traf.lat, bs.traf.lon, bs.traf.alt) self.ingroup[inside] |= self.groups[groupname] acnames = np.array(bs.traf.id)[inside] else: idx = list(args) self.ingroup[idx] |= self.groups[groupname] acnames = np.array(bs.traf.id)[idx] return True, 'Aircraft added to group {}:\n{}'.format( groupname, ', '.join(acnames))
def set_area(self, *args): ''' Set Experiment Area. Aicraft leaving the experiment area are deleted. Input can be exisiting shape name, or a box with optional altitude constrainsts.''' # if all args are empty, then print out the current area status if not args: return True, "Area is currently " + ("ON" if self.active else "OFF") + \ "\nCurrent Area name is: " + str(self.name) # start by checking if the first argument is a string -> then it is an area name if isinstance(args[0], str) and len(args)==1: if areafilter.hasArea(args[0]): # switch on Area, set it to the shape name self.name = args[0] self.active = True self.logger.start() return True, "Area is set to " + str(self.name) if args[0]=='OFF' or args[0]=='OF': # switch off the area areafilter.deleteArea(self.name) self.logger.reset() self.active = False self.name = None return True, "Area is switched OFF" # shape name is unknown return False, "Shapename unknown. " + \ "Please create shapename first or shapename is misspelled!" # if first argument is a float -> then make a box with the arguments if isinstance(args[0],(float, int)) and 4<=len(args)<=6: self.active = True self.name = 'DELAREA' areafilter.defineArea(self.name, 'BOX', args[:4], *args[4:]) self.logger.start() return True, "Area is ON. Area name is: " + str(self.name) return False, "Incorrect arguments" + \ "\nAREA Shapename/OFF or\n Area lat,lon,lat,lon,[top,bottom]"
def group(self, groupname='', *args): '''Add aircraft to group, list aircraft in group, or list existing groups.''' # Return list of groups if no groupname is given if not groupname: if not self.groups: return True, 'There are currently no traffic groups defined.' else: return True, 'Defined traffic groups:\n' + ', '.join(self.groups) if len(self.groups) >= 64: return False, 'Maximum number of 64 groups reached' if groupname not in self.groups: if not args: return False, 'Group {} doesn\'t exist'.format(groupname) # Get first unused group mask for i in range(64): groupmask = (1 << i) if not self.allmasks & groupmask: self.allmasks |= groupmask self.groups[groupname] = groupmask break elif not args: acnames = np.array(bs.traf.id)[self.listgroup(groupname)] return True, 'Aircraft in group {}:\n{}'.format(groupname, ', '.join(acnames)) # Add aircraft to group if areafilter.hasArea(args[0]): inside = areafilter.checkInside( args[0], bs.traf.lat, bs.traf.lon, bs.traf.alt) self.ingroup[inside] |= self.groups[groupname] acnames = np.array(bs.traf.id)[inside] else: idx = list(args) self.ingroup[idx] |= self.groups[groupname] acnames = np.array(bs.traf.id)[idx] return True, 'Aircraft added to group {}:\n{}'.format(groupname, ', '.join(acnames))
def applygeovec(): # Apply each geovector for areaname, vec in geovecs.items(): if areafilter.hasArea(areaname): swinside = areafilter.checkInside(areaname, traf.lat, traf.lon, traf.alt) insids = set(np.array(traf.id)[swinside]) newids = insids - vec.previnside delids = vec.previnside - insids # Store LNAV/VNAV status of new aircraft for acid in newids: idx = traf.id2idx(acid) vec.prevstatus[acid] = [traf.swlnav[idx], traf.swvnav[idx]] # Revert aircraft who have exited the geovectored area to their original status for acid in delids: idx = traf.id2idx(acid) if idx >= 0: traf.swlnav[idx], traf.swvnav[idx] = vec.prevstatus.pop( acid) vec.previnside = insids # -----Ground speed limiting # For now assume no wind: so use tas as gs if vec.gsmin is not None: casmin = vtas2cas(np.ones(traf.ntraf) * vec.gsmin, traf.alt) usemin = traf.selspd < casmin traf.selspd[swinside & usemin] = casmin[swinside & usemin] traf.swvnav[swinside & usemin] = False if vec.gsmax is not None: casmax = vtas2cas(np.ones(traf.ntraf) * vec.gsmax, traf.alt) usemax = traf.selspd > casmax traf.selspd[swinside & usemax] = casmax[swinside & usemax] traf.swvnav[swinside & usemax] = False #------ Limit Track(so hdg) # Max track interval is 180 degrees to avoid ambiguity of what is inside the interval if None not in [vec.trkmin, vec.trkmax]: # Use degto180 to avodi problems for e.g interval [350,30] usemin = swinside & (degto180(traf.trk - vec.trkmin) < 0 ) # Left of minimum usemax = swinside & (degto180(traf.trk - vec.trkmax) > 0 ) # Right of maximum traf.swlnav[swinside & (usemin | usemax)] = False traf.ap.trk[swinside & usemin] = vec.trkmin traf.ap.trk[swinside & usemax] = vec.trkmax # -----Ground speed limiting # For now assume no wind: so use tas as gs if vec.vsmin is not None: traf.selvs[swinside & (traf.vs < vec.vsmin)] = vec.vsmin traf.swvnav[swinside & (traf.vs < vec.vsmin)] = False # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs < vec.vsmin)] = traf.alt[swinside & (traf.vs < vec.vsmin)] + \ np.sign(vec.vsmin)*200.*ft if vec.vsmax is not None: traf.selvs[swinside & (traf.vs > vec.vsmax)] = vec.vsmax traf.swvnav[swinside & (traf.vs < vec.vsmax)] = False # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs > vec.vsmax)] = traf.alt[swinside & (traf.vs > vec.vsmax)] + \ np.sign(vec.vsmax)*200.*ft return
def set_logarea(self, *args): ''' Set logger area ''' # Turning LOGAREA on if the given area exists: if areafilter.hasArea(args[0]): self.areaname = args[0] self.active = True self.geolog.start() self.fstlog.start() self.conlog.start() self.reclog.start() # Log logarea paramters in reclog area = areafilter.basic_shapes[self.areaname] self.reclog.log(f'Logarea set to {self.areaname} which is of ' + \ f'type {type(area)}') try: for n in range(0, len(area.coordinates), 2): self.reclog.log( f'Vertex coordinate: {area.coordinates[n]}, {area.coordinates[n+1]}' ) except IndexError: pass self.reclog.log(f'Logarea top: {area.top}') self.reclog.log(f'Logarea bottom: {area.bottom}') # Initialize geovector previds sets for geoname, geovec in geovector.geovecs.items(): for limname in lims: key = geoname + limname self.previds[key] = set() self.geovecs[geoname] = np.array([geovec.gsmin, \ geovec.gsmax, geovec.trkmin, geovec.trkmax, geovec.vsmin, geovec.vsmax]) return True, f'Logarea is set to {args[0]}' # Turning LOGAREA off: if args[0][:2] == 'OF': # Log unfinished intervals if still logging if self.logging: self.reset_geolog() self.reset_fstlog() self.reset_conlog() # Logarea geovector parameters self.previds = {} self.breaches = {} self.geovecs = {} # Logarea conflict parameters self.concount = int(0) self.rescount = int(0) self.loscount = int(0) self.conpairs = [] self.respairs = [] self.lospairs = [] self.prevconpairs = set() self.prevrespairs = set() self.prevlospairs = set() self.condict = {} self.resdict = {} self.losdict = {} # Deactivate logarea and loggers self.active = False self.name = '' self.geolog.reset() self.fstlog.reset() self.conlog.reset() self.reclog.reset() self.interval = None self.logging = False return True, f'Logarea is switched OFF' # Incorrect arguments: return False, 'Incorrect arguments for LOGAREA function!'