Beispiel #1
0
#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')
Beispiel #2
0
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()
Beispiel #3
0
#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')
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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()
Beispiel #7
0
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')
Beispiel #8
0
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)
Beispiel #9
0
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)