dataCreator.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import numpy as np
  4. from scipy.stats import multivariate_normal
  5. import matplotlib.pyplot as plt
  6. class dataCreator:
  7. '''
  8. Generates a pollution scenario
  9. '''
  10. def __init__(self, sceneWidth, sceneLength, numSensor, numRef, rdvR, mvR, phenLowerBound, phenUpperBound, Mu_beta,
  11. Mu_alpha, Bound_beta, Bound_alpha):
  12. self.sceneWidth = sceneWidth # Width of the scene
  13. self.sceneLength = sceneLength # Length of the scene
  14. self.numArea = self.sceneWidth * self.sceneLength # Number of sampled area in the scene
  15. self.numSensor = numSensor # Number of sensors in the scene
  16. self.numRef = numRef # Number of references in the scene
  17. self.rdvR = rdvR # Rendez-vous rate : number of rendez-vous/number of sensors
  18. self.mvR = mvR # missing value rate
  19. self.phenLowerBound = phenLowerBound # lower bound on the phenomena (air pollution concentrations) standard deviation (normal distribution)
  20. self.phenUpperBound = phenUpperBound # upper bound "
  21. self.Mu_beta = Mu_beta # Mean sensors offset
  22. self.Mu_alpha = Mu_alpha # Mean sensors gain
  23. self.Bound_beta = Bound_beta # Offset boundaries
  24. self.Bound_alpha = Bound_alpha # Gain boundaries
  25. self.numRdv = round(self.numSensor * self.rdvR) # Number of sensors having a rendez-vous in the scene
  26. # self.numAreaVisited = self.numSensor+self.numRef-self.numRdv # Number of not empty areas
  27. def create_scene(self, randSeed):
  28. np.random.seed(randSeed) # Random seed
  29. # Creation of the map
  30. self.S = np.zeros(shape=self.numArea)
  31. x = np.linspace(-1, 1, num=self.sceneLength)
  32. y = np.linspace(-1, 1, num=self.sceneWidth)
  33. # Create meshgrid
  34. xx, yy = np.meshgrid(x, y)
  35. coord = np.vstack((xx.ravel(), yy.ravel())).T
  36. # number of pollution pics fixed to 10
  37. # MUTED FOR DEBUGGIN
  38. # for _ in range(10):
  39. # mean = np.squeeze(np.array([2 * (np.random.rand(1) - 0.5), 2 * (np.random.rand(1) - 0.5)]))
  40. # cxy = 0
  41. # cov = np.squeeze(np.array([[self.phenLowerBound + (self.phenUpperBound - self.phenLowerBound) * np.absolute(
  42. # np.random.randn(1) + 0.5), cxy],
  43. # [cxy,
  44. # self.phenLowerBound + (self.phenUpperBound - self.phenLowerBound) * np.absolute(
  45. # np.random.randn(1) + 0.5)]]))
  46. # z = multivariate_normal.pdf(coord, mean=mean, cov=cov)
  47. # self.S = self.S + z
  48. # REMOVE THIS BLOCK AFTER DEBUG
  49. z = multivariate_normal.pdf(coord, mean=[0, 0], cov=[[1, 0], [0, 1]])
  50. z = z - np.min(z)
  51. z = 0.5 * (z / np.max(z)) + 1e-5
  52. self.S = z
  53. # Random locations for the mobile sensors and the references
  54. posRef = np.random.permutation(self.numArea)[0:self.numRef] # Selection of the references
  55. idxSenRdv = np.random.permutation(self.numSensor)[
  56. 0:self.numRdv] # Selection of the sensors having a rendez-vous
  57. idxRefRdv = np.random.randint(self.numRef,
  58. size=self.numRdv) # Selection of the references corresponding to idxSenRdv
  59. # idxSen = np.arange(self.numSensor)
  60. # idxSen = np.delete(idxSen,idxSenRdv) # Still available sensors
  61. # freePos = np.arange(self.numArea)
  62. # freePos = np.delete(freePos,posRef) # Still available positions
  63. # posSen = np.random.choice(freePos,size=(self.numSensor-self.numRdv)) # Selection of the positions
  64. # self.posAll = np.unique(np.concatenate((posRef,posSen))) # All unique positions of sensors and references
  65. # self.posEmpty = np.arange(self.numArea)
  66. # self.posEmpty = np.delete(self.posEmpty,self.posAll)
  67. # Computation of W,G,F and X
  68. self.W = np.zeros(shape=[self.numArea, self.numSensor + 1])
  69. # The references
  70. self.W[posRef, -1] = 1
  71. # The sensors having a rendez-vous
  72. self.W[posRef[idxRefRdv], idxSenRdv] = 1 # np.put(self.W,(self.numSensor+1)*posRef[idxRefRdv]+idxSenRdv,1)
  73. # The other sensors
  74. Ndata = round((1 - self.mvR) * self.numSensor * (self.numArea - self.numRef))
  75. posSen = np.delete(np.arange(self.numArea), posRef)
  76. xx, yy = np.meshgrid(posSen, np.arange(self.numSensor))
  77. idx_mesh_sensor = np.random.permutation((self.numArea - self.numRef) * self.numSensor)[0:Ndata]
  78. self.W[xx.flat[idx_mesh_sensor], yy.flat[idx_mesh_sensor]] = 1
  79. # The areas that are not measured
  80. self.nW = 1 - self.W
  81. self.G = np.ones([self.numArea, 2]) # The last column of G is only composed of ones
  82. self.G[:, 0] = self.S.flat # The first column of G is composed of the true concentration for each area
  83. self.F = np.squeeze([np.maximum(self.Bound_alpha[0], np.minimum(self.Bound_alpha[1],
  84. self.Mu_alpha + 0.5 * np.random.randn(1,
  85. self.numSensor + 1))),
  86. np.maximum(self.Bound_beta[0], np.minimum(self.Bound_beta[1],
  87. self.Mu_beta + 0.5 * np.random.randn(1,
  88. self.numSensor + 1)))])
  89. self.F[:, -1] = [1, 0]
  90. self.Xtheo = np.dot(self.G, self.F)
  91. self.X = np.multiply(self.Xtheo, self.W)
  92. # Computation of omega and phi
  93. self.Omega_G = np.vstack((self.W[:, -1], np.ones(shape=self.numArea))).T
  94. self.Omega_F = np.hstack((np.zeros(shape=(2, self.numSensor)), np.ones(shape=(2, 1))))
  95. self.Phi_G = np.vstack((self.X[:, -1], np.ones(shape=self.numArea))).T
  96. self.Phi_F = np.zeros(shape=(2, self.numSensor + 1))
  97. self.Phi_F[0, -1] = 1
  98. # Faster access to the fixed values, done to avoid time consuming Hadamard product
  99. self.idxOG = np.argwhere(self.Omega_G.flat)
  100. self.sparsePhi_G = self.Phi_G.flat[self.idxOG]
  101. self.idxOF = np.argwhere(self.Omega_F.flat)
  102. self.sparsePhi_F = self.Phi_F.flat[self.idxOF]
  103. # Initial F and G
  104. self.Finit = np.squeeze([np.maximum(self.Bound_alpha[0], np.minimum(self.Bound_alpha[1],
  105. self.Mu_alpha + 0.5 * np.random.randn(1,
  106. self.numSensor + 1))),
  107. np.maximum(self.Bound_beta[0], np.minimum(self.Bound_beta[1],
  108. self.Mu_beta + 0.5 * np.random.randn(1,
  109. self.numSensor + 1)))])
  110. self.Finit[:, -1] = [1, 0]
  111. self.Ginit = np.absolute(np.mean(self.Phi_G[posRef, 0]) + np.random.randn(self.numArea, 2))
  112. np.put(self.Ginit, self.idxOG, self.sparsePhi_G)
  113. def show_scene(self):
  114. plt.imshow(self.S.reshape((self.sceneWidth, self.sceneLength)))
  115. plt.show()
  116. # def show_measured_scene(self):
  117. # obs = np.zeros(shape=(self.sceneWidth,self.sceneLength))
  118. # np.put(obs,self.posAll,1)
  119. # plt.imshow(np.multiply(obs,self.S.reshape((self.sceneWidth,self.sceneLength))))
  120. # plt.show()