class Simul(SimulationRT): # Sympy 2 #class Simul(sympy.RealtimeEnvironment): """ Attributes ---------- config : config parser instance sim_opt : dictionary of configuration option for simulation ag_opt : dictionary of configuration option for agent lay_opt : dictionary of configuration option for layout meca_opt : dictionary of configuration option for mecanic net_opt : dictionary of configuration option for network loc_opt : dictionary of configuration option for localization save_opt : dictionary of configuration option for save sql_opt : dictionary of configuration option for sql Parameters ---------- self.lAg : list of Agent(Object) list of agents involved in simulation self.L : Layout Layout used in simulation Notes ----- All the previous dictionnary are obtained from the chosen simulnet.ini file in the project directory """ def __init__(self): SimulationRT.__init__(self) #Sympy 2 #sympy.RealtimeEnvironment.__init__(self) #simpy 3 self.initialize() self.config = ConfigParser.ConfigParser() filename = pyu.getlong('simulnet.ini',pstruc['DIRSIMUL']) self.config.read(filename) self.sim_opt = dict(self.config.items('Simulation')) self.lay_opt = dict(self.config.items('Layout')) self.meca_opt = dict(self.config.items('Mechanics')) self.net_opt = dict(self.config.items('Network')) self.loc_opt = dict(self.config.items('Localization')) self.save_opt = dict(self.config.items('Save')) self.sql_opt = dict(self.config.items('Mysql')) self.seed = eval(self.sim_opt['seed']) self.traj=Trajectories() self.verbose = str2bool(self.sim_opt['verbose']) if str2bool(self.net_opt['ipython_nb_show']): self.verbose = False self.roomlist=[] self.finish = False self.create() def __repr__(self): s = 'Simulation information' + '\n----------------------' s = s + '\nLayout: ' + self.lay_opt['filename'] s = s + '\nSimulation duration: ' + self.sim_opt['duration'] s = s + '\nRandom seed: ' + self.sim_opt['seed'] s = s + '\nSave simulation: ' + self.save_opt['savep'] s = s + '\n\nUpdate times' + '\n-------------' s = s + '\nMechanical update: ' + self.meca_opt['mecanic_update_time'] s = s + '\nNetwork update: ' + self.net_opt['network_update_time'] s = s + '\nLocalization update: ' + self.net_opt['communication_mode'] s = s + '\n\nAgents => self.lAg[i]' + '\n------' s = s + '\nNumber of agents :' + str(len(self.lAg)) s = s + '\nAgents IDs: ' + str([self.lAg[i].ID for i in range(len(self.lAg))]) s = s + '\nAgents names: ' + str([self.lAg[i].name for i in range(len(self.lAg))]) s = s + '\nDestination of chosen agents: ' + self.meca_opt['choose_destination'] s = s + '\n\nNetwork' + '\n-------' s = s + '\nNodes per wstd: ' + str(self.net.wstd) s = s + '\n\nLocalization' + '------------' s = s + '\nLocalization enable: ' + self.loc_opt['localization'] s = s + '\nPostion estimation methods: ' + self.loc_opt['method'] return s def create_layout(self): """ create Layout in Simpy the_world thanks to Tk backend """ _filename = self.lay_opt['filename'] self.L = Layout(_filename) self.the_world = world() try: self.L.dumpr() print 'Layout graphs are loaded from ',basename,'/struc/ini' except: #self.L.sl = sl #self.L.loadGr(G1) print 'This is the first time the layout file is used\ Layout graphs are curently being built, it may take few minutes.' self.L.build() self.L.dumpw() # # Create Layout # walls = self.L.thwall(0, 0) for wall in walls: for ii in range(0, len(wall) - 1): self.the_world.add_wall(wall[ii], wall[ii + 1]) def create_agent(self): """ create simulation's Agents ..todo:: change lAg list to a dictionnary ( modification in show.py too) """ self.lAg = [] agents=[] Cf = ConfigParser.ConfigParser() Cf.read(pyu.getlong('agent.ini','ini')) agents=eval(dict(Cf.items('used_agent'))['list']) for i, ag in enumerate(agents): ag_opt = dict(Cf.items(ag)) self.lAg.append(Agent( ID=ag_opt['id'], name=ag_opt['name'], typ=ag_opt['typ'], color=eval(ag_opt['color']), pdshow=str2bool(self.meca_opt['pdshow']), pos=np.array(eval(ag_opt['pos'])), roomId=int(ag_opt['roomid']), froom=eval(ag_opt['froom']), meca_updt=float(self.meca_opt['mecanic_update_time']), wait=float(ag_opt['wait']), cdest=eval(self.meca_opt['choose_destination']), loc=str2bool(self.loc_opt['localization']), loc_updt=float(self.loc_opt['localization_update_time']), loc_method=eval(self.loc_opt['method']), L=self.L, network=str2bool(self.net_opt['network']), net=self.net, epwr=dict([(eval((ag_opt['wstd']))[ep],eval((ag_opt['epwr']))[ep]) for ep in range(len(eval((ag_opt['wstd']))))]), sens=dict([(eval((ag_opt['wstd']))[ep],eval((ag_opt['sensitivity']))[ep]) for ep in range(len(eval((ag_opt['wstd']))))]), world=self.the_world, wstd=eval(ag_opt['wstd']), save=eval(self.save_opt['save']), gcom=self.gcom, comm_mode=eval(self.net_opt['communication_mode']), sim=self, seed=self.seed)) def create_EMS(self): """ electromagnetic Solver object """ self.EMS = EMSolver(L=self.L) def create_network(self): """ create the whole network """ self.net = Network(EMS=self.EMS) self.gcom=Gcom(net=self.net,sim=self) self.create_agent() # create network if str2bool(self.net_opt['network']): self.net.create() # create All Personnal networks for n in self.net.nodes(): self.net.node[n]['PN']._get_wstd() self.net.node[n]['PN']._get_SubNet() self.gcom.create() # create Process Network self.Pnet = PNetwork(net=self.net, net_updt_time=float(self.net_opt['network_update_time']), L=self.L, sim=self, show_sg=str2bool(self.net_opt['show_sg']), disp_inf=str2bool(self.net_opt['dispinfo']), save=eval(self.save_opt['save'])) self.activate(self.Pnet, self.Pnet.run(), 0.0) def create_visual(self): """ create visual Tk process """ self.visu = Updater( interval=float(self.sim_opt['show_interval']), sim=self) self.activate(self.visu, self.visu.execute(), 0.0) def create(self): """ create the simulation This method is called at the end of __init__ """ # this is just to redump the database at each simulation if 'mysql' in self.save_opt['save']: if str2bool(self.sql_opt['dumpdb']): os.popen('mysql -u ' + self.sql_opt['user'] + ' -p ' + self.sql_opt['dbname'] +\ '< /private/staff/t/ot/niamiot/svn2/devel/simulator/pyray/SimWHERE2.sql' ) ## TODO supprimer la ref en dur if 'txt' in self.save_opt['save']: pyu.writeDetails(self) if os.path.isfile(basename+'/output/Nodes.txt'): print 'would you like to erase previous txt files ?' A=raw_input() if A == 'y': for f in os.listdir(basename+'/output/'): try: fi,ext=f.split('.') if ext == 'txt': os.remove(basename+'/output/'+f) except: pass self.create_layout() self.create_EMS() self.create_network() if str2bool(self.sim_opt['showtk']): self.create_visual() self.create_show() if str2bool(self.save_opt['savep']): self.save=Save(L=self.L,net=self.net,sim=self) self.activate(self.save,self.save.run(),0.0) def create_show(self): """ create a vizualization """ plt.ion() fig_net = 'network' fig_table = 'table' if str2bool(self.net_opt['show']): if str2bool(self.net_opt['ipython_nb_show']): notebook=True else: notebook =False self.sh = ShowNet(net=self.net, L=self.L,sim=self,fname=fig_net,notebook=notebook) self.activate(self.sh,self.sh.run(),1.0) if str2bool(self.net_opt['show_table']): self.sht = ShowTable(net=self.net,lAg=self.lAg,sim=self,fname=fig_table) self.activate(self.sht,self.sht.run(),1.0) def savepandas(self): """ save mechanics in pandas hdf5 format """ filename=pyu.getlong(eval(self.sim_opt["filename"]),pstruc['DIRNETSAVE']) layfile = self.L.filename.split('.')[0] store = pd.HDFStore(filename+'_'+layfile+'.h5','w') for a in self.lAg : if a.typ != 'ap': store.put( a.ID,a.meca.df.convert_objects() ) else : # if agent acces point, its position is saved store.put( a.ID,a.posdf ) store.get_storer(a.ID).attrs.typ = a.typ store.get_storer(a.ID).attrs.name = a.name store.get_storer(a.ID).attrs.ID = a.ID store.get_storer(a.ID).attrs.layout = self.L.filename #saving metadata store.close() self.traj.loadh5(eval(self.sim_opt["filename"])+'_'+layfile+'.h5') def runsimul(self): """ run simulation """ if not self.finish : seed(self.seed) self.simulate(until=float(self.sim_opt['duration']), real_time=True, rel_speed=float(self.sim_opt['speedratio'])) self.the_world._boids={} if str2bool(self.save_opt['savep']): print 'Processing save results, please wait' self.save.mat_export() if str2bool(self.save_opt['savepd']): self.savepandas() self.finish = True else : raise NameError('Reinstantiate a new simul object to run again')
class Coverage(object): """ Handle Layout Coverage Methods ------- create grid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout model : a pylayers.network.model object. nx : number of point on x ny : number of point on y tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map """ def __init__(self,_fileini='coverage.ini'): self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong(_fileini,pstruc['DIRSIMUL'])) self.plm = dict(self.config.items('pl_model')) self.layoutopt = dict(self.config.items('layout')) self.gridopt = dict(self.config.items('grid')) self.txopt = dict(self.config.items('tx')) self.rxopt = dict(self.config.items('rx')) self.showopt = dict(self.config.items('show')) self.L = Layout(self.layoutopt['filename']) self.model = PLSmodel(f=eval(self.plm['fghz']), rssnp=eval(self.plm['rssnp']), d0=eval(self.plm['d0']), sigrss=eval(self.plm['sigrss'])) self.nx = eval(self.gridopt['nx']) self.ny = eval(self.gridopt['ny']) self.mode = eval(self.gridopt['full']) self.boundary = eval(self.gridopt['boundary']) # transitter section self.fGHz = eval(self.txopt['fghz']) self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) self.ptdbm = eval(self.txopt['ptdbm']) self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section self.rxsens = eval(self.rxopt['sensitivity']) kBoltzmann = 1.3806503e-23 self.bandwidthmhz = eval(self.rxopt['bandwidthmhz']) self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) Pn = (10**(self.noisefactordb/10.)+1)*kBoltzmann*self.temperaturek*self.bandwidthmhz*1e3 self.pndbm = 10*np.log10(Pn)+60 self.show = str2bool(self.showopt['show']) try: self.L.Gt.nodes() except: pass try: self.L.dumpr('t') except: self.L.buildGt() self.L.dumpw('t') self.creategrid(full=self.mode,boundary=self.boundary) def __repr__(self): st='' st= st+ 'tx :'+str(self.txopt) + '\n' st= st+ 'rx :'+str(self.rxopt) + '\n' def creategrid(self,full=True,boundary=[]): """ create a grid Parameters ---------- full : boolean default (True) use all the layout area boundary : (xmin,ymin,xmax,ymax) if full is False the boundary is used """ if full: mi=np.min(self.L.Gs.pos.values(),axis=0)+0.01 ma=np.max(self.L.Gs.pos.values(),axis=0)-0.01 else: mi = np.array([boundary[0],boundary[1]]) ma = np.array([boundary[2],boundary[3]]) x=np.linspace(mi[0],ma[0],self.nx) y=np.linspace(mi[1],ma[1],self.ny) self.grid=np.array((list(np.broadcast(*np.ix_(x, y))))) def cover(self): """ start the coverage calculation Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showPr() """ self.Lwo,self.Lwp,self.Edo,self.Edp = Loss0_v2(self.L,self.grid,self.model.f,self.tx) self.freespace = PL(self.grid,self.model.f,self.tx) self.prdbmo = self.ptdbm - self.freespace - self.Lwo self.prdbmp = self.ptdbm - self.freespace - self.Lwp self.snro = self.prdbmo - self.pndbm self.snrp = self.prdbmp - self.pndbm def showEd(self,polarization='o'): """ show direct path excess of delay map Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showEdo() """ fig=plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': cov=ax.imshow(self.Edo.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), origin='lower') titre = "Map of LOS excess delay, polar orthogonal" if polarization=='p': cov=ax.imshow(self.Edp.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), origin='lower') titre = "Map of LOS excess delay, polar parallel" ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(titre) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(cov,cax) clb.set_label('excess delay (ns)') if self.show: plt.show() def showPower(self,rxsens=True,nfl=True,polarization='o'): """ show the map of received power Parameters ---------- rxsens : bool clip the map with rx sensitivity set in self.rxsens nfl : bool clip the map with noise floor set in self.pndbm polarization : string 'o'|'p' Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showPower() """ fig=plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': prdbm=self.prdbmo if polarization=='p': prdbm=self.prdbmp # tCM = plt.cm.get_cmap('jet') # tCM._init() # alphas = np.abs(np.linspace(.0,1.0, tCM.N)) # tCM._lut[:-3,-1] = alphas title='Map of received power - Pt = '+str(self.ptdbm)+' dBm' cdict = { 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), 'green': ((0., 0.5, 0.5), (1., 1., 1.)), 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) } #generate the colormap with 1024 interpolated values my_cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) if rxsens : ### values between the rx sensitivity and noise floor mcPrf = np.ma.masked_where((prdbm > self.rxsens) & (prdbm < self.pndbm),prdbm) cov1 = ax.imshow(mcPrf.reshape((self.nx,self.ny)).T, extent=(l,r,b,t),cmap = my_cmap, vmin=self.rxsens,origin='lower') ### values above the sensitivity mcPrs = np.ma.masked_where(prdbm < self.rxsens,prdbm) cov = ax.imshow(mcPrs.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), cmap = 'jet', vmin=self.rxsens,origin='lower') title=title + '\n gray : Pr (dBm) < %.2f' % self.rxsens + ' dBm' else : cov=ax.imshow(prdbm.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), cmap = 'jet', vmin=self.pndbm,origin='lower') if nfl: ### values under the noise floor ### we first clip the value below he noise floor cl = np.nonzero(prdbm<=self.pndbm) cPr = prdbm cPr[cl] = self.pndbm mcPruf = np.ma.masked_where(cPr > self.pndbm,cPr) cov2 = ax.imshow(mcPruf.reshape((self.nx,self.ny)).T, extent=(l,r,b,t),cmap = 'binary', vmax=self.pndbm,origin='lower') title=title + '\n white : Pr (dBm) < %.2f' % self.pndbm + ' dBm' ax.scatter(self.tx[0],self.tx[1],s=10,linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(cov,cax) clb.set_label('Power (dBm)') if self.show: plt.show() def showTransistionRegion(self,polarization='o'): """ Notes ----- See : Analyzing the Transitional Region in Low Power Wireless Links Marco Zuniga and Bhaskar Krishnamachari Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showTransitionRegion() """ frameLength = self.framelengthbytes PndBm = self.pndbm gammaU = 10*np.log10(-1.28*np.log(2*(1-0.9**(1./(8*frameLength))))) gammaL = 10*np.log10(-1.28*np.log(2*(1-0.1**(1./(8*frameLength))))) PrU = PndBm + gammaU PrL = PndBm + gammaL fig=plt.figure() fig,ax = self.L.showGs(fig=fig) l = self.grid[0,0] r = self.grid[-1,0] b = self.grid[0,1] t = self.grid[-1,-1] if polarization=='o': prdbm=self.prdbmo if polarization=='p': prdbm=self.prdbmp zones = np.zeros(len(prdbm)) uconnected = np.nonzero(prdbm>PrU)[0] utransition = np.nonzero((prdbm < PrU)&(prdbm > PrL))[0] udisconnected = np.nonzero(prdbm < PrL)[0] zones[uconnected] = 1 zones[utransition] = (prdbm[utransition]-PrL)/(PrU-PrL) cov = ax.imshow(zones.reshape((self.nx,self.ny)).T, extent=(l,r,b,t),cmap = 'BuGn',origin='lower') title='PDR region' ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) fig.colorbar(cov,cax) if self.show: plt.show() def showLoss(self,polarization='o'): """ show losses map Parameters ---------- polarization : string 'o'|'p'|'both' Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showLoss(polarization='o') >>> C.showLoss(polarization='p') """ fig = plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': cov = ax.imshow(self.Lwo.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), origin='lower') title = ('Map of losses, orthogonal (V) polarization') if polarization=='p': cov = ax.imshow(self.Lwp.reshape((self.nx,self.ny)).T, extent=(l,r,b,t), origin='lower') title = ('Map of losses, parallel (H) polarization') ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) fig.colorbar(cov,cax) if self.show: plt.show()
class Coverage(PyLayers): """ Handle Layout Coverage Methods ------- creategrid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout nx : number of point on x ny : number of point on y tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map na : number of access point """ def __init__(self, _fileini='coverage.ini'): """ object constructor Parameters ---------- _fileini : string name of the configuration file Notes ----- Coverage is described in an ini file. Default file is coverage.ini and is placed in the ini directory of the current project. """ self.config = ConfigParser.ConfigParser(allow_no_value=True) self.config.read(pyu.getlong(_fileini, pstruc['DIRSIMUL'])) # section layout self.layoutopt = dict(self.config.items('layout')) # section sector self.gridopt = dict(self.config.items('grid')) # section ap (access point) self.apopt = dict(self.config.items('ap')) # section receiver parameters self.rxopt = dict(self.config.items('rx')) # section receiver parameters self.showopt = dict(self.config.items('show')) # get the Layout filename = self.layoutopt['filename'] if filename.endswith('lay'): self.typ = 'indoor' self.L = Layout(filename) # get the receiving grid self.nx = eval(self.gridopt['nx']) self.ny = eval(self.gridopt['ny']) if 'zgrid' in self.gridopt: self.zgrid = eval(self.gridopt['zgrid']) else: self.zgrid = 1.0 self.mode = self.gridopt['mode'] assert self.mode in ['file', 'full', 'zone'], "Error reading grid mode " self.boundary = eval(self.gridopt['boundary']) self.filespa = self.gridopt['file'] # # create grid # self.creategrid(mode=self.mode, boundary=self.boundary, _fileini=self.filespa) self.dap = {} for k in self.apopt: kwargs = eval(self.apopt[k]) ap = std.AP(**kwargs) self.dap[eval(k)] = ap try: self.L.Gt.nodes() except: pass try: self.L.dumpr() except: self.L.build() self.L.dumpw() else: self.typ = 'outdoor' self.E = ez.Ezone(filename) self.E.loadh5() self.E.rebase() # The frequency is fixed from the AP nature self.fGHz = np.array([]) #self.fGHz = eval(self.txopt['fghz']) #self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) #self.ptdbm = eval(self.txopt['ptdbm']) #self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section #self.rxsens = eval(self.rxopt['sensitivity']) self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) # show section self.bshow = str2bool(self.showopt['show']) self.sinr = False self.snr = False self.best = False self.egd = False self.Pr = False self.capacity = False self.pr = False self.loss = False def __repr__(self): st = '' if self.typ == 'indoor': st = st + 'Layout file : ' + self.L._filename + '\n\n' st = st + '-----list of Access Points ------' + '\n' for k in self.dap: st = st + self.dap[k].__repr__() + '\n' st = st + '-----Rx------' + '\n' st = st + 'temperature (K) : ' + str(self.temperaturek) + '\n' st = st + 'noisefactor (dB) : ' + str(self.noisefactordb) + '\n\n' st = st + '--- Grid ----' + '\n' st = st + 'mode : ' + str(self.mode) + '\n' if self.mode != 'file': st = st + 'nx : ' + str(self.nx) + '\n' st = st + 'ny : ' + str(self.ny) + '\n' if self.mode == 'zone': st = st + 'boundary (xmin,ymin,xmax,ymax) : ' + str( self.boundary) + '\n\n' if self.mode == 'file': st = st + ' filename : ' + self.filespa + '\n' return (st) def creategrid(self, mode='full', boundary=[], _fileini=''): """ create a grid Parameters ---------- full : boolean default (True) use all the layout area boundary : (xmin,ymin,xmax,ymax) if full is False the boundary argument is used """ if mode == "file": self.RN = RadioNode(name='', typ='rx', _fileini=_fileini, _fileant='def.vsh3') self.grid = self.RN.position[0:2, :].T else: if mode == "full": mi = np.min(np.array(list(self.L.Gs.pos.values())), axis=0) + 0.01 ma = np.max(np.array(list(self.L.Gs.pos.values())), axis=0) - 0.01 if mode == "zone": assert boundary != [] mi = np.array([boundary[0], boundary[1]]) ma = np.array([boundary[2], boundary[3]]) x = np.linspace(mi[0], ma[0], self.nx) y = np.linspace(mi[1], ma[1], self.ny) self.grid = np.array((list(np.broadcast(*np.ix_(x, y))))) self.ng = self.grid.shape[0] def where1(self): """ Unfinished : Not sure this is the right place (too specific) """ M1 = UWBMeasure(1) self.dap = {} self.dap[1] = {} self.dap[2] = {} self.dap[3] = {} self.dap[4] = {} self.dap[1]['p'] = M1.rx[1, 0:2] self.dap[2]['p'] = M1.rx[1, 0:2] self.dap[3]['p'] = M1.rx[1, 0:2] self.dap[4]['p'] = M1.rx[1, 0:2] for k in range(300): try: M = UWBMeasure(k) tx = M.tx self.grid = np.vstack((self.grid, tx[0:2])) D = M.rx - tx[np.newaxis, :] D2 = D * D dist = np.sqrt(np.sum(D2, axis=1))[1:] Emax = M.Emax() Etot = M.Etot()[0] try: td1 = np.hstack((td1, dist[0])) td2 = np.hstack((td2, dist[1])) td3 = np.hstack((td3, dist[2])) td4 = np.hstack((td4, dist[3])) te1 = np.hstack((te1, Emax[0])) te2 = np.hstack((te2, Emax[1])) te3 = np.hstack((te3, Emax[2])) te4 = np.hstack((te4, Emax[3])) tt1 = np.hstack((tt1, Etot[0])) tt2 = np.hstack((tt2, Etot[1])) tt3 = np.hstack((tt3, Etot[2])) tt4 = np.hstack((tt4, Etot[3])) #tdist = np.hstack((tdist,dist)) #te = np.hstack((te,Emax)) except: td1 = np.array(dist[0]) td2 = np.array(dist[1]) td3 = np.array(dist[2]) td4 = np.array(dist[3]) te1 = np.array(Emax[0]) te2 = np.array(Emax[1]) te3 = np.array(Emax[2]) te4 = np.array(Emax[3]) tt1 = np.array(Etot[0]) tt2 = np.array(Etot[1]) tt3 = np.array(Etot[2]) tt4 = np.array(Etot[3]) except: pass def cover(self, **kwargs): """ run the coverage calculation Parameters ---------- sinr : boolean snr : boolean best : boolean size : integer size of grid points block Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a = C.show(typ='sinr',figsize=(10,8)) >>> plt.show() Notes ----- self.fGHz is an array, it means that Coverage is calculated at once for a whole set of frequencies. In practice, it would be the center frequency of a given standard channel. This function is calling `loss.Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as a full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ sizebloc = kwargs.pop('size', 100) # # select active AP # lactiveAP = [] try: del self.aap del self.ptdbm except: pass # Boltzmann constant kB = 1.3806503e-23 # # Loop over access points # set parameter of each active ap # p # PtdBm # BMHz for iap in self.dap: if self.dap[iap]['on']: lactiveAP.append(iap) # set frequency for each AP fGHz = self.dap[iap].s.fcghz self.fGHz = np.unique(np.hstack((self.fGHz, fGHz))) apchan = self.dap[iap]['chan'] # # stacking AP position Power Bandwidth # try: self.aap = np.vstack((self.aap, self.dap[iap]['p'])) self.ptdbm = np.vstack( (self.ptdbm, self.dap[iap]['PtdBm'])) self.bmhz = np.vstack( (self.bmhz, self.dap[iap].s.chan[apchan[0]]['BMHz'])) except: self.aap = self.dap[iap]['p'] self.ptdbm = np.array(self.dap[iap]['PtdBm']) self.bmhz = np.array( self.dap[iap].s.chan[apchan[0]]['BMHz']) self.nf = len(self.fGHz) PnW = np.array((10**(self.noisefactordb / 10.)) * kB * self.temperaturek * self.bmhz * 1e6) # Evaluate Noise Power (in dBm) self.pndbm = np.array(10 * np.log10(PnW) + 30) #lchan = map(lambda x: self.dap[x]['chan'],lap) #apchan = zip(self.dap.keys(),lchan) #self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) self.ptdbm = self.ptdbm.T self.pndbm = self.pndbm.T # creating all links # from all grid point to all ap # if len(self.pndbm.shape) == 0: self.ptdbm = self.ptdbm.reshape(1, 1) self.pndbm = self.pndbm.reshape(1, 1) self.nf = len(self.fGHz) Nbloc = self.ng // sizebloc r1 = np.arange(0, (Nbloc + 1) * sizebloc, sizebloc) r1 = np.append(r1, self.ng) lblock = list(zip(r1[0:-1], r1[1:])) for bg in lblock: p = product(range(bg[0], bg[1]), lactiveAP) # # pa : access point ,3 # pg : grid point ,2 # # 1 x na for k in p: pg = self.grid[k[0], :] pa = np.array(self.dap[k[1]]['p']) # exemple with 3 AP # 321 0 # 321 1 # 321 2 # 322 0 try: self.pa = np.vstack((self.pa, pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg, pg)) except: self.pg = pg self.pa = self.pa.T shpa = self.pa.shape shpg = self.pg.shape # extend in 3 dimensions if necessary if shpa[0] != 3: self.pa = np.vstack((self.pa, np.ones(shpa[1]))) self.pg = self.pg.T self.pg = np.vstack((self.pg, self.zgrid * np.ones(shpg[0]))) # retrieving dimensions along the 3 axis # a : number of active access points # g : grid block # f : frequency na = len(lactiveAP) self.na = na ng = self.ng nf = self.nf # calculate antenna gain from ap to grid point # # loop over all AP # k = 0 for iap in self.dap: # select only one access point # n u = na * np.arange(0, bg[1] - bg[0], 1).astype('int') + k if self.dap[iap]['on']: pa = self.pa[:, u] pg = self.pg[:, u] azoffset = self.dap[iap]['phideg'] * np.pi / 180. # the eval function of antenna should also specify polar self.dap[iap].A.eval(fGHz=self.fGHz, pt=pa, pr=pg, azoffset=azoffset) gain = (self.dap[iap].A.G).T # to handle omnidirectional antenna (nf,1,1) if gain.shape[1] == 1: gain = np.repeat(gain, bg[1] - bg[0], axis=1) if k == 0: tgain = gain[:, :, None] else: tgain = np.dstack((tgain, gain[:, :, None])) k = k + 1 tgain = tgain.reshape(nf, tgain.shape[1] * tgain.shape[2]) Lwo, Lwp, Edo, Edp = loss.Losst(self.L, self.fGHz, self.pa, self.pg, dB=False) freespace = loss.PL(self.fGHz, self.pa, self.pg, dB=False) try: self.Lwo = np.hstack((self.Lwo, Lwo)) self.Lwp = np.hstack((self.Lwp, Lwp)) self.Edo = np.hstack((self.Edo, Edo)) self.Edp = np.hstack((self.Edp, Edp)) self.freespace = np.hstack((self.freespace, freespace)) self.tgain = np.hstack((self.tgain, tgain)) except: self.Lwo = Lwo self.Lwp = Lwp self.Edo = Edo self.Edp = Edp self.freespace = freespace self.tgain = tgain self.Lwo = self.Lwo.reshape(nf, ng, na) self.Edo = self.Edo.reshape(nf, ng, na) self.Lwp = self.Lwp.reshape(nf, ng, na) self.Edp = self.Edp.reshape(nf, ng, na) self.tgain = self.tgain.reshape(nf, ng, na) self.freespace = self.freespace.reshape(nf, ng, na) # transmitting power # f x g x a # CmW : Received Power coverage in mW # TODO : tgain in o and p polarization self.CmWo = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwo * self.freespace * self.tgain self.CmWp = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwp * self.freespace * self.tgain #self.CmWo = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwo*self.freespace #self.CmWp = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwp*self.freespace if self.snr: self.evsnr() if self.sinr: self.evsinr() if self.best: self.evbestsv() def evsnr(self): """ calculates signal to noise ratio """ NmW = 10**(self.pndbm / 10.)[np.newaxis, :] self.snro = self.CmWo / NmW self.snrp = self.CmWp / NmW self.snr = True def evsinr(self): """ calculates sinr """ # na : number of access point na = self.na # U : 1 x 1 x na x na U = (np.ones((na, na)) - np.eye(na))[np.newaxis, np.newaxis, :, :] # CmWo : received power in mW orthogonal polarization # CmWp : received power in mW parallel polarization ImWo = np.einsum('ijkl,ijl->ijk', U, self.CmWo) ImWp = np.einsum('ijkl,ijl->ijk', U, self.CmWp) NmW = 10**(self.pndbm / 10.)[np.newaxis, :] self.sinro = self.CmWo / (ImWo + NmW) self.sinrp = self.CmWp / (ImWp + NmW) self.sinr = True def evbestsv(self): """ determine the best server map Notes ----- C.bestsv """ na = self.na ng = self.ng nf = self.nf # find best server regions Vo = self.CmWo Vp = self.CmWp self.bestsvo = np.empty(nf * ng * na).reshape(nf, ng, na) self.bestsvp = np.empty(nf * ng * na).reshape(nf, ng, na) for kf in range(nf): MaxVo = np.max(Vo[kf, :, :], axis=1) MaxVp = np.max(Vp[kf, :, :], axis=1) for ka in range(na): uo = np.where(Vo[kf, :, ka] == MaxVo) up = np.where(Vp[kf, :, ka] == MaxVp) self.bestsvo[kf, uo, ka] = ka + 1 self.bestsvp[kf, up, ka] = ka + 1 self.best = True # def showEd(self,polar='o',**kwargs): # """ shows a map of direct path excess delay # # Parameters # ---------- # # polar : string # 'o' | 'p' # # Examples # -------- # # .. plot:: # :include-source: # # >> from pylayers.antprop.coverage import * # >> C = Coverage() # >> C.cover() # >> C.showEd(polar='o') # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # # fig,ax = self.L.showG('s',**kwargs) # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # #generate the colormap with 1024 interpolated values # my_cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # # # if polar=='o': # mcEdof = np.ma.masked_where(prdbm < self.rxsens,self.Edo) # # cov=ax.imshow(mcEdof.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # # # cov=ax.imshow(self.Edo.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar orthogonal" # # if polar=='p': # mcEdpf = np.ma.masked_where(prdbm < self.rxsens,self.Edp) # # cov=ax.imshow(mcEdpf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # cov=ax.imshow(self.Edp.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar parallel" # # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # ax.set_title(titre) # # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('excess delay (ns)') # # if self.show: # plt.show() # return fig,ax # # def showPower(self,rxsens=True,nfl=True,polar='o',**kwargs): # """ show the map of received power # # Parameters # ---------- # # rxsens : bool # clip the map with rx sensitivity set in self.rxsens # nfl : bool # clip the map with noise floor set in self.pndbm # polar : string # 'o'|'p' # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showPower() # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # fig,ax = self.L.showG('s',**kwargs) # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # ## tCM = plt.cm.get_cmap('jet') ## tCM._init() ## alphas = np.abs(np.linspace(.0,1.0, tCM.N)) ## tCM._lut[:-3,-1] = alphas # # title='Map of received power - Pt = ' + str(self.ptdbm) + ' dBm'+str(' fGHz =') + str(self.fGHz) + ' polar = '+polar # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # # if not kwargs.has_key('cmap'): # # generate the colormap with 1024 interpolated values # cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # else: # cmap = kwargs['cmap'] # #my_cmap = cm.copper # # # if rxsens : # # ## values between the rx sensitivity and noise floor # mcPrf = np.ma.masked_where((prdbm > self.rxsens) # & (prdbm < self.pndbm),prdbm) # # mcPrf = np.ma.masked_where((prdbm > self.rxsens) ,prdbm) # # cov1 = ax.imshow(mcPrf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = cm.copper, # vmin=self.rxsens,origin='lower') # # ### values above the sensitivity # mcPrs = np.ma.masked_where(prdbm < self.rxsens,prdbm) # cov = ax.imshow(mcPrs.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.rxsens,origin='lower') # title=title + '\n black : Pr (dBm) < %.2f' % self.rxsens + ' dBm' # # else : # cov=ax.imshow(prdbm.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.pndbm,origin='lower') # # if nfl: # ### values under the noise floor # ### we first clip the value below the noise floor # cl = np.nonzero(prdbm<=self.pndbm) # cPr = prdbm # cPr[cl] = self.pndbm # mcPruf = np.ma.masked_where(cPr > self.pndbm,cPr) # cov2 = ax.imshow(mcPruf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'binary', # vmax=self.pndbm,origin='lower') # title=title + '\n white : Pr (dBm) < %.2f' % self.pndbm + ' dBm' # # # ax.scatter(self.tx[0],self.tx[1],s=10,c='k',linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('Power (dBm)') # # if self.show: # plt.show() # # return fig,ax # # # def showTransistionRegion(self,polar='o'): # """ # # Notes # ----- # # See : "Analyzing the Transitional Region in Low Power Wireless Links" # Marco Zuniga and Bhaskar Krishnamachari # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showTransitionRegion() # # """ # # frameLength = self.framelengthbytes # # PndBm = self.pndbm # gammaU = 10*np.log10(-1.28*np.log(2*(1-0.9**(1./(8*frameLength))))) # gammaL = 10*np.log10(-1.28*np.log(2*(1-0.1**(1./(8*frameLength))))) # # PrU = PndBm + gammaU # PrL = PndBm + gammaL # # fig,ax = self.L.showGs() # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # zones = np.zeros(np.shape(prdbm)) # #pdb.set_trace() # # uconnected = np.nonzero(prdbm>PrU) # utransition = np.nonzero((prdbm < PrU)&(prdbm > PrL)) # udisconnected = np.nonzero(prdbm < PrL) # # zones[uconnected] = 1 # zones[utransition] = (prdbm[utransition]-PrL)/(PrU-PrL) # cov = ax.imshow(zones.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'BuGn',origin='lower') # # title='PDR region' # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # fig.colorbar(cov,cax) # if self.show: # plt.show() # def plot(self, **kwargs): """ """ defaults = { 'typ': 'pr', 'grid': False, 'f': 0, 'a': 0, 'db': True, 'label': '', 'pol': 'p', 'col': 'b' } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] if 'fig' in kwargs: fig = kwargs['fig'] else: fig = plt.figure() if 'ax' in kwargs: ax = kwargs['ax'] else: ax = fig.add_subplot(111) if kwargs['typ'] == 'pr': if kwargs['a'] != -1: if kwargs['pol'] == 'p': U = self.CmWp[kwargs['f'], :, kwargs['a']] if kwargs['pol'] == 'o': U = self.CmWo[kwargs['f'], :, kwargs['a']] else: if kwargs['pol'] == 'p': U = self.CmWp[kwargs['f'], :, :].reshape(self.na * self.ng) else: U = self.CmWo[kwargs['f'], :, :].reshape(self.na * self.ng) if kwargs['db']: U = 10 * np.log10(U) D = np.sqrt(np.sum((self.pa - self.pg) * (self.pa - self.pg), axis=0)) if kwargs['a'] != -1: D = D.reshape(self.ng, self.na) ax.semilogx(D[:, kwargs['a']], U, '.', color=kwargs['col'], label=kwargs['label']) else: ax.semilogx(D, U, '.', color=kwargs['col'], label=kwargs['label']) return fig, ax def show(self, **kwargs): """ show coverage Parameters ---------- typ : string 'pr' | 'sinr' | 'capacity' | 'loss' | 'best' | 'egd' | 'ref' grid : boolean polar : string 'o' | 'p' best : boolean draw best server contour if True f : int frequency index a : int access point index (-1 all access point) Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a = C.show(typ='pr',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='best',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='loss',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='sinr',figsize=(10,8)) >>> plt.show() See Also -------- pylayers.gis.layout.Layout.showG """ defaults = { 'typ': 'pr', 'grid': False, 'polar': 'p', 'scale': 30, 'f': 0, 'a': -1, 'db': True, 'cmap': cm.jet, 'best': False, 'title': '' } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] title = self.dap[list( self.dap.keys())[0]].s.name + ' : ' + kwargs['title'] + " :" polar = kwargs['polar'] best = kwargs['best'] scale = kwargs['scale'] assert polar in ['p', 'o'], "polar wrongly defined in show coverage" if 'fig' in kwargs: if 'ax' in kwargs: fig, ax = self.L.showG('s', fig=kwargs['fig'], ax=kwargs['ax']) else: fig, ax = self.L.showG('s', fig=kwargs['fig']) else: if 'figsize' in kwargs: fig, ax = self.L.showG('s', figsize=kwargs['figsize']) else: fig, ax = self.L.showG('s') # plot the grid if kwargs['grid']: for k in self.dap: p = self.dap[k].p ax.plot(p[0], p[1], 'or') f = kwargs['f'] a = kwargs['a'] typ = kwargs['typ'] assert typ in [ 'best', 'egd', 'sinr', 'snr', 'capacity', 'pr', 'loss', 'ref' ], "typ unknown in show coverage" best = kwargs['best'] dB = kwargs['db'] # setting the grid l = self.grid[0, 0] r = self.grid[-1, 0] b = self.grid[0, 1] t = self.grid[-1, -1] if typ == 'best' and self.best: title = title + 'Best server' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar for ka in range(self.na): if polar == 'p': bestsv = self.bestsvp[f, :, ka] if polar == 'o': bestsv = self.bestsvo[f, :, ka] m = np.ma.masked_where(bestsv == 0, bestsv) if self.mode != 'file': W = m.reshape(self.nx, self.ny).T ax.imshow(W, extent=(l, r, b, t), origin='lower', vmin=1, vmax=self.na + 1) else: ax.scatter(self.grid[:, 0], self.grid[:, 1], c=m, s=scale, linewidth=0) ax.set_title(title) else: if typ == 'egd': title = title + 'excess group delay : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar V = self.Ed dB = False legcb = 'Delay (ns)' if typ == 'sinr': title = title + 'SINR : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.sinro if polar == 'p': V = self.sinrp if typ == 'snr': title = title + 'SNR : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.snro if polar == 'p': V = self.snrp if typ == 'capacity': title = title + 'Capacity : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar legcb = 'Mbit/s' if polar == 'o': V = self.bmhz.T[np.newaxis, :] * np.log( 1 + self.sinro) / np.log(2) if polar == 'p': V = self.bmhz.T[np.newaxis, :] * np.log( 1 + self.sinrp) / np.log(2) if typ == "pr": title = title + 'Pr : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dBm' else: lgdcb = 'mW' if polar == 'o': V = self.CmWo if polar == 'p': V = self.CmWp if typ == "ref": title = kwargs['title'] V = 10**(self.ref / 10) if dB: legcb = 'dB' else: legcb = 'Linear scale' if typ == "loss": title = title + 'Loss : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.Lwo * self.freespace if polar == 'p': V = self.Lwp * self.freespace if a == -1: V = np.max(V[f, :, :], axis=1) else: V = V[f, :, a] # reshaping the data on the grid if self.mode != 'file': U = V.reshape((self.nx, self.ny)).T else: U = V if dB: U = 10 * np.log10(U) if 'vmin' in kwargs: vmin = kwargs['vmin'] else: vmin = U.min() if 'vmax' in kwargs: vmax = kwargs['vmax'] else: vmax = U.max() if self.mode != 'file': img = ax.imshow(U, extent=(l, r, b, t), origin='lower', vmin=vmin, vmax=vmax, cmap=kwargs['cmap']) else: img = ax.scatter(self.grid[:, 0], self.grid[:, 1], c=U, s=scale, linewidth=0, cmap=kwargs['cmap'], vmin=vmin, vmax=vmax) # for k in range(self.na): # ax.annotate(str(k),xy=(self.pa[0,k],self.pa[1,k])) for k in self.dap.keys(): ax.annotate(str(self.dap[k]['name']), xy=(self.dap[k]['p'][0], self.dap[k]['p'][1])) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(img, cax) clb.set_label(legcb) if best: if self.mode != 'file': if polar == 'o': ax.contour(np.sum(self.bestsvo, axis=2)[f, :].reshape( self.nx, self.ny).T, extent=(l, r, b, t), linestyles='dotted') if polar == 'p': ax.contour(np.sum(self.bestsvp, axis=2)[f, :].reshape( self.nx, self.ny).T, extent=(l, r, b, t), linestyles='dotted') # display access points if a == -1: ax.scatter(self.pa[0, :], self.pa[1, :], s=scale + 10, c='r', linewidth=0) else: ax.scatter(self.pa[0, a], self.pa[1, a], s=scale + 10, c='r', linewidth=0) plt.tight_layout() return (fig, ax)
class Simul(object): # Simpy 3 """ Attributes ---------- config : config parser instance sim_opt : dictionary of configuration option for simulation ag_opt : dictionary of configuration option for agent lay_opt : dictionary of configuration option for layout meca_opt : dictionary of configuration option for mecanic net_opt : dictionary of configuration option for network loc_opt : dictionary of configuration option for localization save_opt : dictionary of configuration option for save sql_opt : dictionary of configuration option for sql Parameters ---------- self.lAg : list of Agent(Object) list of agents involved in simulation self.L : Layout Layout used in simulation Note ---- All the previous dictionnary are obtained from the chosen simulnet.ini file in the project directory """ def __init__(self): #SimulationRT.__init__(self) # Simpy 2 simpy.RealtimeEnvironment.__init__(self) #simpy 3 #self.initialize() self.config = ConfigParser.ConfigParser(inline_comment_prefixes=(';',),comment_prefixes=('#',';')) filename = pyu.getlong('simulnet.ini', pstruc['DIRSIMUL']) self.config.read(filename) self.sim_opt = dict(self.config.items('Simulation')) self.lay_opt = dict(self.config.items('Layout')) self.meca_opt = dict(self.config.items('Mechanics')) self.net_opt = dict(self.config.items('Network')) self.loc_opt = dict(self.config.items('Localization')) self.save_opt = dict(self.config.items('Save')) self.sql_opt = dict(self.config.items('Mysql')) self.seed = eval(self.sim_opt['seed']) self.traj = Trajectories() self.verbose = str2bool(self.sim_opt['verbose']) if str2bool(self.net_opt['ipython_nb_show']): self.verbose = False self.roomlist = [] self.finish = False self.create() def __repr__(self): s = 'Simulation information' + '\n----------------------' s = s + '\nLayout: ' + self.lay_opt['filename'] s = s + '\nSimulation duration: ' + str(self.sim_opt['duration']) s = s + '\nRandom seed: ' + str(self.sim_opt['seed']) s = s + '\nSave simulation: ' + self.save_opt['savep'] s = s + '\n\nUpdate times' + '\n-------------' s = s + '\nMechanical update: ' + \ str(self.meca_opt['mecanic_update_time']) s = s + '\nNetwork update: ' + str(self.net_opt['network_update_time']) s = s + '\nLocalization update: ' + self.net_opt['communication_mode'] s = s + '\n\nAgents => self.lAg[i]' + '\n------' s = s + '\nNumber of agents :' + str(len(self.lAg)) s = s + '\nAgents IDs: ' + \ str([self.lAg[i].ID for i in range(len(self.lAg))]) s = s + '\nAgents names: ' + \ str([self.lAg[i].name for i in range(len(self.lAg))]) s = s + '\nDestination of chosen agents: ' + \ self.meca_opt['choose_destination'] s = s + '\n\nNetwork' + '\n-------' s = s + '\nNodes per wstd: ' + str(self.net.wstd) s = s + '\n\nLocalization' + '\n------------' s = s + '\nLocalization enable: ' + self.loc_opt['localization'] s = s + '\nPostion estimation methods: ' + self.loc_opt['method'] return s def create_layout(self): """ create Layout in Simpy the_world thanks to Tk backend """ _filename = self.lay_opt['filename'] self.L = Layout(_filename) self.L.build() self.L.buildGr() self.L.buildGw() self.the_world = world() try: self.L.dumpr() print('Layout graphs are loaded from ' + basename + '/struc/ini') except: #self.L.sl = sl # self.L.loadGr(G1) print('This is the first time the layout file is used\ Layout graphs are curently being built, it may take few minutes.') self.L.build() self.L.dumpw() # # Create Layout # walls = self.L.thwall(0, 0) for wall in walls: for ii in range(0, len(wall) - 1): self.the_world.add_wall(wall[ii], wall[ii + 1]) def create_agent(self): """ create simulation's Agents ..todo:: change lAg list to a dictionnary ( modification in show.py too) """ self.lAg = [] agents = [] Cf = ConfigParser.ConfigParser() Cf.read(pyu.getlong('agent.ini', 'ini')) agents = eval(dict(Cf.items('used_agent'))['list']) for i, ag in enumerate(agents): ag_opt = dict(Cf.items(ag)) self.lAg.append( Agent( ID=ag_opt['id'], name=ag_opt['name'], typ=ag_opt['typ'], color=eval(ag_opt['color']), pdshow=str2bool(self.meca_opt['pdshow']), pos=np.array(eval(ag_opt['pos'])), roomId=int(ag_opt['roomid']), froom=eval(ag_opt['froom']), meca_updt=float(self.meca_opt['mecanic_update_time']), wait=float(ag_opt['wait']), cdest=eval(self.meca_opt['choose_destination']), loc=str2bool(self.loc_opt['localization']), loc_updt=float(self.loc_opt['localization_update_time']), loc_method=eval(self.loc_opt['method']), L=self.L, network=str2bool(self.net_opt['network']), net=self.net, epwr=dict([(eval((ag_opt['wstd']))[ep], eval((ag_opt['epwr']))[ep]) for ep in range(len(eval((ag_opt['wstd']))))]), sens=dict([(eval((ag_opt['wstd']))[ep], eval((ag_opt['sensitivity']))[ep]) for ep in range(len(eval((ag_opt['wstd']))))]), world=self.the_world, wstd=eval(ag_opt['wstd']), save=eval(self.save_opt['save']), gcom=self.gcom, comm_mode=eval(self.net_opt['communication_mode']), sim=self, seed=self.seed)) def create_EMS(self): """ create electromagnetic Solver object """ self.EMS = EMSolver(L=self.L) def create_network(self): """ create the whole network """ self.net = Network(EMS=self.EMS) self.gcom = Gcom(net=self.net, sim=self) self.create_agent() # create network if str2bool(self.net_opt['network']): self.net.create() # create All Personnal networks for n in self.net.nodes(): self.net.node[n]['PN']._get_wstd() self.net.node[n]['PN']._get_SubNet() self.gcom.create() # create Process Network self.Pnet = PNetwork(net=self.net, net_updt_time=float( self.net_opt['network_update_time']), L=self.L, sim=self, show_sg=str2bool(self.net_opt['show_sg']), disp_inf=str2bool(self.net_opt['dispinfo']), save=eval(self.save_opt['save'])) self.activate(self.Pnet, self.Pnet.run(), 0.0) def create_visual(self): """ create visual Tk process """ self.visu = Updater( interval=float(self.sim_opt['show_interval']), sim=self) self.activate(self.visu, self.visu.execute(), 0.0) def create(self): """ create the simulation This method is called at the end of __init__ """ # this is to redump the database at each simulation if 'mysql' in self.save_opt['save']: if str2bool(self.sql_opt['dumpdb']): os.popen('mysql -u ' + self.sql_opt['user'] + ' -p ' + self.sql_opt['dbname'] + '< /private/staff/t/ot/niamiot/svn2/devel/simulator/pyray/SimWHERE2.sql') # TODO remove the hard reference if 'txt' in self.save_opt['save']: pyu.writeDetails(self) if os.path.isfile(os.path.join(basename, 'output', 'Nodes.txt')): print('would you like to erase previous txt files ?') A = raw_input() if A == 'y': for f in os.listdir(os.path.join(basename, 'output')): try: fi, ext = f.split('.') if ext == 'txt': os.remove(os.path.join(basename, 'output' + f)) except: pass # Layout self.create_layout() # Electro Magnetic Simulator self.create_EMS() # Network self.create_network() if str2bool(self.sim_opt['showtk']): self.create_visual() self.create_show() if str2bool(self.save_opt['savep']): self.save = Save(L=self.L, net=self.net, sim=self) self.activate(self.save, self.save.run(), 0.0) def create_show(self): """ create a vizualization """ plt.ion() fig_net = 'network' fig_table = 'table' if str2bool(self.net_opt['show']): if str2bool(self.net_opt['ipython_nb_show']): notebook = True else: notebook = False self.sh = ShowNet(net=self.net, L=self.L, sim=self, fname=fig_net, notebook=notebook) self.activate(self.sh, self.sh.run(), 1.0) if str2bool(self.net_opt['show_table']): self.sht = ShowTable(net=self.net, lAg=self.lAg, sim=self, fname=fig_table) self.activate(self.sht, self.sht.run(), 1.0) def savepandas(self): """ save mechanics in pandas hdf5 format """ filename = pyu.getlong( eval(self.sim_opt["filename"]), pstruc['DIRNETSAVE']) layfile = self.L._filename.split('.')[0] store = pd.HDFStore(filename + '_' + layfile + '.h5', 'w') for a in self.lAg: if a.typ != 'ap': store.put(a.ID, a.meca.df.convert_objects()) else: # if agent acces point, its position is saved store.put(a.ID, a.posdf) store.get_storer(a.ID).attrs.typ = a.typ store.get_storer(a.ID).attrs.name = a.name store.get_storer(a.ID).attrs.ID = a.ID store.get_storer(a.ID).attrs.layout = self.L._filename # saving metadata store.root._v_attrs.attributes=self.sim_opt store.close() self.traj.loadh5( eval(self.sim_opt["filename"]) + '_' + layfile + '.h5') def runsimul(self): """ run simulation """ if not self.finish: # random number seed seed(self.seed) self.simulate(until=float(self.sim_opt['duration']), real_time=True, rel_speed=float(self.sim_opt['speedratio'])) self.the_world._boids = {} # if str2bool(self.save_opt['savep']): # print 'Processing save results, please wait' # self.save.mat_export() if str2bool(self.save_opt['savepd']): self.savepandas() self.finish = True else: raise NameError('Reinstantiate a new simul object to run again')
from pylayers.gis.layout import Layout import matplotlib.pyplot as plt import doctest #doctest.testmod(layout) #L = Layout('TA-Office.ini') L = Layout('DLR.ini') try: L.dumpr() except: L.build() L.dumpw() #L.editor() fig = plt.gcf() #ax1 = fig.add_subplot(221) ax1 = fig.add_subplot(321) L.display['thin']=True fig,ax1 = L.showGs(fig=fig,ax=ax1) #L.display['edlabel']=True #L.display['edlblsize']=50 # display selected segments L.display['thin']=True L.showG(fig=fig,ax=ax1,graph='t') fig = plt.gcf() ax1 = plt.gca() fig,ax1 = L.showGs(fig=fig,ax=ax1,edlist=[125],width=4) ax11 = fig.add_subplot(322) L.showG(fig=fig,ax=ax11,graph='') #plt.savefig('graphGs.png')
class Coverage(PyLayers): """ Handle Layout Coverage Methods ------- creategrid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout nx : number of point on x ny : number of point on y tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map na : number of access point """ def __init__(self,_fileini='coverage.ini'): """ object constructor Parameters ---------- _fileini : string name of the configuration file Notes ----- Coverage is described in an ini file. Default file is coverage.ini and is placed in the ini directory of the current project. """ self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong(_fileini,pstruc['DIRSIMUL'])) self.layoutopt = dict(self.config.items('layout')) self.gridopt = dict(self.config.items('grid')) self.apopt = dict(self.config.items('ap')) self.rxopt = dict(self.config.items('rx')) self.showopt = dict(self.config.items('show')) # get the Layout filename = self.layoutopt['filename'] if filename.endswith('ini'): self.typ = 'indoor' self.L = Layout(filename) # get the receiving grid self.nx = eval(self.gridopt['nx']) self.ny = eval(self.gridopt['ny']) self.mode = self.gridopt['mode'] self.boundary = eval(self.gridopt['boundary']) self.filespa = self.gridopt['file'] # # create grid # self.creategrid(mode=self.mode,boundary=self.boundary,_fileini=self.filespa) self.dap = {} for k in self.apopt: kwargs = eval(self.apopt[k]) ap = std.AP(**kwargs) self.dap[eval(k)] = ap try: self.L.Gt.nodes() except: pass try: self.L.dumpr() except: self.L.build() self.L.dumpw() else: self.typ='outdoor' self.E = ez.Ezone(filename) self.E.loadh5() self.E.rebase() self.fGHz = np.array([]) #self.fGHz = eval(self.txopt['fghz']) #self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) #self.ptdbm = eval(self.txopt['ptdbm']) #self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section #self.rxsens = eval(self.rxopt['sensitivity']) self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) # show section self.bshow = str2bool(self.showopt['show']) def __repr__(self): st='' if self.typ=='indoor': st = st+ 'Layout file : '+self.L.filename + '\n\n' st = st + '-----list of Access Points ------'+'\n' for k in self.dap: st = st + self.dap[k].__repr__()+'\n' st = st + '-----Rx------'+'\n' st= st+ 'temperature (K) : '+ str(self.temperaturek) + '\n' st= st+ 'noisefactor (dB) : '+ str(self.noisefactordb) + '\n\n' st = st + '--- Grid ----'+'\n' st= st+ 'mode : ' + str(self.mode) + '\n' if self.mode<>'file': st= st+ 'nx : ' + str(self.nx) + '\n' st= st+ 'ny : ' + str(self.ny) + '\n' if self.mode=='zone': st= st+ 'boundary (xmin,ymin,xmax,ymax) : ' + str(self.boundary) + '\n\n' if self.mode=='file': st = st+' filename : '+self.filespa+'\n' return(st) def creategrid(self,mode='full',boundary=[],_fileini=''): """ create a grid Parameters ---------- full : boolean default (True) use all the layout area boundary : (xmin,ymin,xmax,ymax) if full is False the boundary argument is used """ if mode=="file": self.RN = RadioNode(name='', typ='rx', _fileini = _fileini, _fileant = 'def.vsh3') self.grid =self.RN.position[0:2,:].T else: if mode=="full": mi=np.min(self.L.Gs.pos.values(),axis=0)+0.01 ma=np.max(self.L.Gs.pos.values(),axis=0)-0.01 if mode=="zone": assert boundary<>[] mi = np.array([boundary[0],boundary[1]]) ma = np.array([boundary[2],boundary[3]]) x = np.linspace(mi[0],ma[0],self.nx) y = np.linspace(mi[1],ma[1],self.ny) self.grid=np.array((list(np.broadcast(*np.ix_(x, y))))) self.ng = self.grid.shape[0] def where1(self): """ Unfinished : Not sure this is the right place (too specific) """ M1 = UWBMeasure(1) self.dap={} self.dap[1]={} self.dap[2]={} self.dap[3]={} self.dap[4]={} self.dap[1]['p']=M1.rx[1,0:2] self.dap[2]['p']=M1.rx[1,0:2] self.dap[3]['p']=M1.rx[1,0:2] self.dap[4]['p']=M1.rx[1,0:2] for k in range(300): try: M = UWBMeasure(k) tx = M.tx self.grid=np.vstack((self.grid,tx[0:2])) D = M.rx-tx[np.newaxis,:] D2 = D*D dist = np.sqrt(np.sum(D2,axis=1))[1:] Emax = M.Emax() Etot = M.Etot()[0] try: td1 = np.hstack((td1,dist[0])) td2 = np.hstack((td2,dist[1])) td3 = np.hstack((td3,dist[2])) td4 = np.hstack((td4,dist[3])) te1 = np.hstack((te1,Emax[0])) te2 = np.hstack((te2,Emax[1])) te3 = np.hstack((te3,Emax[2])) te4 = np.hstack((te4,Emax[3])) tt1 = np.hstack((tt1,Etot[0])) tt2 = np.hstack((tt2,Etot[1])) tt3 = np.hstack((tt3,Etot[2])) tt4 = np.hstack((tt4,Etot[3])) #tdist = np.hstack((tdist,dist)) #te = np.hstack((te,Emax)) except: td1=np.array(dist[0]) td2=np.array(dist[1]) td3=np.array(dist[2]) td4=np.array(dist[3]) te1 =np.array(Emax[0]) te2 =np.array(Emax[1]) te3 =np.array(Emax[2]) te4 =np.array(Emax[3]) tt1 =np.array(Etot[0]) tt2 =np.array(Etot[1]) tt3 =np.array(Etot[2]) tt4 =np.array(Etot[3]) except: pass def cover(self,sinr=True,snr=True,best=True): """ run the coverage calculation Parameters ---------- sinr : boolean snr : boolean best : boolean Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a=C.show(typ='sinr',figsize=(10,8)) >>> plt.show() Notes ----- self.fGHz is an array, it means that Coverage is calculated at once for a whole set of frequencies. In practice, it would be the center frequency of a given standard channel. This function is calling `loss.Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as a full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ # # select active AP # lactiveAP = [] try: del self.aap del self.ptdbm except: pass self.kB = 1.3806503e-23 # Boltzmann constant for iap in self.dap: if self.dap[iap]['on']: lactiveAP.append(iap) fGHz = self.dap[iap].s.fcghz self.fGHz=np.unique(np.hstack((self.fGHz,fGHz))) apchan = self.dap[iap]['chan'] try: self.aap = np.vstack((self.aap,self.dap[iap]['p'][0:2])) self.ptdbm = np.vstack((self.ptdbm,self.dap[iap]['PtdBm'])) self.bmhz = np.vstack((self.bmhz, self.dap[iap].s.chan[apchan[0]]['BMHz'])) except: self.aap = self.dap[iap]['p'][0:2] self.ptdbm = np.array(self.dap[iap]['PtdBm']) self.bmhz = np.array(self.dap[iap].s.chan[apchan[0]]['BMHz']) PnW = np.array((10**(self.noisefactordb/10.))*self.kB*self.temperaturek*self.bmhz*1e6) # Evaluate Noise Power (in dBm) self.pndbm = np.array(10*np.log10(PnW)+30) #lchan = map(lambda x: self.dap[x]['chan'],lap) #apchan = zip(self.dap.keys(),lchan) #self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) self.ptdbm = self.ptdbm.T self.pndbm = self.pndbm.T # creating all links p = product(range(self.ng),lactiveAP) # # pa : access point # pg : grid point # # 1 x na for k in p: pg = self.grid[k[0],:] pa = self.dap[k[1]]['p'][0:2] try: self.pa = np.vstack((self.pa,pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg,pg)) except: self.pg = pg self.pa = self.pa.T self.pg = self.pg.T self.nf = len(self.fGHz) # retrieving dimensions along the 3 axis na = len(lactiveAP) self.na = na ng = self.ng nf = self.nf Lwo,Lwp,Edo,Edp = loss.Losst(self.L,self.fGHz,self.pa,self.pg,dB=False) self.Lwo = Lwo.reshape(nf,ng,na) self.Edo = Edo.reshape(nf,ng,na) self.Lwp = Lwp.reshape(nf,ng,na) self.Edp = Edp.reshape(nf,ng,na) freespace = loss.PL(self.fGHz,self.pa,self.pg,dB=False) self.freespace = freespace.reshape(nf,ng,na) # transmitting power # f x g x a # CmW : Received Power coverage in mW self.CmWo = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwo*self.freespace self.CmWp = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwp*self.freespace if snr: self.evsnr() if sinr: self.evsinr() if best: self.evbestsv() def evsnr(self): """ calculates snr """ NmW = 10**(self.pndbm/10.)[np.newaxis,:] self.snro = self.CmWo/NmW self.snrp = self.CmWp/NmW def evsinr(self): """ calculates sinr """ # na : number of access point na = self.na # U : 1 x 1 x na x na U = (np.ones((na,na))-np.eye(na))[np.newaxis,np.newaxis,:,:] # CmWo : received power in mW orthogonal polarization # CmWp : received power in mW parallel polarization ImWo = np.einsum('ijkl,ijl->ijk',U,self.CmWo) ImWp = np.einsum('ijkl,ijl->ijk',U,self.CmWp) NmW = 10**(self.pndbm/10.)[np.newaxis,:] self.sinro = self.CmWo/(ImWo+NmW) self.sinrp = self.CmWp/(ImWp+NmW) def evbestsv(self): """ determine the best server map Notes ----- C.bestsv """ na = self.na ng = self.ng nf = self.nf # find best server regions Vo = self.CmWo Vp = self.CmWp self.bestsvo = np.empty(nf*ng*na).reshape(nf,ng,na) self.bestsvp = np.empty(nf*ng*na).reshape(nf,ng,na) for kf in range(nf): MaxVo = np.max(Vo[kf,:,:],axis=1) MaxVp = np.max(Vp[kf,:,:],axis=1) for ka in range(na): uo = np.where(Vo[kf,:,ka]==MaxVo) up = np.where(Vp[kf,:,ka]==MaxVp) self.bestsvo[kf,uo,ka]=ka+1 self.bestsvp[kf,up,ka]=ka+1 # def showEd(self,polar='o',**kwargs): # """ shows a map of direct path excess delay # # Parameters # ---------- # # polar : string # 'o' | 'p' # # Examples # -------- # # .. plot:: # :include-source: # # >> from pylayers.antprop.coverage import * # >> C = Coverage() # >> C.cover() # >> C.showEd(polar='o') # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # # fig,ax = self.L.showG('s',**kwargs) # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # #generate the colormap with 1024 interpolated values # my_cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # # # if polar=='o': # mcEdof = np.ma.masked_where(prdbm < self.rxsens,self.Edo) # # cov=ax.imshow(mcEdof.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # # # cov=ax.imshow(self.Edo.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar orthogonal" # # if polar=='p': # mcEdpf = np.ma.masked_where(prdbm < self.rxsens,self.Edp) # # cov=ax.imshow(mcEdpf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # cov=ax.imshow(self.Edp.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar parallel" # # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # ax.set_title(titre) # # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('excess delay (ns)') # # if self.show: # plt.show() # return fig,ax # # def showPower(self,rxsens=True,nfl=True,polar='o',**kwargs): # """ show the map of received power # # Parameters # ---------- # # rxsens : bool # clip the map with rx sensitivity set in self.rxsens # nfl : bool # clip the map with noise floor set in self.pndbm # polar : string # 'o'|'p' # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showPower() # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # fig,ax = self.L.showG('s',**kwargs) # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # ## tCM = plt.cm.get_cmap('jet') ## tCM._init() ## alphas = np.abs(np.linspace(.0,1.0, tCM.N)) ## tCM._lut[:-3,-1] = alphas # # title='Map of received power - Pt = ' + str(self.ptdbm) + ' dBm'+str(' fGHz =') + str(self.fGHz) + ' polar = '+polar # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # # if not kwargs.has_key('cmap'): # # generate the colormap with 1024 interpolated values # cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # else: # cmap = kwargs['cmap'] # #my_cmap = cm.copper # # # if rxsens : # # ## values between the rx sensitivity and noise floor # mcPrf = np.ma.masked_where((prdbm > self.rxsens) # & (prdbm < self.pndbm),prdbm) # # mcPrf = np.ma.masked_where((prdbm > self.rxsens) ,prdbm) # # cov1 = ax.imshow(mcPrf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = cm.copper, # vmin=self.rxsens,origin='lower') # # ### values above the sensitivity # mcPrs = np.ma.masked_where(prdbm < self.rxsens,prdbm) # cov = ax.imshow(mcPrs.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.rxsens,origin='lower') # title=title + '\n black : Pr (dBm) < %.2f' % self.rxsens + ' dBm' # # else : # cov=ax.imshow(prdbm.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.pndbm,origin='lower') # # if nfl: # ### values under the noise floor # ### we first clip the value below the noise floor # cl = np.nonzero(prdbm<=self.pndbm) # cPr = prdbm # cPr[cl] = self.pndbm # mcPruf = np.ma.masked_where(cPr > self.pndbm,cPr) # cov2 = ax.imshow(mcPruf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'binary', # vmax=self.pndbm,origin='lower') # title=title + '\n white : Pr (dBm) < %.2f' % self.pndbm + ' dBm' # # # ax.scatter(self.tx[0],self.tx[1],s=10,c='k',linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('Power (dBm)') # # if self.show: # plt.show() # # return fig,ax # # # def showTransistionRegion(self,polar='o'): # """ # # Notes # ----- # # See : "Analyzing the Transitional Region in Low Power Wireless Links" # Marco Zuniga and Bhaskar Krishnamachari # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showTransitionRegion() # # """ # # frameLength = self.framelengthbytes # # PndBm = self.pndbm # gammaU = 10*np.log10(-1.28*np.log(2*(1-0.9**(1./(8*frameLength))))) # gammaL = 10*np.log10(-1.28*np.log(2*(1-0.1**(1./(8*frameLength))))) # # PrU = PndBm + gammaU # PrL = PndBm + gammaL # # fig,ax = self.L.showGs() # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # zones = np.zeros(np.shape(prdbm)) # #pdb.set_trace() # # uconnected = np.nonzero(prdbm>PrU) # utransition = np.nonzero((prdbm < PrU)&(prdbm > PrL)) # udisconnected = np.nonzero(prdbm < PrL) # # zones[uconnected] = 1 # zones[utransition] = (prdbm[utransition]-PrL)/(PrU-PrL) # cov = ax.imshow(zones.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'BuGn',origin='lower') # # title='PDR region' # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # fig.colorbar(cov,cax) # if self.show: # plt.show() # def plot(self,**kwargs): """ """ defaults = { 'typ': 'pr', 'grid': False, 'f' : 0, 'a' : 0, 'db':True, 'col':'b' } for k in defaults: if k not in kwargs: kwargs[k]=defaults[k] if 'fig' in kwargs: fig=kwargs['fig'] else: fig=plt.figure() if 'ax' in kwargs: ax = kwargs['ax'] else: ax = fig.add_subplot(111) if kwargs['typ']=='pr': if kwargs['a']<>-1: U = self.CmW[kwargs['f'],:,kwargs['a']] else: U = self.CmW[kwargs['f'],:,:].reshape(self.na*self.ng) if kwargs['db']: U = 10*np.log10(U) D = np.sqrt(np.sum((self.pa-self.pg)*(self.pa-self.pg),axis=0)) if kwargs['a']<>-1: D = D.reshape(self.ng,self.na) ax.semilogx(D[:,kwargs['a']],U,'.',color=kwargs['col']) else: ax.semilogx(D,U,'.',color=kwargs['col']) return fig,ax def show(self,**kwargs): """ show coverage Parameters ---------- typ : string 'pr' | 'sinr' | 'capacity' | 'loss' | 'best' | 'egd' grid : boolean polar : string 'o' | 'p' best : boolean draw best server contour if True f : int frequency index a : int access point index (-1 all access point) Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a = C.show(typ='pr',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='best',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='loss',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='sinr',figsize=(10,8)) >>> plt.show() See Also -------- pylayers.gis.layout.Layout.showG """ defaults = { 'typ': 'pr', 'grid': False, 'polar':'p', 'f' : 0, 'a' :-1, 'db':True, 'cmap' :cm.jet, 'best':True } title = self.dap[1].s.name+ ' : ' for k in defaults: if k not in kwargs: kwargs[k]=defaults[k] polar = kwargs['polar'] if 'fig' in kwargs: if 'ax' in kwargs: fig,ax=self.L.showG('s',fig=kwargs['fig'],ax=kwargs['ax']) else: fig,ax=self.L.showG('s',fig=kwargs['fig']) else: if 'figsize' in kwargs: fig,ax=self.L.showG('s',figsize=kwargs['figsize']) else: fig,ax=self.L.showG('s') # plot the grid if kwargs['grid']: for k in self.dap: p = self.dap[k].p ax.plot(p[0],p[1],'or') f = kwargs['f'] a = kwargs['a'] typ = kwargs['typ'] best = kwargs['best'] dB = kwargs['db'] # setting the grid l = self.grid[0,0] r = self.grid[-1,0] b = self.grid[0,1] t = self.grid[-1,-1] if typ=='best': title = title + 'Best server'+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar for ka in range(self.na): if polar=='p': bestsv = self.bestsvp[f,:,ka] if polar=='o': bestsv = self.bestsvo[f,:,ka] m = np.ma.masked_where(bestsv == 0,bestsv) if self.mode<>'file': W = m.reshape(self.nx,self.ny).T ax.imshow(W, extent=(l,r,b,t), origin='lower', vmin=1, vmax=self.na+1) else: ax.scatter(self.grid[:,0],self.grid[:,1],c=m,s=20,linewidth=0) ax.set_title(title) else: if typ=='egd': title = title + 'excess group delay : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar V = self.Ed dB = False legcb = 'Delay (ns)' if typ=='sinr': title = title + 'SINR : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar=='o': V = self.sinro if polar=='p': V = self.sinrp if typ=='snr': title = title + 'SNR : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar=='o': V = self.snro if polar=='p': V = self.snrp if typ=='capacity': title = title + 'Capacity : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar legcb = 'Mbit/s' if polar=='o': V = self.bmhz.T[np.newaxis,:]*np.log(1+self.sinro)/np.log(2) if polar=='p': V = self.bmhz.T[np.newaxis,:]*np.log(1+self.sinrp)/np.log(2) if typ=='pr': title = title + 'Pr : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar if dB: legcb = 'dBm' else: lgdcb = 'mW' if polar=='o': V = self.CmWo if polar=='p': V = self.CmWp if typ=='loss': title = title + 'Loss : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar=='o': V = self.Lwo*self.freespace if polar=='p': V = self.Lwp*self.freespace if a == -1: V = np.max(V[f,:,:],axis=1) else: V = V[f,:,a] # reshaping the data on the grid if self.mode!='file': U = V.reshape((self.nx,self.ny)).T else: U = V if dB: U = 10*np.log10(U) if 'vmin' in kwargs: vmin = kwargs['vmin'] else: vmin = U.min() if 'vmax' in kwargs: vmax = kwargs['vmax'] else: vmax = U.max() if self.mode!='file': img = ax.imshow(U, extent=(l,r,b,t), origin='lower', vmin = vmin, vmax = vmax, cmap = kwargs['cmap']) else: img=ax.scatter(self.grid[:,0],self.grid[:,1],c=U,s=20,linewidth=0,cmap=kwargs['cmap']) for k in range(self.na): ax.annotate(str(k),xy=(self.pa[0,k],self.pa[1,k])) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(img,cax) clb.set_label(legcb) if best: if self.mode<>'file': if polar=='o': ax.contour(np.sum(self.bestsvo,axis=2)[f,:].reshape(self.nx,self.ny).T,extent=(l,r,b,t),linestyles='dotted') if polar=='p': ax.contour(np.sum(self.bestsvp,axis=2)[f,:].reshape(self.nx,self.ny).T,extent=(l,r,b,t),linestyles='dotted') # display access points if a==-1: ax.scatter(self.pa[0,:],self.pa[1,:],s=30,c='r',linewidth=0) else: ax.scatter(self.pa[0,a],self.pa[1,a],s=30,c='r',linewidth=0) plt.tight_layout() return(fig,ax)
class Coverage(PyLayers): """ Handle Layout Coverage Methods ------- creategrid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout nx : number of point on x ny : number of point on y tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map na : number of access point """ def __init__(self,_fileini='coverage.ini'): """ object constructor Parameters ---------- _fileini : string name of the configuration file Notes ----- Coverage is described in an ini file. Default file is coverage.ini and is placed in the ini directory of the current project. """ self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong(_fileini,pstruc['DIRSIMUL'])) self.layoutopt = dict(self.config.items('layout')) self.gridopt = dict(self.config.items('grid')) self.apopt = dict(self.config.items('ap')) self.rxopt = dict(self.config.items('rx')) self.showopt = dict(self.config.items('show')) # get the Layout self.L = Layout(self.layoutopt['filename']) # get the receiving grid self.nx = eval(self.gridopt['nx']) self.ny = eval(self.gridopt['ny']) self.ng = self.nx*self.ny self.mode = eval(self.gridopt['full']) self.boundary = eval(self.gridopt['boundary']) # create grid # we could here construct a grid locally around the access point # to be done later for code acceleration # self.creategrid(full=self.mode,boundary=self.boundary) self.dap = {} for k in self.apopt: kwargs = eval(self.apopt[k]) ap = std.AP(**kwargs) self.dap[eval(k)] = ap try: self.aap = np.vstack((self.aap,ap['p'][0:2])) self.ptdbm = np.vstack((self.ptdbm,ap['PtdBm'])) except: self.aap = ap['p'][0:2] self.ptdbm = ap['PtdBm'] # 1 x na self.ptdbm = self.ptdbm.T # number of access points self.na = len(self.dap) # creating all links p = product(range(self.ng),range(self.na)) # # a : access point # g : grid # for k in p: pg = self.grid[k[0],:] pa = self.aap[k[1]] try: self.pa = np.vstack((self.pa,pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg,pg)) except: self.pg = pg self.pa = self.pa.T self.pg = self.pg.T # frequency is chosen as all the center frequencies of the standard # warning assuming the same standard self.fGHz = self.dap[0].s.fcghz self.nf = len(self.fGHz) # AP section #self.fGHz = eval(self.txopt['fghz']) #self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) #self.ptdbm = eval(self.txopt['ptdbm']) #self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section self.rxsens = eval(self.rxopt['sensitivity']) kBoltzmann = 1.3806503e-23 self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) # list of access points lap = self.dap.keys() # list of channels lchan = map(lambda x: self.dap[x]['chan'],lap) apchan = zip(self.dap.keys(),lchan) self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) # Evaluate Noise Power (in dBm) Pn = (10**(self.noisefactordb/10.)+1)*kBoltzmann*self.temperaturek*self.bmhz*1e3 self.pndbm = 10*np.log10(Pn)+60 # show section self.bshow = str2bool(self.showopt['show']) try: self.L.Gt.nodes() except: pass try: self.L.dumpr() except: self.L.build() self.L.dumpw() def __repr__(self): st='' st = st+ 'Layout file : '+self.L.filename + '\n\n' st = st + '-----list of Access Points ------'+'\n' for k in self.dap: st = st + self.dap[k].__repr__()+'\n' st = st + '-----Rx------'+'\n' st= st+ 'rxsens (dBm) : '+ str(self.rxsens) + '\n' st= st+ 'bandwith (Mhz) : '+ str(self.bmhz) + '\n' st= st+ 'temperature (K) : '+ str(self.temperaturek) + '\n' st= st+ 'noisefactor (dB) : '+ str(self.noisefactordb) + '\n\n' st = st + '--- Grid ----'+'\n' st= st+ 'nx : ' + str(self.nx) + '\n' st= st+ 'ny : ' + str(self.ny) + '\n' st= st+ 'nlink : ' + str(self.ng*self.na) + '\n' st= st+ 'full grid : ' + str(self.mode) + '\n' st= st+ 'boundary (xmin,ymin,xmax,ymax) : ' + str(self.boundary) + '\n\n' return(st) def creategrid(self,full=True,boundary=[]): """ create a grid Parameters ---------- full : boolean default (True) use all the layout area boundary : (xmin,ymin,xmax,ymax) if full is False the boundary argument is used """ if full: mi=np.min(self.L.Gs.pos.values(),axis=0)+0.01 ma=np.max(self.L.Gs.pos.values(),axis=0)-0.01 else: assert boundary<>[] mi = np.array([boundary[0],boundary[1]]) ma = np.array([boundary[2],boundary[3]]) x = np.linspace(mi[0],ma[0],self.nx) y = np.linspace(mi[1],ma[1],self.ny) self.grid=np.array((list(np.broadcast(*np.ix_(x, y))))) # def coverold(self): # """ run the coverage calculation (Deprecated) # # Parameters # ---------- # # lay_bound : bool # If True, the coverage is performed only inside the Layout # and clip the values of the grid chosen in coverage.ini # # Examples # -------- # # .. plot:: # :include-source: # # >> from pylayers.antprop.coverage import * # >> C = Coverage() # >> C.cover() # >> C.showPower() # # Notes # ----- # # self.fGHz is an array it means that coverage is calculated at once # for a whole set of frequencies. In practice the center frequency of a # given standard channel. # # This function is calling `Losst` which calculates Losses along a # straight path. In a future implementation we will # abstract the EM solver in order to make use of other calculation # approaches as full or partial Ray Tracing. # # The following members variables are evaluated : # # + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ # + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` # + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` # + snro : SNR polar o (H) # + snrp : SNR polar p (H) # # See Also # -------- # # pylayers.antprop.loss.Losst # pylayers.antprop.loss.PL # # """ # # self.Lwo,self.Lwp,self.Edo,self.Edp = loss.Losst(self.L,self.fGHz,self.grid.T,self.tx) # self.freespace = loss.PL(self.fGHz,self.grid,self.tx) # # self.prdbmo = self.ptdbm - self.freespace - self.Lwo # self.prdbmp = self.ptdbm - self.freespace - self.Lwp # self.snro = self.prdbmo - self.pndbm # self.snrp = self.prdbmp - self.pndbm def cover(self,polar='o',sinr=True,snr=True,best=True): """ run the coverage calculation Parameters ---------- polar : string 'o' | 'p' sinr : boolean snr : boolean best : boolean Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a=C.show(typ='sinr') >>> plt.show() Notes ----- self.fGHz is an array it means that coverage is calculated at once for a whole set of frequencies. In practice the center frequency of a given standard channel. This function is calling `Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ # retrieving dimensions along the 3 axis na = self.na ng = self.ng nf = self.nf Lwo,Lwp,Edo,Edp = loss.Losst(self.L,self.fGHz,self.pa,self.pg,dB=False) if polar=='o': self.polar='o' self.Lw = Lwo.reshape(nf,ng,na) self.Ed = Edo.reshape(nf,ng,na) if polar=='p': self.polar='p' self.Lw = Lwp.reshape(nf,ng,na) self.Ed = Edp.reshape(nf,ng,na) freespace = loss.PL(self.fGHz,self.pa,self.pg,dB=False) self.freespace = freespace.reshape(nf,ng,na) # Warning we are assuming here all transmitters have the same # transmitting power (to be modified) # f x g x a # CmW : Received Power coverage in mW self.CmW = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lw*self.freespace if snr: self.snr() if sinr: self.sinr() if best: self.best() def snr(self): """ calculate snr """ NmW = 10**(self.pndbm/10.)[np.newaxis,np.newaxis,:] self.snr = self.CmW/NmW def sinr(self): """ calculate sinr """ na = self.na U = (np.ones((na,na))-np.eye(na))[np.newaxis,np.newaxis,:,:] ImW = np.einsum('ijkl,ijl->ijk',U,self.CmW) NmW = 10**(self.pndbm/10.)[np.newaxis,np.newaxis,:] self.sinr = self.CmW/(ImW+NmW) def best(self): """ determine best server map Notes ----- C.bestsv """ na = self.na ng = self.ng nf = self.nf # find best server regions V = self.CmW self.bestsv = np.zeros(nf*ng*na).reshape(nf,ng,na) for kf in range(nf): MaxV = np.max(V[kf,:,:],axis=1) for ka in range(na): u = np.where(V[kf,:,ka]==MaxV) self.bestsv[kf,u,ka]=ka+1 # def showEd(self,polar='o',**kwargs): # """ shows a map of direct path excess delay # # Parameters # ---------- # # polar : string # 'o' | 'p' # # Examples # -------- # # .. plot:: # :include-source: # # >> from pylayers.antprop.coverage import * # >> C = Coverage() # >> C.cover() # >> C.showEd(polar='o') # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # # fig,ax = self.L.showG('s',**kwargs) # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # #generate the colormap with 1024 interpolated values # my_cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # # # if polar=='o': # mcEdof = np.ma.masked_where(prdbm < self.rxsens,self.Edo) # # cov=ax.imshow(mcEdof.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # # # cov=ax.imshow(self.Edo.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar orthogonal" # # if polar=='p': # mcEdpf = np.ma.masked_where(prdbm < self.rxsens,self.Edp) # # cov=ax.imshow(mcEdpf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'jet', # origin='lower') # # # cov=ax.imshow(self.Edp.reshape((self.nx,self.ny)).T, # # extent=(l,r,b,t), # # origin='lower') # titre = "Map of LOS excess delay, polar parallel" # # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # ax.set_title(titre) # # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('excess delay (ns)') # # if self.show: # plt.show() # return fig,ax # # def showPower(self,rxsens=True,nfl=True,polar='o',**kwargs): # """ show the map of received power # # Parameters # ---------- # # rxsens : bool # clip the map with rx sensitivity set in self.rxsens # nfl : bool # clip the map with noise floor set in self.pndbm # polar : string # 'o'|'p' # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showPower() # # """ # # if not kwargs.has_key('alphacy'): # kwargs['alphacy']=0.0 # if not kwargs.has_key('colorcy'): # kwargs['colorcy']='w' # if not kwargs.has_key('nodes'): # kwargs['nodes']=False # fig,ax = self.L.showG('s',**kwargs) # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # ## tCM = plt.cm.get_cmap('jet') ## tCM._init() ## alphas = np.abs(np.linspace(.0,1.0, tCM.N)) ## tCM._lut[:-3,-1] = alphas # # title='Map of received power - Pt = ' + str(self.ptdbm) + ' dBm'+str(' fGHz =') + str(self.fGHz) + ' polar = '+polar # # cdict = { # 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), # 'green': ((0., 0.5, 0.5), (1., 1., 1.)), # 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) # } # # if not kwargs.has_key('cmap'): # # generate the colormap with 1024 interpolated values # cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) # else: # cmap = kwargs['cmap'] # #my_cmap = cm.copper # # # if rxsens : # # ## values between the rx sensitivity and noise floor # mcPrf = np.ma.masked_where((prdbm > self.rxsens) # & (prdbm < self.pndbm),prdbm) # # mcPrf = np.ma.masked_where((prdbm > self.rxsens) ,prdbm) # # cov1 = ax.imshow(mcPrf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = cm.copper, # vmin=self.rxsens,origin='lower') # # ### values above the sensitivity # mcPrs = np.ma.masked_where(prdbm < self.rxsens,prdbm) # cov = ax.imshow(mcPrs.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.rxsens,origin='lower') # title=title + '\n black : Pr (dBm) < %.2f' % self.rxsens + ' dBm' # # else : # cov=ax.imshow(prdbm.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t), # cmap = cmap, # vmin=self.pndbm,origin='lower') # # if nfl: # ### values under the noise floor # ### we first clip the value below the noise floor # cl = np.nonzero(prdbm<=self.pndbm) # cPr = prdbm # cPr[cl] = self.pndbm # mcPruf = np.ma.masked_where(cPr > self.pndbm,cPr) # cov2 = ax.imshow(mcPruf.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'binary', # vmax=self.pndbm,origin='lower') # title=title + '\n white : Pr (dBm) < %.2f' % self.pndbm + ' dBm' # # # ax.scatter(self.tx[0],self.tx[1],s=10,c='k',linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # clb = fig.colorbar(cov,cax) # clb.set_label('Power (dBm)') # # if self.show: # plt.show() # # return fig,ax # # # def showTransistionRegion(self,polar='o'): # """ # # Notes # ----- # # See : "Analyzing the Transitional Region in Low Power Wireless Links" # Marco Zuniga and Bhaskar Krishnamachari # # Examples # -------- # # .. plot:: # :include-source: # # > from pylayers.antprop.coverage import * # > C = Coverage() # > C.cover() # > C.showTransitionRegion() # # """ # # frameLength = self.framelengthbytes # # PndBm = self.pndbm # gammaU = 10*np.log10(-1.28*np.log(2*(1-0.9**(1./(8*frameLength))))) # gammaL = 10*np.log10(-1.28*np.log(2*(1-0.1**(1./(8*frameLength))))) # # PrU = PndBm + gammaU # PrL = PndBm + gammaL # # fig,ax = self.L.showGs() # # l = self.grid[0,0] # r = self.grid[-1,0] # b = self.grid[0,1] # t = self.grid[-1,-1] # # if polar=='o': # prdbm=self.prdbmo # if polar=='p': # prdbm=self.prdbmp # # zones = np.zeros(np.shape(prdbm)) # #pdb.set_trace() # # uconnected = np.nonzero(prdbm>PrU) # utransition = np.nonzero((prdbm < PrU)&(prdbm > PrL)) # udisconnected = np.nonzero(prdbm < PrL) # # zones[uconnected] = 1 # zones[utransition] = (prdbm[utransition]-PrL)/(PrU-PrL) # cov = ax.imshow(zones.reshape((self.nx,self.ny)).T, # extent=(l,r,b,t),cmap = 'BuGn',origin='lower') # # title='PDR region' # ax.scatter(self.tx[0],self.tx[1],linewidth=0) # # ax.set_title(title) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # fig.colorbar(cov,cax) # if self.show: # plt.show() # def show(self,**kwargs): """ show coverage Parameters ---------- typ : string 'pr' | 'sinr' | 'capacity' | 'loss' | 'best' grid : boolean best : boolean draw best server contour if True f : int frequency index a : int access point index (-1 all access point) Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover(polar='o') >>> f,a = C.show(typ='pr') >>> plt.show() >>> f,a = C.show(typ='best') >>> plt.show() >>> f,a = C.show(typ='loss') >>> plt.show() >>> f,a = C.show(typ='sinr') >>> plt.show() """ defaults = { 'typ': 'pr', 'grid': False, 'f' : 0, 'a' :-1, 'db':True, 'cmap' :cm.jet, 'best':True } title = self.dap[0].s.name+ ' : ' for k in defaults: if k not in kwargs: kwargs[k]=defaults[k] if 'fig' in kwargs: fig,ax=self.L.showG('s',fig=kwargs['fig']) else: fig,ax=self.L.showG('s') # plot the grid if kwargs['grid']: for k in self.dap: p = self.dap[k].p ax.plot(p[0],p[1],'or') f = kwargs['f'] a = kwargs['a'] typ = kwargs['typ'] best = kwargs['best'] dB = kwargs['db'] # setting the grid l = self.grid[0,0] r = self.grid[-1,0] b = self.grid[0,1] t = self.grid[-1,-1] if typ=='best': title = title + 'Best server'+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar for ka in range(self.na): bestsv = self.bestsv[f,:,ka] m = np.ma.masked_where(bestsv == 0,bestsv) W = m.reshape(self.nx,self.ny).T ax.imshow(W, extent=(l,r,b,t), origin='lower', vmin=1, vmax=self.na+1) ax.set_title(title) else: if typ=='sinr': title = title + 'SINR : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar if dB: legcb = 'dB' else: legcb = 'Linear scale' V = self.sinr if typ=='snr': title = title + 'SNR : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar if dB: legcb = 'dB' else: legcb = 'Linear scale' V = self.snr if typ=='capacity': title = title + 'Capacity : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar legcb = 'Mbit/s' V = self.bmhz[np.newaxis,np.newaxis,:]*np.log(1+self.sinr)/np.log(2) if typ=='pr': title = title + 'Pr : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar if dB: legcb = 'dBm' else: lgdcb = 'mW' V = self.CmW if typ=='loss': title = title + 'Loss : '+' fc = '+str(self.fGHz[f])+' GHz'+ ' polar : '+self.polar if dB: legcb = 'dB' else: legcb = 'Linear scale' V = self.Lw*self.freespace if a == -1: V = np.max(V[f,:,:],axis=1) else: V = V[f,:,a] # reshaping the data on the grid U = V.reshape((self.nx,self.ny)).T if dB: U = 10*np.log10(U) if 'vmin' in kwargs: vmin = kwargs['vmin'] else: vmin = U.min() if 'vmax' in kwargs: vmax = kwargs['vmax'] else: vmax = U.max() img = ax.imshow(U, extent=(l,r,b,t), origin='lower', vmin = vmin, vmax = vmax, cmap = kwargs['cmap']) for k in range(self.na): ax.annotate(str(k),xy=(self.pa[0,k],self.pa[1,k])) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(img,cax) clb.set_label(legcb) if best: ax.contour(np.sum(self.bestsv,axis=2)[f,:].reshape(self.nx,self.ny).T,extent=(l,r,b,t),linestyles='dotted') # display access points ax.scatter(self.pa[0,:],self.pa[1,:],s=10,c='k',linewidth=0) return(fig,ax)
class Simul(SimulationRT): """ Attributes ---------- config : config parser instance sim_opt : dictionary of configuration option for simulation ag_opt : dictionary of configuration option for agent lay_opt : dictionary of configuration option for layout meca_opt : dictionary of configuration option for mecanic net_opt : dictionary of configuration option for network loc_opt : dictionary of configuration option for localization save_opt : dictionary of configuration option for save sql_opt : dictionary of configuration option for sql Notes ------ All the prvious dictionnary are obtained from the chosen simulnet.ini file in the project directory """ def __init__(self): SimulationRT.__init__(self) self.initialize() self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong('simulnet.ini', 'ini')) self.sim_opt = dict(self.config.items('Simulation')) self.lay_opt = dict(self.config.items('Layout')) self.meca_opt = dict(self.config.items('Mechanics')) self.net_opt = dict(self.config.items('Network')) self.loc_opt = dict(self.config.items('Localization')) self.save_opt = dict(self.config.items('Save')) self.sql_opt = dict(self.config.items('Mysql')) self.verbose = str2bool(self.sim_opt['verbose']) if str2bool(self.net_opt['ipython_nb_show']): self.verbose = False self.roomlist = [] def create_layout(self): """ Create Layout in Simpy the_world thantks to Tk backend """ self.the_world = world(width=float(self.lay_opt['the_world_width']), height=float(self.lay_opt['the_world_height']), scale=float(self.lay_opt['the_world_scale'])) # tk = self.the_world.tk # canvas, x_, y_ = tk.canvas, tk.x_, tk.y_ # canvas.create_rectangle(x_(-1), y_(-1), x_(100), y_(100), fill='white') _filename = self.lay_opt['filename'] #sl=Slab.SlabDB(self.lay_opt['slab'],self.lay_opt['slabmat']) #G1 = Graph.Graph(sl=sl,filename=_filename) self.L = Layout() if _filename.split('.')[1] == 'str': self.L.loadstr(_filename) elif _filename.split('.')[1] == 'str2': self.L.loadstr2(_filename) elif _filename.split('.')[1] == 'ini': self.L.loadini(_filename) try: self.L.dumpr() print 'Layout graphs are loaded from ', basename, '/struc' except: #self.L.sl = sl #self.L.loadGr(G1) print 'This is the first time your use this layout file.\ Layout graphs are curently being built, it may take few minutes.' self.L.buildGt() self.L.buildGr() self.L.buildGw() self.L.buildGv() self.L.buildGi() self.L.dumpw() x_offset = 0 # float(self.lay_opt['x_offset']) y_offset = 0 # float(self.lay_opt['y_offset']) for ks in self.L.Gs.pos.keys(): self.L.Gs.pos[ks] = (self.L.Gs.pos[ks][0] + x_offset, self.L.Gs.pos[ks][1] + y_offset) for ks in self.L.Gr.pos.keys(): self.L.Gr.pos[ks] = (self.L.Gr.pos[ks][0] + x_offset, self.L.Gr.pos[ks][1] + y_offset) for ks in self.L.Gw.pos.keys(): self.L.Gw.pos[ks] = (self.L.Gw.pos[ks][0] + x_offset, self.L.Gw.pos[ks][1] + y_offset) # # Create Layout # walls = self.L.thwall(0, 0) for wall in walls: points = [] # for point in wall: # points.append(x_(point[0])) # points.append(y_(point[1])) # canvas.create_polygon(points, fill='maroon', outline='black') for ii in range(0, len(wall) - 1): self.the_world.add_wall(wall[ii], wall[ii + 1]) def create_agent(self): """ create simulation's Agents ..todo:: change lAg list to a dictionnary ( modification in show.py too) """ self.lAg = [] agents = [] Cf = ConfigParser.ConfigParser() Cf.read(pyu.getlong('agent.ini', 'ini')) agents = eval(dict(Cf.items('used_agent'))['list']) for i, ag in enumerate(agents): ag_opt = dict(Cf.items(ag)) self.lAg.append( Agent(ID=ag_opt['id'], name=ag_opt['name'], type=ag_opt['type'], pos=np.array(eval(ag_opt['pos'])), roomId=int(ag_opt['roomid']), froom=eval(ag_opt['froom']), meca_updt=float(self.meca_opt['mecanic_update_time']), wait=float(ag_opt['wait']), cdest=eval(self.meca_opt['choose_destination']), loc=str2bool(self.loc_opt['localization']), loc_updt=float(self.loc_opt['localization_update_time']), loc_method=eval(self.loc_opt['method']), Layout=self.L, net=self.net, epwr=dict([(eval( (ag_opt['rat']))[ep], eval((ag_opt['epwr']))[ep]) for ep in range(len(eval((ag_opt['rat']))))]), sens=dict([(eval( (ag_opt['rat']))[ep], eval( (ag_opt['sensitivity']))[ep]) for ep in range(len(eval((ag_opt['rat']))))]), world=self.the_world, RAT=eval(ag_opt['rat']), save=eval(self.save_opt['save']), gcom=self.gcom, comm_mode=eval(self.net_opt['communication_mode']), sim=self)) # if self.lAg[i].type == 'ag': self.activate(self.lAg[i].meca, self.lAg[i].meca.move(), 0.0) def create_EMS(self): """ Electromagnetic Solver object """ self.EMS = EMSolver(L=self.L) def create_network(self): """ create the whole network """ self.net = Network(EMS=self.EMS) self.gcom = Gcom(net=self.net, sim=self) self.create_agent() # create network self.net.create() # create All Personnal networks for n in self.net.nodes(): self.net.node[n]['PN'].get_RAT() self.net.node[n]['PN'].get_SubNet() self.gcom.create() # create Process Network self.Pnet = PNetwork(net=self.net, net_updt_time=float( self.net_opt['network_update_time']), L=self.L, sim=self, show_sg=str2bool(self.net_opt['show_sg']), disp_inf=str2bool(self.net_opt['dispinfo']), save=eval(self.save_opt['save'])) self.activate(self.Pnet, self.Pnet.run(), 0.0) def create_visual(self): """ Create visual Tk process """ self.visu = Updater(interval=float(self.sim_opt['show_interval']), sim=self) self.activate(self.visu, self.visu.execute(), 0.0) def create(self): """ Create the simulation, to be ready to run """ # this is just to redump the database at each simulation if 'mysql' in self.save_opt['save']: if str2bool(self.sql_opt['dumpdb']): os.popen('mysql -u ' + self.sql_opt['user'] + ' -p ' + self.sql_opt['dbname'] +\ '< /private/staff/t/ot/niamiot/svn2/devel/simulator/pyray/SimWHERE2.sql' ) if 'txt' in self.save_opt['save']: pyu.writeDetails(self) if os.path.isfile(basename + '/output/Nodes.txt'): print 'would you like to erase previous txt files ?' A = raw_input() if A == 'y': for f in os.listdir(basename + '/output/'): try: fi, ext = f.split('.') if ext == 'txt': os.remove(basename + '/output/' + f) except: pass self.create_layout() self.create_EMS() self.create_network() if str2bool(self.sim_opt['showtk']): self.create_visual() self.create_show() if str2bool(self.save_opt['savep']): self.save = Save(L=self.L, net=self.net, sim=self) self.activate(self.save, self.save.run(), 0.0) # if str2bool(self.save_opt['savep']): # self.save=Save(net=self.net, # L= self.L, # sim = self) # self.activate(self.save, self.save.run(), 0.0) def create_show(self): plt.ion() fig_net = 'network' fig_table = 'table' if str2bool(self.net_opt['show']): if str2bool(self.net_opt['ipython_nb_show']): notebook = True else: notebook = False self.sh = ShowNet(net=self.net, L=self.L, sim=self, fname=fig_net, notebook=notebook) self.activate(self.sh, self.sh.run(), 1.0) if str2bool(self.net_opt['show_table']): self.sht = ShowTable(net=self.net, lAg=self.lAg, sim=self, fname=fig_table) self.activate(self.sht, self.sht.run(), 1.0) def runsimul(self): """ Run simulation """ self.create() self.simulate(until=float(self.sim_opt['duration']), real_time=True, rel_speed=float(self.sim_opt['speedratio'])) # self.simulate(until=float(self.sim_opt['duration'])) if self.save_opt['savep']: print 'Processing save results, please wait' self.save.mat_export()
class Simul(SimulationRT): # Sympy 2 #class Simul(sympy.RealtimeEnvironment): """ Attributes ---------- config : config parser instance sim_opt : dictionary of configuration option for simulation ag_opt : dictionary of configuration option for agent lay_opt : dictionary of configuration option for layout meca_opt : dictionary of configuration option for mecanic net_opt : dictionary of configuration option for network loc_opt : dictionary of configuration option for localization save_opt : dictionary of configuration option for save sql_opt : dictionary of configuration option for sql Notes ------ All the prvious dictionnary are obtained from the chosen simulnet.ini file in the project directory """ def __init__(self): SimulationRT.__init__(self) #Sympy 2 #sympy.RealtimeEnvironment.__init__(self) #simpy 3 self.initialize() self.config = ConfigParser.ConfigParser() filename = pyu.getlong('simulnet.ini','ini') self.config.read(filename) self.sim_opt = dict(self.config.items('Simulation')) self.lay_opt = dict(self.config.items('Layout')) self.meca_opt = dict(self.config.items('Mechanics')) self.net_opt = dict(self.config.items('Network')) self.loc_opt = dict(self.config.items('Localization')) self.save_opt = dict(self.config.items('Save')) self.sql_opt = dict(self.config.items('Mysql')) self.verbose = str2bool(self.sim_opt['verbose']) if str2bool(self.net_opt['ipython_nb_show']): self.verbose = False self.roomlist=[] self.create() def create_layout(self): """ Create Layout in Simpy the_world thanks to Tk backend """ self.the_world = world(width = float(self.lay_opt['the_world_width']), height = float(self.lay_opt['the_world_height']), scale=float(self.lay_opt['the_world_scale'])) # tk = self.the_world.tk # canvas, x_, y_ = tk.canvas, tk.x_, tk.y_ # canvas.create_rectangle(x_(-1), y_(-1), x_(100), y_(100), fill='white') _filename = self.lay_opt['filename'] #sl=Slab.SlabDB(self.lay_opt['slab'],self.lay_opt['slabmat']) #G1 = Graph.Graph(sl=sl,filename=_filename) self.L = Layout(_filename) #if _filename.split('.')[1] == 'str': # self.L.loadstr(_filename) #elif _filename.split('.')[1] == 'str2': # self.L.loadstr2(_filename) #elif _filename.split('.')[1] == 'ini': # self.L.loadini(_filename) try: self.L.dumpr() print 'Layout graphs are loaded from ',basename,'/struc/ini' except: #self.L.sl = sl #self.L.loadGr(G1) print 'This is the first time the layout file is used\ Layout graphs are curently being built, it may take few minutes.' self.L.build() self.L.dumpw() x_offset = 0 # float(self.lay_opt['x_offset']) y_offset = 0 # float(self.lay_opt['y_offset']) for ks in self.L.Gs.pos.keys(): self.L.Gs.pos[ks] = (self.L.Gs.pos[ks][0] + x_offset, self.L.Gs.pos[ks][1] + y_offset) for ks in self.L.Gr.pos.keys(): self.L.Gr.pos[ks] = (self.L.Gr.pos[ks][0] + x_offset, self.L.Gr.pos[ks][1] + y_offset) for ks in self.L.Gw.pos.keys(): self.L.Gw.pos[ks] = (self.L.Gw.pos[ks][0] + x_offset, self.L.Gw.pos[ks][1] + y_offset) # # Create Layout # walls = self.L.thwall(0, 0) for wall in walls: points = [] # for point in wall: # points.append(x_(point[0])) # points.append(y_(point[1])) # canvas.create_polygon(points, fill='maroon', outline='black') for ii in range(0, len(wall) - 1): self.the_world.add_wall(wall[ii], wall[ii + 1]) def create_agent(self): """ create simulation's Agents ..todo:: change lAg list to a dictionnary ( modification in show.py too) """ self.lAg = [] agents=[] Cf = ConfigParser.ConfigParser() Cf.read(pyu.getlong('agent.ini','ini')) agents=eval(dict(Cf.items('used_agent'))['list']) for i, ag in enumerate(agents): ag_opt = dict(Cf.items(ag)) self.lAg.append(Agent( ID=ag_opt['id'], name=ag_opt['name'], type=ag_opt['type'], pos=np.array(eval(ag_opt['pos'])), roomId=int(ag_opt['roomid']), froom=eval(ag_opt['froom']), meca_updt=float(self.meca_opt['mecanic_update_time']), wait=float(ag_opt['wait']), cdest=eval(self.meca_opt['choose_destination']), loc=str2bool(self.loc_opt['localization']), loc_updt=float(self.loc_opt['localization_update_time']), loc_method=eval(self.loc_opt['method']), Layout=self.L, net=self.net, epwr=dict([(eval((ag_opt['rat']))[ep],eval((ag_opt['epwr']))[ep]) for ep in range(len(eval((ag_opt['rat']))))]), sens=dict([(eval((ag_opt['rat']))[ep],eval((ag_opt['sensitivity']))[ep]) for ep in range(len(eval((ag_opt['rat']))))]), world=self.the_world, RAT=eval(ag_opt['rat']), save=eval(self.save_opt['save']), gcom=self.gcom, comm_mode=eval(self.net_opt['communication_mode']), sim=self)) # if self.lAg[i].type == 'ag': self.activate(self.lAg[i].meca, self.lAg[i].meca.move(), 0.0) def create_EMS(self): """ Electromagnetic Solver object """ self.EMS = EMSolver(L=self.L) def create_network(self): """ create the whole network """ self.net = Network(EMS=self.EMS) self.gcom=Gcom(net=self.net,sim=self) self.create_agent() # create network self.net.create() # create All Personnal networks for n in self.net.nodes(): self.net.node[n]['PN'].get_RAT() self.net.node[n]['PN'].get_SubNet() self.gcom.create() # create Process Network self.Pnet = PNetwork(net=self.net, net_updt_time=float(self.net_opt['network_update_time']), L=self.L, sim=self, show_sg=str2bool(self.net_opt['show_sg']), disp_inf=str2bool(self.net_opt['dispinfo']), save=eval(self.save_opt['save'])) self.activate(self.Pnet, self.Pnet.run(), 0.0) def create_visual(self): """ Create visual Tk process """ self.visu = Updater( interval=float(self.sim_opt['show_interval']), sim=self) self.activate(self.visu, self.visu.execute(), 0.0) def create(self): """ Create the simulation This method is called at the end of __init__ """ # this is just to redump the database at each simulation if 'mysql' in self.save_opt['save']: if str2bool(self.sql_opt['dumpdb']): os.popen('mysql -u ' + self.sql_opt['user'] + ' -p ' + self.sql_opt['dbname'] +\ '< /private/staff/t/ot/niamiot/svn2/devel/simulator/pyray/SimWHERE2.sql' ) ## TODO supprimer la ref en dur if 'txt' in self.save_opt['save']: pyu.writeDetails(self) if os.path.isfile(basename+'/output/Nodes.txt'): print 'would you like to erase previous txt files ?' A=raw_input() if A == 'y': for f in os.listdir(basename+'/output/'): try: fi,ext=f.split('.') if ext == 'txt': os.remove(basename+'/output/'+f) except: pass self.create_layout() self.create_EMS() self.create_network() if str2bool(self.sim_opt['showtk']): self.create_visual() self.create_show() if str2bool(self.save_opt['savep']): self.save=Save(L=self.L,net=self.net,sim=self) self.activate(self.save,self.save.run(),0.0) # if str2bool(self.save_opt['savep']): # self.save=Save(net=self.net, # L= self.L, # sim = self) # self.activate(self.save, self.save.run(), 0.0) def create_show(self): """ """ plt.ion() fig_net = 'network' fig_table = 'table' if str2bool(self.net_opt['show']): if str2bool(self.net_opt['ipython_nb_show']): notebook=True else: notebook =False self.sh = ShowNet(net=self.net, L=self.L,sim=self,fname=fig_net,notebook=notebook) self.activate(self.sh,self.sh.run(),1.0) if str2bool(self.net_opt['show_table']): self.sht = ShowTable(net=self.net,lAg=self.lAg,sim=self,fname=fig_table) self.activate(self.sht,self.sht.run(),1.0) def runsimul(self): """ Run simulation """ self.simulate(until=float(self.sim_opt['duration']), real_time=True, rel_speed=float(self.sim_opt['speedratio'])) # self.simulate(until=float(self.sim_opt['duration'])) if self.save_opt['savep']: print 'Processing save results, please wait' self.save.mat_export()
from pylayers.gis.layout import Layout import networkx as nx import matplotlib.pyplot as plt import doctest plt.ion() #doctest.testmod(layout) #L = Layout('TA-Office.ini') L = Layout('WHERE1.ini') #L= Layout('11Dbibli.ini') #L.show() #L = Layout('PTIN.ini') #L = Layout('DLR.ini') #L.build() L.dumpr() L.showGi(en=11) #Ga = L.buildGr() #L.showGs() #nx.draw(Ga,Ga.pos)
class Coverage(object): """ Handle Layout Coverage Methods ------- create grid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout model : a pylayers.network.model object. xstep : x step for grid ystep : y step for grid tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map """ def __init__(self,_fileini='coverage.ini'): self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong(_fileini,pstruc['DIRSIMUL'])) self.plm = dict(self.config.items('pl_model')) self.layoutopt = dict(self.config.items('layout')) self.gridopt = dict(self.config.items('grid')) self.txopt = dict(self.config.items('tx')) self.rxopt = dict(self.config.items('rx')) self.showopt=dict(self.config.items('show')) self.L=Layout(self.layoutopt['filename']) self.model=Model(f=eval(self.plm['f']), rssnp=eval(self.plm['rssnp']), d0=eval(self.plm['d0']), sigrss=eval(self.plm['sigrss'])) self.xstep = eval(self.gridopt['xstep']) self.ystep = eval(self.gridopt['ystep']) # transitter section self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) self.ptdbm = eval(self.txopt['ptdbm']) self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section self.rxsens = eval(self.rxopt['sensitivity']) kBoltzmann = 1.3806503e-23 self.bandwidthmhz = eval(self.rxopt['bandwidthmhz']) self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) Pn = (10**(self.noisefactordb/10.)+1)*kBoltzmann*self.temperaturek*self.bandwidthmhz*1e3 self.pndbm = 10*np.log10(Pn)+60 self.show = str2bool(self.showopt['show']) try: self.L.Gt.nodes() except: pass try: self.L.dumpr('t') except: self.L.buildGt() self.L.dumpw('t') self.creategrid() def creategrid(self): """create a grid create a grid for various evaluation """ mi=np.min(self.L.Gs.pos.values(),axis=0)+0.01 ma=np.max(self.L.Gs.pos.values(),axis=0)-0.01 x=np.linspace(mi[0],ma[0],self.xstep) y=np.linspace(mi[1],ma[1],self.ystep) self.grid=np.array((list(np.broadcast(*np.ix_(x, y))))) def cover(self): """ start the coverage calculation Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showPr() """ self.Lwo,self.Lwp,self.Edo,self.Edp = Loss0_v2(self.L,self.grid,self.model.f,self.tx) self.freespace = PL(self.grid,self.model.f,self.tx) self.prdbmo = self.ptdbm - self.freespace - self.Lwo self.prdbmp = self.ptdbm - self.freespace - self.Lwp def showEd(self,polarization='o'): """ show direct path excess of delay map Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showEdo() """ fig=plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': cov=ax.imshow(self.Edo.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), origin='lower') titre = "Map of LOS excess delay, polar orthogonal" if polarization=='p': cov=ax.imshow(self.Edp.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), origin='lower') titre = "Map of LOS excess delay, polar parallel" ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(titre) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(cov,cax) clb.set_label('excess delay (ns)') if self.show: plt.show() def showPower(self,rxsens=True,nfl=True,polarization='o'): """ show the map of received power Parameters ---------- rxsens : bool clip the map with rx sensitivity set in self.rxsens nfl : bool clip the map with noise floor set in self.pndbm polarization : string 'o'|'p' Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showPower() """ fig=plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': prdbm=self.prdbmo if polarization=='p': prdbm=self.prdbmp # tCM = plt.cm.get_cmap('jet') # tCM._init() # alphas = np.abs(np.linspace(.0,1.0, tCM.N)) # tCM._lut[:-3,-1] = alphas title='Map of received power - Pt = '+str(self.ptdbm)+' dBm' cdict = { 'red' : ((0., 0.5, 0.5), (1., 1., 1.)), 'green': ((0., 0.5, 0.5), (1., 1., 1.)), 'blue' : ((0., 0.5, 0.5), (1., 1., 1.)) } #generate the colormap with 1024 interpolated values my_cmap = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024) if rxsens : ### values between the rx sensitivity and noise floor mcPrf = np.ma.masked_where((prdbm > self.rxsens) & (prdbm < self.pndbm),prdbm) cov1 = ax.imshow(mcPrf.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t),cmap = my_cmap, vmin=self.rxsens,origin='lower') ### values above the sensitivity mcPrs = np.ma.masked_where(prdbm < self.rxsens,prdbm) cov = ax.imshow(mcPrs.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), cmap = 'jet', vmin=self.rxsens,origin='lower') title=title + '\n gray : Pr (dBm) < %.2f' % self.rxsens + ' dBm' else : cov=ax.imshow(prdbm.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), cmap = 'jet', vmin=self.PndBm,origin='lower') if nfl: ### values under the noise floor ### we first clip the value below he noise floor cl = np.nonzero(prdbm<=self.pndbm) cPr = prdbm cPr[cl] = self.pndbm mcPruf = np.ma.masked_where(cPr > self.pndbm,cPr) cov2 = ax.imshow(mcPruf.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t),cmap = 'binary', vmax=self.pndbm,origin='lower') title=title + '\n white : Pr (dBm) < %.2f' % self.pndbm + ' dBm' ax.scatter(self.tx[0],self.tx[1],s=10,linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(cov,cax) clb.set_label('Power (dBm)') if self.show: plt.show() def showTransistionRegion(self,polarization='o'): """ Notes ----- See : Analyzing the Transitional Region in Low Power Wireless Links Marco Zuniga and Bhaskar Krishnamachari Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showTransitionRegion() """ frameLength = self.framelengthbytes PndBm = self.pndbm gammaU = 10*np.log10(-1.28*np.log(2*(1-0.9**(1./(8*frameLength))))) gammaL = 10*np.log10(-1.28*np.log(2*(1-0.1**(1./(8*frameLength))))) PrU = PndBm + gammaU PrL = PndBm + gammaL fig=plt.figure() fig,ax = self.L.showGs(fig=fig) l = self.grid[0,0] r = self.grid[-1,0] b = self.grid[0,1] t = self.grid[-1,-1] if polarization=='o': prdbm=self.prdbmo if polarization=='p': prdbm=self.prdbmp zones = np.zeros(len(prdbm)) uconnected = np.nonzero(prdbm>PrU)[0] utransition = np.nonzero((prdbm < PrU)&(prdbm > PrL))[0] udisconnected = np.nonzero(prdbm < PrL)[0] zones[uconnected] = 1 zones[utransition] = (prdbm[utransition]-PrL)/(PrU-PrL) cov = ax.imshow(zones.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t),cmap = 'BuGn',origin='lower') title='PDR region' ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) fig.colorbar(cov,cax) if self.show: plt.show() def showLoss(self,polarization='o'): """ show losses map Parameters ---------- polarization : string 'o'|'p'|'both' Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> C.showLoss(polarization='o') >>> C.showLoss(polarization='p') """ fig = plt.figure() fig,ax=self.L.showGs(fig=fig) l=self.grid[0,0] r=self.grid[-1,0] b=self.grid[0,1] t=self.grid[-1,-1] if polarization=='o': cov = ax.imshow(self.Lwo.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), origin='lower') title = ('Map of losses, orthogonal (V) polarization') if polarization=='p': cov = ax.imshow(self.Lwp.reshape((self.xstep,self.ystep)).T, extent=(l,r,b,t), origin='lower') title = ('Map of losses, parallel (H) polarization') ax.scatter(self.tx[0],self.tx[1],linewidth=0) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) fig.colorbar(cov,cax) if self.show: plt.show()
class Coverage(PyLayers): """ Handle Layout Coverage Methods ------- creategrid() create a uniform grid for evaluating losses cover() run the coverage calculation showPower() display the map of received power showLoss() display the map of losses Attributes ---------- All attributes are read from fileini ino the ini directory of the current project _fileini default coverage.ini L : a Layout nx : number of point on x ny : number of point on y tx : transmitter position txpe : transmitter power emmission level show : boolean for automatic display power map na : number of access point """ def __init__(self, _fileini='coverage.ini'): """ object constructor Parameters ---------- _fileini : string name of the configuration file Notes ----- Coverage is described in an ini file. Default file is coverage.ini and is placed in the ini directory of the current project. """ self.config = ConfigParser.ConfigParser() self.config.read(pyu.getlong(_fileini, pstruc['DIRSIMUL'])) self.layoutopt = dict(self.config.items('layout')) self.gridopt = dict(self.config.items('grid')) self.apopt = dict(self.config.items('ap')) self.rxopt = dict(self.config.items('rx')) self.showopt = dict(self.config.items('show')) # get the Layout filename = self.layoutopt['filename'] if filename.endswith('lay'): self.typ = 'indoor' self.L = Layout(filename) # get the receiving grid self.nx = eval(self.gridopt['nx']) self.ny = eval(self.gridopt['ny']) if 'zgrid' in self.gridopt: self.zgrid = eval(self.gridopt['zgrid']) else: self.zgrid = 1.0 self.mode = self.gridopt['mode'] assert self.mode in ['file', 'full', 'zone'], "Error reading grid mode " self.boundary = eval(self.gridopt['boundary']) self.filespa = self.gridopt['file'] # # create grid # self.creategrid(mode=self.mode, boundary=self.boundary, _fileini=self.filespa) self.dap = {} for k in self.apopt: kwargs = eval(self.apopt[k]) ap = std.AP(**kwargs) self.dap[eval(k)] = ap try: self.L.Gt.nodes() except: pass try: self.L.dumpr() except: self.L.build() self.L.dumpw() else: self.typ = 'outdoor' self.E = ez.Ezone(filename) self.E.loadh5() self.E.rebase() # The frequency is fixed from the AP nature self.fGHz = np.array([]) #self.fGHz = eval(self.txopt['fghz']) #self.tx = np.array((eval(self.txopt['x']),eval(self.txopt['y']))) #self.ptdbm = eval(self.txopt['ptdbm']) #self.framelengthbytes = eval(self.txopt['framelengthbytes']) # receiver section #self.rxsens = eval(self.rxopt['sensitivity']) self.temperaturek = eval(self.rxopt['temperaturek']) self.noisefactordb = eval(self.rxopt['noisefactordb']) self.PtDB = eval(self.rxopt['ptdb']) self.Gt = eval(self.rxopt['gt']) self.Gr = eval(self.rxopt['gr']) self.do = eval(self.rxopt['do']) self.Prdo = eval(self.rxopt['prdo']) self.n = eval(self.rxopt['n']) self.desviopadrao = eval(self.rxopt['desviopadrao']) self.x0 = eval(self.rxopt['x0']) self.y0 = eval(self.rxopt['y0']) self.xt = eval(self.rxopt['xt']) self.yt = eval(self.rxopt['yt']) # show section self.bshow = str2bool(self.showopt['show']) def __repr__(self): st = '' if self.typ == 'indoor': st = st + 'Layout file : ' + self.L._filename + '\n\n' st = st + '-----list of Access Points ------' + '\n' for k in self.dap: st = st + self.dap[k].__repr__() + '\n' st = st + '-----Rx------' + '\n' st = st + 'temperature (K) : ' + str(self.temperaturek) + '\n' st = st + 'noisefactor (dB) : ' + str(self.noisefactordb) + '\n\n' st = st + '--- Grid ----' + '\n' st = st + 'mode : ' + str(self.mode) + '\n' if self.mode <> 'file': st = st + 'nx : ' + str(self.nx) + '\n' st = st + 'ny : ' + str(self.ny) + '\n' if self.mode == 'zone': st = st + 'boundary (xmin,ymin,xmax,ymax) : ' + str( self.boundary) + '\n\n' if self.mode == 'file': st = st + ' filename : ' + self.filespa + '\n' return (st) def creategrid(self, mode='full', boundary=[], _fileini=''): """ create a grid Parameters ---------- full : boolean default (True) use all the layout area boundary : (xmin,ymin,xmax,ymax) if full is False the boundary argument is used """ if mode == "file": self.RN = RadioNode(name='', typ='rx', _fileini=_fileini, _fileant='def.vsh3') self.grid = self.RN.position[0:2, :].T else: if mode == "full": mi = np.min(self.L.Gs.pos.values(), axis=0) + 0.01 ma = np.max(self.L.Gs.pos.values(), axis=0) - 0.01 if mode == "zone": assert boundary <> [] mi = np.array([boundary[0], boundary[1]]) ma = np.array([boundary[2], boundary[3]]) x = np.linspace(mi[0], ma[0], self.nx) y = np.linspace(mi[1], ma[1], self.ny) self.grid = np.array((list(np.broadcast(*np.ix_(x, y))))) self.ng = self.grid.shape[0] def where1(self): """ Unfinished : Not sure this is the right place (too specific) """ M1 = UWBMeasure(1) self.dap = {} self.dap[1] = {} self.dap[2] = {} self.dap[3] = {} self.dap[4] = {} self.dap[1]['p'] = M1.rx[1, 0:2] self.dap[2]['p'] = M1.rx[1, 0:2] self.dap[3]['p'] = M1.rx[1, 0:2] self.dap[4]['p'] = M1.rx[1, 0:2] for k in range(300): try: M = UWBMeasure(k) tx = M.tx self.grid = np.vstack((self.grid, tx[0:2])) D = M.rx - tx[np.newaxis, :] D2 = D * D dist = np.sqrt(np.sum(D2, axis=1))[1:] Emax = M.Emax() Etot = M.Etot()[0] try: td1 = np.hstack((td1, dist[0])) td2 = np.hstack((td2, dist[1])) td3 = np.hstack((td3, dist[2])) td4 = np.hstack((td4, dist[3])) te1 = np.hstack((te1, Emax[0])) te2 = np.hstack((te2, Emax[1])) te3 = np.hstack((te3, Emax[2])) te4 = np.hstack((te4, Emax[3])) tt1 = np.hstack((tt1, Etot[0])) tt2 = np.hstack((tt2, Etot[1])) tt3 = np.hstack((tt3, Etot[2])) tt4 = np.hstack((tt4, Etot[3])) #tdist = np.hstack((tdist,dist)) #te = np.hstack((te,Emax)) except: td1 = np.array(dist[0]) td2 = np.array(dist[1]) td3 = np.array(dist[2]) td4 = np.array(dist[3]) te1 = np.array(Emax[0]) te2 = np.array(Emax[1]) te3 = np.array(Emax[2]) te4 = np.array(Emax[3]) tt1 = np.array(Etot[0]) tt2 = np.array(Etot[1]) tt3 = np.array(Etot[2]) tt4 = np.array(Etot[3]) except: pass def cover(self, sinr=True, snr=True, best=True): """ run the coverage calculation Parameters ---------- sinr : boolean snr : boolean best : boolean Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a=C.show(typ='sinr',figsize=(10,8)) >>> plt.show() Notes ----- self.fGHz is an array, it means that Coverage is calculated at once for a whole set of frequencies. In practice, it would be the center frequency of a given standard channel. This function is calling `loss.Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as a full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ # # select active AP # lactiveAP = [] try: del self.aap del self.ptdbm except: pass self.kB = 1.3806503e-23 # Boltzmann constant # # Loop opver access points # for iap in self.dap: if self.dap[iap]['on']: lactiveAP.append(iap) fGHz = self.dap[iap].s.fcghz # The frequency band is set here self.fGHz = np.unique(np.hstack((self.fGHz, fGHz))) apchan = self.dap[iap]['chan'] try: self.aap = np.vstack((self.aap, self.dap[iap]['p'])) self.ptdbm = np.vstack( (self.ptdbm, self.dap[iap]['PtdBm'])) self.bmhz = np.vstack( (self.bmhz, self.dap[iap].s.chan[apchan[0]]['BMHz'])) except: self.aap = self.dap[iap]['p'] self.ptdbm = np.array(self.dap[iap]['PtdBm']) self.bmhz = np.array( self.dap[iap].s.chan[apchan[0]]['BMHz']) PnW = np.array((10**(self.noisefactordb / 10.)) * self.kB * self.temperaturek * self.bmhz * 1e6) self.pnw = PnW # Evaluate Noise Power (in dBm) self.pndbm = np.array(10 * np.log10(PnW) + 30) #lchan = map(lambda x: self.dap[x]['chan'],lap) #apchan = zip(self.dap.keys(),lchan) #self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) self.ptdbm = self.ptdbm.T self.pndbm = self.pndbm.T # creating all links # all grid to all ap # if len(self.pndbm.shape) == 0: self.ptdbm = self.ptdbm.reshape(1, 1) self.pndbm = self.pndbm.reshape(1, 1) p = product(range(self.ng), lactiveAP) # # pa : access point # pg : grid point # # 1 x na for k in p: pg = self.grid[k[0], :] pa = np.array(self.dap[k[1]]['p']) # exemple with 3 AP # 321 0 # 321 1 # 321 2 # 322 0 try: self.pa = np.vstack((self.pa, pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg, pg)) except: self.pg = pg self.pa = self.pa.T shpa = self.pa.shape shpg = self.pg.shape if shpa[0] != 3: self.pa = np.vstack((self.pa, np.ones(shpa[1]))) self.pg = self.pg.T self.pg = np.vstack((self.pg, self.zgrid * np.ones(shpg[0]))) self.nf = len(self.fGHz) # retrieving dimensions along the 3 axis na = len(lactiveAP) self.na = na ng = self.ng nf = self.nf for k, iap in enumerate(self.dap): # select only one access point u = na * np.arange(0, ng, 1).astype('int') + k if self.dap[iap]['on']: pt = self.pa[:, u] pr = self.pg[:, u] azoffset = self.dap[iap]['phideg'] * np.pi / 180. self.dap[iap].A.eval(fGHz=self.fGHz, pt=pt, pr=pr, azoffset=azoffset) gain = (self.dap[iap].A.G).T #pdb.set_trace() # to handle omnidirectional antenna (nf,1,1) if gain.shape[1] == 1: gain = np.repeat(gain, ng, axis=1) try: tgain = np.dstack((tgain, gain[:, :, None])) except: tgain = gain[:, :, None] #Lwo,Lwp,Edo,Edp = loss.Losst(self.L,self.fGHz,self.pa,self.pg,dB=False) Lwo, Lwp, Edo, Edp = loss.Losst(self.L, self.fGHz, self.pa, self.pg, dB=False) self.Lwo = Lwo.reshape(nf, ng, na) self.Edo = Edo.reshape(nf, ng, na) self.Lwp = Lwp.reshape(nf, ng, na) self.Edp = Edp.reshape(nf, ng, na) freespace = loss.PL(self.fGHz, self.pa, self.pg, dB=False) self.freespace = freespace.reshape(nf, ng, na) # transmitting power # f x g x a # CmW : Received Power coverage in mW self.CmWo = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwo * self.freespace * tgain self.CmWp = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwp * self.freespace * tgain if self.typ == 'intensity': self.cmWo = 10 * np.log10(self.cmWo) self.cmWo = 10 * np.log10(self.cmWp) if snr: self.evsnr() if sinr: self.evsinr() if best: self.evbestsv() def evsnr(self): """ calculates signal to noise ratio """ NmW = 10**(self.pndbm / 10.)[np.newaxis, :] self.snro = self.CmWo / NmW self.snrp = self.CmWp / NmW def evsinr(self): """ calculates sinr """ # na : number of access point na = self.na # U : 1 x 1 x na x na U = (np.ones((na, na)) - np.eye(na))[np.newaxis, np.newaxis, :, :] # CmWo : received power in mW orthogonal polarization # CmWp : received power in mW parallel polarization ImWo = np.einsum('ijkl,ijl->ijk', U, self.CmWo) ImWp = np.einsum('ijkl,ijl->ijk', U, self.CmWp) NmW = 10**(self.pndbm / 10.)[np.newaxis, :] self.sinro = self.CmWo / (ImWo + NmW) self.sinrp = self.CmWp / (ImWp + NmW) def evbestsv(self): """ determine the best server map Notes ----- C.bestsv """ na = self.na ng = self.ng nf = self.nf # find best server regions Vo = self.CmWo Vp = self.CmWp self.bestsvo = np.empty(nf * ng * na).reshape(nf, ng, na) self.bestsvp = np.empty(nf * ng * na).reshape(nf, ng, na) for kf in range(nf): MaxVo = np.max(Vo[kf, :, :], axis=1) MaxVp = np.max(Vp[kf, :, :], axis=1) for ka in range(na): uo = np.where(Vo[kf, :, ka] == MaxVo) up = np.where(Vp[kf, :, ka] == MaxVp) self.bestsvo[kf, uo, ka] = ka + 1 self.bestsvp[kf, up, ka] = ka + 1 def plot(self, **kwargs): """ """ defaults = { 'typ': 'pr', 'grid': False, 'f': 0, 'a': 0, 'db': True, 'label': '', 'pol': 'p', 'col': 'b' } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] if 'fig' in kwargs: fig = kwargs['fig'] else: fig = plt.figure() if 'ax' in kwargs: ax = kwargs['ax'] else: ax = fig.add_subplot(111) if kwargs['typ'] == 'pr': if kwargs['a'] <> -1: if kwargs['pol'] == 'p': U = self.CmWp[kwargs['f'], :, kwargs['a']] if kwargs['pol'] == 'o': U = self.CmWo[kwargs['f'], :, kwargs['a']] else: if kwargs['pol'] == 'p': U = self.CmWp[kwargs['f'], :, :].reshape(self.na * self.ng) else: U = self.CmWo[kwargs['f'], :, :].reshape(self.na * self.ng) if kwargs['db']: U = 10 * np.log10(U) D = np.sqrt(np.sum((self.pa - self.pg) * (self.pa - self.pg), axis=0)) if kwargs['a'] <> -1: D = D.reshape(self.ng, self.na) ax.semilogx(D[:, kwargs['a']], U, '.', color=kwargs['col'], label=kwargs['label']) else: ax.semilogx(D, U, '.', color=kwargs['col'], label=kwargs['label']) return fig, ax def show(self, **kwargs): """ show coverage Parameters ---------- typ : string 'pr' | 'sinr' | 'capacity' | 'loss' | 'best' | 'egd' grid : boolean polar : string 'o' | 'p' best : boolean draw best server contour if True f : int frequency index a : int access point index (-1 all access point) Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a = C.show(typ='pr',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='best',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='loss',figsize=(10,8)) >>> plt.show() >>> f,a = C.show(typ='sinr',figsize=(10,8)) >>> plt.show() See Also -------- pylayers.gis.layout.Layout.showG """ defaults = { 'typ': 'pr', 'grid': False, 'polar': 'p', 'f': 0, 'a': -1, 'db': True, 'cmap': cm.jet, 'best': True } title = self.dap[self.dap.keys()[0]].s.name + ' : ' for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] polar = kwargs['polar'] assert polar in ['p', 'o'], "polar wrongly defined in show coverage" if 'fig' in kwargs: if 'ax' in kwargs: fig, ax = self.L.showG('s', fig=kwargs['fig'], ax=kwargs['ax']) else: fig, ax = self.L.showG('s', fig=kwargs['fig']) else: if 'figsize' in kwargs: fig, ax = self.L.showG('s', figsize=kwargs['figsize']) else: fig, ax = self.L.showG('s') # plot the grid self.typ = kwargs['typ'] typ = kwargs['typ'] if kwargs['grid']: for k in self.dap: p = self.dap[k].p ax.plot(p[0], p[1], 'or') f = kwargs['f'] a = kwargs['a'] assert typ in [ 'best', 'egd', 'sinr', 'snr', 'capacity', 'pr', 'loss', 'intensity', 'losssombreamento', 'prsombreamento', 'snrsombreamento' ], "typ unknown in show coverage" best = kwargs['best'] dB = kwargs['db'] # setting the grid l = self.grid[0, 0] r = self.grid[-1, 0] b = self.grid[0, 1] t = self.grid[-1, -1] arq = open('cobertura.txt', 'w') texto = '''dBm e V/m \n''' arq.write(texto) arq.close() if typ == 'best': title = title + 'Best server' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar for ka in range(self.na): if polar == 'p': bestsv = self.bestsvp[f, :, ka] if polar == 'o': bestsv = self.bestsvo[f, :, ka] m = np.ma.masked_where(bestsv == 0, bestsv) if self.mode <> 'file': W = m.reshape(self.nx, self.ny).T ax.imshow(W, extent=(l, r, b, t), origin='lower', vmin=1, vmax=self.na + 1) else: ax.scatter(self.grid[:, 0], self.grid[:, 1], c=m, s=20, linewidth=0) ax.set_title(title) else: if typ == 'egd': title = title + 'excess group delay : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar V = self.Ed dB = False legcb = 'Delay (ns)' if typ == 'sinr': title = title + 'SINR : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.sinro if polar == 'p': V = self.sinrp if typ == 'snr': title = title + 'SNR : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.snro if polar == 'p': V = self.snrp if typ == 'capacity': title = title + 'Capacity : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar legcb = 'Mbit/s' if polar == 'o': V = self.bmhz.T[np.newaxis, :] * np.log( 1 + self.sinro) / np.log(2) if polar == 'p': V = self.bmhz.T[np.newaxis, :] * np.log( 1 + self.sinrp) / np.log(2) if typ == 'pr': title = title + 'Pr : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dBm' else: lgdcb = 'mW' if polar == 'o': V = self.CmWo if polar == 'p': V = self.CmWp if typ == 'loss': title = title + 'Loss : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: legcb = 'Linear scale' if polar == 'o': V = self.Lwo * self.freespace if polar == 'p': V = self.Lwp * self.freespace if typ == 'losssombreamento': #relaxa que esse so muda no final title = title + 'Loss Log : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: lgdcb = 'Linear scale' if polar == 'o': V = self.CmWo if polar == 'p': V = self.CmWp if typ == 'prsombreamento': #relaxa que esse so muda no final title = title + 'Pr Log : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dBm' else: lgdcb = 'Linear scale' if polar == 'o': V = self.CmWo if polar == 'p': V = self.CmWp if typ == 'snrsombreamento': #relaxa que esse so muda no final title = title + 'SNR Log : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar if dB: legcb = 'dB' else: lgdcb = 'Linear scale' if polar == 'o': V = self.CmWo if polar == 'p': V = self.CmWp if typ == 'intensity': title = title + 'Intensity : ' + ' fc = ' + str( self.fGHz[f]) + ' GHz' + ' polar : ' + polar legcb = 'V/m' if polar == 'o': V = np.power(10, ( (self.CmWo + 20 * np.log10(self.fGHz[f] * 1000) + 77.2) / 20)) * 0.000001 if polar == 'p': V = np.power(10, ( (self.CmWp + 20 * np.log10(self.fGHz[f] * 1000) + 77.2) / 20)) * 0.000001 if a == -1: V = np.max(V[f, :, :], axis=1) else: V = V[f, :, a] # reshaping the data on the grid if self.mode != 'file': U = V.reshape((self.nx, self.ny)).T else: U = V if dB and typ != 'intensity': if typ == 'losssombreamento' or typ == 'prsombreamento' or typ == 'snrsombreamento': f = self.fGHz[f] * 1000 Lf = self.PtDB - self.Prdo + self.Gt + self.Gr medidas1 = [] dx = np.linspace(0, self.xt, self.nx) dy = np.linspace(0, self.yt, self.ny) for i in range(self.ny): medidas1.append([]) for i in range(self.ny): for j in range(self.nx): medidas1[i].append( np.sqrt( np.power(dx[j] - self.x0, 2) + np.power(dy[i] - self.y0, 2)) / 1000) desvio = 0 X = np.random.normal(0, self.desviopadrao, len(medidas1)) PL2 = [] maior, menor = 0, 100 for i in range(self.ny): PL2.append([]) for i in range(self.ny): for j in range(self.nx): oi = Lf + 10 * self.n * np.log10( medidas1[i][j] / self.do) + X[i] PL2[i].append(oi) if (maior < oi): maior = oi if (menor > oi): menor = oi menor = np.floor(menor / 10) * 10 maior = np.ceil(maior / 10) * 10 if typ == 'prsombreamento': maior, menor = -100, 0 pr = [] for i in range(self.ny): pr.append([]) for i in range(self.ny): for j in range(self.nx): oi = self.PtDB - PL2[i][j] pr[i].append(oi) if (maior < oi): maior = oi if (menor > oi): menor = oi menor = np.floor(menor / 10) * 10 maior = np.ceil(maior / 10) * 10 U = pr elif typ == 'snrsombreamento': maior, menor = -100, 100 pr = [] for i in range(self.ny): pr.append([]) for i in range(self.ny): for j in range(self.nx): oi = PL2[i][j] / self.pnw[0][0] pr[i].append(oi) if (maior < oi): maior = oi if (menor > oi): menor = oi menor = np.floor(menor / 10) * 10 maior = np.ceil(maior / 10) * 10 U = pr else: U = PL2 else: U = 10 * np.log10(U) #print U arq = open('cobertura.txt', 'w') texto = [] for linha in U: texto.append(str(linha) + '\n') arq.writelines(texto) arq.close() if 'vmin' in kwargs: vmin = kwargs['vmin'] else: if typ == 'losssombreamento' or typ == 'prsombreamento' or typ == 'snrsombreamento': vmin = menor else: vmin = U.min() if 'vmax' in kwargs: vmax = kwargs['vmax'] else: if typ == 'losssombreamento' or typ == 'prsombreamento' or typ == 'snrsombreamento': vmax = maior else: vmax = U.max() if self.mode != 'file': img = ax.imshow(U, extent=(l, r, b, t), origin='lower', vmin=vmin, vmax=vmax, cmap=kwargs['cmap']) else: img = ax.scatter(self.grid[:, 0], self.grid[:, 1], c=U, s=20, linewidth=0, cmap=kwargs['cmap'], vmin=vmin, vmax=vmax) for k in range(self.na): ax.annotate(str(k), xy=(self.pa[0, k], self.pa[1, k])) ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) clb = fig.colorbar(img, cax) clb.set_label(legcb) if typ == 'losssombreamento' or typ == 'prsombreamento' or typ == 'snrsombreamento': print 'Modelo do Sombreamento Log Normal' else: if best: if self.mode <> 'file': if polar == 'o': ax.contour(np.sum(self.bestsvo, axis=2)[f, :].reshape( self.nx, self.ny).T, extent=(l, r, b, t), linestyles='dotted') if polar == 'p': ax.contour(np.sum(self.bestsvp, axis=2)[f, :].reshape( self.nx, self.ny).T, extent=(l, r, b, t), linestyles='dotted') # display access points if a == -1: ax.scatter(self.pa[0, :], self.pa[1, :], s=30, c='r', linewidth=0) else: ax.scatter(self.pa[0, a], self.pa[1, a], s=30, c='r', linewidth=0) plt.tight_layout() return (fig, ax)