@@ -14,22 +14,21 import datetime | |||
|
14 | 14 | import numpy |
|
15 | 15 | import h5py |
|
16 | 16 | |
|
17 | try: | |
|
18 | import madrigal | |
|
19 | import madrigal.cedar | |
|
20 | except: | |
|
21 | print 'You should install "madrigal library" module if you want to read/write Madrigal data' | |
|
22 | ||
|
23 | from schainpy.model.io.jroIO_base import JRODataReader | |
|
17 | from schainpy.model.io.jroIO_base import JRODataReader | |
|
24 | 18 | from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation |
|
25 | 19 | from schainpy.model.data.jrodata import Parameters |
|
26 | 20 | from schainpy.utils import log |
|
27 | 21 | |
|
22 | try: | |
|
23 | import madrigal.cedar | |
|
24 | except: | |
|
25 | log.warning( | |
|
26 | 'You should install "madrigal library" module if you want to read/write Madrigal data' | |
|
27 | ) | |
|
28 | 28 | |
|
29 | 29 | DEF_CATALOG = { |
|
30 | 30 | 'principleInvestigator': 'Marco Milla', |
|
31 | 31 | 'expPurpose': None, |
|
32 | 'expMode': None, | |
|
33 | 32 | 'cycleTime': None, |
|
34 | 33 | 'correlativeExp': None, |
|
35 | 34 | 'sciRemarks': None, |
@@ -60,6 +59,8 def load_json(obj): | |||
|
60 | 59 | |
|
61 | 60 | if isinstance(obj, str): |
|
62 | 61 | iterable = json.loads(obj) |
|
62 | else: | |
|
63 | iterable = obj | |
|
63 | 64 | |
|
64 | 65 | if isinstance(iterable, dict): |
|
65 | 66 | return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, unicode) else v |
@@ -92,8 +93,7 class MADReader(JRODataReader, ProcessingUnit): | |||
|
92 | 93 | startTime=datetime.time(0, 0, 0), |
|
93 | 94 | endTime=datetime.time(23, 59, 59), |
|
94 | 95 | **kwargs): |
|
95 | ||
|
96 | self.started = True | |
|
96 | ||
|
97 | 97 | self.path = path |
|
98 | 98 | self.startDate = startDate |
|
99 | 99 | self.endDate = endDate |
@@ -135,7 +135,7 class MADReader(JRODataReader, ProcessingUnit): | |||
|
135 | 135 | path - Path to find files |
|
136 | 136 | ''' |
|
137 | 137 | |
|
138 |
|
|
|
138 | log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader') | |
|
139 | 139 | foldercounter = 0 |
|
140 | 140 | fileList0 = glob.glob1(path, '*{}'.format(self.ext)) |
|
141 | 141 | fileList0.sort() |
@@ -200,16 +200,18 class MADReader(JRODataReader, ProcessingUnit): | |||
|
200 | 200 | |
|
201 | 201 | for param in self.oneDDict.keys(): |
|
202 | 202 | if param.lower() not in self.parameters: |
|
203 | print('\x1b[33m[Warning]\x1b[0m Parameter \x1b[1;32m{}\x1b[0m not found will be ignored'.format( | |
|
204 | param | |
|
205 |
) |
|
|
203 | log.warning( | |
|
204 | 'Parameter {} not found will be ignored'.format( | |
|
205 | param), | |
|
206 | 'MADReader') | |
|
206 | 207 | self.oneDDict.pop(param, None) |
|
207 | 208 | |
|
208 | 209 | for param, value in self.twoDDict.items(): |
|
209 | 210 | if param.lower() not in self.parameters: |
|
210 | print('\x1b[33m[Warning]\x1b[0m Parameter \x1b[1;32m{}\x1b[0m not found will be ignored'.format( | |
|
211 | param | |
|
212 |
) |
|
|
211 | log.warning( | |
|
212 | 'Parameter {} not found, it will be ignored'.format( | |
|
213 | param), | |
|
214 | 'MADReader') | |
|
213 | 215 | self.twoDDict.pop(param, None) |
|
214 | 216 | continue |
|
215 | 217 | if isinstance(value, list): |
@@ -237,14 +239,15 class MADReader(JRODataReader, ProcessingUnit): | |||
|
237 | 239 | file_id = self.fileId |
|
238 | 240 | |
|
239 | 241 | if file_id == len(self.fileList): |
|
240 |
|
|
|
241 | print 'Total number of file(s) read : {}'.format(self.fileId) | |
|
242 | log.success('No more files', 'MADReader') | |
|
242 | 243 | self.flagNoMoreFiles = 1 |
|
243 | 244 | return 0 |
|
244 | 245 | |
|
245 | print('\x1b[32m[Info]\x1b[0m Opening: {}'.format( | |
|
246 | self.fileList[file_id] | |
|
247 |
|
|
|
246 | log.success( | |
|
247 | 'Opening: {}'.format(self.fileList[file_id]), | |
|
248 | 'MADReader' | |
|
249 | ) | |
|
250 | ||
|
248 | 251 | filename = os.path.join(self.path, self.fileList[file_id]) |
|
249 | 252 | |
|
250 | 253 | if self.filename is not None: |
@@ -270,7 +273,7 class MADReader(JRODataReader, ProcessingUnit): | |||
|
270 | 273 | def readNextBlock(self): |
|
271 | 274 | |
|
272 | 275 | while True: |
|
273 | ||
|
276 | self.flagDiscontinuousBlock = 0 | |
|
274 | 277 | if self.flagIsNewFile: |
|
275 | 278 | if not self.setNextFile(): |
|
276 | 279 | return 0 |
@@ -279,17 +282,21 class MADReader(JRODataReader, ProcessingUnit): | |||
|
279 | 282 | |
|
280 | 283 | if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \ |
|
281 | 284 | (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)): |
|
282 | print "\x1b[32m[Reading]\x1b[0m Record No. %d/%d -> %s \x1b[33m[Skipping]\x1b[0m" %( | |
|
283 | self.counter_records, | |
|
284 | self.nrecords, | |
|
285 |
self. |
|
|
285 | log.warning( | |
|
286 | 'Reading Record No. {}/{} -> {} [Skipping]'.format( | |
|
287 | self.counter_records, | |
|
288 | self.nrecords, | |
|
289 | self.datatime.ctime()), | |
|
290 | 'MADReader') | |
|
286 | 291 | continue |
|
287 | 292 | break |
|
288 | 293 | |
|
289 | print "\x1b[32m[Reading]\x1b[0m Record No. %d/%d -> %s" %( | |
|
290 | self.counter_records, | |
|
291 | self.nrecords, | |
|
292 | self.datatime.ctime()) | |
|
294 | log.log( | |
|
295 | 'Reading Record No. {}/{} -> {}'.format( | |
|
296 | self.counter_records, | |
|
297 | self.nrecords, | |
|
298 | self.datatime.ctime()), | |
|
299 | 'MADReader') | |
|
293 | 300 | |
|
294 | 301 | return 1 |
|
295 | 302 | |
@@ -311,6 +318,8 class MADReader(JRODataReader, ProcessingUnit): | |||
|
311 | 318 | break |
|
312 | 319 | continue |
|
313 | 320 | self.intervals.add((datatime-self.datatime).seconds) |
|
321 | if datatime.date() > self.datatime.date(): | |
|
322 | self.flagDiscontinuousBlock = 1 | |
|
314 | 323 | break |
|
315 | 324 | elif self.ext == '.hdf5': |
|
316 | 325 | datatime = datetime.datetime.utcfromtimestamp( |
@@ -326,12 +335,14 class MADReader(JRODataReader, ProcessingUnit): | |||
|
326 | 335 | tmp = self.data['2D Parameters'][param].value.T |
|
327 | 336 | dum.append(tmp[self.counter_records]) |
|
328 | 337 | self.intervals.add((datatime-self.datatime).seconds) |
|
338 | if datatime.date()>self.datatime.date(): | |
|
339 | self.flagDiscontinuousBlock = 1 | |
|
329 | 340 | self.datatime = datatime |
|
330 | 341 | self.counter_records += 1 |
|
331 | 342 | if self.counter_records == self.nrecords: |
|
332 | 343 | self.flagIsNewFile = True |
|
333 | 344 | |
|
334 |
self.buffer = numpy.array(dum) |
|
|
345 | self.buffer = numpy.array(dum) | |
|
335 | 346 | return |
|
336 | 347 | |
|
337 | 348 | def set_output(self): |
@@ -344,7 +355,7 class MADReader(JRODataReader, ProcessingUnit): | |||
|
344 | 355 | for param, attr in self.oneDDict.items(): |
|
345 | 356 | x = self.parameters.index(param.lower()) |
|
346 | 357 | setattr(self.dataOut, attr, self.buffer[0][x]) |
|
347 | ||
|
358 | ||
|
348 | 359 | for param, value in self.twoDDict.items(): |
|
349 | 360 | x = self.parameters.index(param.lower()) |
|
350 | 361 | if self.ext == '.txt': |
@@ -355,10 +366,9 class MADReader(JRODataReader, ProcessingUnit): | |||
|
355 | 366 | index = numpy.where(numpy.in1d(self.ranges, ranges))[0] |
|
356 | 367 | dummy = numpy.zeros(self.ranges.shape) + numpy.nan |
|
357 | 368 | dummy[index] = self.buffer[:,x] |
|
358 | else: | |
|
359 | ||
|
360 | dummy = self.buffer[x] | |
|
361 | ||
|
369 | else: | |
|
370 | dummy = self.buffer[x] | |
|
371 | ||
|
362 | 372 | if isinstance(value, str): |
|
363 | 373 | if value not in self.ind2DList: |
|
364 | 374 | setattr(self.dataOut, value, dummy.reshape(1,-1)) |
@@ -375,8 +385,9 class MADReader(JRODataReader, ProcessingUnit): | |||
|
375 | 385 | self.dataOut.utctimeInit = self.dataOut.utctime |
|
376 | 386 | self.dataOut.paramInterval = min(self.intervals) |
|
377 | 387 | self.dataOut.useLocalTime = False |
|
378 | self.dataOut.flagNoData = False | |
|
379 |
self.dataOut. |
|
|
388 | self.dataOut.flagNoData = False | |
|
389 | self.dataOut.nrecords = self.nrecords | |
|
390 | self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock | |
|
380 | 391 | |
|
381 | 392 | def getData(self): |
|
382 | 393 | ''' |
@@ -384,7 +395,7 class MADReader(JRODataReader, ProcessingUnit): | |||
|
384 | 395 | ''' |
|
385 | 396 | if self.flagNoMoreFiles: |
|
386 | 397 | self.dataOut.flagNoData = True |
|
387 |
|
|
|
398 | log.error('No file left to process', 'MADReader') | |
|
388 | 399 | return 0 |
|
389 | 400 | |
|
390 | 401 | if not self.readNextBlock(): |
@@ -396,19 +407,19 class MADReader(JRODataReader, ProcessingUnit): | |||
|
396 | 407 | return 1 |
|
397 | 408 | |
|
398 | 409 | |
|
399 |
class MAD |
|
|
410 | class MADWriter(Operation): | |
|
400 | 411 | |
|
401 | missing = -32767 | |
|
402 | ext = '.dat' | |
|
412 | missing = -32767 | |
|
403 | 413 | |
|
404 | 414 | def __init__(self, **kwargs): |
|
405 | ||
|
415 | ||
|
406 | 416 | Operation.__init__(self, **kwargs) |
|
407 | 417 | self.dataOut = Parameters() |
|
408 | 418 | self.path = None |
|
409 |
self. |
|
|
410 | ||
|
411 |
def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}', |
|
|
419 | self.fp = None | |
|
420 | ||
|
421 | def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}', | |
|
422 | metadata='{}', format='cedar', **kwargs): | |
|
412 | 423 | ''' |
|
413 | 424 | Inputs: |
|
414 | 425 | path - path where files will be created |
@@ -434,22 +445,21 class MAD2Writer(Operation): | |||
|
434 | 445 | metadata - json of madrigal metadata (kinst, kindat, catalog and header) |
|
435 | 446 | ''' |
|
436 | 447 | if not self.isConfig: |
|
437 |
self.setup( |
|
|
448 | self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs) | |
|
438 | 449 | self.isConfig = True |
|
439 |
|
|
|
450 | ||
|
451 | self.dataOut = dataOut | |
|
440 | 452 | self.putData() |
|
441 | 453 | return |
|
442 | 454 | |
|
443 |
def setup(self |
|
|
455 | def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs): | |
|
444 | 456 | ''' |
|
445 | 457 | Configure Operation |
|
446 | 458 | ''' |
|
447 | ||
|
448 | self.dataOut = dataOut | |
|
449 | self.nmodes = self.dataOut.nmodes | |
|
459 | ||
|
450 | 460 | self.path = path |
|
451 | 461 | self.blocks = kwargs.get('blocks', None) |
|
452 |
self.counter = 0 |
|
|
462 | self.counter = 0 | |
|
453 | 463 | self.oneDDict = load_json(oneDDict) |
|
454 | 464 | self.twoDDict = load_json(twoDDict) |
|
455 | 465 | self.ind2DList = load_json(ind2DList) |
@@ -458,8 +468,18 class MAD2Writer(Operation): | |||
|
458 | 468 | self.kindat = meta.get('kindat') |
|
459 | 469 | self.catalog = meta.get('catalog', DEF_CATALOG) |
|
460 | 470 | self.header = meta.get('header', DEF_HEADER) |
|
461 | ||
|
462 | return | |
|
471 | if format == 'cedar': | |
|
472 | self.ext = '.dat' | |
|
473 | self.extra_args = {} | |
|
474 | elif format == 'hdf5': | |
|
475 | self.ext = '.hdf5' | |
|
476 | self.extra_args = {'ind2DList': self.ind2DList} | |
|
477 | ||
|
478 | self.keys = [k.lower() for k in self.twoDDict] | |
|
479 | if 'range' in self.keys: | |
|
480 | self.keys.remove('range') | |
|
481 | if 'gdalt' in self.keys: | |
|
482 | self.keys.remove('gdalt') | |
|
463 | 483 | |
|
464 | 484 | def setFile(self): |
|
465 | 485 | ''' |
@@ -467,24 +487,30 class MAD2Writer(Operation): | |||
|
467 | 487 | ''' |
|
468 | 488 | |
|
469 | 489 | self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal |
|
470 |
date = datetime.datetime. |
|
|
490 | date = datetime.datetime.fromtimestamp(self.dataOut.utctime) | |
|
471 | 491 | |
|
472 |
filename = ' |
|
|
473 | date.strftime('%Y%m%d_%H%M%S'), | |
|
474 |
self. |
|
|
475 | self.ext) | |
|
492 | filename = '{}{}{}'.format(self.mnemonic, | |
|
493 | date.strftime('%Y%m%d_%H%M%S'), | |
|
494 | self.ext) | |
|
476 | 495 | |
|
477 | 496 | self.fullname = os.path.join(self.path, filename) |
|
478 | 497 | |
|
479 | 498 | if os.path.isfile(self.fullname) : |
|
480 | print "Destination path '%s' already exists. Previous file deleted. " %self.fullname | |
|
499 | log.warning( | |
|
500 | 'Destination path {} already exists. Previous file deleted.'.format( | |
|
501 | self.fullname), | |
|
502 | 'MADWriter') | |
|
481 | 503 | os.remove(self.fullname) |
|
482 | 504 | |
|
483 | 505 | try: |
|
484 | print '[Writing] creating file : %s' % (self.fullname) | |
|
485 | self.cedarObj = madrigal.cedar.MadrigalCedarFile(self.fullname, True) | |
|
506 | log.success( | |
|
507 | 'Creating file: {}'.format(self.fullname), | |
|
508 | 'MADWriter') | |
|
509 | self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True) | |
|
486 | 510 | except ValueError, e: |
|
487 | print '[Error]: Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile" ' | |
|
511 | log.error( | |
|
512 | 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"', | |
|
513 | 'MADWriter') | |
|
488 | 514 | return |
|
489 | 515 | |
|
490 | 516 | return 1 |
@@ -496,10 +522,33 class MAD2Writer(Operation): | |||
|
496 | 522 | Allowed parameters in: parcodes.tab |
|
497 | 523 | ''' |
|
498 | 524 | |
|
499 |
startTime = datetime.datetime. |
|
|
525 | startTime = datetime.datetime.fromtimestamp(self.dataOut.utctime) | |
|
500 | 526 | endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval) |
|
501 |
|
|
|
502 | ||
|
527 | heights = self.dataOut.heightList | |
|
528 | ||
|
529 | if self.ext == '.dat': | |
|
530 | invalid = numpy.isnan(self.dataOut.data_output) | |
|
531 | self.dataOut.data_output[invalid] = self.missing | |
|
532 | out = {} | |
|
533 | for key, value in self.twoDDict.items(): | |
|
534 | key = key.lower() | |
|
535 | if isinstance(value, str): | |
|
536 | if 'db' in value.lower(): | |
|
537 | tmp = getattr(self.dataOut, value.replace('_db', '')) | |
|
538 | SNRavg = numpy.average(tmp, axis=0) | |
|
539 | tmp = 10*numpy.log10(SNRavg) | |
|
540 | else: | |
|
541 | tmp = getattr(self.dataOut, value) | |
|
542 | out[key] = tmp.flatten() | |
|
543 | elif isinstance(value, (tuple, list)): | |
|
544 | attr, x = value | |
|
545 | data = getattr(self.dataOut, attr) | |
|
546 | out[key] = data[int(x)] | |
|
547 | ||
|
548 | a = numpy.array([out[k] for k in self.keys]) | |
|
549 | nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))]) | |
|
550 | index = numpy.where(nrows == False)[0] | |
|
551 | ||
|
503 | 552 | rec = madrigal.cedar.MadrigalDataRecord( |
|
504 | 553 | self.kinst, |
|
505 | 554 | self.kindat, |
@@ -519,45 +568,43 class MAD2Writer(Operation): | |||
|
519 | 568 | endTime.microsecond/10000, |
|
520 | 569 | self.oneDDict.keys(), |
|
521 | 570 | self.twoDDict.keys(), |
|
522 |
|
|
|
523 | ) | |
|
524 | ||
|
571 | len(index), | |
|
572 | **self.extra_args | |
|
573 | ) | |
|
574 | ||
|
525 | 575 | # Setting 1d values |
|
526 | 576 | for key in self.oneDDict: |
|
527 | 577 | rec.set1D(key, getattr(self.dataOut, self.oneDDict[key])) |
|
528 | 578 | |
|
529 | 579 | # Setting 2d values |
|
530 | invalid = numpy.isnan(self.dataOut.data_output) | |
|
531 | self.dataOut.data_output[invalid] = self.missing | |
|
532 | out = {} | |
|
533 | for key, value in self.twoDDict.items(): | |
|
534 | if isinstance(value, str): | |
|
535 | out[key] = getattr(self.dataOut, value) | |
|
536 | elif isinstance(value, tuple): | |
|
537 | attr, x = value | |
|
538 | if isinstance(x, (int, float)): | |
|
539 | out[key] = getattr(self.dataOut, attr)[int(x)] | |
|
540 | elif x.lower()=='db': | |
|
541 | tmp = getattr(self.dataOut, attr) | |
|
542 | SNRavg = numpy.average(tmp, axis=0) | |
|
543 | out[key] = 10*numpy.log10(SNRavg) | |
|
544 | ||
|
545 | for n in range(nrows): | |
|
580 | nrec = 0 | |
|
581 | for n in index: | |
|
546 | 582 | for key in out: |
|
547 | rec.set2D(key, n, out[key][n]) | |
|
548 | ||
|
549 | self.cedarObj.append(rec) | |
|
550 | self.cedarObj.dump() | |
|
551 | print '[Writing] Record No. {} (mode {}).'.format( | |
|
552 |
self. |
|
|
553 | self.dataOut.mode | |
|
554 |
|
|
|
583 | rec.set2D(key, nrec, out[key][n]) | |
|
584 | nrec += 1 | |
|
585 | ||
|
586 | self.fp.append(rec) | |
|
587 | if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0: | |
|
588 | self.fp.dump() | |
|
589 | if self.counter % 10 == 0 and self.counter > 0: | |
|
590 | log.log( | |
|
591 | 'Writing {} records'.format( | |
|
592 | self.counter), | |
|
593 | 'MADWriter') | |
|
555 | 594 | |
|
556 | 595 | def setHeader(self): |
|
557 | 596 | ''' |
|
558 | 597 | Create an add catalog and header to cedar file |
|
559 | 598 | ''' |
|
560 | 599 | |
|
600 | log.success('Closing file {}'.format(self.fullname), 'MADWriter') | |
|
601 | ||
|
602 | if self.ext == '.dat': | |
|
603 | self.fp.write() | |
|
604 | else: | |
|
605 | self.fp.dump() | |
|
606 | self.fp.close() | |
|
607 | ||
|
561 | 608 | header = madrigal.cedar.CatalogHeaderCreator(self.fullname) |
|
562 | 609 | header.createCatalog(**self.catalog) |
|
563 | 610 | header.createHeader(**self.header) |
@@ -566,15 +613,20 class MAD2Writer(Operation): | |||
|
566 | 613 | def putData(self): |
|
567 | 614 | |
|
568 | 615 | if self.dataOut.flagNoData: |
|
569 | return 0 | |
|
616 | return 0 | |
|
570 | 617 | |
|
618 | if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks: | |
|
619 | if self.counter > 0: | |
|
620 | self.setHeader() | |
|
621 | self.counter = 0 | |
|
622 | ||
|
571 | 623 | if self.counter == 0: |
|
572 | 624 | self.setFile() |
|
573 | 625 | |
|
574 | if self.counter <= self.dataOut.nrecords: | |
|
575 | self.writeBlock() | |
|
576 | self.counter += 1 | |
|
626 | self.writeBlock() | |
|
627 | self.counter += 1 | |
|
628 | ||
|
629 | def close(self): | |
|
577 | 630 | |
|
578 | if self.counter == self.dataOut.nrecords or self.counter == self.blocks: | |
|
631 | if self.counter > 0: | |
|
579 | 632 | self.setHeader() |
|
580 | self.counter = 0 |
General Comments 0
You need to be logged in to leave comments.
Login now