You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

413 lines
12 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. from collections import OrderedDict
  2. import numpy as np
  3. import pymongo
  4. import xarray_mongodb
  5. import bson
  6. import builtins
  7. import xarray as xr
  8. from ToolFunction.ToolFunction import get_date
  9. npTypeDict = {v: getattr(builtins, k) for k, v in np.sctypeDict.items() if k in vars(builtins)}
  10. npArrayType = type(np.array([0]))
  11. class MongoDB:
  12. def __init__(self, mongoClient, mongoDB, date=None) -> None:
  13. self.mongoClient = mongoClient
  14. self.mongoDB = mongoDB
  15. self.xdb = xarray_mongodb.XarrayMongoDB(mongoDB)
  16. if date is None:
  17. date= get_date()
  18. self.set_date(date)
  19. def _convert_numpy_type(self, data):
  20. for key in data:
  21. typeKey = type(data[key])
  22. if typeKey in npTypeDict:
  23. data[key] = data[key].item()
  24. elif typeKey == npArrayType:
  25. data[key] = data[key].tolist()
  26. else:
  27. try:
  28. data[key] = data[key].item()
  29. except:
  30. pass
  31. return data
  32. def _break_dataSet(self, dataSet, scanAxis=None):
  33. if scanAxis is None:
  34. scanAxis = dataSet.attrs['scanAxis']
  35. dataArray = dataSet.shotNum
  36. stackedDataArray = dataArray.stack(_scanAxis=tuple(scanAxis))
  37. return stackedDataArray
  38. def set_date(self, date):
  39. date = date.split("/")
  40. self.year = int(date[0])
  41. self.month = int(date[1])
  42. self.day = int(date[2])
  43. def create_global(self, shotNum, dataSet=None, date=None):
  44. if not date is None:
  45. self.set_date(date)
  46. data = {
  47. 'year': self.year,
  48. 'month': self.month,
  49. 'day': self.day,
  50. 'shotNum': shotNum,
  51. }
  52. self.mongoDB['global'].delete_many(data)
  53. data = {
  54. 'year': self.year,
  55. 'month': self.month,
  56. 'day': self.day,
  57. 'shotNum': shotNum,
  58. 'runNum': 0,
  59. 'global_parameters' : {},
  60. }
  61. global_parameters = self._convert_numpy_type(dataSet.attrs)
  62. if not dataSet is None:
  63. data['global_parameters'].update(global_parameters)
  64. data = self._convert_numpy_type(data)
  65. if 'scanAxis' in dataSet.attrs:
  66. del data['global_parameters']['scanAxis']
  67. del data['global_parameters']['scanAxisLength']
  68. scanAxis = dataSet.attrs['scanAxis']
  69. data['global_parameters'].update(
  70. {
  71. key:0
  72. for key in scanAxis
  73. }
  74. )
  75. stackedDataArray = self._break_dataSet(dataSet)
  76. try:
  77. stackedDataArray.load()
  78. except:
  79. pass
  80. stackedDataArray = stackedDataArray.groupby('_scanAxis')
  81. for i in stackedDataArray:
  82. stackedDataArray_single = i[1]
  83. data.update(
  84. {
  85. 'runNum': int(stackedDataArray_single.item())
  86. }
  87. )
  88. data['global_parameters'].update(
  89. {
  90. key: stackedDataArray_single[key].item()
  91. for key in scanAxis
  92. }
  93. )
  94. if '_id' in data:
  95. del data['_id']
  96. self.mongoDB['global'].insert_one(data)
  97. else:
  98. self.mongoDB['global'].insert_one(data)
  99. def _add_data_normal(self, shotNum, runNum, data):
  100. if runNum is None:
  101. runNum = 0
  102. filter = {
  103. 'year': self.year,
  104. 'month': self.month,
  105. 'day': self.day,
  106. 'shotNum': shotNum,
  107. 'runNum': runNum,
  108. }
  109. self.mongoDB['global'].update_one(filter, {"$set": data}, upsert=False)
  110. def _add_data_xarray_dataArray(self, shotNum, dataArray, name=None, scanAxis=None):
  111. if scanAxis is None:
  112. scanAxis = list(dataArray.coords)
  113. dataArray.attrs = self._convert_numpy_type(dataArray.attrs)
  114. stackedDataArray = dataArray.stack(_scanAxis=tuple(scanAxis))
  115. stackedDataArray = stackedDataArray.groupby('_scanAxis')
  116. filter = {
  117. 'year': self.year,
  118. 'month': self.month,
  119. 'day': self.day,
  120. 'shotNum': shotNum,
  121. }
  122. for i in stackedDataArray:
  123. stackedDataArray_single = i[1].drop('_scanAxis')
  124. global_parameters = {
  125. 'global_parameters.' + key: stackedDataArray_single[key].item()
  126. for key in scanAxis
  127. }
  128. filter.update(global_parameters)
  129. mongoID, _ = self.xdb.put(stackedDataArray_single)
  130. data_label = {
  131. dataArray.name:
  132. {
  133. 'name': dataArray.name,
  134. 'mongoID': mongoID,
  135. 'engine': 'xarray',
  136. 'dtype': 'dataArray',
  137. }
  138. }
  139. self.mongoDB['global'].update_one(filter, {"$set": data_label}, upsert=False)
  140. def _add_data_xarray_dataSet(self, shotNum, dataSet, name, scanAxis=None):
  141. if scanAxis is None:
  142. scanAxis = list(dataSet.coords)
  143. dataSet.attrs = self._convert_numpy_type(dataSet.attrs)
  144. for key in list(dataSet.data_vars):
  145. dataSet[key].attrs = self._convert_numpy_type(dataSet[key].attrs)
  146. stackedDataSet = dataSet.stack(_scanAxis=tuple(scanAxis))
  147. stackedDataSet = stackedDataSet.groupby('_scanAxis')
  148. filter = {
  149. 'year': self.year,
  150. 'month': self.month,
  151. 'day': self.day,
  152. 'shotNum': shotNum,
  153. }
  154. for i in stackedDataSet:
  155. stackedDataSet_single = i[1].drop('_scanAxis')
  156. global_parameters = {
  157. 'global_parameters.' + key: stackedDataSet_single[key].item()
  158. for key in scanAxis
  159. }
  160. filter.update(global_parameters)
  161. mongoID, _ = self.xdb.put(dataSet)
  162. data_label = {
  163. name:
  164. {
  165. 'name': name,
  166. 'mongoID': mongoID,
  167. 'engine': 'xarray',
  168. 'dtype': 'dataSet',
  169. }
  170. }
  171. self.mongoDB['global'].update_one(filter, {"$set": data_label}, upsert=False)
  172. def _add_data_additional(self, shotNum, runNum, data, name):
  173. if runNum is None:
  174. runNum = 0
  175. filter = {
  176. 'year': self.year,
  177. 'month': self.month,
  178. 'day': self.day,
  179. 'shotNum': shotNum,
  180. 'runNum': runNum,
  181. }
  182. mongoID = self.mongoDB.additional.insert_one(data).inserted_id
  183. data_label = {
  184. name:
  185. {
  186. 'name': name,
  187. 'mongoID': mongoID,
  188. 'engine': 'additional',
  189. 'dtype': 'dict',
  190. }
  191. }
  192. self.mongoDB['global'].update_one(filter, {"$set": data_label}, upsert=False)
  193. def add_data(self, shotNum, data, runNum=None, date=None, name=None, engine='normal'):
  194. if not date is None:
  195. self.set_date(date)
  196. if engine == 'normal':
  197. self._add_data_normal(shotNum=shotNum, runNum=runNum, data=data)
  198. elif engine == 'xarray':
  199. if isinstance(data, type(xr.Dataset())):
  200. self._add_data_xarray_dataSet(shotNum=shotNum, dataSet=data, name=name)
  201. else:
  202. self._add_data_xarray_dataArray(shotNum=shotNum, dataArray=data, name=name)
  203. elif engine == 'additional':
  204. self._add_data_additional(shotNum=shotNum, runNum=runNum, data=data, name=name)
  205. def read_global_single(self, shotNum, runNum, date=None):
  206. if not date is None:
  207. self.set_date(date)
  208. filter = {
  209. 'year': self.year,
  210. 'month': self.month,
  211. 'day': self.day,
  212. 'shotNum': shotNum,
  213. 'runNum': runNum,
  214. }
  215. return self.mongoDB['global'].find_one(filter)
  216. def read_global_all(self, shotNum, date=None):
  217. from xarray.core.utils import equivalent
  218. if not date is None:
  219. self.set_date(date)
  220. filter = {
  221. 'year': self.year,
  222. 'month': self.month,
  223. 'day': self.day,
  224. 'shotNum': shotNum,
  225. }
  226. result = {}
  227. dropped_attrs = OrderedDict()
  228. docs = self.mongoDB['global'].find(filter).sort('runNum')
  229. docs = [doc['global_parameters'] for doc in docs]
  230. for doc in docs:
  231. global_parameters = doc
  232. result.update(
  233. {
  234. key: value
  235. for key, value in global_parameters.items()
  236. if key not in result and key not in dropped_attrs.keys()
  237. }
  238. )
  239. result = {
  240. key: value
  241. for key, value in result.items()
  242. if key not in global_parameters or equivalent(global_parameters[key], value)
  243. }
  244. dropped_attrs.update(
  245. {
  246. key: []
  247. for key in global_parameters if key not in result
  248. }
  249. )
  250. for doc in docs:
  251. global_parameters = doc
  252. dropped_attrs.update(
  253. {
  254. key: np.append(dropped_attrs[key], global_parameters[key])
  255. for key in dropped_attrs.keys()
  256. }
  257. )
  258. scan_attrs = OrderedDict()
  259. scan_length = []
  260. for attrs_key in dropped_attrs.keys():
  261. flag = True
  262. for key in scan_attrs.keys():
  263. if equivalent(scan_attrs[key], dropped_attrs[attrs_key]):
  264. flag = False
  265. result.update({attrs_key: key})
  266. break
  267. if flag:
  268. scan_attrs.update({
  269. attrs_key: dropped_attrs[attrs_key]
  270. })
  271. scan_length = np.append(scan_length, len(dropped_attrs[attrs_key]))
  272. result.update(
  273. {
  274. key: value
  275. for key, value in scan_attrs.items()
  276. }
  277. )
  278. result.update(
  279. {
  280. "scanAxis": list(scan_attrs.keys()),
  281. "scanAxisLength": scan_length,
  282. }
  283. )
  284. return result
  285. def _load_data_single(self, mongoID, engine):
  286. if engine == 'xarray':
  287. return self.xdb.get(mongoID)
  288. if engine == 'additional':
  289. return self.mongoDB.additional.find_one({'_id': mongoID})
  290. def load_data_single(self, shotNum=None, runNum=None, globalDict=None, date=None, field=None):
  291. if not date is None:
  292. self.set_date(date)
  293. if globalDict is None:
  294. globalDict = self.read_global_single(shotNum=shotNum, runNum=runNum)
  295. if field is None:
  296. field = globalDict
  297. res = {}
  298. for key in field:
  299. if isinstance(globalDict[key], dict) and ('mongoID' in globalDict[key]):
  300. mongoID = globalDict[key]['mongoID']
  301. engine = globalDict[key]['engine']
  302. res.update(
  303. {
  304. key: self._load_data_single(mongoID=mongoID, engine=engine)
  305. }
  306. )
  307. return res
  308. def load_data(self, shotNum=None, globalDict=None, date=None, field=None):
  309. pass