def cover(self, **kwargs): """ run the coverage calculation Parameters ---------- sinr : boolean snr : boolean best : boolean size : integer size of grid points block Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a = C.show(typ='sinr',figsize=(10,8)) >>> plt.show() Notes ----- self.fGHz is an array, it means that Coverage is calculated at once for a whole set of frequencies. In practice, it would be the center frequency of a given standard channel. This function is calling `loss.Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as a full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ sizebloc = kwargs.pop('size', 100) # # select active AP # lactiveAP = [] try: del self.aap del self.ptdbm except: pass # Boltzmann constant kB = 1.3806503e-23 # # Loop over access points # set parameter of each active ap # p # PtdBm # BMHz for iap in self.dap: if self.dap[iap]['on']: lactiveAP.append(iap) # set frequency for each AP fGHz = self.dap[iap].s.fcghz self.fGHz = np.unique(np.hstack((self.fGHz, fGHz))) apchan = self.dap[iap]['chan'] # # stacking AP position Power Bandwidth # try: self.aap = np.vstack((self.aap, self.dap[iap]['p'])) self.ptdbm = np.vstack( (self.ptdbm, self.dap[iap]['PtdBm'])) self.bmhz = np.vstack( (self.bmhz, self.dap[iap].s.chan[apchan[0]]['BMHz'])) except: self.aap = self.dap[iap]['p'] self.ptdbm = np.array(self.dap[iap]['PtdBm']) self.bmhz = np.array( self.dap[iap].s.chan[apchan[0]]['BMHz']) self.nf = len(self.fGHz) PnW = np.array((10**(self.noisefactordb / 10.)) * kB * self.temperaturek * self.bmhz * 1e6) # Evaluate Noise Power (in dBm) self.pndbm = np.array(10 * np.log10(PnW) + 30) #lchan = map(lambda x: self.dap[x]['chan'],lap) #apchan = zip(self.dap.keys(),lchan) #self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) self.ptdbm = self.ptdbm.T self.pndbm = self.pndbm.T # creating all links # from all grid point to all ap # if len(self.pndbm.shape) == 0: self.ptdbm = self.ptdbm.reshape(1, 1) self.pndbm = self.pndbm.reshape(1, 1) self.nf = len(self.fGHz) Nbloc = self.ng // sizebloc r1 = np.arange(0, (Nbloc + 1) * sizebloc, sizebloc) r1 = np.append(r1, self.ng) lblock = list(zip(r1[0:-1], r1[1:])) for bg in lblock: p = product(range(bg[0], bg[1]), lactiveAP) # # pa : access point ,3 # pg : grid point ,2 # # 1 x na for k in p: pg = self.grid[k[0], :] pa = np.array(self.dap[k[1]]['p']) # exemple with 3 AP # 321 0 # 321 1 # 321 2 # 322 0 try: self.pa = np.vstack((self.pa, pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg, pg)) except: self.pg = pg self.pa = self.pa.T shpa = self.pa.shape shpg = self.pg.shape # extend in 3 dimensions if necessary if shpa[0] != 3: self.pa = np.vstack((self.pa, np.ones(shpa[1]))) self.pg = self.pg.T self.pg = np.vstack((self.pg, self.zgrid * np.ones(shpg[0]))) # retrieving dimensions along the 3 axis # a : number of active access points # g : grid block # f : frequency na = len(lactiveAP) self.na = na ng = self.ng nf = self.nf # calculate antenna gain from ap to grid point # # loop over all AP # k = 0 for iap in self.dap: # select only one access point # n u = na * np.arange(0, bg[1] - bg[0], 1).astype('int') + k if self.dap[iap]['on']: pa = self.pa[:, u] pg = self.pg[:, u] azoffset = self.dap[iap]['phideg'] * np.pi / 180. # the eval function of antenna should also specify polar self.dap[iap].A.eval(fGHz=self.fGHz, pt=pa, pr=pg, azoffset=azoffset) gain = (self.dap[iap].A.G).T # to handle omnidirectional antenna (nf,1,1) if gain.shape[1] == 1: gain = np.repeat(gain, bg[1] - bg[0], axis=1) if k == 0: tgain = gain[:, :, None] else: tgain = np.dstack((tgain, gain[:, :, None])) k = k + 1 tgain = tgain.reshape(nf, tgain.shape[1] * tgain.shape[2]) Lwo, Lwp, Edo, Edp = loss.Losst(self.L, self.fGHz, self.pa, self.pg, dB=False) freespace = loss.PL(self.fGHz, self.pa, self.pg, dB=False) try: self.Lwo = np.hstack((self.Lwo, Lwo)) self.Lwp = np.hstack((self.Lwp, Lwp)) self.Edo = np.hstack((self.Edo, Edo)) self.Edp = np.hstack((self.Edp, Edp)) self.freespace = np.hstack((self.freespace, freespace)) self.tgain = np.hstack((self.tgain, tgain)) except: self.Lwo = Lwo self.Lwp = Lwp self.Edo = Edo self.Edp = Edp self.freespace = freespace self.tgain = tgain self.Lwo = self.Lwo.reshape(nf, ng, na) self.Edo = self.Edo.reshape(nf, ng, na) self.Lwp = self.Lwp.reshape(nf, ng, na) self.Edp = self.Edp.reshape(nf, ng, na) self.tgain = self.tgain.reshape(nf, ng, na) self.freespace = self.freespace.reshape(nf, ng, na) # transmitting power # f x g x a # CmW : Received Power coverage in mW # TODO : tgain in o and p polarization self.CmWo = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwo * self.freespace * self.tgain self.CmWp = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwp * self.freespace * self.tgain #self.CmWo = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwo*self.freespace #self.CmWp = 10**(self.ptdbm[np.newaxis,...]/10.)*self.Lwp*self.freespace if self.snr: self.evsnr() if self.sinr: self.evsinr() if self.best: self.evbestsv()
def solve(self,p,e,LDP,RAT,epwr,sens): """ computes and returns a LDP value Parameters ---------- p : np.array e : np.array LDP : string Type of LDP ( TOA, Pr, .... any other are to be add in teh todo list) epwr : list nodes transmitted power sens : list nodes sensitivity Returns ------- value : float A LDP value : * A time in ns for LDP ='TOA' * A received power in dBm for LDP ='Pr' std : float A LDP value standard deviation: * A time in ns for LDP ='TOA' * A received power in dBm for LDP ='Pr' LDP (Location Dependent Parameter) """ try: model= self.model[RAT] except: try: self.load_model(RAT) model = self.model[RAT] except: self.model[RAT] = PLSmodel() self.save_model(RAT,self.model[RAT]) model = self.model[RAT] # if self.EMS_method == 'direct': # dd={} # distance dictionnary # if len(e) > 0: # lp=np.array([np.array((p[e[i][0]],p[e[i][1]])) for i in range(len(e))]) # d=np.sqrt(np.sum((lp[:,0]-lp[:,1])**2,axis=1)) # if LDP == 'TOA': # std = self.sigmaTOA*sp.randn(len(d)) # return ([[max(0.0,(d[i]+std[i])*0.3),self.sigmaTOA*0.3] for i in range(len(d))],d) # elif LDP == 'Pr': # std = self.model.sigrss*sp.randn(len(d)) # r=model.getPL(d,model.sigrss) # return ([[- r[i]-model.PL0,model.sigrss] for i in range(len(d))],d) # # # else : # raise NameError('invalid LDP name') # else : # return ([[0.],[0.]]) if self.EMS_method == 'multiwall': dd = {} # distance dictionnary if len(e) > 0: lp = np.array([np.array((p[e[i][0]],p[e[i][1]])) for i in range(len(e))]) # MW is 2D only now. # This explain the following licenses lp = lp[:,:,:2] dim = lp.shape[2] # d euclidian distance d = np.sqrt(np.sum((lp[:,0]-lp[:,1])**2,axis=1)) slp = np.shape(lp)[1] # evaluation of all LDPs if LDP=='all': pa = np.vstack(p.values()) lpa = len(pa) Pr = [] TOA = [] lsens = np.array(()) loss = np.array(()) frees = np.array(()) lepwr = np.array(()) for i in range(lpa-1): # excess time of flight + losses computation # # Losst returns 4 parameters # Lo Lp Edo Edp # pdb.set_trace() MW = lo.Losst(self.L,model.f,pa[i+1:lpa,:dim].T,pa[i,:dim]) # MW = lo.Loss0_v2(self.L,pa[i+1:lpa],model.f,pa[i]) # loss free space frees=np.hstack((frees, lo.PL(np.array([model.f]), pa[i+1:lpa,:dim].T, pa[i,:dim].reshape(2,1), model.rssnp)[0] )) # Pr.extend(lepwr - MW[0] - frees) # WARNING : only one polarization is taken into # account here # save losses computation loss = np.hstack((loss,MW[0][0])) # save excess tof computation TOA = np.hstack((TOA,MW[2][0])) # emmited power for the first nodes of computed edges lepwr1 = [epwr[i[0]][RAT] for i in e] lepwr2 = [epwr[i[1]][RAT] for i in e] Pr = lepwr1 - loss - frees # concatenate reverse link Pr = np.hstack((Pr, lepwr2 - loss - frees)) P = np.outer(Pr,[1,1]) P[:,1] = model.sigrss lsens = [sens[i[0]][RAT] for i in e] + [sens[i[1]][RAT] for i in e] # visibility or not v = P[:,0] > lsens # same toa for link and reverse link T = np.hstack((TOA+d/0.3,TOA+d/0.3)) T=np.outer(T,[1,1]) T[:,1]=self.sigmaTOA*0.3 d=np.hstack((d,d)) return (P,T,d,v) # elif LDP == 'Pr': # pa = np.vstack(p.values()) # pn = p.keys() # lpa = len(pa) # Lwo = [] # frees=[] # lepwr=[] # for i in range(lpa-1): # lo.append(Loss0_v2(self.L,pa[i+1:lpa],model.f,pa[i])) # Lwo.extend(Loss0_v2(self.L,pa[i+1:lpa],model.f,pa[i])[0]) # frees.extend(PL(pa[i+1:lpa],model.f,pa[i],model.rssnp)) # lepwr.extend(epwr[i+1:lpa]) # return ([[lepwr[i] - Lwo[i]-frees[i],model.sigrss] for i in range(len(Lwo))],d) # # elif LDP == 'TOA': #### NOT CORRECT ! # std = self.sigmaTOA*sp.randn(len(d)) # return ([[max(0.0,(d[i]+std[i])*0.3),self.sigmaTOA*0.3] for i in range(len(d))],d) else : return (np.array((0.,0.)),np.array((0.,0.)),np.array((0.,0.)),np.array((0.,0.))) elif self.method == 'raytracing': print 'Okay, I think we\'ve got something to append in the TODO list' else : raise NameError('invalid method name')
def cover(self, sinr=True, snr=True, best=True): """ run the coverage calculation Parameters ---------- sinr : boolean snr : boolean best : boolean Examples -------- .. plot:: :include-source: >>> from pylayers.antprop.coverage import * >>> C = Coverage() >>> C.cover() >>> f,a=C.show(typ='sinr',figsize=(10,8)) >>> plt.show() Notes ----- self.fGHz is an array, it means that Coverage is calculated at once for a whole set of frequencies. In practice, it would be the center frequency of a given standard channel. This function is calling `loss.Losst` which calculates Losses along a straight path. In a future implementation we will abstract the EM solver in order to make use of other calculation approaches as a full or partial Ray Tracing. The following members variables are evaluated : + freespace Loss @ fGHz PL() PathLoss (shoud be rename FS as free space) $ + prdbmo : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{odB}` + prdbmp : Received power in dBm .. math:`P_{rdBm} =P_{tdBm} - L_{pdB}` + snro : SNR polar o (H) + snrp : SNR polar p (H) See Also -------- pylayers.antprop.loss.Losst pylayers.antprop.loss.PL """ # # select active AP # lactiveAP = [] try: del self.aap del self.ptdbm except: pass self.kB = 1.3806503e-23 # Boltzmann constant for iap in self.dap: if self.dap[iap]['on']: lactiveAP.append(iap) fGHz = self.dap[iap].s.fcghz # The frequency band is set here self.fGHz = np.unique(np.hstack((self.fGHz, fGHz))) apchan = self.dap[iap]['chan'] try: self.aap = np.vstack((self.aap, self.dap[iap]['p'][0:2])) self.ptdbm = np.vstack( (self.ptdbm, self.dap[iap]['PtdBm'])) self.bmhz = np.vstack( (self.bmhz, self.dap[iap].s.chan[apchan[0]]['BMHz'])) except: self.aap = self.dap[iap]['p'][0:2] self.ptdbm = np.array(self.dap[iap]['PtdBm']) self.bmhz = np.array( self.dap[iap].s.chan[apchan[0]]['BMHz']) PnW = np.array((10**(self.noisefactordb / 10.)) * self.kB * self.temperaturek * self.bmhz * 1e6) # Evaluate Noise Power (in dBm) self.pndbm = np.array(10 * np.log10(PnW) + 30) #lchan = map(lambda x: self.dap[x]['chan'],lap) #apchan = zip(self.dap.keys(),lchan) #self.bmhz = np.array(map(lambda x: self.dap[x[0]].s.chan[x[1][0]]['BMHz']*len(x[1]),apchan)) self.ptdbm = self.ptdbm.T self.pndbm = self.pndbm.T # creating all links p = product(range(self.ng), lactiveAP) # # pa : access point # pg : grid point # # 1 x na for k in p: pg = self.grid[k[0], :] pa = np.array(self.dap[k[1]]['p'][0:2]) try: self.pa = np.vstack((self.pa, pa)) except: self.pa = pa try: self.pg = np.vstack((self.pg, pg)) except: self.pg = pg self.pa = self.pa.T shpa = self.pa.shape shpg = self.pg.shape self.pa = np.vstack((self.pa, np.ones(shpa[1]))) self.pg = self.pg.T self.pg = np.vstack((self.pg, np.ones(shpg[0]))) self.nf = len(self.fGHz) # retrieving dimensions along the 3 axis na = len(lactiveAP) self.na = na ng = self.ng nf = self.nf #Lwo,Lwp,Edo,Edp = loss.Losst(self.L,self.fGHz,self.pa,self.pg,dB=False) Lwo, Lwp, Edo, Edp = loss.Losst(self.L, self.fGHz, self.pa, self.pg, dB=False) self.Lwo = Lwo.reshape(nf, ng, na) self.Edo = Edo.reshape(nf, ng, na) self.Lwp = Lwp.reshape(nf, ng, na) self.Edp = Edp.reshape(nf, ng, na) freespace = loss.PL(self.fGHz, self.pa, self.pg, dB=False) self.freespace = freespace.reshape(nf, ng, na) # transmitting power # f x g x a # CmW : Received Power coverage in mW self.CmWo = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwo * self.freespace self.CmWp = 10**(self.ptdbm[np.newaxis, ...] / 10.) * self.Lwp * self.freespace if snr: self.evsnr() if sinr: self.evsinr() if best: self.evbestsv()