├── Cell.py
├── InterSliceSch.py
├── IntraSliceSch.py
├── LICENSE
├── LICENSE.md
├── README.md
├── Results.py
├── Scheds_Inter.py
├── Scheds_Intra.py
├── Slice.py
├── UE.py
├── doc
├── Py5cheSim.Cell.Cell.html
├── Py5cheSim.Cell.html
├── Py5cheSim.InterSliceSch.InterSliceScheduler.html
├── Py5cheSim.InterSliceSch.html
├── Py5cheSim.IntraSliceSch.Format.html
├── Py5cheSim.IntraSliceSch.IntraSliceScheduler.html
├── Py5cheSim.IntraSliceSch.LTE_scheduler.html
├── Py5cheSim.IntraSliceSch.TBqueue.html
├── Py5cheSim.IntraSliceSch.TransportBlock.html
├── Py5cheSim.IntraSliceSch.html
├── Py5cheSim.Results.UEgroup.html
├── Py5cheSim.Results.html
├── Py5cheSim.Scheds_Inter.PF_Scheduler.html
├── Py5cheSim.Scheds_Inter.RRplus_Scheduler.html
├── Py5cheSim.Scheds_Inter.html
├── Py5cheSim.Scheds_Intra.PF_Scheduler.html
├── Py5cheSim.Scheds_Intra.TBqueueTDD.html
├── Py5cheSim.Scheds_Intra.TDD_Scheduler.html
├── Py5cheSim.Scheds_Intra.html
├── Py5cheSim.Slice.Slice.html
├── Py5cheSim.Slice.html
├── Py5cheSim.UE.Bearer.html
├── Py5cheSim.UE.Format.html
├── Py5cheSim.UE.Packet.html
├── Py5cheSim.UE.PacketFlow.html
├── Py5cheSim.UE.PcktQueue.html
├── Py5cheSim.UE.RadioLink.html
├── Py5cheSim.UE.UE.html
├── Py5cheSim.UE.html
├── Py5cheSim.html
├── Py5cheSim.simulation.html
├── apidocs.css
├── bootstrap.min.css
├── classIndex.html
├── index.html
├── moduleIndex.html
├── nameIndex.html
├── objects.inv
├── pydoctor.js
└── undoccedSummary.html
└── simulation.py
/Cell.py:
--------------------------------------------------------------------------------
1 | """ This module contains the Cell class.
2 | """
3 | import os
4 | import sys
5 | import simpy #from SimPy.Simulation import * (simpy2.2)
6 | from collections import deque
7 | import math
8 | import random
9 | from Slice import *
10 | from Scheds_Inter import *
11 |
12 | # Cell Class: cell description
13 |
14 | class Cell():
15 | """Cell class has cell relative parameters and collect kpi ststistics. """
16 | def __init__(self,i,b,fr,dm,mBue,tdd,gr,schInter):
17 | """This method creates a cell instance.
18 |
19 | It initialices cell parameters and interSliceScheduler according to the algorithm specified on the sch attribute."""
20 | self.id = i
21 | self.bw = b
22 | self.inactTimer = 3000
23 | self.tUdQueue = 0.05
24 | self.maxBuffUE = mBue
25 | """Maximum bearer buffer size by UE, in bytes"""
26 | self.sch = schInter
27 | if schInter[0:3] == 'RRp':
28 | self.interSliceSched = RRplus_Scheduler(self.bw,fr,dm,tdd,gr)
29 | elif schInter[0:2] == 'PF':
30 | self.interSliceSched = PF_Scheduler(self.bw,fr,dm,tdd,gr,schInter)
31 | elif schInter[0:2] == 'DT':
32 | self.interSliceSched = dynTDD_Scheduler(self.bw,fr,dm,tdd,gr)
33 | else:
34 | self.interSliceSched = InterSliceScheduler(self.bw,fr,dm,tdd,gr)
35 | self.sch = 'RR'
36 | self.slicesStsts = {}
37 |
38 | def updateStsts(self,env,interv,tSim): # ---------- PEM -------------
39 | """This method manages the statistics collection. This is a PEM Method.
40 |
41 | This method creates statistics files and stores counter values to calculate later the main kpi considered. \n
42 | Inter Slice statistics are stored in the dlStsts_InterSlice.txt file for DL and ulStsts_InterSlice.txt file for UL. \n
43 | Intra Slice statistics are stored in the dlStsts_ SUBFRAME NUMBER: '+str(env.now)+'
')
37 | if len(list(self.slices.keys()))>0:
38 | if len(list(self.slices.keys()))>1:
39 | for slice in list(self.slices.keys()):
40 | self.slices[slice].updateConfig(int((self.PRBs/len(list(self.slices.keys())))/self.slices[slice].numRefFactor))
41 | self.printSliceConfig(slice)
42 | else:
43 | slice = self.slices[list(self.slices.keys())[0]]
44 | prbs = 0
45 | for b in self.bw:
46 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz']
47 | slice.updateConfig(prbs)
48 | #slice.updateConfig(1) # For 1PRB IoT test example! ################################################3
49 | self.dbFile.write('
')
50 | yield env.timeout(self.granularity)
51 |
52 | def createSlice(self,dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,sch):
53 | """This method creates a slice and stores it in the slices dictionary."""
54 | self.slices[lbl] = Slice(dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,self.tdd,sch)
55 |
56 |
57 | def printSliceConfig(self,slice):
58 | """This method stores inter slice scheduling debugging information on the log file."""
59 | if slice == 'LTE':
60 | sliceCnx = len(list(self.slices[slice].schedulerDL.ues.keys()))
61 | sliceBrBuffSz = self.slices[slice].schedulerDL.updSumPcks()
62 | sliceRessources = self.slices[slice].schedulerDL.nrbUEmax
63 | self.dbFile.write(' Slice '+self.slices[slice].label+' data:
')
64 | else:
65 | sliceCnx = max(len(list(self.slices[slice].schedulerDL.ues.keys())),len(list(self.slices[slice].schedulerUL.ues.keys())))
66 | sliceBrBuffSz = max(self.slices[slice].schedulerDL.updSumPcks(),self.slices[slice].schedulerUL.updSumPcks())
67 | sliceRessources = max(self.slices[slice].schedulerDL.nrbUEmax,self.slices[slice].schedulerUL.nrbUEmax)
68 | self.dbFile.write(' Slice '+self.slices[slice].label+' data:
')
69 | self.dbFile.write('DL/UL symbols: '+str(self.slices[slice].schedulerDL.TDDsmb)+'/'+str(self.slices[slice].schedulerUL.TDDsmb)+'
')
70 |
71 | self.dbFile.write('Connections: '+str(sliceCnx)+'
')
72 | self.dbFile.write('Bearer Buffer Size (Packets): '+str(sliceBrBuffSz)+'
')
73 | self.dbFile.write('Resources (PRBs): '+str(sliceRessources)+'
')
74 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2021
2 | Instituto de Ingenieria Electrica, Facultad de Ingenieria,
3 | Universidad de la Republica, Uruguay.
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Py5cheSim
2 | Py5cheSim is a flexible and open-source simulator based on Python and
3 | specially oriented to simulate cell capacity in 3GPP 5G networks and beyond.
4 | To the best of our knowledge, Py5cheSim is the first simulator that supports
5 | Network Slicing at the Radio Access Network (RAN), one of the main innovations of 5G.
6 |
7 | Py5cheSim was designed to simplify new schedulers implementation.
8 | The main network model abstractions are contained in the simulator Core, so there is no need to have deep knowledge on that field to run a simulation or to integrate a new scheduler. In this way Py5cheSim provides a framework for 5G new scheduler algorithms implementation in a straightforward and intuitive way.
9 |
10 | The tool used to implement Discrete Event Simulation was SimPy and code documentation was made using pydoctor.
11 |
12 | Py5cheSim is build on the next modules:
13 | • UE.py: UE parameters and traffic generation.
14 | • Cell.py: Cell configuration and statistics management.
15 | • Slice.py: Slice configuration.
16 | • IntraSliceSch.py: Base intra slice scheduler implementation.
17 | • InterSliceSch.py: Base inter slice scheduler implementation.
18 | • Scheds Intra.py: Other intra slice schedulers implementation.
19 | • Scheds Inter.py: Other inter slice schedulers implementation.
20 | • simulation.py: Is the simulation script. It configures and runs a simulation.
21 | • Results.py: Provides auxiliary methods to present simulation results, and configure traffic profiles.
22 |
23 | Py5cheSim 1.0 is the result of the Master Thesis of Gabriela Pereyra (Facultad de Ingeniería, UdelaR).
24 | Thesis: Pereyra, G. (2021.). Scheduling in 5G networks : Developing a 5G cell capacity simulator. Tesis de maestría. Universidad de la República (Uruguay). Facultad de Ingeniería.
25 | Article: https://hdl.handle.net/20.500.12008/30549
26 |
27 | Code Documentation: https://htmlpreview.github.io/?https://github.com/ClaudinaRattaro/Py5cheSim/blob/main/doc/Py5cheSim.html
28 |
29 |
30 | In https://github.com/linglesloggia/py5chesim is the improved version of the simulator (version 2 )
31 | it is related to article: https://www.colibri.udelar.edu.uy/jspui/bitstream/20.500.12008/31723/1/PIRB22.pdf
32 |
33 | In https://github.com/charluy/PFC we have integrated the framework deepmimo (https://deepmimo.net/) as an input of py5chesim (improving the channel model and mimo feature)
34 |
--------------------------------------------------------------------------------
/Scheds_Inter.py:
--------------------------------------------------------------------------------
1 | """This module contains different implemented inter slice schedulers.
2 | New schedulers should be implemented here following the current structure."""
3 | import math
4 | from InterSliceSch import InterSliceScheduler
5 | from Slice import *
6 | import random
7 |
8 | class RRplus_Scheduler(InterSliceScheduler):
9 | """This class implements Round Robin Plus inter slice scheduling algorithm."""
10 | def __init__(self,ba,fr,dm,tdd,gr):
11 | InterSliceScheduler.__init__(self,ba,fr,dm,tdd,gr)
12 |
13 | def resAlloc(self,env): #PEM ------------------------------------------------
14 | """This method implements Round Robin Plus PRB allocation between the different configured slices.
15 | This PEM method overwrites the resAlloc method from InterSliceScheduler class.
16 |
17 | Round Robin Plus scheduler allocates the same amount of resources to each slice with packets in buffer. """
18 | while True:
19 | self.dbFile.write(' SUBFRAME NUMBER: '+str(env.now)+'
')
20 | if len(list(self.slices.keys()))>0:
21 | if len(list(self.slices.keys()))>1:
22 | slicesWithPacks = 0
23 | for slice in list(self.slices.keys()):
24 | sliceHasPackets = self.slices[slice].schedulerDL.updSumPcks()>0 or self.slices[slice].schedulerUL.updSumPcks()>0
25 | if sliceHasPackets:
26 | slicesWithPacks = slicesWithPacks + 1
27 | if slicesWithPacks == 0:
28 | for slice in list(self.slices.keys()):
29 | self.slices[slice].updateConfig(int((self.PRBs/len(list(self.slices.keys())))/self.slices[slice].numRefFactor))
30 | self.printSliceConfig(slice)
31 | else:
32 | for slice in list(self.slices.keys()):
33 | sliceHasPackets = self.slices[slice].schedulerDL.updSumPcks()>0 or self.slices[slice].schedulerUL.updSumPcks()>0
34 | if not sliceHasPackets:
35 | self.slices[slice].updateConfig(0)
36 | else:
37 | self.slices[slice].updateConfig(int((self.PRBs/slicesWithPacks)/self.slices[slice].numRefFactor))
38 | self.printSliceConfig(slice)
39 | else:
40 | slice = self.slices[list(self.slices.keys())[0]]
41 | prbs = 0
42 | for b in self.bw:
43 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz']
44 | slice.updateConfig(prbs)
45 | self.dbFile.write('
')
46 | yield env.timeout(self.granularity)
47 |
48 |
49 | class PF_Scheduler(InterSliceScheduler):
50 | """This class implements Proportional Fair inter slice scheduling algorithm."""
51 | def __init__(self,ba,fr,dm,tdd,gr,sch):
52 | InterSliceScheduler.__init__(self,ba,fr,dm,tdd,gr)
53 | self.sch = sch
54 | """String formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent. """
55 | self.rcvdBytesLen = 10
56 | """rcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored."""
57 |
58 | def resAlloc(self,env): #PEM ------------------------------------------------
59 | """This method implements Proportional Fair resource allocation between the different configured slices.
60 | This PEM method overwrites the resAlloc method from InterSliceScheduler class.
61 |
62 | Proportional Fair scheduler allocates all PRBs in the cell to the slice with the biggest metric.
63 | Metric for each slice is calculated as PossibleAverageUEtbs/ReceivedBytes."""
64 | while True:
65 | self.dbFile.write(' SUBFRAME NUMBER: '+str(env.now)+'
')
66 | if len(list(self.slices.keys()))>0:
67 | if len(list(self.slices.keys()))>1:
68 | if env.now>0:
69 | self.setMetric(float(self.sch[2]),float(self.sch[3]))
70 | maxMetSlice = self.findMaxMetSlice()
71 | self.assign2aSlice(maxMetSlice)
72 | self.printSliceConfig(maxMetSlice)
73 | else:
74 | initialSlice = random.choice(list(self.slices.keys()))
75 | self.assign2aSlice(initialSlice)
76 | self.printSliceConfig(initialSlice)
77 | else:
78 | slice = self.slices[list(self.slices.keys())[0]]
79 | prbs = 0
80 | for b in self.bw:
81 | prbs = prbs + self.nRBtable[self.FR][slice.scs][str(b)+'MHz']
82 | slice.updateConfig(prbs)
83 | self.printSliceConfig(slice.label)
84 | self.dbFile.write('
')
85 | yield env.timeout(self.granularity)
86 |
87 | def setMetric(self,exp_n,exp_d):
88 | """This method sets the PF metric for each slice"""
89 | if len(list(self.slices.keys()))>0:
90 | for slice in list(self.slices.keys()):
91 | rcvdBt_end = self.slices[slice].rcvdBytes[len(self.slices[slice].rcvdBytes)-1]
92 | rcvdBt_in = self.slices[slice].rcvdBytes[0]
93 | if rcvdBt_end - rcvdBt_in == 0:
94 | den = 1
95 | else:
96 | den = rcvdBt_end - rcvdBt_in
97 | num = 0
98 | for ue in list(self.slices[slice].schedulerDL.ues.keys()):
99 | [tbs, mod, bi, mcs] = self.slices[slice].schedulerDL.setMod(ue,self.PRBs)
100 | num = num + tbs
101 | for ue in list(self.slices[slice].schedulerUL.ues.keys()):
102 | [tbs, mod, bi, mcs] = self.slices[slice].schedulerUL.setMod(ue,self.PRBs)
103 | num = num + tbs
104 | num = num/(len(list(self.slices[slice].schedulerDL.ues.keys()))+len(list(self.slices[slice].schedulerUL.ues.keys())))
105 | self.slices[slice].metric = math.pow(float(num), exp_n)/math.pow(den,exp_d)
106 |
107 | def findMaxMetSlice(self):
108 | """This method finds and returns the Slice with the highest metric"""
109 | metric = 0
110 | for slice in list(self.slices.keys()):
111 | if self.slices[slice].metric > metric:
112 | metric = self.slices[slice].metric
113 | maxSliceM = slice
114 | if self.slices[slice].metric == metric:
115 | slicesMlist = [maxSliceM,slice]
116 | maxSliceM = random.choice(slicesMlist)
117 | return maxSliceM
118 |
119 | def assign2aSlice(self,slice):
120 | """This method allocates cell's PRBs to the indicated slice"""
121 | for sl in list(self.slices.keys()):
122 | if sl == slice:
123 | self.slices[sl].updateConfig(int(self.PRBs/self.slices[sl].numRefFactor))
124 | else:
125 | self.slices[sl].updateConfig(0)
126 |
127 | def printSliceConfig(self,slice):
128 | """This method stores inter slice scheduling debugging information on the log file, adding PF metric values."""
129 | super().printSliceConfig(slice)
130 | for s in list(self.slices.keys()):
131 | self.dbFile.write('Slice: '+str(s)+' -> PF Metric: '+str(self.slices[s].metric)+'
')
132 |
--------------------------------------------------------------------------------
/Scheds_Intra.py:
--------------------------------------------------------------------------------
1 | """This module contains different implemented intra slice schedulers.
2 | New schedulers should be implemented here following the current structure."""
3 |
4 | import math
5 | from IntraSliceSch import IntraSliceScheduler, Format
6 | from collections import deque
7 |
8 | class PF_Scheduler(IntraSliceScheduler): # PF Sched ---------
9 | """This class implements Proportional Fair intra slice scheduling algorithm."""
10 | def __init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch):
11 | IntraSliceScheduler.__init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch)
12 | self.promLen = 30
13 | """Past Throughput average length considered in PF metric"""
14 | def resAlloc(self,band):
15 | """This method implements Proportional Fair resource allocation between the different connected UEs.
16 | This method overwrites the resAlloc method from IntraSliceScheduler class.
17 |
18 | Proportional Fair scheduler allocates all PRBs in the slice to the UE with the biggest metric.
19 | Metric for each UE is calculated as PossibleUEtbs/AveragePastTbs."""
20 | schd = self.schType[0:2]
21 | if schd=='PF' and len(list(self.ues.keys()))>0:
22 | exp_num = float(self.schType[2])
23 | exp_den = float(self.schType[3])
24 | self.setUEfactor(exp_num, exp_den)
25 | maxInd = self.findMaxFactor()
26 | for ue in list(self.ues.keys()):
27 | if ue == maxInd:
28 | self.ues[ue].prbs = band
29 | else:
30 | self.ues[ue].prbs = 0
31 | if len(self.ues[ue].pastTbsz)>self.promLen:
32 | self.ues[ue].pastTbsz.popleft()
33 | self.ues[ue].pastTbsz.append(self.ues[ue].tbsz)
34 | self.ues[ue].tbsz = 1
35 | # Print Resource Allocation
36 | self.printResAlloc()
37 |
38 | def setUEfactor(self, exp_n, exp_d):
39 | """This method sets the PF metric for each UE"""
40 | for ue in list(self.ues.keys()):
41 | sumTBS = 0
42 | for t in self.ues[ue].pastTbsz:
43 | sumTBS = sumTBS + t
44 | actual_den = sumTBS/len(self.ues[ue].pastTbsz)
45 | [tbs, mod, bi, mcs] = self.setMod(ue,self.nrbUEmax)
46 | self.ues[ue].pfFactor = math.pow(float(tbs), exp_n)/math.pow(actual_den,exp_d)
47 | self.ues[ue].lastDen = actual_den
48 | self.ues[ue].num = tbs
49 |
50 | def findMaxFactor(self):
51 | """This method finds and returns the UE with the highest metric"""
52 | factorMax = 0
53 | factorMaxInd = ''
54 | for ue in list(self.ues.keys()):
55 | if len(self.ues[ue].bearers[0].buffer.pckts)>0 and self.ues[ue].pfFactor>factorMax:
56 | factorMax = self.ues[ue].pfFactor
57 | factorMaxInd = ue
58 | if factorMaxInd=='':
59 | ue = list(self.ues.keys())[self.ind_u]
60 | q = 0
61 | while len(self.ues[ue].bearers[0].buffer.pckts)==0 and q
')
73 | resAllocMsg = ''
74 | for ue in list(self.ues.keys()):
75 | resAllocMsg = resAllocMsg + ue +' '+ str(self.ues[ue].pfFactor)+' '+str(self.ues[ue].prbs)+ ' '+str(self.ues[ue].num)+' '+ str(self.ues[ue].lastDen)+'
'
76 | self.printDebData(resAllocMsg)
77 | self.printDebData('+++++++++++++++++++++++++++++++++++'+'
')
78 |
79 | class TDD_Scheduler(IntraSliceScheduler): # TDD Sched ---------
80 | """This class implements TDD intra slice scheduling."""
81 | def __init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch):
82 | IntraSliceScheduler.__init__(self,ba,n,debMd,sLod,ttiByms,mmd_,ly_,dir,Smb,robustMCS,slcLbl,sch)
83 | self.symMax = Smb
84 | self.queue = TBqueueTDD(self.symMax)
85 | """TDD scheduler TB queue.
86 |
87 | IntraSliceScheduler class attribute queue is overwriten here by a new type of queue
88 | which handles symbols. This queue will contain as much TB as a slot can contain. If resource allocation is made
89 | in terms of slots, it will contain 1 element, else, it will contain as much mini-slots as can be supported in 1 slot."""
90 |
91 | def resAlloc(self,band):
92 | """This method implements resource allocation between the different connected UEs in a TDD slice.
93 |
94 | It overwrites the resAlloc method from IntraSliceScheduler class.
95 | In this Py5cheSim version TDD scheduler allocates all PRBs in the slice to a UE during 1 slot.
96 | Future Py5cheSim versions could support mini-slot allocation by changing the UE symbol allocation in this method.
97 | Note that in that case, althoug there is no need to update the queueUpdate method,
98 | TBS calculation must be adjusted to avoid losing capacity when trunking the Nre__ value."""
99 |
100 | if len(list(self.ues.keys()))>0:
101 | for ue in list(self.ues.keys()):
102 | self.ues[ue].prbs = band
103 | self.ues[ue].symb = self.TDDsmb
104 | # Print Resource Allocation
105 | self.printResAlloc()
106 |
107 | def queueUpdate(self):
108 | """This method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes.
109 |
110 | It overwrites queueUpdate method from IntraSliceScheduler class, making Resource allocation in terms of slot Symbols
111 | and insert generated TBs into Scheduler queue in a TTI. Althoug in this version Resource allocation is made by slot,
112 | it is prepared to support mini-slot resource allocation by handling a scheduler TB queue in terms of symbols."""
113 | packts = 1
114 | self.ueLst = list(self.ues.keys())
115 | self.resAlloc(self.nrbUEmax)
116 | sym = 0
117 | if self.nrbUEmax == 0:
118 | self.sm_lim = 0
119 | else:
120 | if self.mimomd == 'MU':
121 | self.sm_lim = self.symMax*self.nlayers
122 | else:
123 | self.sm_lim = self.symMax
124 |
125 | while len(self.ueLst)>0 and packts>0 and sym < self.sm_lim:
126 | ue = self.ueLst[self.ind_u]
127 | self.printDebDataDM('---------------- '+ue+' ------------------
') # print more info in debbug mode
128 | if self.ues[ue].symb>0:
129 | if len(self.ues[ue].bearers)>0 and sym < self.sm_lim:
130 | if len(self.ues[ue].pendingTB)==0: # No TB to reTX
131 | sym = sym + self.rrcUncstSigIn(ue)
132 | if sym < self.sm_lim and len(self.ues[ue].bearers[0].buffer.pckts)>0:
133 | sym = sym + self.dataPtoTB(ue)
134 | else: # There are TB to reTX
135 | self.printPendTB()
136 | sym = sym + self.retransmitTB(ue)
137 | if self.dbMd:
138 | self.printQtb() # Print TB queue in debbug mode
139 | self.updIndUE()
140 | packts = self.updSumPcks()
141 |
142 | def rrcUncstSigIn(self,u):
143 | ueN = int(self.ues[u].id[2:])
144 | sfSig = int(float(1)/self.sLoad)
145 | rrcUESigCond = (self.sbFrNum-ueN)%sfSig == 0
146 | if rrcUESigCond:
147 | p_l = []
148 | p_l.append(self.ues[u].packetFlows[0].pId)
149 | self.ues[u].packetFlows[0].pId = self.ues[u].packetFlows[0].pId + 1
150 | ins = self.insertTB(self.ues[u].TBid,'4-QAM',u,'Sig',p_l,self.ues[u].prbs,19)
151 | r = self.symMax
152 | else:
153 | r = 0
154 | return r
155 |
156 | def retransmitTB(self,u):
157 | pendingTbl = self.ues[u].pendingTB[0]
158 | if pendingTbl.reTxNum < 3000: # TB retransmission
159 | intd = self.queue.insertTB(pendingTbl)
160 | self.ues[u].pendingTB.pop(0)
161 | pendingTbl.reTxNum = pendingTbl.reTxNum + 1
162 | r = self.symMax
163 | else:
164 | self.ues[u].pendingTB.pop(0) # Drop!!!
165 | r = 0
166 | return r
167 |
168 | def dataPtoTB(self,u):
169 | """This method takes UE data bytes, builds TB and puts them in the scheduler TB queue.
170 |
171 | It overwrites dataPtoTB method from IntraSliceScheduler class. In this case it returns
172 | the amount of allocated symbols to the UE."""
173 | n = self.ues[u].prbs
174 | [tbSbits,mod,bits,mcs__] = self.setMod(u,n)
175 | if self.schType[0:2]=='PF':
176 | if len(self.ues[u].pastTbsz)>self.promLen:
177 | self.ues[u].pastTbsz.popleft()
178 | self.ues[u].pastTbsz.append(self.ues[u].tbsz)
179 |
180 | self.ues[u].tbsz = tbSbits
181 | self.ues[u].MCS = mcs__
182 | self.setBLER(u)
183 | tbSize = int(float(tbSbits)/8) # TB size in bytes
184 | self.printDebDataDM('TBs: '+str(tbSize)+' nrb: '+str(n)+' FreeSp: '+str(self.queue.getFreeSpace())+'
')
185 | pks_s = 0
186 | list_p = []
187 | while pks_s
')
213 | self.printDebData('PRBs: '+str(self.nrbUEmax)+'
')
214 | resAllocMsg = ''
215 | for ue in list(self.ues.keys()):
216 | resAllocMsg = resAllocMsg + ue +': '+ str(self.ues[ue].symb)+' symbols'+'
'
217 | self.printDebData(resAllocMsg)
218 | self.printDebData('+++++++++++++++++++++++++++++++++++'+'
')
219 |
220 | class TBqueueTDD: # TB queue!!!
221 | """This class is used to model scheduler TB queue in TDD scheduler."""
222 | def __init__(self,symb):
223 | self.res = deque([])
224 | self.numRes = symb
225 |
226 | def getFreeSpace(self):
227 | freeSpace = self.numRes
228 | if len(self.res)>0:
229 | for tbl in self.res:
230 | freeSpace = freeSpace - 1
231 | return freeSpace
232 |
233 | def insertTB(self,tb):
234 | succ = False
235 | freeSpace = self.getFreeSpace()
236 | if freeSpace>=1:
237 | self.res.append(tb) # The TB fits the free space
238 | succ = True
239 | else:
240 | succ = False
241 | print (Format.CRED+'Not enough space!!! : '+str(freeSpace)+'/'+str(tb.numRB)+Format.CEND)
242 | return succ
243 |
244 | def removeTB(self):
245 | if len(self.res)>0:
246 | return self.res.popleft()
247 |
248 | def updateSize(self,newSize):
249 | self.numRes = newSize
250 |
--------------------------------------------------------------------------------
/Slice.py:
--------------------------------------------------------------------------------
1 | """This module contains the Slice class.
2 | """
3 | from IntraSliceSch import IntraSliceScheduler, LTE_scheduler
4 | from Scheds_Intra import *
5 | from collections import deque
6 |
7 | class Slice:
8 | """This class has Slice relative parameters and is used to implement the mapping between service requirements and slice configuration."""
9 | def __init__(self,dly,thDL,thUL,avl,cnxDL,cnxUL,ba,dm,mmd,ly,lbl,tdd,sch):
10 | self.reqDelay = dly
11 | self.reqThroughputDL = thDL
12 | self.reqThroughputUL = thUL
13 | self.reqAvailability = avl
14 | self.reqDLconnections = cnxDL
15 | self.reqULconnections = cnxUL
16 |
17 | self.band = ba
18 | self.PRBs = 0
19 | self.signLoad = 0.000001
20 | self.scs = '15kHz'
21 | self.ttiBms = 1
22 | self.robustMCS = False
23 | self.mimoMd = mmd
24 | self.layers = ly
25 | self.tddSymb = 14
26 | self.schType = sch
27 | self.label = lbl
28 | self.tdd = tdd
29 | self.dm = dm
30 | self.rcvdBytes = deque([0]) # interSlice PF scheduler
31 | self.metric = 0 # interSlice PF scheduler
32 | self.setInitialConfig()
33 | self.schedulerDL = self.createSliceSched('DL',self.tddSymb)
34 | if self.label != 'LTE':
35 | self.schedulerUL = self.createSliceSched('UL',14-self.tddSymb)
36 |
37 | def createSliceSched(self,dir,tddSymb):
38 | """This method initializes and returns slice UL or DL scheduler. Scheduler algorithm is selected according to the Slice attribute schType."""
39 | if self.tdd:
40 | if self.schType[0:2] == 'PF':
41 | scheduler = PF_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,tddSymb,self.robustMCS,self.label,self.schType)
42 | else:
43 | scheduler = TDD_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,tddSymb,self.robustMCS,self.label,self.schType)
44 | else: # FDD Schedulers
45 | if self.label == 'LTE':
46 | scheduler = LTE_scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.mimoMd,self.layers,dir)
47 | elif self.schType[0:2] == 'PF':
48 | scheduler = PF_Scheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,14,self.robustMCS,self.label,self.schType)
49 | else: # RR Scheduler by default
50 | scheduler = IntraSliceScheduler(self.band,self.PRBs,self.dm,self.signLoad,self.ttiBms,self.mimoMd,self.layers,dir,14,self.robustMCS,self.label,self.schType)
51 |
52 | return scheduler
53 |
54 | def setInitialConfig(self):
55 | """This method sets initial Slice configuration according to service requirements."""
56 | self.dly2scs(self.reqDelay)
57 | if self.band == 'n257' or self.band == 'n258' or self.band == 'n260' or self.band == 'n261':
58 | self.tdd = True
59 | numReftable = {'60kHz':1,'120kHz':2}
60 | self.numRefFactor = numReftable[self.scs]
61 | if self.reqDLconnections > 0 and self.reqULconnections == 0:
62 | self.tddSymb = 14
63 | if self.reqULconnections > 0 and self.reqDLconnections == 0:
64 | self.tddSymb = 0
65 | if self.reqULconnections > 0 and self.reqDLconnections > 0:
66 | DLfactor = float(self.reqDLconnections*self.reqThroughputDL)/(self.reqDLconnections*self.reqThroughputDL+self.reqULconnections*self.reqThroughputUL)
67 | self.tddSymb = int(14*DLfactor)
68 | # print(DLfactor,self.tddSymb)
69 | else:
70 | #self.tdd = False
71 | self.numRefFactor = self.ttiBms
72 |
73 | if self.reqAvailability == 'High':
74 | self.robustMCS = True
75 |
76 | if 'mMTC' in self.label:
77 | self.signLoad = 0.003
78 |
79 | def dly2scs(self,delay):
80 | """This method sets Slice numerology depending on delay requirements."""
81 | if self.band == 'n257' or self.band == 'n258' or self.band == 'n260' or self.band == 'n261': #FR2
82 | if delay<=2.5:
83 | self.scs = '120kHz'
84 | self.ttiBms = 8
85 | else:
86 | self.scs = '60kHz'
87 | self.ttiBms = 4
88 | else: # FR1
89 | if delay<=5:
90 | self.scs = '60kHz'
91 | self.ttiBms = 4
92 | elif delay<=10:
93 | self.scs = '30kHz'
94 | self.ttiBms = 2
95 | else:
96 | self.scs = '15kHz'
97 | self.ttiBms = 1
98 |
99 | def updateConfig(self,n):
100 | """This method updates Slice allocated PRBs."""
101 | self.PRBs = n
102 | self.schedulerDL.nrbUEmax = self.PRBs
103 | if self.label != 'LTE':
104 | self.schedulerUL.nrbUEmax = self.PRBs
105 | if self.mimoMd == 'MU':
106 | self.schedulerDL.queue.updateSize(self.PRBs*self.layers)
107 | if self.label != 'LTE':
108 | self.schedulerUL.queue.updateSize(self.PRBs*self.layers)
109 | else:
110 | self.schedulerDL.queue.updateSize(self.PRBs)
111 | if self.label != 'LTE':
112 | self.schedulerUL.queue.updateSize(self.PRBs)
113 |
--------------------------------------------------------------------------------
/UE.py:
--------------------------------------------------------------------------------
1 | """ This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases.
2 | This clases are oriented to describe UE traffic profile, and UE relative concepts
3 | """
4 | import os
5 | import sys
6 | import random
7 | import simpy
8 | from collections import deque
9 |
10 | # UE class: terminal description
11 |
12 | class UE():
13 | """ This class is used to model UE behabiour and relative properties """
14 | def __init__(self, i,ue_sinr0,p,npM):
15 | self.id = i
16 | self.state = 'RRC-IDLE'
17 | self.packetFlows = []
18 | self.bearers = []
19 | self.radioLinks = RadioLink(1,ue_sinr0,self.id)
20 | self.TBid = 1
21 | self.pendingPckts = {}
22 | self.prbs = p
23 | self.resUse = 0
24 | self.pendingTB = []
25 | self.bler = 0
26 | self.tbsz = 1
27 | self.MCS = 0
28 | self.pfFactor = 1 # PF Scheduler
29 | self.pastTbsz = deque([1]) # PF Scheduler
30 | self.lastDen = 0.001 # PF Scheduler
31 | self.num = 0 # PF Scheduler
32 | self.BWPs = npM
33 | self.TXedTB = 1
34 | self.lostTB = 0
35 | self.symb = 0
36 |
37 | def addPacketFlow(self,pckFl):
38 | self.packetFlows.append(pckFl)
39 |
40 | def addBearer(self,br):
41 | self.bearers.append(br)
42 |
43 | def receivePckt(self,env,c): # PEM -------------------------------------------
44 | """This method takes packets on the application buffers and leave them on the bearer buffers. This is a PEM method."""
45 | while True:
46 | if len(self.packetFlows[0].appBuff.pckts)>0:
47 | if self.state == 'RRC-IDLE': # Not connected
48 | self.connect(c)
49 | nextPackTime = c.tUdQueue
50 | yield env.timeout(nextPackTime)
51 | if nextPackTime > c.inactTimer:
52 | self.releaseConnection(c)
53 | else: # Already connecter user
54 | self.queueDataPckt(c)
55 | nextPackTime = c.tUdQueue
56 | yield env.timeout(nextPackTime)
57 | if nextPackTime > c.inactTimer:
58 | self.releaseConnection(c)
59 | else:
60 | nextPackTime = c.tUdQueue
61 | yield env.timeout(nextPackTime)
62 |
63 | def connect(self,cl):
64 | """This method creates bearers and bearers buffers."""
65 | bD = Bearer(1,9,self.packetFlows[0].type)
66 | self.addBearer(bD)
67 | self.queueDataPckt(cl)
68 | if self.packetFlows[0].type == 'DL':
69 | if (list(cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues.keys()).count(self.id))<1:
70 | cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues[self.id] = self
71 | else:
72 | if (list(cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues.keys()).count(self.id))<1:
73 | cl.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues[self.id] = self
74 | self.state = 'RRC-CONNECTED'
75 |
76 |
77 | def queueDataPckt(self,cell):
78 | """This method queues the packets taken from the application buffer in the bearer buffers."""
79 | pD = self.packetFlows[0].appBuff.removePckt()
80 | buffSizeAllUEs = 0
81 | buffSizeThisUE = 0
82 | if self.packetFlows[0].type == 'DL':
83 | for ue in list(cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues.keys()):
84 | buffSizeUE = 0
85 | for p in cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerDL.ues[ue].bearers[0].buffer.pckts:
86 | buffSizeUE = buffSizeUE + p.size
87 | if self.id == ue:
88 | buffSizeThisUE = buffSizeUE
89 | buffSizeAllUEs = buffSizeAllUEs + buffSizeUE
90 | else:
91 | for ue in list(cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues.keys()):
92 | buffSizeUE = 0
93 | for p in cell.interSliceSched.slices[self.packetFlows[0].sliceName].schedulerUL.ues[ue].bearers[0].buffer.pckts:
94 | buffSizeUE = buffSizeUE + p.size
95 | if self.id == ue:
96 | buffSizeThisUE = buffSizeUE
97 | buffSizeAllUEs = buffSizeAllUEs + buffSizeUE
98 |
99 | if buffSizeThisUE
'+str(self.id)+' packet '+str(pcktN)+' lost .....'+str(pD.tIn)+'
') 108 | self.packetFlows[0].lostPackets = self.packetFlows[0].lostPackets + 1 109 | 110 | def releaseConnection(self,cl): 111 | self.state = 'RRC-IDLE' 112 | self.bearers = [] 113 | 114 | # ------------------------------------------------ 115 | # PacketFlow class: PacketFlow description 116 | class PacketFlow(): 117 | """ This class is used to describe UE traffic profile for the simulation.""" 118 | def __init__(self,i,pckSize,pckArrRate,u,tp,slc): 119 | self.id = i 120 | self.tMed = 0 121 | self.sMed = 0 122 | self.type = tp 123 | self.sliceName = slc 124 | self.pckArrivalRate = pckArrRate 125 | self.qosFlowId = 0 126 | self.packetSize = pckSize 127 | self.ue = u 128 | self.sMax = (float(self.packetSize)/350)*600 129 | self.tMax = (float(self.pckArrivalRate)/6)*12.5 130 | self.tStart = 0 131 | self.appBuff = PcktQueue() 132 | self.lostPackets = 0 133 | self.sentPackets = 0 134 | self.rcvdBytes = 0 135 | self.pId = 1 136 | self.header = 30 137 | self.meassuredKPI = {'Throughput':0,'Delay':0,'PacketLossRate':0} 138 | 139 | 140 | def setQosFId(self,q): 141 | qosFlowId = q 142 | 143 | def queueAppPckt(self,env,tSim): # --- PEM ----- 144 | """This method creates packets according to the packet flow traffic profile and stores them in the application buffer. """ 145 | ueN = int(self.ue[2:]) # number of UEs in simulation 146 | self.tStart = (random.expovariate(1.0)) 147 | yield env.timeout(self.tStart) # each UE start transmission after tStart 148 | while env.now<(tSim*0.83): 149 | self.sentPackets = self.sentPackets + 1 150 | size = self.getPsize() 151 | pD = Packet(self.pId,size+self.header,self.qosFlowId,self.ue) 152 | self.pId = self.pId + 1 153 | pD.tIn = env.now 154 | self.appBuff.insertPckt(pD) 155 | nextPackTime = self.getParrRate() 156 | yield env.timeout(nextPackTime) 157 | 158 | def getPsize(self): 159 | pSize = random.paretovariate(1.2)*(self.packetSize*(0.2/1.2)) 160 | while pSize > self.sMax: 161 | pSize = random.paretovariate(1.2)*(self.packetSize*(0.2/1.2)) 162 | self.sMed = self.sMed + pSize 163 | return pSize 164 | 165 | def getParrRate(self): 166 | pArrRate = random.paretovariate(1.2)*(self.pckArrivalRate*(0.2/1.2)) 167 | while pArrRate > self.tMax: 168 | pArrRate = random.paretovariate(1.2)*(self.pckArrivalRate*(0.2/1.2)) 169 | self.tMed = self.tMed + pArrRate 170 | return pArrRate 171 | 172 | def setMeassures(self,tsim): 173 | """This method calculates average PLR and throughput for the simulation.""" 174 | self.meassuredKPI['PacketLossRate'] = float(100*self.lostPackets)/self.sentPackets 175 | if tsim>1000: 176 | self.meassuredKPI['Throughput'] = (float(self.rcvdBytes)*8000)/(0.83*tsim*1024*1024) 177 | else: 178 | self.meassuredKPI['Throughput'] = 0 179 | 180 | class Packet: 181 | """This class is used to model packets properties and behabiour.""" 182 | def __init__(self,sn,s,qfi,u): 183 | self.secNum = sn 184 | self.size = s 185 | self.qosFlowId = qfi 186 | self.ue = u 187 | self.tIn = 0 188 | 189 | def printPacket(self): 190 | print (Format.CYELLOW + Format.CBOLD + self.ue+ '+packet '+str(self.secNum)+' arrives at t ='+str(now()) + Format.CEND) 191 | 192 | class Bearer: 193 | """This class is used to model Bearers properties and behabiour.""" 194 | def __init__(self,i,q,tp): 195 | self.id = i 196 | self.qci = q 197 | self.type = tp 198 | self.buffer = PcktQueue() 199 | 200 | class PcktQueue: 201 | """This class is used to model application and bearer buffers.""" 202 | def __init__(self): 203 | self.pckts = deque([]) 204 | 205 | def insertPckt(self,p): 206 | self.pckts.append(p) 207 | 208 | def insertPcktLeft(self,p): 209 | self.pckts.appendleft(p) 210 | 211 | def removePckt(self): 212 | if len(self.pckts)>0: 213 | return self.pckts.popleft() 214 | 215 | class RadioLink(): 216 | """This class is used to model radio link properties and behabiour.""" 217 | def __init__(self,i,lq_0,u): 218 | self.id = i 219 | state = 'ON' 220 | self.linkQuality = lq_0 221 | self.ue = u 222 | self.totCount = 0 223 | self.maxVar = 0.1 224 | 225 | def updateLQ(self,env,udIntrv,tSim,fl,u,r): 226 | """This method updates UE link quality in terms of SINR during the simulation. This is a PEM method. 227 | 228 | During the simulation it is assumed that UE SINR varies following a normal distribution with mean value equal to initial SINR value, and a small variance.""" 229 | 230 | while env.now<(tSim*0.83): 231 | yield env.timeout(udIntrv) 232 | deltaSINR = random.normalvariate(0, self.maxVar) 233 | while deltaSINR > self.maxVar or deltaSINR<(0-self.maxVar): 234 | deltaSINR = random.normalvariate(0, self.maxVar) 235 | self.linkQuality = self.linkQuality + deltaSINR 236 | 237 | class Format: 238 | CEND = '\33[0m' 239 | CBOLD = '\33[1m' 240 | CITALIC = '\33[3m' 241 | CURL = '\33[4m' 242 | CBLINK = '\33[5m' 243 | CBLINK2 = '\33[6m' 244 | CSELECTED = '\33[7m' 245 | CBLACK = '\33[30m' 246 | CRED = '\33[31m' 247 | CGREEN = '\33[32m' 248 | CYELLOW = '\33[33m' 249 | CBLUE = '\33[34m' 250 | CVIOLET = '\33[35m' 251 | CBEIGE = '\33[36m' 252 | CWHITE = '\33[37m' 253 | CGREENBG = '\33[42m' 254 | CBLUEBG = '\33[44m' 255 | -------------------------------------------------------------------------------- /doc/Py5cheSim.Cell.Cell.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 |class Cell:
Cell class has cell relative parameters and collect kpi ststistics.
| Method | 51 |__init__ |
52 | This method creates a cell instance. | 53 |
| Instance Variable | 56 |id |
57 | Undocumented | 58 |
| Instance Variable | 61 |bw |
62 | Undocumented | 63 |
| Instance Variable | 66 |inactTimer |
67 | Undocumented | 68 |
| Instance Variable | 71 |tUdQueue |
72 | Undocumented | 73 |
| Instance Variable | 76 |maxBuffUE |
77 | Maximum bearer buffer size by UE, in bytes | 78 |
| Instance Variable | 81 |sch |
82 | Undocumented | 83 |
| Instance Variable | 86 |interSliceSched |
87 | Undocumented | 88 |
| Instance Variable | 91 |slicesStsts |
92 | Undocumented | 93 |
| Method | 96 |updateStsts |
97 | This method manages the statistics collection. This is a PEM Method. | 98 |
This method creates a cell instance.
It initialices cell parameters and interSliceScheduler according to the algorithm specified on the sch attribute.
Undocumented
Undocumented
Undocumented
int)
178 | Undocumented
float)
196 | Maximum bearer buffer size by UE, in bytes
Undocumented
str)
232 | Undocumented
Undocumented
dict)
268 | This method manages the statistics collection. This is a PEM Method.
This method creates statistics files and stores counter values to calculate later the main kpi considered.
Inter Slice statistics are stored in the dlStsts_InterSlice.txt file for DL and ulStsts_InterSlice.txt file for UL.
Intra Slice statistics are stored in the dlStsts_<Slicename>Slice.txt file for DL and ulStsts_<Slicename>Slice.txt file for UL.
This module contains the Cell class.
| Class | 51 |Cell |
52 | Cell class has cell relative parameters and collect kpi ststistics. | 53 |
Py5cheSim.InterSliceSch.InterSliceSchedulerclass InterSliceScheduler:
Basic inter slice scheduler. It implements Round Robin algorithm.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |bw |
57 | Undocumented | 58 |
| Instance Variable | 61 |FR |
62 | Undocumented | 63 |
| Instance Variable | 66 |nRBtable |
67 | Undocumented | 68 |
| Instance Variable | 71 |PRBs |
72 | Undocumented | 73 |
| Instance Variable | 76 |slices |
77 | Undocumented | 78 |
| Instance Variable | 81 |dm |
82 | Undocumented | 83 |
| Instance Variable | 86 |dbFile |
87 | Undocumented | 88 |
| Instance Variable | 91 |tdd |
92 | Undocumented | 93 |
| Instance Variable | 96 |granularity |
97 | Undocumented | 98 |
| Method | 101 |resAlloc |
102 | This method implements Round Robin PRB allocation between the different configured slices. This is a PEM method | 103 |
| Method | 106 |createSlice |
107 | This method creates a slice and stores it in the slices dictionary. | 108 |
| Method | 111 |printSliceConfig |
112 | This method stores inter slice scheduling debugging information on the log file. | 113 |
Undocumented
Undocumented
Undocumented
Undocumented
dict[str, dict])
193 | Undocumented
Undocumented
dict)
229 | Undocumented
Undocumented
Undocumented
Undocumented
This method implements Round Robin PRB allocation between the different configured slices. This is a PEM method
This method creates a slice and stores it in the slices dictionary.
This method stores inter slice scheduling debugging information on the log file.
Py5cheSim.InterSliceSchThis module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this.
| Class | 51 |InterSliceScheduler |
52 | Basic inter slice scheduler. It implements Round Robin algorithm. | 53 |
Py5cheSim.IntraSliceSch.TBqueueclass TBqueue:
This class is used to model scheduler TB queue.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |res |
57 | Undocumented | 58 |
| Instance Variable | 61 |numRB |
62 | Undocumented | 63 |
| Method | 66 |getFreeSpace |
67 | Undocumented | 68 |
| Method | 71 |insertTB |
72 | Undocumented | 73 |
| Method | 76 |removeTB |
77 | Undocumented | 78 |
| Method | 81 |updateSize |
82 | Undocumented | 83 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Py5cheSim.IntraSliceSch.TransportBlockclass TransportBlock:
This class is used to describe TB properties and behabiour.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |id |
57 | Undocumented | 58 |
| Instance Variable | 61 |mod |
62 | Undocumented | 63 |
| Instance Variable | 66 |ue |
67 | Undocumented | 68 |
| Instance Variable | 71 |type |
72 | Undocumented | 73 |
| Instance Variable | 76 |pckt_l |
77 | Undocumented | 78 |
| Instance Variable | 81 |numRB |
82 | Undocumented | 83 |
| Instance Variable | 86 |reTxNum |
87 | Undocumented | 88 |
| Instance Variable | 91 |size |
92 | Undocumented | 93 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
int)
245 | Undocumented
Py5cheSim.IntraSliceSchThis module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this.
| Class | 51 |IntraSliceScheduler |
52 | Basic intra slice scheduler. It implements Round Robin algorithm. | 53 |
| Class | 56 |LTE_scheduler |
57 | Basic intra slice LTE scheduler. It implements Round Robin algorithm for scheduling in a LTE Slice. | 58 |
| Class | 61 |TBqueue |
62 | This class is used to model scheduler TB queue. | 63 |
| Class | 66 |TransportBlock |
67 | This class is used to describe TB properties and behabiour. | 68 |
| Class | 71 |Format |
72 | Undocumented | 73 |
This module contains auxiliary simulation classes and methods along with results processing.
| Function | 51 |initialSinrGenerator |
52 | Auxiliary method for SINR generation. This method is used to generate initial UE SINR. Later, during the simulation SINR will have small variations with time. | 53 |
| Class | 56 |UEgroup |
57 | This class is used to describe traffic profile and requirements of group of UE which the simulation will run for. It is assumed that all UEs shares the same traffic profile and service requirements, and will be served by the same slice. | 58 |
| Function | 61 |printResults |
62 | This method prints main simulation results on the terminal | 63 |
| Function | 66 |getKPIs |
67 | This method gets the intra slice kpi from the statistic files | 68 |
| Function | 71 |getKPIsInter |
72 | This method gets the inter Slice kpi from the statistic files | 73 |
| Function | 76 |makeTimePlot |
77 | This method makes basic time plots. Labels deppend on which kpi is being plotted. | 78 |
| Function | 81 |makeIntraSlicePlot |
82 | This method makes and stores any Intra Slice plot | 83 |
| Function | 86 |makeInterSlicePlot |
87 | This method makes and stores any Inter Slice plot | 88 |
| Function | 91 |makePlotsIntra |
92 | This method makes all Intra Slice kpi plots | 93 |
| Function | 96 |makePlotsInter |
97 | This method makes all Inter Slice kpi plots | 98 |
Auxiliary method for SINR generation. This method is used to generate initial UE SINR. Later, during the simulation SINR will have small variations with time.
This method prints main simulation results on the terminal
This method gets the intra slice kpi from the statistic files
This method gets the inter Slice kpi from the statistic files
This method makes basic time plots. Labels deppend on which kpi is being plotted.
This method makes and stores any Intra Slice plot
This method makes and stores any Inter Slice plot
This method makes all Intra Slice kpi plots
This method makes all Inter Slice kpi plots
Py5cheSim.Scheds_Inter.PF_Schedulerclass PF_Scheduler(InterSliceScheduler):
This class implements Proportional Fair inter slice scheduling algorithm.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |sch |
57 | String formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent. | 58 |
| Instance Variable | 61 |rcvdBytesLen |
62 | rcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored. | 63 |
| Method | 66 |resAlloc |
67 | This method implements Proportional Fair resource allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class. | 68 |
| Method | 71 |setMetric |
72 | This method sets the PF metric for each slice | 73 |
| Method | 76 |findMaxMetSlice |
77 | This method finds and returns the Slice with the highest metric | 78 |
| Method | 81 |assign2aSlice |
82 | This method allocates cell's PRBs to the indicated slice | 83 |
| Method | 86 |printSliceConfig |
87 | This method stores inter slice scheduling debugging information on the log file, adding PF metric values. | 88 |
Undocumented
String formatted as PFXY, with X=numerator exponent for metric formula, and Y=denominator exponent.
rcvdBytes list length in Slice instance. No more that rcvdBytesLen values are stored.
int)
150 | This method implements Proportional Fair resource allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.
Proportional Fair scheduler allocates all PRBs in the cell to the slice with the biggest metric. Metric for each slice is calculated as PossibleAverageUEtbs/ReceivedBytes.
This method sets the PF metric for each slice
This method finds and returns the Slice with the highest metric
This method allocates cell's PRBs to the indicated slice
This method stores inter slice scheduling debugging information on the log file, adding PF metric values.
Py5cheSim.Scheds_Inter.RRplus_Schedulerclass RRplus_Scheduler(InterSliceScheduler):
This class implements Round Robin Plus inter slice scheduling algorithm.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Method | 56 |resAlloc |
57 | This method implements Round Robin Plus PRB allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class. | 58 |
Undocumented
This method implements Round Robin Plus PRB allocation between the different configured slices. This PEM method overwrites the resAlloc method from InterSliceScheduler class.
Round Robin Plus scheduler allocates the same amount of resources to each slice with packets in buffer.
Py5cheSim.Scheds_InterThis module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure.
| Class | 51 |RRplus_Scheduler |
52 | This class implements Round Robin Plus inter slice scheduling algorithm. | 53 |
| Class | 56 |PF_Scheduler |
57 | This class implements Proportional Fair inter slice scheduling algorithm. | 58 |
Py5cheSim.Scheds_Intra.PF_Schedulerclass PF_Scheduler(IntraSliceScheduler):
This class implements Proportional Fair intra slice scheduling algorithm.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |promLen |
57 | Past Throughput average length considered in PF metric | 58 |
| Method | 61 |resAlloc |
62 | This method implements Proportional Fair resource allocation between the different connected UEs. This method overwrites the resAlloc method from IntraSliceScheduler class. | 63 |
| Method | 66 |setUEfactor |
67 | This method sets the PF metric for each UE | 68 |
| Method | 71 |findMaxFactor |
72 | This method finds and returns the UE with the highest metric | 73 |
| Method | 76 |printResAlloc |
77 | Undocumented | 78 |
Undocumented
Past Throughput average length considered in PF metric
int)
122 | This method implements Proportional Fair resource allocation between the different connected UEs. This method overwrites the resAlloc method from IntraSliceScheduler class.
Proportional Fair scheduler allocates all PRBs in the slice to the UE with the biggest metric. Metric for each UE is calculated as PossibleUEtbs/AveragePastTbs.
This method sets the PF metric for each UE
This method finds and returns the UE with the highest metric
Undocumented
Py5cheSim.Scheds_Intra.TBqueueTDDclass TBqueueTDD:
This class is used to model scheduler TB queue in TDD scheduler.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |res |
57 | Undocumented | 58 |
| Instance Variable | 61 |numRes |
62 | Undocumented | 63 |
| Method | 66 |getFreeSpace |
67 | Undocumented | 68 |
| Method | 71 |insertTB |
72 | Undocumented | 73 |
| Method | 76 |removeTB |
77 | Undocumented | 78 |
| Method | 81 |updateSize |
82 | Undocumented | 83 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Py5cheSim.Scheds_Intra.TDD_Schedulerclass TDD_Scheduler(IntraSliceScheduler):
This class implements TDD intra slice scheduling.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |symMax |
57 | Undocumented | 58 |
| Instance Variable | 61 |queue |
62 | TDD scheduler TB queue. | 63 |
| Method | 66 |resAlloc |
67 | This method implements resource allocation between the different connected UEs in a TDD slice. | 68 |
| Method | 71 |queueUpdate |
72 | This method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes. | 73 |
| Instance Variable | 76 |ueLst |
77 | Undocumented | 78 |
| Instance Variable | 81 |sm_lim |
82 | Undocumented | 83 |
| Method | 86 |rrcUncstSigIn |
87 | Undocumented | 88 |
| Method | 91 |retransmitTB |
92 | Undocumented | 93 |
| Method | 96 |dataPtoTB |
97 | This method takes UE data bytes, builds TB and puts them in the scheduler TB queue. | 98 |
| Method | 101 |setTBS |
102 | Undocumented | 103 |
| Method | 106 |printResAlloc |
107 | Undocumented | 108 |
Undocumented
Undocumented
TDD scheduler TB queue.
IntraSliceScheduler class attribute queue is overwriten here by a new type of queue which handles symbols. This queue will contain as much TB as a slot can contain. If resource allocation is made in terms of slots, it will contain 1 element, else, it will contain as much mini-slots as can be supported in 1 slot.
This method implements resource allocation between the different connected UEs in a TDD slice.
It overwrites the resAlloc method from IntraSliceScheduler class. In this Py5cheSim version TDD scheduler allocates all PRBs in the slice to a UE during 1 slot. Future Py5cheSim versions could support mini-slot allocation by changing the UE symbol allocation in this method. Note that in that case, althoug there is no need to update the queueUpdate method, TBS calculation must be adjusted to avoid losing capacity when trunking the Nre__ value.
This method fills scheduler TB queue at each TTI with TBs built with UE data/signalling bytes.
It overwrites queueUpdate method from IntraSliceScheduler class, making Resource allocation in terms of slot Symbols and insert generated TBs into Scheduler queue in a TTI. Althoug in this version Resource allocation is made by slot, it is prepared to support mini-slot resource allocation by handling a scheduler TB queue in terms of symbols.
Undocumented
Undocumented
Undocumented
Undocumented
This method takes UE data bytes, builds TB and puts them in the scheduler TB queue.
It overwrites dataPtoTB method from IntraSliceScheduler class. In this case it returns the amount of allocated symbols to the UE.
Undocumented
Undocumented
Py5cheSim.Scheds_IntraThis module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure.
| Class | 51 |PF_Scheduler |
52 | This class implements Proportional Fair intra slice scheduling algorithm. | 53 |
| Class | 56 |TDD_Scheduler |
57 | This class implements TDD intra slice scheduling. | 58 |
| Class | 61 |TBqueueTDD |
62 | This class is used to model scheduler TB queue in TDD scheduler. | 63 |
This module contains the Slice class.
| Class | 51 |Slice |
52 | This class has Slice relative parameters and is used to implement the mapping between service requirements and slice configuration. | 53 |
class Bearer:
This class is used to model Bearers properties and behabiour.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |id |
57 | Undocumented | 58 |
| Instance Variable | 61 |qci |
62 | Undocumented | 63 |
| Instance Variable | 66 |type |
67 | Undocumented | 68 |
| Instance Variable | 71 |buffer |
72 | Undocumented | 73 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
class Format:
Undocumented
| Class Variable | 51 |CEND |
52 | Undocumented | 53 |
| Class Variable | 56 |CBOLD |
57 | Undocumented | 58 |
| Class Variable | 61 |CITALIC |
62 | Undocumented | 63 |
| Class Variable | 66 |CURL |
67 | Undocumented | 68 |
| Class Variable | 71 |CBLINK |
72 | Undocumented | 73 |
| Class Variable | 76 |CBLINK2 |
77 | Undocumented | 78 |
| Class Variable | 81 |CSELECTED |
82 | Undocumented | 83 |
| Class Variable | 86 |CBLACK |
87 | Undocumented | 88 |
| Class Variable | 91 |CRED |
92 | Undocumented | 93 |
| Class Variable | 96 |CGREEN |
97 | Undocumented | 98 |
| Class Variable | 101 |CYELLOW |
102 | Undocumented | 103 |
| Class Variable | 106 |CBLUE |
107 | Undocumented | 108 |
| Class Variable | 111 |CVIOLET |
112 | Undocumented | 113 |
| Class Variable | 116 |CBEIGE |
117 | Undocumented | 118 |
| Class Variable | 121 |CWHITE |
122 | Undocumented | 123 |
| Class Variable | 126 |CGREENBG |
127 | Undocumented | 128 |
| Class Variable | 131 |CBLUEBG |
132 | Undocumented | 133 |
Undocumented
str)
159 | Undocumented
str)
177 | Undocumented
str)
195 | Undocumented
str)
213 | Undocumented
str)
231 | Undocumented
str)
249 | Undocumented
str)
267 | Undocumented
str)
285 | Undocumented
str)
303 | Undocumented
str)
321 | Undocumented
str)
339 | Undocumented
str)
357 | Undocumented
str)
375 | Undocumented
str)
393 | Undocumented
str)
411 | Undocumented
str)
429 | Undocumented
str)
447 | class Packet:
This class is used to model packets properties and behabiour.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |secNum |
57 | Undocumented | 58 |
| Instance Variable | 61 |size |
62 | Undocumented | 63 |
| Instance Variable | 66 |qosFlowId |
67 | Undocumented | 68 |
| Instance Variable | 71 |ue |
72 | Undocumented | 73 |
| Instance Variable | 76 |tIn |
77 | Undocumented | 78 |
| Method | 81 |printPacket |
82 | Undocumented | 83 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
int)
199 | Undocumented
class PcktQueue:
This class is used to model application and bearer buffers.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |pckts |
57 | Undocumented | 58 |
| Method | 61 |insertPckt |
62 | Undocumented | 63 |
| Method | 66 |insertPcktLeft |
67 | Undocumented | 68 |
| Method | 71 |removePckt |
72 | Undocumented | 73 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
class RadioLink:
This class is used to model radio link properties and behabiour.
| Method | 51 |__init__ |
52 | Undocumented | 53 |
| Instance Variable | 56 |id |
57 | Undocumented | 58 |
| Instance Variable | 61 |linkQuality |
62 | Undocumented | 63 |
| Instance Variable | 66 |ue |
67 | Undocumented | 68 |
| Instance Variable | 71 |totCount |
72 | Undocumented | 73 |
| Instance Variable | 76 |maxVar |
77 | Undocumented | 78 |
| Method | 81 |updateLQ |
82 | This method updates UE link quality in terms of SINR during the simulation. This is a PEM method. | 83 |
Undocumented
Undocumented
Undocumented
Undocumented
Undocumented
int)
181 | Undocumented
float)
199 | This method updates UE link quality in terms of SINR during the simulation. This is a PEM method.
During the simulation it is assumed that UE SINR varies following a normal distribution with mean value equal to initial SINR value, and a small variance.
This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative concepts
| Class | 51 |UE |
52 | This class is used to model UE behabiour and relative properties | 53 |
| Class | 56 |PacketFlow |
57 | This class is used to describe UE traffic profile for the simulation. | 58 |
| Class | 61 |Packet |
62 | This class is used to model packets properties and behabiour. | 63 |
| Class | 66 |Bearer |
67 | This class is used to model Bearers properties and behabiour. | 68 |
| Class | 71 |PcktQueue |
72 | This class is used to model application and bearer buffers. | 73 |
| Class | 76 |RadioLink |
77 | This class is used to model radio link properties and behabiour. | 78 |
| Class | 81 |Format |
82 | Undocumented | 83 |
Py5cheSimUndocumented
| Module | 51 |Cell |
52 | This module contains the Cell class. | 53 |
| Module | 56 |InterSliceSch |
57 | This module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this. | 58 |
| Module | 61 |IntraSliceSch |
62 | This module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this. | 63 |
| Module | 66 |Results |
67 | This module contains auxiliary simulation classes and methods along with results processing. | 68 |
| Module | 71 |Scheds_Inter |
72 | This module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure. | 73 |
| Module | 76 |Scheds_Intra |
77 | This module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure. | 78 |
| Module | 81 |Slice |
82 | This module contains the Slice class. | 83 |
| Module | 86 |UE |
87 | This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative concepts | 88 |
| Module | 91 |simulation |
92 | This is the simulation script. Simulation, cell and traffic profile parameters can be set here. | 93 |
label
208 | This applies to inline docstring content marked up as code,
209 | for example L{foo} in epytext or `bar` in restructuredtext,
210 | but also to links that are present in summary tables.
211 | - 'functionHeader' is used for lines like `def func():` and `var =`
212 | */
213 | code, .pre, #childList > div .functionHeader,
214 | #splitTables > table tr td:nth-child(2), .fieldTable tr td.fieldArg {
215 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
216 | }
217 | code, #childList > div .functionHeader, .fieldTable tr td.fieldArg {
218 | font-size: 90%;
219 | color: #222222;
220 | }
221 | code > a {
222 | color:#c7254e;
223 | background-color:#f9f2f4;
224 | }
225 | /* top navagation bar */
226 | .page-header > h1 {
227 | margin-top: 0;
228 | }
229 | .page-header > h1 > code {
230 | color: #971c3a;
231 | }
232 |
233 | /*
234 | This defines the code style, it's black on light gray.
235 | It also overwrite the default values inherited from bootstrap min
236 | */
237 | code {
238 | padding:2px 4px;
239 | background-color: #f4f4f4;
240 | border-radius:4px
241 | }
242 |
243 |
244 | a.functionSourceLink {
245 | font-weight: normal;
246 | }
247 |
248 |
249 | #childList > div {
250 | border-left-color: #03a9f4;
251 | border-left-width: 1px;
252 | border-left-style: solid;
253 | background: #fafafa;
254 | }
255 |
256 | .moduleDocstring {
257 | margin: 20px;
258 | }
259 |
260 | #partOf {
261 | margin-top: -13px;
262 | margin-bottom: 19px;
263 | }
264 |
265 | .fromInitPy {
266 | font-style: italic;
267 | }
268 |
269 | pre {
270 | padding-left: 0px;
271 | }
272 |
273 | /* Private stuff */
274 |
275 | body.private-hidden #splitTables .private,
276 | body.private-hidden #childList .private,
277 | body.private-hidden #summaryTree .private {
278 | display: none;
279 | }
280 |
281 | #showPrivate {
282 | padding: 10px;
283 | }
284 |
285 | #current-docs-container {
286 | font-style: italic;
287 | padding-top: 11px;
288 | }
289 |
290 | /* Deprecation stuff */
291 |
292 | .deprecationNotice {
293 | margin: 10px;
294 | }
295 |
296 | /* Syntax highlighting for source code */
297 |
298 | .py-string {
299 | color: #337ab7;
300 | }
301 | .py-comment {
302 | color: #309078;
303 | font-style: italic;
304 | }
305 | .py-keyword {
306 | font-weight: bold;
307 | }
308 | .py-defname {
309 | color: #a947b8;
310 | font-weight: bold;
311 | }
312 | .py-builtin {
313 | color: #fc7844;
314 | font-weight: bold;
315 | }
316 |
317 | /* Doctest */
318 |
319 | pre.py-doctest {
320 | padding: .5em;
321 | }
322 | .py-prompt, .py-more {
323 | color: #a8a8a8;
324 | }
325 | .py-output {
326 | color: #c7254e;
327 | }
328 |
329 | /* Admonitions */
330 |
331 | div.rst-admonition p.rst-admonition-title:after {
332 | content: ":";
333 | }
334 |
335 | div.rst-admonition p.rst-admonition-title {
336 | margin: 0;
337 | padding: 0.1em 0 0.35em 0em;
338 | font-weight: bold;
339 | }
340 |
341 | div.rst-admonition p.rst-admonition-title {
342 | color: #333333;
343 | }
344 |
345 | div.rst-admonition {
346 | padding: 8px;
347 | margin-bottom: 20px;
348 | background-color: #EEE;
349 | border: 1px solid #CCC;
350 | border-radius: 4px;
351 | }
352 |
353 | div.warning, div.attention, div.danger, div.error, div.caution {
354 | background-color: #ffcf9cb0;
355 | border: 1px solid #ffbbaa;
356 | }
357 |
358 | div.danger p.rst-admonition-title, div.error p.rst-admonition-title, div.caution p.rst-admonition-title {
359 | color: #b94a48;
360 | }
361 |
362 | div.tip p.rst-admonition-title, div.hint p.rst-admonition-title, div.important p.rst-admonition-title{
363 | color: #3a87ad;
364 | }
365 |
366 | div.tip, div.hint, div.important {
367 | background-color: #d9edf7;
368 | border-color: #bce8f1;
369 | }
370 |
--------------------------------------------------------------------------------
/doc/classIndex.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | InterSliceSch.InterSliceSchedulerPy5cheSim.Scheds_Inter.PF_Scheduler - This class implements Proportional Fair inter slice scheduling algorithm.Py5cheSim.Scheds_Inter.RRplus_Scheduler - This class implements Round Robin Plus inter slice scheduling algorithm.IntraSliceSch.IntraSliceSchedulerPy5cheSim.Scheds_Intra.PF_Scheduler - This class implements Proportional Fair intra slice scheduling algorithm.Py5cheSim.Scheds_Intra.TDD_Scheduler - This class implements TDD intra slice scheduling.Py5cheSim.Cell.Cell - Cell class has cell relative parameters and collect kpi ststistics.Py5cheSim.InterSliceSch.InterSliceScheduler - Basic inter slice scheduler. It implements Round Robin algorithm.Py5cheSim.IntraSliceSch.Format - UndocumentedPy5cheSim.IntraSliceSch.IntraSliceScheduler - Basic intra slice scheduler. It implements Round Robin algorithm.Py5cheSim.IntraSliceSch.LTE_scheduler - Basic intra slice LTE scheduler. It implements Round Robin algorithm for scheduling in a LTE Slice.Py5cheSim.IntraSliceSch.TBqueue - This class is used to model scheduler TB queue.Py5cheSim.IntraSliceSch.TransportBlock - This class is used to describe TB properties and behabiour.Py5cheSim.Results.UEgroup - This class is used to describe traffic profile and requirements of group of UE which the simulation will run for. It is assumed that all UEs shares the same traffic profile and service requirements, and will be served by the same slice.Py5cheSim.Scheds_Intra.TBqueueTDD - This class is used to model scheduler TB queue in TDD scheduler.Py5cheSim.Slice.Slice - This class has Slice relative parameters and is used to implement the mapping between service requirements and slice configuration.Py5cheSim.UE.Bearer - This class is used to model Bearers properties and behabiour.Py5cheSim.UE.Format - UndocumentedPy5cheSim.UE.Packet - This class is used to model packets properties and behabiour.Py5cheSim.UE.PacketFlow - This class is used to describe UE traffic profile for the simulation.Py5cheSim.UE.PcktQueue - This class is used to model application and bearer buffers.Py5cheSim.UE.RadioLink - This class is used to model radio link properties and behabiour.Py5cheSim.UE.UE - This class is used to model UE behabiour and relative propertiesPy5cheSim, the root package.48 | This documentation was automatically generated by 49 | pydoctor 50 | 21.2.2 51 | at 2021-09-05 13:11:47. 52 |
53 | 54 |Py5cheSim - No package docstring; 9/9 modules documentedPy5cheSim.Cell - This module contains the Cell class.Py5cheSim.InterSliceSch - This module contains the basic Inter Slice Scheduler class. All possible inter slice schedulers should inherit from this.Py5cheSim.IntraSliceSch - This module contains the basic Intra Slice Scheduler class. All possible intra slice schedulers should inherit from this.Py5cheSim.Results - This module contains auxiliary simulation classes and methods along with results processing.Py5cheSim.Scheds_Inter - This module contains different implemented inter slice schedulers. New schedulers should be implemented here following the current structure.Py5cheSim.Scheds_Intra - This module contains different implemented intra slice schedulers. New schedulers should be implemented here following the current structure.Py5cheSim.Slice - This module contains the Slice class.Py5cheSim.UE - This module contains the UE, Packet Flow, Packet, PcktQueue, Bearer and RadioLink clases. This clases are oriented to describe UE traffic profile, and UE relative conceptsPy5cheSim.simulation - This is the simulation script. Simulation, cell and traffic profile parameters can be set here.