#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') #build topological graph ax2 = fig.add_subplot(323) L.showG(fig=fig,ax=ax2,graph='t') plt.title('Topological graph')
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()
#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') #build topological graph ax2 = fig.add_subplot(323) L.showG(fig=fig, ax=ax2, graph='t') plt.title('Topological graph')
class Simul(PyLayers): """ Link oriented simulation A simulation requires : + A Layout + A Person + A Trajectory or a CorSer instance Members ------- dpersons : dictionnary of persons (agent) dap : dictionnary of access points Methods ------- load_simul : load configuration file load_Corser : load a Corser file _gen_net : generate network and asociated links show : show layout and network evaldeter : run simulation over time """ def __init__(self, source ='simulnet_TA-Office.h5',verbose=False): """ object constructor Parameters ---------- source : string h5 trajectory file default simulnet_TA-Office.h5 verbose : boolean Notes ----- The simultraj has a dataframe """ # self.progress = -1 # simulation not loaded self.verbose = verbose self.cfield = [] self.dpersons = {} self.dap = {} self.Nag = 0 self.Nap = 0 # source analysis if isinstance(source,str): self.filetraj = source self.load_simul(source) self.source = 'simul' elif 'pylayers' in source.__module__: self.filetraj = source._filename self.load_CorSer(source) cutoff=2 self.source = 'CorSer' # generate the Network # The wireless standard and frequency is fixed in this function # self._gen_net() # initialize Stochastic Link self.SL = SLink() # initialize Deterministic Link self.DL = DLink(L=self.L,verbose=self.verbose) self.DL.cutoff=cutoff self.filename = 'simultraj_' + self.filetraj + '.h5' # data is a panda container which is initialized # # We do not save all the simulation in a DataFRame anymore # #self.data = pd.DataFrame(columns=['id_a', 'id_b', # 'x_a', 'y_a', 'z_a', # 'x_b', 'y_b', 'z_b', # 'd', 'eng', 'typ', # 'wstd', 'fcghz', # 'fbminghz', 'fbmaxghz', 'fstep', 'aktk_id', # 'sig_id', 'ray_id', 'Ct_id', 'H_id' # ]) #self.data.index.name='t' self._filecsv = self.filename.split('.')[0] + '.csv' self.todo = {'OB': True, 'B2B': True, 'B2I': True, 'I2I': False} filenameh5 = pyu.getlong(self.filename,pstruc['DIRLNK']) if os.path.exists(filenameh5) : self.loadpd() self.settime(0.) # self._saveh5_init() def __repr__(self): s = 'Simul trajectories class\n' s = s + '------------------------\n' s = s +'\n' s = s + 'Used layout: ' + self.L.filename + '\n' s = s + 'Number of Agents: ' + str(self.Nag) + '\n' s = s + 'Number of Access Points: ' + str(self.Nap) + '\n' s = s + 'Link to be evaluated: ' + str(self.todo) + '\n' s = s + 'tmin: ' + str(self._tmin) + '\n' s = s + 'tmax: ' + str(self._tmax) + '\n' s = s +'\n' # network info s = s + 'self.N :\n' s = s + self.N.__repr__() + '\n' s = s + 'CURRENT TIME: ' + str(self.ctime) + '\n' return s def load_simul(self, source): """ load a simultraj configuration file Parameters ---------- source : string name of simulation file to be loaded """ self.filetraj = source if not os.path.isfile(source): raise AttributeError('Trajectory file'+source+'has not been found.\ Please make sure you have run a simulnet simulation before runining simultraj.') # get the trajectory traj = tr.Trajectories() traj.loadh5(self.filetraj) # get the layout self.L = Layout(traj.Lfilename) # resample trajectory for ut, t in enumerate(traj): if t.typ == 'ag': person = Body(t.name + '.ini') tt = t.time() self.dpersons.update({t.name: person}) self._tmin = tt[0] self._tmax = tt[-1] self.time = tt else: pos = np.array([t.x[0], t.y[0], t.z[0]]) self.dap.update({t.ID: {'pos': pos, 'ant': antenna.Antenna(), 'name': t.name } }) self.ctime = np.nan self.Nag = len(self.dpersons.keys()) self.Nap = len(self.dap.keys()) self.traj = traj def load_CorSer(self,source): """ load CorSer file for simulation Parameters ---------- source : name of simulation file to be loaded """ if isinstance(source.B,Body): B=[source.B] elif isinstance(source.B,list): B=source.B elif isinstance(source.B,dict): B=source.B.values() else: raise AttributeError('CorSer.B must be a list or a Body') self.L=source.L self.traj = tr.Trajectories() self.traj.Lfilename=self.L.filename for b in B: self.dpersons.update({b.name: b}) self._tmin = b.time[0] self._tmax = b.time[-1] self.time = b.time self.traj.append(b.traj) for ap in source.din: techno,ID=ap.split(':') if techno == 'HKB': techno = 'hikob' if techno == 'TCR': techno = 'tcr' if techno == 'BS': techno = 'bespoon' self.dap.update({ap: {'pos': source.din[ap]['p'], 'ant': source.din[ap]['ant'], 'T': source.din[ap]['T'], 'name': techno } }) self.ctime = np.nan self.Nag = len(B) self.Nap = len(source.din) self.corser = source def _gen_net(self): """ generate Network and associated links Notes ----- Create self.N : Network object See Also -------- pylayers.network.network """ # # Create Network # N = Network() # # get devices on bodies # # forall person # forall device for p in self.dpersons: D = [] for dev in self.dpersons[p].dev: aDev = Device(self.dpersons[p].dev[dev]['name'], ID = dev) D.append(aDev) D[-1].ant['A1']['name'] = self.dpersons[p].dev[dev]['file'] D[-1].ant['antenna'] = self.dpersons[p].dev[dev]['ant'] N.add_devices(D, grp=p) # # get access point devices # for ap in self.dap: D = Device(self.dap[ap]['name'], ID = ap) D.ant['antenna'] = self.dap[ap]['ant'] N.add_devices(D, grp = 'ap', p = self.dap[ap]['pos']) N.update_orient(ap, self.dap[ap]['T'], now = 0.) # create Network # # _get_wstd # _get_grp # _connect # _init_PN # N.create() self.N = N def show(self): """ show actual simlulation configuration """ fig, ax = self.L.showGs() fig, ax = self.N.show(fig=fig, ax=ax) return fig, ax def evaldeter(self, na, nb, wstd, fmod='force',nf=10,fGHz=[], **kwargs): """ deterministic evaluation of a link Parameters ---------- na : string: node a id in self.N (Network) nb : string: node b id in self.N (Network) wstd : string: wireless standard used for commmunication between na and nb fmode : string ('center'|'band'|'force') mode of frequency evaluation center : single frequency (center frequency of a channel) band : nf points on the whole band force : takes directly fGHz nf : int: number of frequency points (if fmode = 'band') **kwargs : argument of DLink Returns ------- (a, t ) a : ndarray alpha_k t : ndarray tau_k See Also -------- pylayers.simul.link.DLink """ # todo in network : # take into consideration the postion and rotation of antenna and not device self.DL.Aa = self.N.node[na]['ant']['antenna'] self.DL.a = self.N.node[na]['p'] self.DL.Ta = self.N.node[na]['T'] self.DL.Ab = self.N.node[nb]['ant']['antenna'] self.DL.b = self.N.node[nb]['p'] self.DL.Tb = self.N.node[nb]['T'] # # The frequency band is chosen from the selected standard # if fmode == 'center' # only center frequency is calculated # #' if fmod == 'center': self.DL.fGHz = self.N.node[na]['wstd'][wstd]['fcghz'] if fmod == 'band': fminGHz = self.N.node[na]['wstd'][wstd]['fbminghz'] fmaxGHz = self.N.node[na]['wstd'][wstd]['fbmaxghz'] self.DL.fGHz = np.linspace(fminGHz, fmaxGHz, nf) if fmod == 'force': assert len(fGHz)>0,"fGHz has not been defined" self.DL.fGHz = fGHz a, t = self.DL.eval(**kwargs) return a, t def evalstat(self, na, nb): """ statistical evaluation of a link Parameters ---------- na : string: node a id in self.N (Netwrok) nb : string: node b id in self.N (Netwrok) Returns ------- (a, t, eng) a : ndarray alpha_k t : ndarray tau_k eng : float engagement """ pa = self.N.node[na]['p'] pb = self.N.node[nb]['p'] if self.source == 'simul': dida, name = na.split('_') didb, name = nb.split('_') elif self.source =='CorSer': bpa,absolutedida,dida,name,technoa = self.corser.devmapper(na) bpb,absolutedidb,didb,name,technob = self.corser.devmapper(nb) ak, tk, eng = self.SL.onbody(self.dpersons[name], dida, didb, pa, pb) return ak, tk, eng def settime(self,t): """ set current time """ self.ctime = t self._traj=copy.copy(self.traj) self.update_pos(t) def run(self, **kwargs): """ run the link evaluation along a trajectory Parameters ---------- OB: boolean perform on body statistical link evaluation B2B: boolean perform body to body deterministic link evaluation B2I: boolean perform body to infrastructure deterministic link evaluation I2I: boolean perform infrastructure to infrastructure deterministic link eval. links: dict dictionnary of link to be evaluated (key is wtsd and value is a list of links) (if [], all link are considered) wstd: list list of wstd to be evaluated (if [], all wstd are considered) t: np.array list of timestamp to be evaluated (if [], all timestamps are considered) tbr : boolean time in bit reverse order (tmin,tmax,N) Npoints=2**N replace_data: boolean (True) if True , reference id of all already simulated link will be erased and replace by new simulation id fGHz : np.array frequency in GHz Examples -------- >>> from pylayers.simul.simultraj import * >>> from pylayers.measures.cormoran import * >>> C=CorSer() >>> S=Simul(C,verbose=True) >>> link={'ieee802154':[]} >>> link['ieee802154'].append(S.N.links['ieee802154'][0]) >>> lt = [0,0.2,0.3,0.4,0.5] >>> S.run(links=link,t=lt) """ defaults = {'OB': True, 'B2B': True, 'B2I': True, 'I2I': False, 'links': {}, 'wstd': [], 't': np.array([]), 'btr':True, 'DLkwargs':{}, 'replace_data':True, 'fmod':'force', 'fGHz':np.array([2.45]) } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] DLkwargs = kwargs.pop('DLkwargs') links = kwargs.pop('links') wstd = kwargs.pop('wstd') OB = kwargs.pop('OB') B2B = kwargs.pop('B2B') B2I = kwargs.pop('B2I') I2I = kwargs.pop('I2I') fmod = kwargs.pop('fmod') self.fGHz = kwargs.pop('fGHz') self.todo.update({'OB':OB,'B2B':B2B,'B2I':B2I,'I2I':I2I}) # Check link attribute if links == {}: links = self.N.links elif not isinstance(links, dict): raise AttributeError('links is {wstd:[list of links]}, see self.N.links') for k in links.keys(): checkl = [l in self.N.links[k] for l in links[k]] if len(np.where(checkl==False)[0])>0: # if sum(checkl) != len(self.N.links): uwrong = np.where(np.array(checkl) is False)[0] raise AttributeError(str(np.array(links)[uwrong]) + ' links does not exist in Network') wstd = links.keys() # # Check wstd attribute # if wstd == []: # wstd = self.N.wstd.keys() # elif not isinstance(wstd, list): # wstd = [wstd] checkw = [w in self.N.wstd.keys() for w in wstd] if sum(checkw) != len(wstd): uwrong = np.where(np.array(checkw) is False)[0] raise AttributeError(str(np.array(wstd)[uwrong]) + ' wstd are not in Network') # force time attribute compliant if not isinstance(kwargs['t'],np.ndarray): if isinstance(kwargs['t'],list): lt = np.array(kwargs['t']) elif (isinstance(kwargs['t'], int) or isinstance(kwargs['t'],float)): lt = np.array([kwargs['t']]) else : lt = kwargs['t'] #if len(lt) == 0: # lt = self.time # check time attribute if kwargs['btr']: if (lt[0] < self._tmin) or\ (lt[1] > self._tmax) : raise AttributeError('Requested time range not available') # self._traj is a copy of self.traj, which is affected by resampling. # it is only a temporary attribute for a given run # if len(lt) > 1: # sf = 1/(1.*lt[1]-lt[0]) # self._traj = self.traj.resample(sf=sf, tstart=lt[0]) # else: # self._traj = self.traj.resample(sf=1.0, tstart=lt[0]) # self._traj.time() # self.time = self._traj.t # self._time = pd.to_datetime(self.time,unit='s') # # Nested Loops # # time # standard # links # evaldeter &| evalstat # #lt = self.get_sim_time(lt) #self._time=self.get_sim_time(lt) init = True if kwargs['btr']: tmin = lt[0] tmax = lt[1] Nt = int(2**lt[2]) ta = np.linspace(tmin,tmax,Nt) it = np.hstack((np.r_[0],np.r_[pyu.bitreverse(Nt,int(lt[2]))])) #trev = t[it] else: ta = kwargs['t'] it = range(len(ta)) ## Start to loop over time ## ut : counter ## t : time value (s) #for ut, t in enumerate(lt): for ks,ut in enumerate(it): t = ta[ut] self.ctime = t # update spatial configuration of the scene for time t self.update_pos(t) # print self.N.__repr__() ## Start to loop over available Wireless standard ## for w in wstd: ## Start to loop over the chosen links stored in links ## for na, nb, typ in links[w]: # If type of link is valid (Body 2 Body,...) # if self.todo[typ]: if self.verbose: print '-'*30 print 'time:', t, '/', lt[-1] ,' time idx:', ut, '/',len(ta),'/',ks print 'processing: ',na, ' <-> ', nb, 'wstd: ', w print '-'*30 eng = 0 # # Invoque link deterministic simulation # # node : na # node : nb # wstd : w # self.evaldeter(na, nb, w, applywav=False, fmod = fmod, fGHz = self.fGHz, **DLkwargs) # if typ == 'OB': # self.evalstat(na, nb) # eng = self.SL.eng # L = self.DL + self.SL # self._ak = L.H.ak # self._tk = L.H.tk # else : # Get alphak an tauk self._ak = self.DL.H.ak self._tk = self.DL.H.tk aktk_id = str(ut) + '_' + na + '_' + nb + '_' + w # this is a dangerous way to proceed ! # the id as a finite number of characters while len(aktk_id)<40: aktk_id = aktk_id + ' ' df = pd.DataFrame({ 'id_a': na, 'id_b': nb, 'x_a': self.N.node[na]['p'][0], 'y_a': self.N.node[na]['p'][1], 'z_a': self.N.node[na]['p'][2], 'x_b': self.N.node[nb]['p'][0], 'y_b': self.N.node[nb]['p'][1], 'z_b': self.N.node[nb]['p'][2], 'd': self.N.edge[na][nb]['d'], 'eng': eng, 'typ': typ, 'wstd': w, 'fcghz': self.N.node[na]['wstd'][w]['fcghz'], 'fbminghz': self.fGHz[0], 'fbmaxghz': self.fGHz[-1], 'nf': len(self.fGHz), 'aktk_id':aktk_id, 'sig_id': self.DL.dexist['sig']['grpname'], 'ray_id': self.DL.dexist['ray']['grpname'], 'Ct_id': self.DL.dexist['Ct']['grpname'], 'H_id': self.DL.dexist['H']['grpname'], },columns=['id_a', 'id_b', 'x_a', 'y_a', 'z_a', 'x_b', 'y_b', 'z_b', 'd', 'eng', 'typ', 'wstd', 'fcghz', 'fbminghz', 'fbmaxghz', 'fstep', 'aktk_id', 'sig_id', 'ray_id', 'Ct_id', 'H_id' ],index= [t]) #self._time[ut]]) self.savepd(df) def replace_data(self, df): """check if a dataframe df already exists in self.data Parameters ---------- df : pd.DataFrame Returns ------- boolean True if already exists False otherwise """ self.data[(self.data.index == df.index) & (self.data['id_a'] == df['id_a'].values[0]) & (self.data['id_b'] == df['id_b'].values[0]) & (self.data['wstd'] == df['wstd'].values[0])]=df.values def check_exist(self, df): """check if a dataframe df already exists in self.data Parameters ---------- df : pd.DataFrame Returns ------- boolean True if already exists False otherwise """ # check init case if not len(self.data.index) == 0: ud = self.data[(self.data.index == df.index) & (self.data['id_a'] == df['id_a'].values[0]) & (self.data['id_b'] == df['id_b'].values[0]) & (self.data['wstd'] == df['wstd'].values[0])] if len(ud) == 0: return False else : return True else : return False def savepd(self,df): """ save data information of a simulation Parameters ---------- df : one index data Notes ----- """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) store = pd.HDFStore(filenameh5) #self.data=self.data.sort() store.append('df',df) store.close() def loadpd(self): """ load data from previous simulations """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) store = pd.HDFStore(filenameh5) #self.data = pd.read_hdf(filenameh5,'df') self.data = store.get('df') self.data.index.name='t' self.data = self.data.sort() def get_sim_time(self,t): """ retrieve closest time value in regard of passed t value in parameter """ if not isinstance(t,list) and not isinstance(t,np.ndarray): return np.array([self.time[np.where(self.time <=t)[0][-1]]]) else : return np.array([self.get_sim_time(tt) for tt in t])[:,0] def get_df_from_link(self,id_a,id_b,wstd=''): """ Return a restricted data frame for a specific link Parameters ---------- id_a : str node id a id_b: str node id b wstd: str optionnal :wireslees standard """ if wstd == '': return self.data[(self.data['id_a']==id_a) & (self.data['id_b']==id_b)] else : return self.data[(self.data['id_a']==id_a) & (self.data['id_b']==id_b) & self.data['wstd']==wstd] def update_pos(self, t): """ update positions of devices and bodies for a given time index Parameters ---------- t : int time value """ # if a bodies are involved in simulation if ((self.todo['OB']) or (self.todo['B2B']) or (self.todo['B2I'])): nodeid = [] pos = [] devlist = [] orient = [] for up, person in enumerate(self.dpersons.values()): person.settopos(self._traj[up], t=t, cs=True) name = person.name dev = person.dev.keys() devlist.extend(dev) #nodeid.extend([n + '_' + name for n in dev]) pos.extend([person.dcs[d][:, 0] for d in dev]) orient.extend([person.acs[d] for d in dev]) # TODO !!!!!!!!!!!!!!!!!!!! # in a future version , the network update must also update # antenna position in the device coordinate system self.N.update_pos(devlist, pos, now=t) self.N.update_orient(devlist, orient, now=t) self.N.update_dis() def get_value(self,**kwargs): """ retrieve output parameter at a specific time Parameters ---------- typ : list list of parameters to be retrieved (R | C |H | ak | tk | rss ) links: list dictionnary of link to be evaluated (key is wtsd and value is a list of links) (if [], all link are considered) t: int or np.array list of timestamp to be evaluated | singlr time instant Returns ------- output: dict [link_key]['t'] ['ak'] ... """ # get time defaults = {'t': 0, 'typ':['ak'], 'links': {}, 'wstd':[], 'angles':False } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] # allocate an empty dictionnary for wanted selected output output={} # manage time t can be a list or a float t = kwargs['t'] t = self.get_sim_time(t) dt = self.time[1]-self.time[0] # manage links plinks = kwargs['links'] links=[] if isinstance(plinks,dict): for l in plinks.keys(): links.extend(plinks[l]) if len(links) == 0: raise AttributeError('Please give valid links to get values') # output['t']=[] # output['time_to_simul']=[] # for each requested time step for tt in t : # for each requested links for link in links: linkname=link[0]+'-'+link[1] if not output.has_key(linkname): output[linkname] = {} if not output[linkname].has_key('t'): output[linkname]['t'] = [] # restrict global dataframe self.data to the specific link df = self.get_df_from_link(link[0],link[1]) # restrict global dataframe self.data to the specific z df = df[(df.index > tt-dt) & (df.index <= tt+dt)] if len(df) != 0: output[linkname]['t'].append(tt) if len(df)>1: print 'Warning possible issue in self.get_value' line = df.iloc[-1] # # get info of the corresponding timestamp # line = df[(df['id_a'] == link[0]) & (df['id_b'] == link[1])].iloc[-1] # if len(line) == 0: # line = df[(df['id_b'] == link[0]) & (df['id_a'] == link[1])] # if len(line) == 0: # raise AttributeError('invalid link') #retrieve correct position and orientation given the time #self.update_pos(t=tt) # antennas positions #self.DL.a = self.N.node[link[0]]['p'] #self.DL.b = self.N.node[link[1]]['p'] # antennas orientation #self.DL.Ta = self.N.node[link[0]]['T'] #self.DL.Tb = self.N.node[link[1]]['T'] # antennas object #self.DL.Aa = self.N.node[link[0]]['ant']['antenna'] #self.DL.Ab = self.N.node[link[1]]['ant']['antenna'] # get the antenna index #uAa_opt, uAa = self.DL.get_idx('A_map',self.DL.Aa._filename) #uAb_opt, uAb = self.DL.get_idx('A_map',self.DL.Ab._filename) if 'ak' in kwargs['typ'] or 'tk' in kwargs['typ'] or 'rss' in kwargs['typ']: H_id = line['H_id'].decode('utf8') # load the proper link # parse index lid = H_id.split('_') #if (lid[5]==str(uAa))&(lid[6]==str(uAb)): self.DL.load(self.DL.H,H_id) if 'ak' in kwargs['typ']: if not output[linkname].has_key('ak'): output[linkname]['ak']=[] output[linkname]['ak'].append(copy.deepcopy(self.DL.H.ak)) if 'tk' in kwargs['typ']: if not output[linkname].has_key('tk'): output[linkname]['tk']=[] output[linkname]['tk'].append(copy.deepcopy(self.DL.H.tk)) if 'rss' in kwargs['typ']: if not output[linkname].has_key('rss'): output[linkname]['rss']=[] output[linkname]['rss'].append(copy.deepcopy(self.DL.H.rssi())) if 'R' in kwargs['typ']: if not output[linkname].has_key('R'): output[linkname]['R']=[] ray_id = line['ray_id'] self.DL.load(self.DL.R,ray_id) output[linkname]['R'].append(copy.deepcopy(self.DL.R)) if 'C' in kwargs['typ']: if not output[linkname].has_key('C'): output[linkname]['C']=[] Ct_id = line['Ct_id'] self.DL.load(self.DL.C,Ct_id) if kwargs['angles']: self.DL.C.islocal=False self.DL.C.locbas(Tt=self.DL.Ta, Tr=self.DL.Tb) #T channel output[linkname]['C'].append(copy.deepcopy(self.DL.C)) if 'H' in kwargs['typ']: if not output[linkname].has_key('H'): output[linkname]['H']=[] H_id = line['H_id'] lid = H_id.split('_') #if (lid[5]==str(uAa))&(lid[6]==str(uAb)): self.DL.load(self.DL.H,H_id) output[linkname]['H'].append(copy.deepcopy(self.DL.H)) # if time value not found in dataframe else: if not output[linkname].has_key('time_to_simul'): output[linkname]['time_to_simul'] = [] output[linkname]['time_to_simul'].append(tt) for l in output.keys(): if output[l].has_key('time_to_simul'): print 'link', l , 'require simulation for timestamps', output[l]['time_to_simul'] return(output) def get_link(self,**kwargs): """ retrieve a Link specific time from a simultraj Parameters ---------- typ : list list of parameters to be retrieved (ak | tk | R |C) links: list dictionnary of link to be evaluated (key is wtsd and value is a list of links) (if [], all link are considered) t: int or np.array list of timestamp to be evaluated | singlr time instant Returns ------- DL : DLink Examples -------- >>> from pylayers.simul.simultraj import * >>> from pylayers.measures.cormoran import * >>> C=CorSer(serie=6i,day=11) >>> S = Simul(C,verb ose=False) >>> DL = S.get_link(typ=['R','C','H']) ... """ # get time defaults = {'t': 0, 'typ':['ak'], 'links': {}, 'wstd':[], 'angles':False } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] output={} # manage time t = kwargs['t'] t = self.get_sim_time(t) dt = self.time[1]-self.time[0] # manage links plinks = kwargs['links'] links=[] if isinstance(plinks,dict): for l in plinks.keys(): links.extend(plinks[l]) if len(links) == 0: raise AttributeError('Please give valid links to get values') # output['t']=[] # output['time_to_simul']=[] # for each requested time step for tt in t : # for each requested links for link in links: linkname=link[0]+'-'+link[1] if not output.has_key(linkname): output[linkname] = {} if not output[linkname].has_key('t'): output[linkname]['t'] = [] # restrict global dataframe self.data to the specific link df = self.get_df_from_link(link[0],link[1]) # restrict global dataframe self.data to the specific z df = df[(df.index > tt-dt) & (df.index <= tt+dt)] if len(df) != 0: output[linkname]['t'].append(tt) if len(df)>1: print 'Warning possible issue in self.get_link' line = df.iloc[-1] # # get info of the corresponding timestamp # line = df[(df['id_a'] == link[0]) & (df['id_b'] == link[1])].iloc[-1] # if len(line) == 0: # line = df[(df['id_b'] == link[0]) & (df['id_a'] == link[1])] # if len(line) == 0: # raise AttributeError('invalid link') #retrieve correct position and orientation given the time self.update_pos(t=tt) self.DL.a = self.N.node[link[0]]['p'] self.DL.b = self.N.node[link[1]]['p'] self.DL.Ta = self.N.node[link[0]]['T'] self.DL.Tb = self.N.node[link[1]]['T'] #self.DL.Aa = self.N.node[link[0]]['ant']['antenna'] #self.DL.Ab = self.N.node[link[1]]['ant']['antenna'] #H_id = line['H_id'].decode('utf8') #self.DL.load(self.DL.H,H_id) if 'R' in kwargs['typ']: ray_id = line['ray_id'] self.DL.load(self.DL.R,ray_id) if 'C' in kwargs['typ']: Ct_id = line['Ct_id'] self.DL.load(self.DL.C,Ct_id) if kwargs['angles']: self.DL.C.islocal=False self.DL.C.locbas(Tt=self.DL.Ta, Tr=self.DL.Tb) if 'H' in kwargs['typ']: H_id = line['H_id'] self.DL.load(self.DL.H,H_id) return(self.DL) def _show3(self, **kwargs): """ 3D show using Mayavi Parameters ---------- t: float time index link: list [id_a, id_b] id_a : node id a id_b : node id b 'lay': bool show layout 'net': bool show net 'body': bool show bodies 'rays': bool show rays """ defaults = {'t': 0, 'link': [], 'wstd':[], 'lay': True, 'net': True, 'body': True, 'rays': True, 'ant': False } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] link = kwargs['link'] self.update_pos(kwargs['t']) if len(self.data) != 0: df = self.data[self.data.index == pd.to_datetime(kwargs['t'])] if len(df) != 0: raise AttributeError('invalid time') # default if link ==[]: line = df[df.index<=pd.to_datetime(0)] link = [line['id_a'].values[0],line['id_b'].values[0]] else : # get info of the corresponding timestamp line = df[(df['id_a'] == link[0]) & (df['id_b'] == link[1])] if len(line) == 0: line = df[(df['id_b'] == link[0]) & (df['id_a'] == link[1])] if len(line) == 0: raise AttributeError('invalid link') rayid = line['ray_id'].values[0] self.DL.a = self.N.node[link[0]]['p'] self.DL.b = self.N.node[link[1]]['p'] self.DL.Ta = self.N.node[link[0]]['T'] self.DL.Tb = self.N.node[link[1]]['T'] self.DL.load(self.DL.R,rayid) self.DL._show3(newfig= False, lay= kwargs['lay'], rays= kwargs['rays'], ant=False) else : self.DL._show3(newfig= False, lay= True, rays= False, ant=False) if kwargs['net']: self.N._show3(newfig=False) if kwargs['body']: for p in self.dpersons: self.dpersons[p]._show3(newfig=False, topos=True, pattern=kwargs['ant']) # def _saveh5_init(self): # """ initialization of the h5py file # """ # filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) # import ipdb # try: # f5 = h5py.File(filenameh5, 'w') # f5.create_dataset('time', shape=self.time.shape, data=self.time) # f5.close() # except: # f5.close() # raise NameError('simultra.saveinit: \ # issue when writting h5py file') def _saveh5(self, ut, ida, idb, wstd): """ Save in h5py format Parameters ---------- ut : int time index in self.time ida : string node a index idb : string node b index wstd : string wireless standard of used link Notes ----- Dataset organisation: simultraj_<trajectory_filename.h5>.h5 | |time | ... | |/<tidx_ida_idb_wstd>/ |attrs | |a_k | |t_k Root dataset : time : array range of simulation time Group identifier : tidx : index in time dataset ida : node a index in Network idb : node b index in Network wstd : wireless standar of link interest Inside group: a_k : alpha_k values t_k : tau_k values See Also -------- pylayers.simul.links """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) grpname = str(ut) + '_' + ida + '_' + idb + '_' + wstd # try/except to avoid loosing the h5 file if # read/write error try: fh5 = h5py.File(filenameh5, 'a') if not grpname in fh5.keys(): fh5.create_group(grpname) f = fh5[grpname] # for k in kwargs: # f.attrs[k] = kwargs[k] f.create_dataset('alphak', shape=self._ak.shape, maxshape=(None), data=self._ak) f.create_dataset('tauk', shape=self._tk.shape, maxshape=(None), data=self._tk) else: pass#print grpname + ' already exists in ' + filenameh5 fh5.close() except: fh5.close() raise NameError('Simultraj._saveh5: issue when writting h5py file') def _loadh5(self, grpname): """ Load in h5py format Parameters ---------- grpname : string group name which can be found sin self.data aktk_idx column Returns ------- (ak, tk, conf) ak : ndarray: alpha_k tk : ndarray: alpha_k """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) # try/except to avoid loosing the h5 file if # read/write error try: fh5 = h5py.File(filenameh5, 'r') if not grpname in fh5.keys(): fh5.close() raise NameError(grpname + ' cannot be reached in ' + self.filename) f = fh5[grpname] # for k in f.attrs.keys(): # conf[k]=f.attrs[k] ak = f['alphak'][:] tk = f['tauk'][:] fh5.close() return ak, tk except: fh5.close() raise NameError('Simultraj._loadh5: issue when reading h5py file') def tocsv(self, ut, ida, idb, wstd,init=False): filecsv = pyu.getlong(self._filecsv,pstruc['DIRLNK']) with open(filecsv, 'a') as csvfile: fil = csv.writer(csvfile, delimiter=';', quoting=csv.QUOTE_MINIMAL) if init: keys = self.data.iloc[-1].keys() data = [k for k in keys] data .append('ak') data .append('tk') fil.writerow(data) values = self.data.iloc[-1].values data = [v for v in values] sak = str(self._ak.tolist()) stk = str(self._tk.tolist()) data.append(sak) data.append(stk) fil.writerow(data)
class Simul(PyLayers): """ Simulation Class Methods ------- gui() graphical user interface choose() choose a simulation file in simuldir info() info about the simulation showray(itx,irx,iray) show a single ray help() help on using Simulation object freq() return the frequency base save() save Simulation file layout load a Layout file load() load Simulation show3() geomview vizualization show3l(itx,irx) geomview vizualization of link itx irx show() 2D visualization of simulation with furniture run(itx,irx) run simulation for links (itx,irx) cir(itx,irx,store_level=0,alpha=1.0) Channel Impulse Response calculation Attributes ---------- fileconf filetauk filetang filerang tx rx progress indoor mat sl Notes ------ This class group together all the parametrization files of a simulation Directory list file : fileconf Constitutive parameters file : fileslab filemat Ray Tracing parameters files : filepalch filetra Frequency list file : filefreq """ def __init__(self, _filesimul='default.ini'): self.filesimul = _filesimul self.config = ConfigParser.ConfigParser() self.config.add_section("files") self.config.add_section("frequency") self.config.add_section("waveform") self.config.add_section("output") self.dtang = {} self.drang = {} self.dtauk = {} self.dfield = {} self.dcir = {} self.output = {} # # Here was a nasty bug : Rule for the future # "Always precise the key value of the passed argument" # # Mal nommer les choses, c'est ajouter au malheur du monde ( Albert Camus ) # self.tx = RadioNode(name = '', typ = 'tx', _fileini = 'radiotx.ini', _fileant = 'defant.vsh3', ) self.rx = RadioNode(name = '', typ = 'rx', _fileini = 'radiorx.ini', _fileant = 'defant.vsh3', ) self.filefreq = "def.freq" self.progress = -1 # simulation not loaded self.filetang = [] self.filerang = [] self.filetauk = [] self.filefield = [] self.fileconf = "project.conf" self.cfield = [] self.fGHz = np.linspace(2, 11, 181, endpoint=True) self.wav = wvf.Waveform() try: self.load(_filesimul) except: pass def gui(self): """ gui to modify the simulation file """ simulgui = multenterbox('', 'Simulation file', ('filesimul', 'filestr', 'filefreq', 'filespaTx', 'filespaRx', 'fileantTx' 'fileantRx'), (self.filesimul, self.filestr, self.filefreq, self.filespaTx, self.filespaRx, self.fileantTx, self.fileantRx)) if simulgui is not None: self.filesimul = simulgui[0] self.filestr = simulgui[1] self.filefreq = simulgui[6] self.filespaTx = simulgui[7] self.filespaRx = simulgui[8] self.fileantTx = simulgui[9] self.fileantRx = simulgui[10] def updcfg(self): """ update simulation .ini config file with values currently in use. """ self.config.set("files", "struc", self.filestr) self.config.set("files", "conf", self.fileconf) self.config.set("files", "txant", self.tx.fileant) self.config.set("files", "rxant", self.rx.fileant) self.config.set("files", "tx", self.tx.fileini) self.config.set("files", "rx", self.rx.fileini) self.config.set("files", "mat", self.filematini) self.config.set("files", "slab", self.fileslabini) self.config.set("tud", "purc", str(self.patud.purc)) self.config.set("tud", "nrmax", str(self.patud.nrmax)) self.config.set("tud", "num", str(self.patud.num)) # # frequency section # self.config.set("frequency", "fghzmin", self.fGHz[0]) self.config.set("frequency", "fghzmax", self.fGHz[-1]) self.config.set("frequency", "nf", str(len(self.fGHz))) # # waveform section # self.config.set("waveform", "tw", str(self.wav['twns'])) self.config.set("waveform", "band", str(self.wav['bandGHz'])) self.config.set("waveform", "fc", str(self.wav['fcGHz'])) self.config.set("waveform", "thresh", str(self.wav['threshdB'])) self.config.set("waveform", "type", str(self.wav['typ'])) self.config.set("waveform", "fe", str(self.wav['feGHz'])) # # output section # for k in self.output.keys(): self.config.set("output",str(k),self.dout[k]) # Initialize waveform self.wav = wvf.Waveform() # Update waveform self.wav.read(self.config) self.save() def clean(self, level=1): """ clean Notes ----- obsolete Parameters ---------- level = 1 """ if level > 0: for itx in range(self.tx.N): filename = pyu.getlong(self.filelch[itx], pstruc['DIRLCH']) print filename if level > 1: for itx in range(self.tx.N): for irx in range(self.rx.N): filename = pyu.getlong(self.filetra[itx][irx], pstruc(['DIRTRA'])) print filename if level > 2: for itx in range(self.tx.N): for irx in range(self.rx.N): filename = pyu.getlong(self.filetud[itx][irx], pstruc['DIRTUD']) print filename filename = pyu.getlong(self.filetauk[itx][irx],pstruc['DIRTUD']) print filename if level > 3: for itx in range(self.tx.N): for irx in range(self.rx.N): filename = pyu.getlong(self.filetang[itx][irx], pstruc['DIRTUD']) print filename filename = pyu.getlong(self.filerang[itx][irx], pstruc['DIRTUD']) print filename filename = pyu.getlong(self.filefield[itx][irx], pstruc['DIRTUD']) print filename def clean_project(self,verbose= True): """ Clean Pyrpoject directory remove .lch, .tra, .field .tud, .tauk, .tang, .rang, <pyproject>/output remove [output] entries into .ini of self.filesimul Parameters ---------- verbose : boolean Verbose mode on/off Returns ------- Boolean: True if the project has been cleaned, False otherwise """ if verbose: print "-----------------------------------" print "-----------------------------------" print " WARNING " print "-----------------------------------" print "-----------------------------------" print "You are about to remove ALL previous computed raytracing files." print "If you decide to remove it, you will need to restart the entire \ raytracing simulation to exploit simulation results" print "\n Do you want to remove these simulation files ? y/n" r=raw_input() else : r =='y' if r == 'y': inifile=self.filesimul try: path=os.getenv('BASENAME') except: print('Error : there is no project directory in $BASENAME') dirlist=['output'] extension=['.lch','.field','.tra','.tud','.tang','.rang','.tauk'] rindic=False # remove file for d in dirlist: for ex in extension: files = os.listdir(path +'/' +d ) for f in files: if not os.path.isdir(path+'/'+d+'/'+f) and ex in f: rindic=True if verbose: print f os.remove(path+'/'+d+'/'+f) if rindic: if verbose: print 'removed *' + ex +' from ' +d +'\n' rindic=False # remove output into the self.filesimul ini file simcfg = ConfigParser.ConfigParser() simcfg.read(pyu.getlong(inifile,pstruc['DIRSIMUL'])) simcfg.remove_section('output') f=open(pyu.getlong(inifile,pstruc['DIRSIMUL']),'wb') simcfg.write(f) f.close() self.dout = {} self.dlch = {} self.dtra = {} self.dtud = {} self.dtang = {} self.drang = {} self.dtauk = {} self.dfield = {} self.dcir = {} self.output = {} if verbose: print 'removed [output] entries into ' +inifile +'\n' print 'Project CLEANED' return True else : if verbose: print "clean project process ABORTED" return False def save(self): """ save simulation file Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ filesimul = pyu.getlong(self.filesimul, "ini") fd = open(filesimul, "w") # getting current spa file if any try: self.config.set("files", "tx", self.tx.fileini) except: pass try: self.config.set("files", "rx", self.rx.fileini) except: pass self.config.write(fd) fd.close() # save tx self.tx.save() # save rx self.rx.save() # save slab and mat file # -- # self.slab.save(self.fileslabini) # self.slab.mat.save(self.filematini) # -- # fix bug #189 # slab is a member of S.L not of S anymore # mat is a member of S.L.sl not of S.slab try: self.L.sl.save(self.fileslabini) except: pass try: self.L.sl.mat.save(self.filematini) except: pass # def saveold(self): # """ save simulation file # """ # filesimul = pyu.getlong(self.filesimul, "ini") # fd = open(filesimul, "w") # config = ConfigParser.ConfigParser() # # # # files section # # # #config.add_section("files") # self.config.set("files", "conf", self.fileconf) # self.config.set("files", "struc", self.filestr) # self.config.set("files", "slab", self.fileslab) # self.config.set("files", "mat", self.filemat) # try: # self.config.set("files", "tx", self.tx.filespa) # except: # pass # try: # self.config.set("files", "rx", self.rx.filespa) # except: # pass # try: # self.config.set("files", "txant", self.tx.fileant) # except: # pass # try: # self.config.set("files", "rxant", self.rx.fileant) # except: # pass # self.config.set("files", "patra", self.filepatra) # self.config.set("files", "palch", self.filepalch) # self.palch.save() # self.patra.save() # # # # tud section # # # self.config.set("tud", "purc", self.patud.purc) # self.config.set("tud", "nrmax", self.patud.nrmax) # self.config.set("tud", "num", self.patud.num) # # # # frequency section # # # self.config.set("frequency", "fghzmin", self.freq[0]) # self.config.set("frequency", "fghzmax", self.freq[-1]) # self.config.set("frequency", "Nf", len(self.freq)) # # # # output section # # # #filelch exists # if self.progress > 0: # #config.add_section("output") # for k in range(len(self.filelch)): # _fileout = "out" + "???" # filename = self.filelch[k] # self.config.set("launch", str(k + 1), filename) # # filetra exists # for k in range(len(self.filelch)): # if self.progress > 1: # #self.config.add_section("trace") # for l in arange(len(self.filetra[k])): # filename = self.filetra[k][l] # self.config.set("trace", "rx" + str(l + 1), filename) # # .tang exists # # .rang exists # # .tud exists # if self.progress > 2: # #config.add_section("tud") # #config.add_section("tang") # #config.add_section("rang") # for l in arange(len(self.filetud[k])): # ftud = self.filetud[k][l] # self.config.set("tud", "rx" + str(l + 1), ftud) # for l in arange(len(self.filetang[k])): # ftang = self.filetang[k][l] # self.config.set("tang", "rx" + str(l + 1), ftang) # for l in arange(len(self.filerang[k])): # frang = self.filerang[k][l] # self.config.set("rang", "rx" + str(l + 1), frang) # # .field exist # # .tauk exist # if self.progress > 3: # #config.add_section("tauk") # #config.add_section("field") # for l in arange(len(self.filetud[k])): # ftauk = self.filetud[k][l] # self.config.set("tauk", "rx" + str(l + 1), ftauk) # for l in arange(len(self.filefield[k])): # ffield = self.filefield[k][l] # self.config.set("field", "rx" + str(l + 1), ffield) # self.config.write(fd) # fd.close() def save_project(self): """ save Simulation files in a zipfile Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ root = Tkinter.Tk() zipfileName = tkFileDialog.asksaveasfilename(parent=root, filetypes = [("zipped file","zip")] , title="Save Project", ) pyu.zipd(basename,zipfileName) root.withdraw() print "Current project saved in", zipfileName def load_project(self): """ load Simulation files from a zipfile Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ root = Tkinter.Tk() zipfileName= tkFileDialog.askopenfile(parent=root, mode='rb', title='Choose a project') dirname = tkFileDialog.askdirectory(parent=root, initialdir=basename, title='Please select a directory', mustexist=0) pyu.unzipd(dirname,zipfileName) root.withdraw() print "Current project loaded in", dirname def choose(self): """ Choose a simulation file in simuldir """ import tkFileDialog as FD fichsimul = FD.askopenfilename(filetypes=[("Fichiers simul ", "*.simul"), ("All", "*")], title="Please choose a simulation file", initialdir=simuldir) self.filesimul = pyu.getshort(fichsimul) self.load() def load(self, _filesimul): """ load a simulation configuration file each transmiter simulation results in the creation of an .ini file with the following sections related to the results obtained for different receivers Parameters ---------- _filesimul : file in the simul directory of the Project """ self.filesimul = _filesimul filesimul = pyu.getlong(self.filesimul, "ini") self.config.read(filesimul) sections = self.config.sections() try: _filetx = self.config.get("files", "tx") except: raise NameError('Error in section tx from '+ _filesimul) try: _filerx = self.config.get("files", "rx") except: raise NameError('Error in section rx from '+ _filesimul) try: _fileanttx = self.config.get("files", "txant") except: raise NameError('Error in section txant from '+ _filesimul) try: _fileantrx = self.config.get("files", "rxant") except: raise NameError('Error in section rxant from '+ _filesimul) try: self.tx = RadioNode(name = '', typ = 'tx', _fileini = _filetx, _fileant = _fileanttx, _filestr = self.filestr) self.rx = RadioNode(name = '', typ = 'rx', _fileini = _filerx, _fileant = _fileantrx, _filestr = self.filestr) except: raise NameError('Error during Radionode load') # # Load Layout # try: self.L = Layout(self.filestr) except: raise NameError('Layout load error') # # Frequency base # if "frequency" in sections: try: self.fGHz = np.linspace(float(self.config.getfloat("frequency", "fghzmin")), float(self.config.getfloat("frequency", "fghzmax")), int(self.config.getint("frequency", "nf")), endpoint=True) except: raise NameError('Error in section frequency from '+ _filesimul) # update .freq file in tud directory filefreq = pyu.getlong(self.filefreq, pstruc['DIRTUD']) fd = open(filefreq, "w") chaine = self.config.get("frequency", "fghzmin") + ' ' + \ self.config.get("frequency", "fghzmax") + ' ' + \ self.config.get("frequency", "nf") fd.write(chaine) fd.close # # Simulation Progress # self.output = {} if "output" in sections: for itx in self.config.options("output"): _filename = self.config.get("output", itx) self.dout[int(itx)] = _filename filename = pyu.getlong(_filename, "output") output = ConfigParser.ConfigParser() output.read(filename) secout = output.sections() self.dtra[int(itx)] = {} self.dtud[int(itx)] = {} self.dtang[int(itx)] = {} self.drang[int(itx)] = {} self.dtauk[int(itx)] = {} self.dfield[int(itx)] = {} self.dcir[int(itx)] = {} if "launch" in secout: self.progress = 1 keys_launch = output.options("launch") for kl in keys_launch: self.dlch[int(kl)] = output.get("launch", kl) if "trace" in secout: self.progress = 2 keys_tra = output.options("trace") for kt in keys_tra: self.dtra[int(itx)][int(kt)] = output.get("trace", kt) if "tang" in secout: self.progress = 3 keys_tang = output.options("tang") for kt in keys_tang: self.dtang[int(itx)][int(kt)] = output.get("tang", kt) self.drang[int(itx)][int(kt)] = output.get("rang", kt) self.dtud[int(itx)][int(kt)] = output.get("tud", kt) if "field" in secout: self.progress = 4 keys_field = output.options("field") for kt in keys_field: self.dfield[int(itx)][int(kt)] = output.get( "field", kt) self.dtauk[int(itx)][int(kt)] = output.get("tauk", kt) if "cir" in secout: self.progress = 5 keys_cir = output.options("cir") for kt in keys_cir: self.dcir[int(itx)][int(kt)] = output.get("cir", kt) self.output[int(itx)] = output # # Waveform section # self.wav = wvf.Waveform() self.wav.read(self.config) def layout(self, _filestruc): """ load a layout in the simulation oject Parameters ---------- _filestruc : string short file name of the Layout object Examples -------- >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.layout('defstr.ini') """ self.filestr = _filestruc self.L = Layout(_filestruc) # update config self.config.set("files", "struc", self.filestr) self.save() def show(self, itx=[-1], irx=[-1], furniture=True, s=8, c='b', traj=False, num=False,fig=[],ax=[]): """ show simulation Parameters ----------- itx : list of tx indices irx : list of rx indices furniture : boolean for METALIC furniture display s : scale fir scatter plot (default 8) c : color for scatter plot (default 'b') traj : boolean (def False) num : boolean (def False) display a number Examples -------- >>> import matplotlib.pyplot as plt >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.load('w1.ini') >>> S.L.loadfur('FurW1.ini') >>> S.show() >>> plt.show() """ if type(itx) == int: itx = [itx] if type(irx) == int: irx = [irx] if fig ==[]: fig = plt.gcf() if ax==[]: ax = fig.gca() #self.L.display['scaled']=False fig,ax=self.L.showG('s',fig=fig,ax=ax, aw=True) # if furniture: if 'lfur' in self.L.__dict__: for fur in self.L.lfur: if fur.Matname == 'METAL': fur.show(fig, ax) else: print "Warning : no furniture file loaded" if irx[0] == -1: ax.scatter(self.rx.position[0,:], self.rx.position[1,:], c='b', s=s, alpha=0.5) #ax.scatter(self.rx.position[0,0],self.rx.position[0,1],c='k',s=s,linewidth=0) #ax.scatter(self.rx.position[1,0],self.rx.position[1,1],c='b',s=s,linewidth=0) #ax.scatter(self.rx.position[2,0],self.rx.position[2,1],c='g',s=s,linewidth=0) #ax.scatter(self.rx.position[3,0],self.rx.position[3,1],c='c',s=s,linewidth=0) else: for k in irx: ax.scatter(self.rx.position[0,k - 1], self.rx.position[1,k - 1], c='b', s=s, alpha=0.5) if num: ax.text(self.rx.position[0,k - 1], self.rx.position[1,k - 1], str(k), color='blue') if itx[0] == -1: ax.scatter(self.tx.position[0,:], self.tx.position[1,:], c='r', s=s) else: if traj: cpt = 1 for k in itx: ax.scatter(self.tx.position[0,k - 1], self.tx.position[1,k - 1], c=c, s=s, linewidth=0) if num: if traj: ax.text(self.tx.position[0,k - 1], self.tx.position[1,k - 1], str(cpt), color='black') cpt = cpt + 1 else: ax.text(self.tx.position[0,k - 1], self.tx.position[1,k - 1], str(k), color='black') return (fig,ax) #for k in range(self.tx.N): # ax.text(self.tx.position[0,k],self.tx.position[1,k],str(k+1),color='black') # ax.scatter(self.tx.position[0,:],self.tx.position[0,:], #for k in range(self.rx.N): # ax.text(self.rx.position[0,k],self.rx.position[1,k],str(k),color='black') def PL(self, itx): """ plot Path Loss itx """ td = [] tEa = [] tEo = [] for irx in self.dcir[itx].keys(): d = self.delay(itx, irx) * 0.3 cira, ciro = self.loadcir(itx, irx) td.append(d) tEa.append(Ea) tEo.append(Eo) plt.semilogx(td, 10 * np.log10(tEa), 'xr') plt.semilogx(td, 10 * np.log10(tEo), 'xb') plt.show() return td, tEa, tEo def evalcir(self,cutoff=4,algo='new'): """ Parameters ---------- S tx rx wav cutoff """ crxp =-1 ctxp =-1 tcir = {} tx = self.tx.position Ntx = len(tx[0]) rx = self.rx.position Nrx = len(rx[0]) #for kt in range(1,Ntx-1): #print kt+1 kt=0 tcir[kt] = {} t = np.array([self.tx.position[0,kt],self.tx.position[1,kt],self.tx.position[2,kt]]) for kr in range(Nrx): if (np.mod(kr,10)==0): print kr+1 r = np.array([self.rx.position[0,kr],self.rx.position[1,kr],self.rx.position[2,kr]]) ctx = self.L.pt2cy(t) crx = self.L.pt2cy(r) if (ctx<>ctxp)|(crx<>crxp): Si = signature.Signatures(self.L,ctx,crx) ctxp = ctx crxp = crx Si.run4(cutoff=cutoff,algo=algo) r2d = Si.rays(t,r) #r2d.show(S.L) r3d = r2d.to3D(self.L) r3d.locbas(self.L) r3d.fillinter(self.L) Ct = r3d.eval(self.fGHz) sca = Ct.prop2tran(self.tx.A,self.rx.A) cir = sca.applywavB(self.wav.sfg) tcir[kt][kr] = cir return(tcir) def loadcir(self, itx, irx): """ Parameters ---------- itx : Tx index irx : Rx index Returns ------- cir(itx,irx) """ _filecir = self.dcir[itx][irx] + '.mat' ext = str(itx) if len(ext) == 1: ext = '00' + ext if len(ext) == 2: ext = '0' + ext filecir = pyu.getlong(_filecir, pstruc['DIRCIR']+'/Tx' + ext) D = spio.loadmat(filecir) kxa = 'ta' + str(irx) kya = 'cira' + str(irx) kxo = 'to' + str(irx) kyo = 'ciro' + str(irx) cira = bs.TUsignal(D[kxa], D[kya][:, 0]) ciro = bs.TUsignal(D[kxo], D[kyo][:, 0]) return(cira, ciro) def pltcir(self, itx=1, irx=1, mode='linear', noise=False, color='b',format='a',fig=[],ax=[]): """ plot Channel Impulse Response Parameters ---------- itx : Tx index irx : Rx index mode : str {'linear','dB'} noise : boolean color : string default 'b' >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.load('where2.ini') >>> S.run(1,1) >>> S.pltcir(1,1,mode='linear',noise=False,color='k') """ if fig ==[]: fig = plt.gcf() #if ax==[]: # ax = fig.gca() _filecir = self.dcir[itx][irx] + '.mat' filecir = pyu.getlong(_filecir, pstruc['DIRCIR']+'/Tx' + str('%0.3d' % itx)) D = spio.loadmat(filecir) ax = fig.add_subplot('211') fig,ax=self.show(itx, irx,fig=fig,ax=ax) ax=fig.add_subplot('212') if 'a' in format : kxa = 't' kya = 'cir' ta = D[kxa] Tobs = ta[-1] - ta[0] te = ta[1] - ta[0] if noise: na = bs.Noise(Tobs + te, 1. / te) naf = na.gating(4.493, 0.5) cira = bs.TUsignal(ta, D[kya][:, 0]) if 'o' in format: kxo = 'to' + str(irx) kyo = 'ciro' + str(irx) to = D[kxo] Tobs = to[-1] - to[0] te = to[1] - to[0] if noise: no = bs.Noise(Tobs + te, 1. / te) nof = no.gating(4.493, 0.5) ciro = bs.TUsignal(to, D[kyo][:, 0]) if mode == 'linear': #plt.plot(ta,naf.y,color='k',label='Noise') plt.plot(ta, D[kya], label='Rx ' + str(irx), color=color) plt.xlabel('Time (ns)') '''if noise: naf.plot(col='k') cira.plot(col=color)''' else: '''if noise: naf.plotdB(col='k') cira.plotdB()''' plt.plot(ta, 20 * np.log10(abs(D[kya])), label='Rx ' + str(irx), color=color) plt.xlabel('Time (ns)') # plt.legend() plt.show() #plt.savefig('Tx'+str(itx),format=pdf,dpi=300) def scatter(self, itx, irx, values, cmap=plt.cm.gray, s=30, spl=221, title='', vaxis=((-30, 10, 2, 18)), vmin=0, vmax=1, colbool=False, cblabel='dB'): """ Parameters ---------- itx irx values cmap s spl title vaxis vmin vmax colbool clabel """ fig = plt.gcf() ax = fig.add_subplot(spl) xtx = self.tx.position[itx, 0] ytx = self.tx.position[itx, 1] xrx = self.rx.position[irx, 0] yrx = self.rx.position[irx, 1] self.L.display['title'] = title self.L.showGs(ax) for furk in siradel.siradel_furniture.keys(): fur = siradel.siradel_furniture[furk] if fur.Matname == 'METAL': fur.show(fig, ax) #self.show(furniture=True) plt.axis(vaxis) b1 = ax.scatter(xtx, ytx, s=s, c=values, cmap=cmap, linewidths=0, vmin=vmin, vmax=vmax) ax.scatter(xrx, yrx, s=30, c='b', linewidths=0) if colbool: cb = colorbar(b1) cb.set_label(cblabel, fontsize=14) return(b1) def info(self, itx=[], irx=[]): """ display simulation information Parameters ---------- itx : Tx index irx : Rx index """ print self.filesimul print '------------------------------------------' try: print "Layout Info : \n", self.L.info() except: print "provide a Layout in the simulation : S.L " print ">>> S.layout(filename.str) " print "or " print ">>> S.layout(filename.str2 " print "or " print ">>> S.layout(filename.str,filematini,filematini) " print "default files exists for filematini and fileslabini " return try: print "Tx Info :\n", self.tx.info() except: print "provide a tx in the simulation : S.tx " return try: print "Rx Info :\n", self.rx.info() except: print "provide a rx in the simulation : S.rx " return # print "Tx : ",self.tx.points[itx] print "Rx : ", self.rx.points[itx] print "Delay (ns) :", self.delay(itx, irx) print "Distance (m) :", 0.3 / self.delay(itx, irx) print "" if itx in self.dlch.keys(): print "-----" print "Launching " print "-----" print " ", self.dlch[itx] if irx in self.dtra[itx].keys(): print "-----" print "Tracing " print "-----" print " ", self.dtra[itx][irx] gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) gr.info() if irx in self.dtud[itx].keys(): print "-----" print "Tud parameters " print "-----" print " ", self.dtud[itx][irx] print " ", self.dtang[itx][irx] print " ", self.drang[itx][irx] gt = GrRay3D.GrRayTud() gt.load(self.dtud[itx][irx], self.dtang[itx][irx], self.drang[itx][irx], self.sl) if irx in self.dtauk[itx].keys(): print self.dtauk[itx][irx] print self.dfield[itx][irx] VC = self.VC(itx, irx) if irx in self.dcir[itx].keys(): print self.dcir[itx][irx] def info2(self): for i, j in enumerate(self.__dict__.keys()): print j, ':', self.__dict__.values()[i] def filtray(self, itx, irx, tau0, tau1, col='b'): """ filter rays Parameters ---------- itx : irx : tau0 : tau1 : col : Display ray and nstr """ gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) self.L.display['Thin'] = True self.L.display['Node'] = False self.L.display['NodeNum'] = False self.L.display['EdgeNum'] = False plt.axis('scaled') #self.L.show(fig,ax,nodelist,seglist) self.L.showGs() delays = gr.delay() rayset = np.nonzero((delays >= tau0) & (delays <= tau1))[0] fig = plt.gcf() ax = fig.get_axes()[0] gr.show(ax, rayset, col=col, node=False) plt.title('Tx' + str(itx) + '-Rx' + str(irx) + ' : ' + str( tau0) + ' < tau < ' + str(tau1)) def showray(self, itx, irx, iray=np.array([]), fig=[], ax=[]): """ show layout and rays for a radio link Parameters ---------- itx : tx index irx : rx index iray : list of rays to be displayed ndarray """ #if ax==[]: # fig = plt.figure() # ax = fig.add_subplot('111') gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) if len(iray == 1): ray = gr.ray3d[iray[0]] nstr = ray.nstr[1:-1] uneg = np.nonzero(nstr < 0) upos = np.nonzero((nstr > 0) & (nstr <= self.L.Ne)) uceil = np.nonzero(nstr == self.L.Ne + 1) ufloor = np.nonzero(nstr == self.L.Ne + 2) #seglist = nstr[upos[0]]-1 #nodelist = -nstr[uneg[0]]-1 #seglist2 = S.L.segpt(nodelist) self.L.display['Thin'] = True self.L.display['Node'] = False self.L.display['NodeNum'] = False self.L.display['EdgeNum'] = False #self.L.show(fig,ax) #print ray.nn #print len(ray.nstr) #print ray.nstr #print nodelist #print seglist #print seglist2 #seglist = hstack((seglist,seglist2)) self.L.display['Node'] = False self.L.display['Thin'] = False self.L.display['NodeNum'] = True self.L.display['EdgeNum'] = True plt.axis('scaled') #self.L.show(fig,ax,nodelist,seglist) fig, ax = self.L.showGs(show=False) gr.show(ax, iray, col='b', node=False) if len(iray) == 1: plt.title(str(nstr)) else: plt.title('Tx' + str(itx) + '-Rx' + str(irx) + ' ' + str(min(iray)) + ' ' + str(max(iray))) def show3l(self, itx, irx): """ geomview display of a specific link g = S.show3l(itx,irx) Parameters ---------- itx transmitter index irx receiver index """ filetra = self.dtra[itx][irx] gr = GrRay3D() gr.load(filetra, self.L) gr.show3() return(gr) def _show3(self,rays=[],newfig = False,**kwargs): """ display of the simulation configuration using Mayavi Parameters ---------- rays: Ray3d object : display the rays of the simulation newfig : boolean (default : False) kwargs of Rays.show3() see also -------- pylayers.gis.layout pylayers.antprop.antenna pylayers.antprop.rays """ Atx = self.tx.A Arx = self.rx.A Ttx = self.tx.orientation Trx = self.rx.orientation ptx = self.tx.position prx = self.rx.position self.L._show3(newfig=False,opacity=0.7) Atx._show3(T=Ttx.reshape(3,3),po=ptx, title=False,colorbar=False,newfig=False) Arx._show3(T=Trx.reshape(3,3),po=prx, title=False,colorbar=False,newfig=False) if rays != []: rays._show3(**kwargs) def show3(self,rays=[],**kwargs): """ geomview display of the simulation configuration Parameters ---------- centered : boolean center the scene if True bdis : boolean display local basis """ try: self.tx.save() except: print('tx set is no defined') try: self.rx.save() except: print('rx set is no defined') _filename = self.filesimul.replace('.ini', '.off') filename = pyu.getlong(_filename, pstruc['DIRGEOM']) fo = open(filename, "w") fo.write("LIST\n") try: sttx = "{<" + self.tx.filegeom + "}\n" except: sttx = "\n" try: strx = "{<" + self.rx.filegeom + "}\n" except: strx = "\n" try: stst = "{<" + self.L.filegeom + "}\n" except: stst = "\n" fo.write(sttx) fo.write(strx) fo.write(stst) fo.write("{</usr/share/geomview/geom/xyz.vect}\n") if rays !=[]: kwargs['bdis']=False kwargs['L']=self.L kwargs['centered']=False fo.write("{<" + rays.show3(**kwargs) + "}") fo.close() command = "geomview -nopanel -b 1 1 1 " + filename + " 2>/dev/null &" os.system(command) def run(self, link, cirforce=True,verbose=False,cutoff=4): """ run the simulation for 1 tx and a set of rx Parameters ---------- itx : tx index srx : list of rx index cirforce : boolean Warnings -------- index point start with 1 Example ------- >>> from pylayers.simul.simulem import * >>> itx = 1 >>> srx = [1,2,3] >>> S = Simul() >>> S.load('where2.ini') >>> out = S.run(itx,srx) """ # get file prefix link = DLink(force=True,L=self.L,fGHz=self.fGHz, verbose=False) prefix = self.filesimul.replace('.ini', '') lsig = [] for k,il in enumerate(link): tx = self.tx.points[il[0]] rx = self.rx.points[il[1]] ctx = S.L.pt2cy(tx) crx = S.L.pt2cy(rx) _filecir = prefix +'-cir-'+str(k)+'-'+str(link)+'-'+str((ctx,crx)) D = {} D['Tx'] = tx D['Rx'] = rx link.a = tx link.b = rx ak,tauk = link.eval(verbose=False,diffrction=True) if (ctx,crx) not in lsig: Si = signature.Signatures(S.L,ctx,crx) # # Change the run number depending on # the algorithm used for signature determination # Si.run4(cutoff=cutoff) # keep track and save signature _filesir = prefix + '-sig-'+str((ctx,crx)) fd = open(filesig,'w') pickle.dump(Si,filesig) fd.close() lsig.appeng((ctx,crx)) Si.dump(S.L,(ctx,crx)) r2d = Si.rays(tx,rx) r2d.show(S.L) r3d = r2d.to3D() r3d.locbas(S.L) r3d.fillinter(S.L) Ct = r3d.eval(S.freq) sco = Ct.prop2tran(a='theta',b='phi') sca = Ct.prop2tran(a=S.tx.A,b=S.rx.A) ciro = sco.applywavB(self.wav.sfg) cira = sca.applywavB(self.wav.sfg) D['to'] = ciro.x D['ciro'] = ciro.y D['t'] = cira.x D['cir'] = cira.y filename = pyu.getlong(_filename, cirdir) spio.savemat(filename, D) def delay(self, itx, irx): """ calculate LOS link delay Parameters ---------- itx irx Returns ------- delay : float delay in ns """ tx = self.tx.points[itx] rx = self.rx.points[irx] df = tx - rx dist = np.sqrt(np.dot(df, df)) return(dist / 0.3)
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()
from pylayers.gis.layout import Layout import matplotlib.pyplot as plt import doctest #doctest.testmod(layout) L = Layout() L.load('TA-Office.str') #L.editor() fig = plt.gcf() #ax1 = fig.add_subplot(221) ax1 = fig.add_subplot(111) L.display['thin']=True fig,ax1 = L.showGs(fig=fig,ax=ax1) L.display['thin']=False L.display['edlabel']=True L.display['edlblsize']=50 fig,ax1 = L.showGs(fig=fig,ax=ax1,edlist=[10,7,54],width=4) plt.show() #plt.savefig('graphGs.png') # build topological graph #L.buildGt() #ax2 = fig.add_subplot(222) #L.showG(fig=fig,ax=ax2,graph='t') #plt.title('Topological graph') #plt.savefig('graphGt.png') # build graph of rooms #L.buildGr() #ax3 = fig.add_subplot(223) #L.showG(fig=fig,ax=ax3,graph='r')
class Simul(PyLayers): """ Simulation Class Methods ------- gui() graphical user interface choose() choose a simulation file in simuldir info() info about the simulation showray(itx,irx,iray) show a single ray help() help on using Simulation object freq() return the frequency base save() save Simulation file layout load a Layout file load() load Simulation show3() geomview vizualization show3l(itx,irx) geomview vizualization of link itx irx show() 2D visualization of simulation with furniture run(itx,irx) run simulation for links (itx,irx) cir(itx,irx,store_level=0,alpha=1.0) Channel Impulse Response calculation Attributes ---------- fileconf filetauk filetang filerang tx rx progress indoor mat sl Notes ------ This class group together all the parametrization files of a simulation """ def __init__(self, _filesimul='default.ini'): self.filesimul = _filesimul self.config = ConfigParser.ConfigParser() self.config.add_section("files") self.config.add_section("frequency") self.config.add_section("waveform") self.config.add_section("output") self.dtang = {} self.drang = {} self.dtauk = {} self.dfield = {} self.dcir = {} self.output = {} # # Here was a nasty bug : Rule for the future # "Always precise the key value of the passed argument" # # Mal nommer les choses, c'est ajouter au malheur du monde ( Albert Camus ) # self.tx = RadioNode( name='', typ='tx', _fileini='radiotx.ini', _fileant='defant.vsh3', ) self.rx = RadioNode( name='', typ='rx', _fileini='radiorx.ini', _fileant='defant.vsh3', ) self.filefreq = "def.freq" self.progress = -1 # simulation not loaded self.filetang = [] self.filerang = [] self.filetauk = [] self.filefield = [] self.fileconf = "project.conf" self.cfield = [] self.fGHz = np.linspace(2, 11, 181, endpoint=True) self.wav = wvf.Waveform() self.load(_filesimul) def gui(self): """ gui to modify the simulation file """ simulgui = multenterbox( '', 'Simulation file', ('filesimul', 'filestr', 'filefreq', 'filespaTx', 'filespaRx', 'fileantTx' 'fileantRx'), (self.filesimul, self.filestr, self.filefreq, self.filespaTx, self.filespaRx, self.fileantTx, self.fileantRx)) if simulgui is not None: self.filesimul = simulgui[0] self.filestr = simulgui[1] self.filefreq = simulgui[6] self.filespaTx = simulgui[7] self.filespaRx = simulgui[8] self.fileantTx = simulgui[9] self.fileantRx = simulgui[10] def updcfg(self): """ update simulation .ini config file with values currently in use. """ self.config.set("files", "struc", self.filestr) self.config.set("files", "conf", self.fileconf) self.config.set("files", "txant", self.tx.fileant) self.config.set("files", "rxant", self.rx.fileant) self.config.set("files", "tx", self.tx.fileini) self.config.set("files", "rx", self.rx.fileini) self.config.set("files", "mat", self.filematini) self.config.set("files", "slab", self.fileslabini) self.config.set("tud", "purc", str(self.patud.purc)) self.config.set("tud", "nrmax", str(self.patud.nrmax)) self.config.set("tud", "num", str(self.patud.num)) # # frequency section # self.config.set("frequency", "fghzmin", self.fGHz[0]) self.config.set("frequency", "fghzmax", self.fGHz[-1]) self.config.set("frequency", "nf", str(len(self.fGHz))) # # waveform section # self.config.set("waveform", "tw", str(self.wav['twns'])) self.config.set("waveform", "band", str(self.wav['bandGHz'])) self.config.set("waveform", "fc", str(self.wav['fcGHz'])) self.config.set("waveform", "thresh", str(self.wav['threshdB'])) self.config.set("waveform", "type", str(self.wav['typ'])) self.config.set("waveform", "fe", str(self.wav['feGHz'])) # # output section # for k in self.output.keys(): self.config.set("output", str(k), self.dout[k]) # Initialize waveform self.wav = wvf.Waveform() # Update waveform self.wav.read(self.config) self.save() def clean_project(self, verbose=True): """ Clean Pyrpoject directory remove .lch, .tra, .field .tud, .tauk, .tang, .rang, <pyproject>/output remove [output] entries into .ini of self.filesimul Parameters ---------- verbose : boolean Verbose mode on/off Returns ------- Boolean: True if the project has been cleaned, False otherwise """ if verbose: print "-----------------------------------" print "-----------------------------------" print " WARNING " print "-----------------------------------" print "-----------------------------------" print "You are about to remove ALL previous computed raytracing files." print "If you decide to remove it, you will need to restart the entire \ raytracing simulation to exploit simulation results" print "\n Do you want to remove these simulation files ? y/n" r = raw_input() else: r == 'y' if r == 'y': inifile = self.filesimul try: path = os.getenv('BASENAME') except: print('Error : there is no project directory in $BASENAME') dirlist = ['output'] extension = [ '.lch', '.field', '.tra', '.tud', '.tang', '.rang', '.tauk' ] rindic = False # remove file for d in dirlist: for ex in extension: files = os.listdir(path + '/' + d) for f in files: if not os.path.isdir(path + '/' + d + '/' + f) and ex in f: rindic = True if verbose: print f os.remove(path + '/' + d + '/' + f) if rindic: if verbose: print 'removed *' + ex + ' from ' + d + '\n' rindic = False # remove output into the self.filesimul ini file simcfg = ConfigParser.ConfigParser() simcfg.read(pyu.getlong(inifile, pstruc['DIRSIMUL'])) simcfg.remove_section('output') f = open(pyu.getlong(inifile, pstruc['DIRSIMUL']), 'wb') simcfg.write(f) f.close() self.dout = {} self.dlch = {} self.dtra = {} self.dtud = {} self.dtang = {} self.drang = {} self.dtauk = {} self.dfield = {} self.dcir = {} self.output = {} if verbose: print 'removed [output] entries into ' + inifile + '\n' print 'Project CLEANED' return True else: if verbose: print "clean project process ABORTED" return False def save(self): """ save simulation file Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ filesimul = pyu.getlong(self.filesimul, "ini") fd = open(filesimul, "w") # getting current spa file if any try: self.config.set("files", "tx", self.tx.fileini) except: pass try: self.config.set("files", "rx", self.rx.fileini) except: pass self.config.write(fd) fd.close() # save tx self.tx.save() # save rx self.rx.save() # save slab and mat file # -- # self.slab.save(self.fileslabini) # self.slab.mat.save(self.filematini) # -- # fix bug #189 # slab is a member of S.L not of S anymore # mat is a member of S.L.sl not of S.slab try: self.L.sl.save(self.fileslabini) except: pass try: self.L.sl.mat.save(self.filematini) except: pass # def saveold(self): # """ save simulation file # """ # filesimul = pyu.getlong(self.filesimul, "ini") # fd = open(filesimul, "w") # config = ConfigParser.ConfigParser() # # # # files section # # # #config.add_section("files") # self.config.set("files", "conf", self.fileconf) # self.config.set("files", "struc", self.filestr) # self.config.set("files", "slab", self.fileslab) # self.config.set("files", "mat", self.filemat) # try: # self.config.set("files", "tx", self.tx.filespa) # except: # pass # try: # self.config.set("files", "rx", self.rx.filespa) # except: # pass # try: # self.config.set("files", "txant", self.tx.fileant) # except: # pass # try: # self.config.set("files", "rxant", self.rx.fileant) # except: # pass # self.config.set("files", "patra", self.filepatra) # self.config.set("files", "palch", self.filepalch) # self.palch.save() # self.patra.save() # # # # tud section # # # self.config.set("tud", "purc", self.patud.purc) # self.config.set("tud", "nrmax", self.patud.nrmax) # self.config.set("tud", "num", self.patud.num) # # # # frequency section # # # self.config.set("frequency", "fghzmin", self.freq[0]) # self.config.set("frequency", "fghzmax", self.freq[-1]) # self.config.set("frequency", "Nf", len(self.freq)) # # # # output section # # # #filelch exists # if self.progress > 0: # #config.add_section("output") # for k in range(len(self.filelch)): # _fileout = "out" + "???" # filename = self.filelch[k] # self.config.set("launch", str(k + 1), filename) # # filetra exists # for k in range(len(self.filelch)): # if self.progress > 1: # #self.config.add_section("trace") # for l in arange(len(self.filetra[k])): # filename = self.filetra[k][l] # self.config.set("trace", "rx" + str(l + 1), filename) # # .tang exists # # .rang exists # # .tud exists # if self.progress > 2: # #config.add_section("tud") # #config.add_section("tang") # #config.add_section("rang") # for l in arange(len(self.filetud[k])): # ftud = self.filetud[k][l] # self.config.set("tud", "rx" + str(l + 1), ftud) # for l in arange(len(self.filetang[k])): # ftang = self.filetang[k][l] # self.config.set("tang", "rx" + str(l + 1), ftang) # for l in arange(len(self.filerang[k])): # frang = self.filerang[k][l] # self.config.set("rang", "rx" + str(l + 1), frang) # # .field exist # # .tauk exist # if self.progress > 3: # #config.add_section("tauk") # #config.add_section("field") # for l in arange(len(self.filetud[k])): # ftauk = self.filetud[k][l] # self.config.set("tauk", "rx" + str(l + 1), ftauk) # for l in arange(len(self.filefield[k])): # ffield = self.filefield[k][l] # self.config.set("field", "rx" + str(l + 1), ffield) # self.config.write(fd) # fd.close() def save_project(self): """ save Simulation files in a zipfile Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ root = Tkinter.Tk() zipfileName = tkFileDialog.asksaveasfilename( parent=root, filetypes=[("zipped file", "zip")], title="Save Project", ) pyu.zipd(basename, zipfileName) root.withdraw() print "Current project saved in", zipfileName def load_project(self): """ load Simulation files from a zipfile Simulation files are .ini files which are saved in a dedicated directory basename/ini in the Project tree """ root = Tkinter.Tk() zipfileName = tkFileDialog.askopenfile(parent=root, mode='rb', title='Choose a project') dirname = tkFileDialog.askdirectory(parent=root, initialdir=basename, title='Please select a directory', mustexist=0) pyu.unzipd(dirname, zipfileName) root.withdraw() print "Current project loaded in", dirname def choose(self): """ Choose a simulation file in simuldir """ import tkFileDialog as FD fichsimul = FD.askopenfilename(filetypes=[("Fichiers simul ", "*.simul"), ("All", "*")], title="Please choose a simulation file", initialdir=simuldir) self.filesimul = pyu.getshort(fichsimul) self.load() def load(self, _filesimul): """ load a simulation configuration file each transmiter simulation results in the creation of an .ini file with the following sections related to the results obtained for different receivers Parameters ---------- _filesimul : file in the simul directory of the Project """ self.filesimul = _filesimul filesimul = pyu.getlong(self.filesimul, "ini") self.config.read(filesimul) sections = self.config.sections() try: _filetx = self.config.get("files", "tx") except: raise NameError('Error in section tx from ' + _filesimul) try: _filerx = self.config.get("files", "rx") except: raise NameError('Error in section rx from ' + _filesimul) try: _fileini = self.config.get("files", "struc") except: raise NameError('Error in section struc from ' + _fileini) try: _fileanttx = self.config.get("files", "txant") except: raise NameError('Error in section txant from ' + _filesimul) try: _fileantrx = self.config.get("files", "rxant") except: raise NameError('Error in section rxant from ' + _filesimul) try: self.tx = RadioNode(name='', typ='tx', _fileini=_filetx, _fileant=_fileanttx) self.rx = RadioNode(name='', typ='rx', _fileini=_filerx, _fileant=_fileantrx) except: raise NameError('Error during Radionode load') # # Load Layout # try: self.L = Layout(_fileini) except: raise NameError('Layout load error') # # Frequency base # if "frequency" in sections: try: self.fGHz = np.linspace( float(self.config.getfloat("frequency", "fghzmin")), float(self.config.getfloat("frequency", "fghzmax")), int(self.config.getint("frequency", "nf")), endpoint=True) except: raise NameError('Error in section frequency from ' + _filesimul) # update .freq file in tud directory filefreq = pyu.getlong(self.filefreq, pstruc['DIRTUD']) fd = open(filefreq, "w") chaine = self.config.get("frequency", "fghzmin") + ' ' + \ self.config.get("frequency", "fghzmax") + ' ' + \ self.config.get("frequency", "nf") fd.write(chaine) fd.close # # Simulation Progress # # self.output = {} # if "output" in sections: # for itx in self.config.options("output"): # _filename = self.config.get("output", itx) # self.dout[int(itx)] = _filename # filename = pyu.getlong(_filename, "output") # output = ConfigParser.ConfigParser() # output.read(filename) # secout = output.sections() # self.dtra[int(itx)] = {} # self.dtud[int(itx)] = {} # self.dtang[int(itx)] = {} # self.drang[int(itx)] = {} # self.dtauk[int(itx)] = {} # self.dfield[int(itx)] = {} # self.dcir[int(itx)] = {} # if "launch" in secout: # self.progress = 1 # keys_launch = output.options("launch") # for kl in keys_launch: # self.dlch[int(kl)] = output.get("launch", kl) # if "trace" in secout: # self.progress = 2 # keys_tra = output.options("trace") # for kt in keys_tra: # self.dtra[int(itx)][int(kt)] = output.get("trace", kt) # # if "tang" in secout: # self.progress = 3 # keys_tang = output.options("tang") # for kt in keys_tang: # self.dtang[int(itx)][int(kt)] = output.get("tang", kt) # self.drang[int(itx)][int(kt)] = output.get("rang", kt) # self.dtud[int(itx)][int(kt)] = output.get("tud", kt) # if "field" in secout: # self.progress = 4 # keys_field = output.options("field") # for kt in keys_field: # self.dfield[int(itx)][int(kt)] = output.get( # "field", kt) # self.dtauk[int(itx)][int(kt)] = output.get("tauk", kt) # if "cir" in secout: # self.progress = 5 # keys_cir = output.options("cir") # for kt in keys_cir: # self.dcir[int(itx)][int(kt)] = output.get("cir", kt) # # self.output[int(itx)] = output # # Waveform section # self.wav = wvf.Waveform() self.wav.read(self.config) def layout(self, _filestruc): """ load a layout in the simulation oject Parameters ---------- _filestruc : string short file name of the Layout object Examples -------- >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.layout('defstr.ini') """ self.filestr = _filestruc self.L = Layout(_filestruc) # update config self.config.set("files", "struc", self.filestr) self.save() #def show(self, itx=[-1], irx=[-1], furniture=True, s=8, c='b', traj=False, num=False,fig=[],ax=[]): def show(self, **kwargs): """ show simulation Parameters ----------- itx : list of tx indices irx : list of rx indices furniture : boolean for METALIC furniture display s : scale fir scatter plot (default 8) c : color for scatter plot (default 'b') traj : boolean (def False) num : boolean (def False) display a number Examples -------- >>> import matplotlib.pyplot as plt >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.load('w1.ini') >>> S.L.loadfur('FurW1.ini') >>> S.show() >>> plt.show() """ defaults = { 'itx': [-1], 'irx': [-1], 'furniture': True, 's': 8, 'c': 'b', 'num': False, 'fig': [], 'ax': [], 'aw': False } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] st = k + "=kwargs['" + k + "']" exec(st) if type(itx) == int: itx = [itx] if type(irx) == int: irx = [irx] if fig == []: fig = plt.gcf() if ax == []: ax = fig.gca() #self.L.display['scaled']=False fig, ax = self.L.showG('s', fig=fig, ax=ax, aw=aw) # if furniture: if 'lfur' in self.L.__dict__: for fur in self.L.lfur: if fur.Matname == 'METAL': fur.show(fig, ax) else: print "Warning : no furniture file loaded" if irx[0] == -1: ax.scatter(self.rx.position[0, :], self.rx.position[1, :], c='b', s=s, alpha=0.5) #ax.scatter(self.rx.position[0,0],self.rx.position[0,1],c='k',s=s,linewidth=0) #ax.scatter(self.rx.position[1,0],self.rx.position[1,1],c='b',s=s,linewidth=0) #ax.scatter(self.rx.position[2,0],self.rx.position[2,1],c='g',s=s,linewidth=0) #ax.scatter(self.rx.position[3,0],self.rx.position[3,1],c='c',s=s,linewidth=0) else: for k in irx: ax.scatter(self.rx.position[0, k - 1], self.rx.position[1, k - 1], c='b', s=s, alpha=0.5) if num: ax.text(self.rx.position[0, k - 1], self.rx.position[1, k - 1], str(k), color='blue') if itx[0] == -1: ax.scatter(self.tx.position[0, :], self.tx.position[1, :], c='r', s=s) else: if traj: cpt = 1 for k in itx: ax.scatter(self.tx.position[0, k - 1], self.tx.position[1, k - 1], c=c, s=s, linewidth=0) if num: if traj: ax.text(self.tx.position[0, k - 1], self.tx.position[1, k - 1], str(cpt), color='black') cpt = cpt + 1 else: ax.text(self.tx.position[0, k - 1], self.tx.position[1, k - 1], str(k), color='black') return (fig, ax) #for k in range(self.tx.N): # ax.text(self.tx.position[0,k],self.tx.position[1,k],str(k+1),color='black') # ax.scatter(self.tx.position[0,:],self.tx.position[0,:], #for k in range(self.rx.N): # ax.text(self.rx.position[0,k],self.rx.position[1,k],str(k),color='black') def PL(self, itx): """ plot Path Loss itx """ td = [] tEa = [] tEo = [] for irx in self.dcir[itx].keys(): d = self.delay(itx, irx) * 0.3 cira, ciro = self.loadcir(itx, irx) td.append(d) tEa.append(Ea) tEo.append(Eo) plt.semilogx(td, 10 * np.log10(tEa), 'xr') plt.semilogx(td, 10 * np.log10(tEo), 'xb') plt.show() return td, tEa, tEo def eval(self, **kwrgs): """ """ for kt in range(Nb_tx): tx = np.array([ self.tx.position[0, kt + 1], self.tx.position[1, kt + 1], self.tx.position[2, kt + 1] ]) link.a = tx for kr in range(Nb_Run): rx = np.array([ S.rx.position[0, Run], S.rx.position[1, Run], S.rx.position[2, Run] ]) link.b = rx tic = time.clock() ak, tk = link.eval(verbose=False, diffraction=True) toc = time.clock() ciro = link.H.applywav(wav.sfg) cir = bs.TUsignal(ciro.x, np.squeeze(np.sum(ciro.y, axis=0))) tac = time.clock() tcir[Run] = cir print toc - tic, tac - toc def evalcir(self, cutoff=4, algo='new'): """ Parameters ---------- S tx rx wav cutoff """ crxp = -1 ctxp = -1 tcir = {} tx = self.tx.position Ntx = len(tx[0]) rx = self.rx.position Nrx = len(rx[0]) #for kt in range(1,Ntx-1): #print kt+1 kt = 0 tcir[kt] = {} t = np.array([ self.tx.position[0, kt], self.tx.position[1, kt], self.tx.position[2, kt] ]) for kr in range(Nrx): if (np.mod(kr, 10) == 0): print kr + 1 r = np.array([ self.rx.position[0, kr], self.rx.position[1, kr], self.rx.position[2, kr] ]) ctx = self.L.pt2cy(t) crx = self.L.pt2cy(r) if (ctx <> ctxp) | (crx <> crxp): Si = signature.Signatures(self.L, ctx, crx) ctxp = ctx crxp = crx Si.run4(cutoff=cutoff, algo=algo) r2d = Si.rays(t, r) #r2d.show(S.L) r3d = r2d.to3D(self.L) r3d.locbas(self.L) r3d.fillinter(self.L) Ct = r3d.eval(self.fGHz) sca = Ct.prop2tran(self.tx.A, self.rx.A) cir = sca.applywavB(self.wav.sfg) tcir[kt][kr] = cir return (tcir) def loadcir(self, itx, irx): """ Parameters ---------- itx : Tx index irx : Rx index Returns ------- cir(itx,irx) """ _filecir = self.dcir[itx][irx] + '.mat' ext = str(itx) if len(ext) == 1: ext = '00' + ext if len(ext) == 2: ext = '0' + ext filecir = pyu.getlong(_filecir, pstruc['DIRCIR'] + '/Tx' + ext) D = spio.loadmat(filecir) kxa = 'ta' + str(irx) kya = 'cira' + str(irx) kxo = 'to' + str(irx) kyo = 'ciro' + str(irx) cira = bs.TUsignal(D[kxa], D[kya][:, 0]) ciro = bs.TUsignal(D[kxo], D[kyo][:, 0]) return (cira, ciro) def pltcir(self, itx=1, irx=1, mode='linear', noise=False, color='b', format='a', fig=[], ax=[]): """ plot Channel Impulse Response Parameters ---------- itx : Tx index irx : Rx index mode : str {'linear','dB'} noise : boolean color : string default 'b' >>> from pylayers.simul.simulem import * >>> S = Simul() >>> S.load('where2.ini') >>> S.run(1,1) >>> S.pltcir(1,1,mode='linear',noise=False,color='k') """ if fig == []: fig = plt.gcf() #if ax==[]: # ax = fig.gca() _filecir = self.dcir[itx][irx] + '.mat' filecir = pyu.getlong(_filecir, pstruc['DIRCIR'] + '/Tx' + str('%0.3d' % itx)) D = spio.loadmat(filecir) ax = fig.add_subplot('211') fig, ax = self.show(itx, irx, fig=fig, ax=ax) ax = fig.add_subplot('212') if 'a' in format: kxa = 't' kya = 'cir' ta = D[kxa] Tobs = ta[-1] - ta[0] te = ta[1] - ta[0] if noise: na = bs.Noise(Tobs + te, 1. / te) naf = na.gating(4.493, 0.5) cira = bs.TUsignal(ta, D[kya][:, 0]) if 'o' in format: kxo = 'to' + str(irx) kyo = 'ciro' + str(irx) to = D[kxo] Tobs = to[-1] - to[0] te = to[1] - to[0] if noise: no = bs.Noise(Tobs + te, 1. / te) nof = no.gating(4.493, 0.5) ciro = bs.TUsignal(to, D[kyo][:, 0]) if mode == 'linear': #plt.plot(ta,naf.y,color='k',label='Noise') plt.plot(ta, D[kya], label='Rx ' + str(irx), color=color) plt.xlabel('Time (ns)') '''if noise: naf.plot(col='k') cira.plot(col=color)''' else: '''if noise: naf.plotdB(col='k') cira.plotdB()''' plt.plot(ta, 20 * np.log10(abs(D[kya])), label='Rx ' + str(irx), color=color) plt.xlabel('Time (ns)') # plt.legend() plt.show() #plt.savefig('Tx'+str(itx),format=pdf,dpi=300) def scatter(self, itx, irx, values, cmap=plt.cm.gray, s=30, spl=221, title='', vaxis=((-30, 10, 2, 18)), vmin=0, vmax=1, colbool=False, cblabel='dB'): """ Parameters ---------- itx irx values cmap s spl title vaxis vmin vmax colbool clabel """ fig = plt.gcf() ax = fig.add_subplot(spl) xtx = self.tx.position[itx, 0] ytx = self.tx.position[itx, 1] xrx = self.rx.position[irx, 0] yrx = self.rx.position[irx, 1] self.L.display['title'] = title self.L.showGs(ax) for furk in siradel.siradel_furniture.keys(): fur = siradel.siradel_furniture[furk] if fur.Matname == 'METAL': fur.show(fig, ax) #self.show(furniture=True) plt.axis(vaxis) b1 = ax.scatter(xtx, ytx, s=s, c=values, cmap=cmap, linewidths=0, vmin=vmin, vmax=vmax) ax.scatter(xrx, yrx, s=30, c='b', linewidths=0) if colbool: cb = colorbar(b1) cb.set_label(cblabel, fontsize=14) return (b1) def info(self, itx=[], irx=[]): """ display simulation information Parameters ---------- itx : Tx index irx : Rx index """ print self.filesimul print '------------------------------------------' try: print "Layout Info : \n", self.L.info() except: print "provide a Layout in the simulation : S.L " print ">>> S.layout(filename.str) " print "or " print ">>> S.layout(filename.str2 " print "or " print ">>> S.layout(filename.str,filematini,filematini) " print "default files exists for filematini and fileslabini " return try: print "Tx Info :\n", self.tx.info() except: print "provide a tx in the simulation : S.tx " return try: print "Rx Info :\n", self.rx.info() except: print "provide a rx in the simulation : S.rx " return # print "Tx : ",self.tx.points[itx] print "Rx : ", self.rx.points[itx] print "Delay (ns) :", self.delay(itx, irx) print "Distance (m) :", 0.3 / self.delay(itx, irx) print "" if itx in self.dlch.keys(): print "-----" print "Launching " print "-----" print " ", self.dlch[itx] if irx in self.dtra[itx].keys(): print "-----" print "Tracing " print "-----" print " ", self.dtra[itx][irx] gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) gr.info() if irx in self.dtud[itx].keys(): print "-----" print "Tud parameters " print "-----" print " ", self.dtud[itx][irx] print " ", self.dtang[itx][irx] print " ", self.drang[itx][irx] gt = GrRay3D.GrRayTud() gt.load(self.dtud[itx][irx], self.dtang[itx][irx], self.drang[itx][irx], self.sl) if irx in self.dtauk[itx].keys(): print self.dtauk[itx][irx] print self.dfield[itx][irx] VC = self.VC(itx, irx) if irx in self.dcir[itx].keys(): print self.dcir[itx][irx] def info2(self): for i, j in enumerate(self.__dict__.keys()): print j, ':', self.__dict__.values()[i] def filtray(self, itx, irx, tau0, tau1, col='b'): """ filter rays Parameters ---------- itx : irx : tau0 : tau1 : col : Display ray and nstr """ gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) self.L.display['Thin'] = True self.L.display['Node'] = False self.L.display['NodeNum'] = False self.L.display['EdgeNum'] = False plt.axis('scaled') #self.L.show(fig,ax,nodelist,seglist) self.L.showGs() delays = gr.delay() rayset = np.nonzero((delays >= tau0) & (delays <= tau1))[0] fig = plt.gcf() ax = fig.get_axes()[0] gr.show(ax, rayset, col=col, node=False) plt.title('Tx' + str(itx) + '-Rx' + str(irx) + ' : ' + str(tau0) + ' < tau < ' + str(tau1)) def showray(self, itx, irx, iray=np.array([]), fig=[], ax=[]): """ show layout and rays for a radio link Parameters ---------- itx : tx index irx : rx index iray : list of rays to be displayed ndarray """ #if ax==[]: # fig = plt.figure() # ax = fig.add_subplot('111') gr = GrRay3D() gr.load(self.dtra[itx][irx], self.L) if len(iray == 1): ray = gr.ray3d[iray[0]] nstr = ray.nstr[1:-1] uneg = np.nonzero(nstr < 0) upos = np.nonzero((nstr > 0) & (nstr <= self.L.Ne)) uceil = np.nonzero(nstr == self.L.Ne + 1) ufloor = np.nonzero(nstr == self.L.Ne + 2) #seglist = nstr[upos[0]]-1 #nodelist = -nstr[uneg[0]]-1 #seglist2 = S.L.segpt(nodelist) self.L.display['Thin'] = True self.L.display['Node'] = False self.L.display['NodeNum'] = False self.L.display['EdgeNum'] = False #self.L.show(fig,ax) #print ray.nn #print len(ray.nstr) #print ray.nstr #print nodelist #print seglist #print seglist2 #seglist = hstack((seglist,seglist2)) self.L.display['Node'] = False self.L.display['Thin'] = False self.L.display['NodeNum'] = True self.L.display['EdgeNum'] = True plt.axis('scaled') #self.L.show(fig,ax,nodelist,seglist) fig, ax = self.L.showGs(show=False) gr.show(ax, iray, col='b', node=False) if len(iray) == 1: plt.title(str(nstr)) else: plt.title('Tx' + str(itx) + '-Rx' + str(irx) + ' ' + str(min(iray)) + ' ' + str(max(iray))) def show3l(self, itx, irx): """ geomview display of a specific link g = S.show3l(itx,irx) Parameters ---------- itx transmitter index irx receiver index """ filetra = self.dtra[itx][irx] gr = GrRay3D() gr.load(filetra, self.L) gr.show3() return (gr) def _show3(self, rays=[], newfig=False, **kwargs): """ display of the simulation configuration using Mayavi Parameters ---------- rays: Ray3d object : display the rays of the simulation newfig : boolean (default : False) kwargs of Rays.show3() see also -------- pylayers.gis.layout pylayers.antprop.antenna pylayers.antprop.rays """ Atx = self.tx.A Arx = self.rx.A Ttx = self.tx.orientation Trx = self.rx.orientation ptx = self.tx.position prx = self.rx.position self.L._show3(newfig=False, opacity=0.7) Atx._show3(T=Ttx.reshape(3, 3), po=ptx, title=False, colorbar=False, newfig=False) Arx._show3(T=Trx.reshape(3, 3), po=prx, title=False, colorbar=False, newfig=False) if rays != []: rays._show3(**kwargs) def show3(self, rays=[], **kwargs): """ geomview display of the simulation configuration Parameters ---------- centered : boolean center the scene if True bdis : boolean display local basis """ try: self.tx.save() except: print('tx set is no defined') try: self.rx.save() except: print('rx set is no defined') _filename = self.filesimul.replace('.ini', '.off') filename = pyu.getlong(_filename, pstruc['DIRGEOM']) fo = open(filename, "w") fo.write("LIST\n") try: sttx = "{<" + self.tx.filegeom + "}\n" except: sttx = "\n" try: strx = "{<" + self.rx.filegeom + "}\n" except: strx = "\n" try: stst = "{<" + self.L.filegeom + "}\n" except: stst = "\n" fo.write(sttx) fo.write(strx) fo.write(stst) fo.write("{</usr/share/geomview/geom/xyz.vect}\n") if rays != []: kwargs['bdis'] = False kwargs['L'] = self.L kwargs['centered'] = False fo.write("{<" + rays.show3(**kwargs) + "}") fo.close() command = "geomview -nopanel -b 1 1 1 " + filename + " 2>/dev/null &" os.system(command) def run(self, link, cirforce=True, verbose=False, cutoff=4): """ run the simulation for 1 tx and a set of rx Parameters ---------- itx : tx index srx : list of rx index cirforce : boolean Warnings -------- index point start with 1 Example ------- >>> from pylayers.simul.simulem import * >>> itx = 1 >>> srx = [1,2,3] >>> S = Simul() >>> S.load('where2.ini') >>> out = S.run(itx,srx) """ # get file prefix dl = DLink(force=True, L=self.L, fGHz=self.fGHz, verbose=False) prefix = self.filesimul.replace('.ini', '') lsig = [] self.chan = {} for k, il in enumerate(link): tx = self.tx.points[il[0]] rx = self.rx.points[il[1]] ctx = self.L.pt2cy(tx) crx = self.L.pt2cy(rx) _filecir = prefix + '-cir-' + str(k) + '-' + str(link) + '-' + str( (ctx, crx)) D = {} D['Tx'] = tx D['Rx'] = rx dl.a = tx dl.b = rx ak, tauk = dl.eval(verbose=False, diffraction=True) self.chan[k] = dl #cira = dl.H.applywavB(self.wav.sf) #cira = dl.H.applywavB(self.wav.sfg) #D['t'] = cira.x #D['cir'] = cira.y #filename = pyu.getlong(_filecir, 'output') #spio.savemat(filename, D) def delay(self, itx, irx): """ calculate LOS link delay Parameters ---------- itx irx Returns ------- delay : float delay in ns """ tx = self.tx.points[itx] rx = self.rx.points[irx] df = tx - rx dist = np.sqrt(np.dot(df, df)) return (dist / 0.3)
class Simul(PyLayers): """ Link oriented simulation A simulation requires : A Layout A Person A Trajectory """ def __init__(self, _filetraj='simulnet_TA-Office.h5',verbose=False): """ object constructor Parameters ---------- _filetraj : string h5 trajectory verbose : boolean """ self.filetraj = _filetraj # self.progress = -1 # simulation not loaded self.verbose = verbose self.cfield = [] self.dpersons = {} self.dap = {} self.Nag = 0 self.Nap = 0 self.load_config(_filetraj) self.gen_net() self.SL = SLink() self.DL = DLink(L=self.L,verbose=self.verbose) self.filename = 'simultraj_' + self.filetraj self.data = pd.DataFrame(columns=['id_a', 'id_b', 'x_a', 'y_a', 'z_a', 'x_b', 'y_b', 'z_b', 'd', 'eng', 'typ', 'wstd', 'fcghz', 'fbminghz', 'fbmaxghz', 'fstep', 'aktk_id', 'sig_id', 'ray_id', 'Ct_id', 'H_id' ]) self.data.index.name='t' self._filecsv = self.filename.split('.')[0] + '.csv' self.todo = {'OB': True, 'B2B': True, 'B2I': True, 'I2I': False} filenameh5 = pyu.getlong(self.filename,pstruc['DIRLNK']) if os.path.exists(filenameh5) : self.loadpd() # self._saveh5_init() def __repr__(self): s = 'Simul trajectories class\n' s = s + '------------------------\n' s = s +'\n' s = s + 'Used layout: ' + self.L.filename + '\n' s = s + 'Number of Agents: ' + str(self.Nag) + '\n' s = s + 'Number of Access Points: ' + str(self.Nap) + '\n' s = s + 'Link to be evaluated: ' + str(self.todo) + '\n' s = s + 'tmin: ' + str(self._tmin) + '\n' s = s + 'tmax: ' + str(self._tmax) + '\n' s = s +'\n' # network info s = s + 'self.N :\n' s = s + self.N.__repr__() + '\n' s = s + 'CURRENT TIME: ' + str(self.ctime) + '\n' return s def load_config(self, _filetraj): """ load a simultraj configuration file Parameters ---------- _filetraj : string name of simulation file to be loaded """ self.filetraj = _filetraj # get the trajectory traj = tr.Trajectories() traj.loadh5(self.filetraj) # get the layout self.L = Layout(traj.Lfilename) # resample trajectory for ut, t in enumerate(traj): if t.typ == 'ag': person = Body(t.name + '.ini') tt = t.time() self.dpersons.update({t.name: person}) self._tmin = tt[0] self._tmax = tt[-1] self.time = tt else: pos = np.array([t.x[0], t.y[0], t.z[0]]) self.dap.update({t.ID: {'pos': pos, 'ant': antenna.Antenna(), 'name': t.name } }) self.ctime = np.nan self.Nag = len(self.dpersons.keys()) self.Nap = len(self.dap.keys()) self.traj = traj def gen_net(self): """ generate Network and associated links Notes ----- Create self.N : Network object See Also -------- pylayers.network.network """ N = Network() # get devices on bodies for p in self.dpersons: D = [] for dev in self.dpersons[p].dev: D.append( Device(self.dpersons[p].dev[dev]['name'], ID=dev + '_' + p)) N.add_devices(D, grp=p) # get access point devices for ap in self.dap: D = Device(self.dap[ap]['name'], ID=ap) N.add_devices(D, grp='ap', p=self.dap[ap]['pos']) # create Network N.create() self.N = N def show(self): """ show actual simlulation configuration """ fig, ax = self.L.showGs() fig, ax = self.N.show(fig=fig, ax=ax) return fig, ax def evaldeter(self, na, nb, wstd, fmode='band', nf=10): """ deterministic evaluation of a link Parameters ---------- na : string: node a id in self.N (Network) nb : string: node b id in self.N (Network) wstd : string: wireless standard used for commmunication between na and nb fmode : string ('center'|'band') mode of frequency evaluation center : only on the centered frequency band : on the whole band nf : int: number of frequency points (if fmode = 'band') Returns ------- (a, t ) a : ndarray alpha_k t : ndarray tau_k """ # todo in network : # take into consideration the postion and rotation of antenna and not device self.DL.a = self.N.node[na]['p'] self.DL.Ta = self.N.node[na]['T'] self.DL.b = self.N.node[nb]['p'] self.DL.Tb = self.N.node[nb]['T'] if fmode == 'center': self.DL.fGHz = self.N.node[na]['wstd'][wstd]['fcghz'] else: minb = self.N.node[na]['wstd'][wstd]['fbminghz'] maxb = self.N.node[na]['wstd'][wstd]['fbmaxghz'] self.DL.fGHz = np.linspace(minb, maxb, nf) a, t = self.DL.eval() return a, t def evalstat(self, na, nb): """ statistical evaluation of a link Parameters ---------- na : string: node a id in self.N (Netwrok) nb : string: node b id in self.N (Netwrok) Returns ------- (a, t, eng) a : ndarray alpha_k t : ndarray tau_k eng : float engagement """ pa = self.N.node[na]['p'] pb = self.N.node[nb]['p'] dida, name = na.split('_') didb, name = nb.split('_') ak, tk, eng = self.SL.onbody(self.dpersons[name], dida, didb, pa, pb) return ak, tk, eng def run(self, **kwargs): """ run the link evaluation along a trajectory Parameters ---------- 'OB': boolean perform on body statistical link evaluation 'B2B': boolean perform body to body deterministic link evaluation 'B2I': boolean perform body to infrastructure deterministic link evaluation 'I2I': boolean perform infrastructure to infrastructure deterministic link eval. 'llink': list list of link to be evaluated (if [], all link are considered) 'wstd': list list of wstd to be evaluated (if [], all wstd are considered) 't': np.array list of timestamp to be evaluated (if [], all timestamps are considered) """ defaults = {'OB': True, 'B2B': True, 'B2I': True, 'I2I': False, 'llink': [], 'wstd': [], 't': np.array([]), } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] llink = kwargs.pop('llink') wstd = kwargs.pop('wstd') OB = kwargs.pop('OB') B2B = kwargs.pop('B2B') B2I = kwargs.pop('B2I') I2I = kwargs.pop('I2I') self.todo.update({'OB':OB,'B2B':B2B,'B2I':B2I,'I2I':I2I}) # Check link attribute if llink == []: llink = self.N.links elif not isinstance(llink, list): llink = [llink] checkl = [l in self.N.links for l in llink] if sum(checkl) != len(self.N.links): uwrong = np.where(np.array(checkl) is False)[0] raise AttributeError(str(np.array(llink)[uwrong]) + ' links does not exist in Network') # Check wstd attribute if wstd == []: wstd = self.N.wstd.keys() elif not isinstance(wstd, list): wstd = [wstd] checkw = [w in self.N.wstd.keys() for w in wstd] if sum(checkw) != len(self.N.wstd.keys()): uwrong = np.where(np.array(checkw) is False)[0] raise AttributeError(str(np.array(wstd)[uwrong]) + ' wstd are not in Network') # force time attribute compliant if not isinstance(kwargs['t'],np.ndarray): if isinstance(kwargs['t'],list): lt = np.array(kwargs['t']) elif (isinstance(kwargs['t'], int) or isinstance(kwargs['t'],float)): lt = np.array([kwargs['t']]) else : lt = kwargs['t'] if len(lt) == 0: lt = self.time # check time attribute if not lt[0] >= self._tmin and\ lt[-1] <= self._tmax: raise AttributeError('Requested time range not available') # self._traj is a copy of self.traj, which is affected by resampling. # it is only a temporary attribute for a given run if len(lt) > 1: sf = 1/(1.*lt[1]-lt[0]) self._traj = self.traj.resample(sf=sf, tstart=lt[0]) else: self._traj = self.traj.resample(sf=1.0, tstart=lt[0]) self._traj.time() self.time = self._traj.t self._time = pd.to_datetime(self.time,unit='s') # # Code # init = True for ut, t in enumerate(lt): self.ctime = t self.update_pos(t) print self.N.__repr__() for w in wstd: for na, nb, typ in llink[w]: if self.todo[typ]: if self.verbose: print '-'*30 print 'time:', t, '/', lt[-1] ,' time idx:', ut, '/',len(lt) print 'processing: ',na, ' <-> ', nb, 'wstd: ', w print '-'*30 eng = 0 self.evaldeter(na, nb, w) if typ == 'OB': self.evalstat(na, nb) eng = self.SL.eng L = self.DL + self.SL self._ak = L.H.ak self._tk = L.H.tk else : self._ak = self.DL.H.ak self._tk = self.DL.H.tk df = pd.DataFrame({\ 'id_a': na, 'id_b': nb, 'x_a': self.N.node[na]['p'][0], 'y_a': self.N.node[na]['p'][1], 'z_a': self.N.node[na]['p'][2], 'x_b': self.N.node[nb]['p'][0], 'y_b': self.N.node[nb]['p'][1], 'z_b': self.N.node[nb]['p'][2], 'd': self.N.edge[na][nb]['d'], 'eng': eng, 'typ': typ, 'wstd': w, 'fcghz': self.N.node[na]['wstd'][w]['fcghz'], 'fbminghz': self.DL.fmin, 'fbmaxghz': self.DL.fmax, 'fstep': self.DL.fstep, 'aktk_id': str(ut) + '_' + na + '_' + nb + '_' + w, 'sig_id': self.DL.dexist['sig']['grpname'], 'ray_id': self.DL.dexist['ray']['grpname'], 'Ct_id': self.DL.dexist['Ct']['grpname'], 'H_id': self.DL.dexist['H']['grpname'], },columns=['id_a', 'id_b', 'x_a', 'y_a', 'z_a', 'x_b', 'y_b', 'z_b', 'd', 'eng', 'typ', 'wstd', 'fcghz', 'fbminghz', 'fbmaxghz', 'fstep', 'aktk_id', 'sig_id', 'ray_id', 'Ct_id', 'H_id' ],index=[self._time[ut]]) if not self.check_exist(df): self.data = self.data.append(df) # self._index = self._index + 1 # save csv self.tocsv(ut, na, nb, w,init=init) init=False # save pandas self.data self.savepd() # save ak tauk self._saveh5(ut, na, nb, w) def check_exist(self, df): """check if a dataframe df already exists in self.data Parameters ---------- df : pd.DataFrame Returns ------- boolean True if already exists False otherwise """ ud = self.data[(self.data.index == df.index) & (self.data['id_a'] == df['id_a'].values[0]) & (self.data['id_b'] == df['id_b'].values[0]) & (self.data['wstd'] == df['wstd'].values[0]) ] if len(ud) == 0: return False else : return True def savepd(self): """ save data information of a simulation """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) store = pd.HDFStore(filenameh5,'a') self.data=self.data.sort() store['df'] = self.data store.close() def loadpd(self): """ load data from previous simulations """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) self.data = pd.read_hdf(filenameh5,'df') self.data.index.name='t' def update_pos(self, t): """ update positions of devices and bodies for a given time index Parameters ---------- t : int time value """ # if a bodies are involved in simulation if ((self.todo['OB']) or (self.todo['B2B']) or (self.todo['B2I'])): nodeid = [] pos = [] orient = [] for up, person in enumerate(self.dpersons.values()): person.settopos(self._traj[up], t=t, cs=True) name = person.name dev = person.dev.keys() nodeid.extend([n + '_' + name for n in dev]) pos.extend([person.dcs[d][:, 0] for d in dev]) orient.extend([person.acs[d] for d in dev]) # TODO !!!!!!!!!!!!!!!!!!!! # in a future version , the network update must also update # antenna positon in the device coordinate system self.N.update_pos(nodeid, pos, now=t) self.N.update_orient(nodeid, orient, now=t) self.N.update_dis() def _show3(self, **kwargs): """ 3D show using Mayavi Parameters ---------- t: float time index link: list [id_a, id_b] id_a : node id a id_b : node id b 'lay': bool show layout 'net': bool show net 'body': bool show bodies 'rays': bool show rays """ defaults = {'t': 0, 'link': [], 'wstd':[], 'lay': True, 'net': True, 'body': True, 'rays': True, 'ant': False } for k in defaults: if k not in kwargs: kwargs[k] = defaults[k] link = kwargs['link'] df = self.data[self.data['t'] == kwargs['t']] if len(df) == 0: raise AttributeError('invalid time') # default if link ==[]: line = df[df.index==1] link = [line['id_a'].values[0],line['id_b'].values[0]] else : # get info of the corresponding timestamp line = df[(df['id_a'] == link[0]) & (df['id_b'] == link[1])] if len(line) == 0: line = df[(df['id_b'] == link[0]) & (df['id_a'] == link[1])] if len(line) == 0: raise AttributeError('invalid link') rayid = line['ray_id'].values[0] self.update_pos(kwargs['t']) self.DL.a = self.N.node[link[0]]['p'] self.DL.b = self.N.node[link[1]]['p'] self.DL.Ta = self.N.node[link[0]]['T'] self.DL.Tb = self.N.node[link[1]]['T'] self.DL.load(self.DL.R,rayid) self.DL._show3(newfig= False, lay= kwargs['lay'], rays= kwargs['rays'], ant=False) if kwargs['net']: self.N._show3(newfig=False) if kwargs['body']: for p in self.dpersons: self.dpersons[p]._show3(newfig=False, topos=True, pattern=kwargs['ant']) # def _saveh5_init(self): # """ initialization of the h5py file # """ # filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) # import ipdb # try: # f5 = h5py.File(filenameh5, 'w') # f5.create_dataset('time', shape=self.time.shape, data=self.time) # f5.close() # except: # f5.close() # raise NameError('simultra.saveinit: \ # issue when writting h5py file') def _saveh5(self, ut, ida, idb, wstd): """ Save in h5py format Parameters ---------- ut : int time index in self.time ida : string node a index idb : string node b index wstd : string wireless standard of used link Notes ----- Dataset organisation: simultraj_<trajectory_filename.h5>.h5 | |time | ... | |/<tidx_ida_idb_wstd>/ |attrs | |a_k | |t_k Root dataset : time : array range of simulation time Group identifier : tidx : index in time dataset ida : node a index in Network idb : node b index in Network wstd : wireless standar of link interest Inside group: a_k : alpha_k values t_k : tau_k values See Also -------- pylayers.simul.links """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) grpname = str(ut) + '_' + ida + '_' + idb + '_' + wstd # try/except to avoid loosing the h5 file if # read/write error try: fh5 = h5py.File(filenameh5, 'a') if not grpname in fh5.keys(): fh5.create_group(grpname) f = fh5[grpname] # for k in kwargs: # f.attrs[k] = kwargs[k] f.create_dataset('alphak', shape=self._ak.shape, maxshape=(None), data=self._ak) f.create_dataset('tauk', shape=self._tk.shape, maxshape=(None), data=self._tk) else: pass#print grpname + ' already exists in ' + filenameh5 fh5.close() except: fh5.close() raise NameError('Simultraj._saveh5: issue when writting h5py file') def _loadh5(self, grpname): """ Load in h5py format Parameters ---------- grpname : string group name which can be found sin self.data aktk_idx column Returns ------- (ak, tk, conf) ak : ndarray: alpha_k tk : ndarray: alpha_k """ filenameh5 = pyu.getlong(self.filename, pstruc['DIRLNK']) # try/except to avoid loosing the h5 file if # read/write error try: fh5 = h5py.File(filenameh5, 'r') if not grpname in fh5.keys(): fh5.close() raise NameError(grpname + ' cannot be reached in ' + self.filename) f = fh5[grpname] # for k in f.attrs.keys(): # conf[k]=f.attrs[k] ak = f['alphak'][:] tk = f['tauk'][:] fh5.close() return ak, tk except: fh5.close() raise NameError('Simultraj._loadh5: issue when reading h5py file') def tocsv(self, ut, ida, idb, wstd,init=False): filecsv = pyu.getlong(self._filecsv,pstruc['DIRLNK']) with open(filecsv, 'a') as csvfile: fil = csv.writer(csvfile, delimiter=';', quoting=csv.QUOTE_MINIMAL) if init: keys = self.data.iloc[-1].keys() data = [k for k in keys] data .append('ak') data .append('tk') fil.writerow(data) values = self.data.iloc[-1].values data = [v for v in values] sak = str(self._ak.tolist()) stk = str(self._tk.tolist()) data.append(sak) data.append(stk) fil.writerow(data)