403 # Read global attributes |
415 # Read global attributes |
404 station_id = read_global_attribute(netcdf_file_path, 'station_ID') |
416 station_id = read_global_attribute(netcdf_file_path, 'station_ID') |
405 station_location = read_global_attribute(netcdf_file_path, 'location') |
417 station_location = read_global_attribute(netcdf_file_path, 'location') |
406 |
418 |
407 # Read data |
419 # Read data |
|
420 h = 0 |
408 for g in range(len(groups)): |
421 for g in range(len(groups)): |
409 # Read the altitude variable |
422 if check_group_presence(netcdf_file_path, groups[g]): |
410 altitude = read_variable_in_group(netcdf_file_path, groups[g], 'altitude') |
423 # Read the altitude variable |
411 |
424 altitude = read_variable_in_group(netcdf_file_path, groups[g], 'altitude') |
412 if altitude['metadata']['units'] == 'm': |
425 |
413 altitude['data'] = altitude['data'] / 1000.0 |
426 if altitude['metadata']['units'] == 'm': |
414 altitude['metadata']['units'] = 'km' |
427 altitude['data'] = altitude['data'] / 1000.0 |
415 |
428 altitude['metadata']['units'] = 'km' |
416 # Initialize variables |
429 |
417 data = None |
430 # Initialize variables |
418 variables_with_data = None |
431 data = None |
419 variables_axis = None |
432 variables_with_data = None |
420 |
433 variables_axis = None |
421 # Read the data |
434 |
422 for v in range(len(variable)): |
435 # Read the data |
423 # Initialize var |
436 for v in range(len(variable)): |
424 var = None |
437 # Initialize var |
425 |
438 var = None |
426 try: |
439 |
427 var, dim, met = read_variable_in_group2(netcdf_file_path, groups[g], variable[v]) |
440 try: |
428 except TypeError: |
441 var, dim, met = read_variable_in_group2(netcdf_file_path, groups[g], variable[v]) |
429 print(f"The variable {variable[v]} is not present. Cannot unpack non-iterable NoneType object") |
442 except TypeError: |
430 |
443 print(f"The variable {variable[v]} is not present. Cannot unpack non-iterable NoneType object") |
431 if var is not None: # If the variable that we're trying to read exists |
444 |
432 if var.max() != var.min(): # If there is data in the array |
445 if var is not None: # If the variable that we're trying to read exists |
433 if variables_with_data is None: |
446 if var.max() != var.min(): # If there is data in the array |
434 variables_with_data = [variable[v]] |
447 if variables_with_data is None: |
435 variables_axis = [met['long_name'] + ' [ ' + met['units'] + ' ]'] |
448 variables_with_data = [variable[v]] |
|
449 variables_axis = [met['long_name'] + ' [ ' + met['units'] + ' ]'] |
|
450 else: |
|
451 variables_with_data += [variable[v]] |
|
452 variables_axis += [met['long_name'] + ' [ ' + met['units'] + ' ]'] |
|
453 |
|
454 var_error, dim_error, met_error = read_variable_in_group2(netcdf_file_path, groups[g], |
|
455 variable_error[v]) |
|
456 if variable[v] == 'volumedepolarization': |
|
457 var_error_negative, dim, met = read_variable_in_group2(netcdf_file_path, groups[g], |
|
458 variable_negative_error_volumedepol) |
|
459 else: |
|
460 var_error_negative = var_error |
|
461 |
|
462 # Add read data to the data variable to have it all grouped |
|
463 if data is None: |
|
464 # Start populating data and data_error |
|
465 data = {variable[v]: var} |
|
466 data_error_positive = {variable[v]: var_error} |
|
467 data_error_negative = {variable[v]: var_error_negative} |
|
468 else: |
|
469 # Add more data to data and data_error |
|
470 data[variable[v]] = var |
|
471 data_error_positive[variable[v]] = var_error |
|
472 data_error_negative[variable[v]] = var_error_negative |
436 else: |
473 else: |
437 variables_with_data += [variable[v]] |
474 print(f'There is no data for {variable[v]} in the {groups_names[g]} group.') |
438 variables_axis += [met['long_name'] + ' [ ' + met['units'] + ' ]'] |
475 |
439 |
476 dimensions = dim |
440 var_error, dim_error, met_error = read_variable_in_group2(netcdf_file_path, groups[g], |
477 |
441 variable_error[v]) |
478 # Save lowres and highres in variables to plot them together afterwards |
442 if variable[v] == 'volumedepolarization': |
479 if groups[g] == 'lowres_products': |
443 var_error_negative, dim, met = read_variable_in_group2(netcdf_file_path, groups[g], |
480 altitude_lr = altitude |
444 variable_negative_error_volumedepol) |
481 dimensions_lr = dim |
445 else: |
482 data_lr = data |
446 var_error_negative = var_error |
483 data_error_positive_lr = data_error_positive |
447 |
484 data_error_negative_lr = data_error_negative |
448 # Add read data to the data variable to have it all grouped |
485 variables_with_data_lr = variables_with_data |
449 if data is None: |
486 variables_axis_lr = variables_axis |
450 # Start populating data and data_error |
487 if groups[g] == 'highres_products': |
451 data = {variable[v]: var} |
488 altitude_hr = altitude |
452 data_error_positive = {variable[v]: var_error} |
489 dimensions_hr = dim |
453 data_error_negative = {variable[v]: var_error_negative} |
490 data_hr = data |
454 else: |
491 data_error_positive_hr = data_error_positive |
455 # Add more data to data and data_error |
492 data_error_negative_hr = data_error_negative |
456 data[variable[v]] = var |
493 variables_with_data_hr = variables_with_data |
457 data_error_positive[variable[v]] = var_error |
494 variables_axis_hr = variables_axis |
458 data_error_negative[variable[v]] = var_error_negative |
495 |
459 else: |
496 # If interactive is set to True, ask user if he/she wants to plot different temporal profiles in different rows |
460 print(f'There is no data for {variable[v]} in the {groups_names[g]} group.') |
497 # If interactive is set to False, proceed with default values |
461 |
498 if h == 0: |
462 dimensions = dim |
499 # Initialize |
463 |
500 timeinplots = True |
464 # Save lowres and highres in variables to plot them together afterwards |
501 timeinrows = False |
465 if groups[g] == 'lowres_products': |
502 # If interactive (config.py) = True, ask user how he/she wants the plot |
466 altitude_lr = altitude |
503 if interactive and len(dimensions['time']) > 1: |
467 dimensions_lr = dim |
|
468 data_lr = data |
|
469 data_error_positive_lr = data_error_positive |
|
470 data_error_negative_lr = data_error_negative |
|
471 variables_with_data_lr = variables_with_data |
|
472 variables_axis_lr = variables_axis |
|
473 if groups[g] == 'highres_products': |
|
474 altitude_hr = altitude |
|
475 dimensions_hr = dim |
|
476 data_hr = data |
|
477 data_error_positive_hr = data_error_positive |
|
478 data_error_negative_hr = data_error_negative |
|
479 variables_with_data_hr = variables_with_data |
|
480 variables_axis_hr = variables_axis |
|
481 |
|
482 # If interactive is set to True, ask user if he/she wants to plot different temporal profiles in different rows |
|
483 # If interactive is set to False, proceed with default values |
|
484 if g == 0: |
|
485 # Initialize |
|
486 timeinplots = True |
|
487 timeinrows = False |
|
488 # If interactive (config.py) = True, ask user how he/she wants the plot |
|
489 if interactive and len(dimensions['time']) > 1: |
|
490 answer = input( |
|
491 f"There are {len(dimensions['time'])} temporal profiles, " |
|
492 f"do you want to plot them on different plots [y/n]? ") |
|
493 if answer[0:1].lower() == 'n': |
|
494 timeinplots = False |
|
495 if not timeinplots: |
|
496 answer = input( |
504 answer = input( |
497 f"There are {len(dimensions['time'])} temporal profiles, " |
505 f"There are {len(dimensions['time'])} temporal profiles, " |
498 f"do you want to plot them on different rows [y/n]? ") |
506 f"do you want to plot them on different plots [y/n]? ") |
499 if answer[0:1].lower() == 'y': |
507 if answer[0:1].lower() == 'n': |
500 timeinrows = True |
508 timeinplots = False |
501 |
509 if not timeinplots: |
502 if variables_with_data is not None: |
510 answer = input( |
503 timeiter = dimensions['time'] |
511 f"There are {len(dimensions['time'])} temporal profiles, " |
504 if timeinplots: |
512 f"do you want to plot them on different rows [y/n]? ") |
505 # Default plotting |
513 if answer[0:1].lower() == 'y': |
506 dimensions_t = dimensions |
514 timeinrows = True |
507 for t in range(len(dimensions['time'])): |
515 |
508 dimensions_t['time'] = [timeiter[t]] |
516 if variables_with_data is not None: |
509 for vr in range(len(variables_with_data)): |
517 timeiter = dimensions['time'] |
510 if vr == 0: |
518 if timeinplots: |
511 data_t = {variables_with_data[vr]: data[variables_with_data[vr]][:, t:t + 1, :]} |
519 # Default plotting |
|
520 dimensions_t = dimensions |
|
521 for t in range(len(dimensions['time'])): |
|
522 dimensions_t['time'] = [timeiter[t]] |
|
523 for vr in range(len(variables_with_data)): |
|
524 if vr == 0: |
|
525 data_t = {variables_with_data[vr]: data[variables_with_data[vr]][:, t:t + 1, :]} |
|
526 else: |
|
527 data_t[variables_with_data[vr]] = data[variables_with_data[vr]][:, t:t + 1, :] |
|
528 |
|
529 title = station_location + " (" + station_id.upper() + ") - " + str( |
|
530 datetime.fromtimestamp(dimensions_t['time'][0], tz=timezone.utc).strftime( |
|
531 '%d/%m/%Y %H:%M:%S')) + " - ELDA MWL " + groups_names[g] |
|
532 |
|
533 # Timestamps for the filename |
|
534 t0 = datetime.fromtimestamp(timeiter[t], tz=timezone.utc).strftime('%Y%m%d%H%M') |
|
535 if t + 1 < len(timeiter): |
|
536 t1 = datetime.fromtimestamp( |
|
537 timeiter[t+1], tz=timezone.utc).strftime('%Y%m%d%H%M') |
512 else: |
538 else: |
513 data_t[variables_with_data[vr]] = data[variables_with_data[vr]][:, t:t + 1, :] |
539 t1 = netcdf_file[29:41] |
514 |
540 |
|
541 filename = "ELDAmwl_" + netcdf_file[0:3].upper() + "_" + t0 + "-" + t1 + "_" + \ |
|
542 groups[g] + ".html" |
|
543 |
|
544 fig = plot_vertical_profiles_plotly( |
|
545 variables=variables_with_data, |
|
546 data=data_t, |
|
547 dimensions=dimensions_t, |
|
548 y_array=altitude, |
|
549 positive_error_array=data_error_positive, |
|
550 negative_error_array=data_error_negative, |
|
551 xaxis_label=variables_axis, |
|
552 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
|
553 title=title, |
|
554 timeinrows=True |
|
555 ) |
|
556 |
|
557 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
|
558 # fig.show() |
|
559 |
|
560 # Save the plot |
|
561 fig.write_html(html_path + filename) |
|
562 |
|
563 else: |
|
564 # Plotting in one plot (even if there are different time profiles) |
515 fig = plot_vertical_profiles_plotly( |
565 fig = plot_vertical_profiles_plotly( |
516 variables=variables_with_data, |
566 variables_with_data, |
517 data=data_t, |
567 data, |
518 dimensions=dimensions_t, |
568 dimensions, |
519 y_array=altitude, |
569 altitude, |
520 positive_error_array=data_error_positive, |
570 data_error_positive, |
521 negative_error_array=data_error_negative, |
571 data_error_negative, |
522 xaxis_label=variables_axis, |
572 xaxis_label=variables_axis, |
523 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
573 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
524 title=station_location + " (" + station_id.upper() + ") - " + str( |
574 title=station_location + " (" + station_id.upper() + ") - " + str( |
525 datetime.fromtimestamp(dimensions_t['time'][0]).strftime('%d/%m/%Y %H:%M:%S')) + |
575 datetime.fromtimestamp(dimensions['time'][0], tz=timezone.utc).strftime( |
526 " - ELDA MWL " + groups_names[g], |
576 '%d/%m/%Y')) + " - ELDA MWL " + groups_names[ |
527 timeinrows=True |
577 g], |
|
578 timeinrows=timeinrows |
528 ) |
579 ) |
529 |
580 |
530 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
581 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
531 # fig.show() |
582 # fig.show() |
532 |
583 |
533 # Save the plot |
584 # Save the plot |
534 filename = "ELDAmwl_" + netcdf_file[0:3].upper() + "_" + datetime.fromtimestamp( |
585 if timeinrows: |
535 dimensions['time'][0]).strftime('%Y%m%d-%H%M%S') + "_" + groups[g] + ".html" |
586 filename = "ELDAmwl_" + station_id.upper() + "_" + datetime.fromtimestamp( |
|
587 dimensions['time'][0], tz=timezone.utc).strftime('%Y%m%d%H%M') + '-' + datetime.fromtimestamp( |
|
588 dimensions['time'][-1], tz=timezone.utc).strftime('%Y%m%d%H%M') + "_" + groups[ |
|
589 g] + "_timeinrows.html" |
|
590 else: |
|
591 filename = "ELDAmwl_" + station_id.upper() + "_" + datetime.fromtimestamp( |
|
592 dimensions['time'][0], tz=timezone.utc).strftime('%Y%m%d%H%M') + '-' + datetime.fromtimestamp( |
|
593 dimensions['time'][-1], tz=timezone.utc).strftime('%Y%m%d%H%M') + "_" + groups[g] + ".html" |
|
594 |
536 fig.write_html(html_path + filename) |
595 fig.write_html(html_path + filename) |
537 |
596 |
|
597 dimensions['time'] = timeiter |
|
598 |
538 else: |
599 else: |
539 # Plotting in one plot (even if there are different time profiles) |
600 print(f'There is no data to be plotted in the {groups_names[g]} group.') |
540 fig = plot_vertical_profiles_plotly( |
601 |
541 variables_with_data, |
602 h = h + 1 |
542 data, |
603 |
543 dimensions, |
604 # Plotting high and low resolution together |
544 altitude, |
605 if 'variables_with_data_lr' in locals() and 'variables_with_data_hr' in locals(): |
545 data_error_positive, |
606 if len(variables_with_data_lr) > 0 and len(variables_with_data_hr) > 0: |
546 data_error_negative, |
607 print(f'We have low and high resolution data, let''s combine it!') |
|
608 |
|
609 # Variables with data |
|
610 variables_with_data = list(variables_with_data_lr) |
|
611 variables_with_data.extend(x for x in variables_with_data_hr if x not in variables_with_data) |
|
612 print(f'Variables with data: {variables_with_data}') |
|
613 |
|
614 # Variables axis |
|
615 variables_axis = list(variables_axis_lr) |
|
616 variables_axis.extend(x for x in variables_axis_hr if x not in variables_axis) |
|
617 |
|
618 # Joining dimensions for both resolutions |
|
619 # Wavelength |
|
620 wav = list(dimensions_lr['wavelength']) |
|
621 dhrw = list(dimensions_hr['wavelength']) |
|
622 wav.extend(x for x in dimensions_hr['wavelength'] if x not in wav) |
|
623 dimensions['wavelength'] = wav |
|
624 # Add LR/HR to the wavelength |
|
625 wlr = list(dimensions_lr['wavelength']) |
|
626 for r in range(len(wlr)): |
|
627 wlr[r] = str(wlr[r]) + ' (LR)' |
|
628 whr = list(dhrw) |
|
629 for r in range(len(whr)): |
|
630 whr[r] = str(whr[r]) + ' (HR)' |
|
631 dimensions['wavelength_res'] = wlr + whr |
|
632 dimensions_hr['wavelength'] = dhrw |
|
633 dimensions['wavelength'] = wav |
|
634 # Time |
|
635 tim = list(dimensions_lr['time']) |
|
636 tim.extend(x for x in dimensions_hr['time'] if x not in tim) |
|
637 dimensions['time'] = tim |
|
638 # Level |
|
639 lev = list(dimensions_lr['level']) |
|
640 lev.extend(x for x in dimensions_hr['level'] if x not in lev) |
|
641 dimensions['level'] = lev |
|
642 |
|
643 # Populate the arrays with data and errors |
|
644 for v in variables_with_data: |
|
645 # Create array to store the joint data |
|
646 # data_var = np.ma.masked_all((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
647 data_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
648 data_error_positive_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
649 data_error_negative_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
650 # ToDo check if needed |
|
651 data_var = np.ma.masked_values(data_var, 0) |
|
652 data_error_positive_var = np.ma.masked_values(data_error_positive_var, 0) |
|
653 data_error_negative_var = np.ma.masked_values(data_error_negative_var, 0) |
|
654 for w in range(len(dimensions['wavelength_res'])): |
|
655 for t in range(len(dimensions['time'])): |
|
656 # Incorporate data into the main array |
|
657 print(f"{v} - Wavelength: {dimensions['wavelength_res'][w]}. Time: {dimensions['time'][t]}.") |
|
658 |
|
659 # High resolution |
|
660 if dimensions['wavelength_res'][w].find('HR') >= 0: |
|
661 # Is there HR data? |
|
662 if v in data_hr: |
|
663 try: |
|
664 # Find position of w and t |
|
665 wl = float(dimensions['wavelength_res'][w].split(' ')[0]) |
|
666 wp = dimensions_hr['wavelength'].index(wl) |
|
667 wp = dhrw.index(wl) # ToDo test |
|
668 tp = dimensions_hr['time'].index(dimensions['time'][t]) |
|
669 # Check if there is data |
|
670 a = data_hr[v][wp, tp, :] |
|
671 d = np.average(np.ma.masked_array(a, np.isnan(a))) |
|
672 if np.ma.min(d) is not np.ma.masked: |
|
673 print(f'\tWe have HR data for {v}') |
|
674 # Save data into common structure |
|
675 data_var[w, t, :] = a |
|
676 if np.average(np.ma.masked_array(data_error_positive_hr[v][wp, tp, :], np.isnan( |
|
677 data_error_positive_hr[v][wp, tp, :]))) is not np.ma.masked: |
|
678 data_error_positive_var[w, t, :] = data_error_positive_hr[v][wp, tp, :] |
|
679 if np.average(np.ma.masked_array(data_error_negative_hr[v][wp, tp, :], np.isnan( |
|
680 data_error_negative_hr[v][wp, tp, :]))) is not np.ma.masked: |
|
681 data_error_negative_var[w, t, :] = data_error_negative_hr[v][wp, tp, :] |
|
682 except ValueError: |
|
683 pass |
|
684 |
|
685 # Low resolution |
|
686 if dimensions['wavelength_res'][w].find('LR') >= 0: |
|
687 # Is there LR data? |
|
688 if v in data_lr: |
|
689 # Find position of w and t |
|
690 try: |
|
691 wl = float(dimensions['wavelength_res'][w].split(' ')[0]) |
|
692 # wp = dimensions_hr['wavelength'].index(wl) # ToDo check |
|
693 if wl in dimensions_lr['wavelength']: |
|
694 wp = dimensions_lr['wavelength'].index(dimensions['wavelength'][w]) |
|
695 else: |
|
696 wp = -1 |
|
697 # if dimensions['time'][t] in dimensions_lr['time']: |
|
698 tp = dimensions_lr['time'].index(dimensions['time'][t]) |
|
699 # else: |
|
700 # tp = -1 |
|
701 if wp > -1 and tp > -1: |
|
702 # Check if there is data |
|
703 a = data_lr[v][wp, tp, :] |
|
704 d = np.average(np.ma.masked_array(a, np.isnan(a))) |
|
705 if np.ma.min(d) is not np.ma.masked: |
|
706 print(f'\tWe have LR data for {v}') |
|
707 # Save data into common structure |
|
708 data_var[w, t, :] = a |
|
709 if np.average(np.ma.masked_array(data_error_positive_lr[v][wp, tp, :], np.isnan( |
|
710 data_error_positive_lr[v][wp, tp, :]))) is not np.ma.masked: |
|
711 data_error_positive_var[w, t, :] = data_error_positive_lr[v][wp, tp, :] |
|
712 if np.average(np.ma.masked_array(data_error_negative_lr[v][wp, tp, :], np.isnan( |
|
713 data_error_negative_lr[v][wp, tp, :]))) is not np.ma.masked: |
|
714 data_error_negative_var[w, t, :] = data_error_negative_lr[v][wp, tp, :] |
|
715 except ValueError: |
|
716 # i.e. no 1064 wavelength in dimensions_lr |
|
717 pass |
|
718 # except IndexError: |
|
719 # pass |
|
720 |
|
721 # Store data in the global matrices |
|
722 if variables_with_data.index(v) == 0: |
|
723 data_all = {v: data_var} |
|
724 data_error_positive = {v: data_error_positive_var} |
|
725 data_error_negative = {v: data_error_negative_var} |
|
726 else: |
|
727 data_all[v] = data_var |
|
728 data_error_positive[v] = data_error_positive_var |
|
729 data_error_negative[v] = data_error_negative_var |
|
730 |
|
731 # Plot |
|
732 timeiter = dimensions['time'] |
|
733 # Default plotting |
|
734 dimensions_t = dimensions |
|
735 for t in range(len(dimensions['time'])): |
|
736 print(f'plotting hr & lr for {timeiter[t]}') |
|
737 dimensions_t['time'] = [timeiter[t]] |
|
738 for vr in range(len(variables_with_data)): |
|
739 if vr == 0: |
|
740 data_t = {variables_with_data[vr]: data_all[variables_with_data[vr]][:, t:t + 1, :]} |
|
741 else: |
|
742 data_t[variables_with_data[vr]] = data_all[variables_with_data[vr]][:, t:t + 1, :] |
|
743 |
|
744 fig = plot_vertical_profiles_plotly_allres( |
|
745 variables=variables_with_data, |
|
746 data=data_t, |
|
747 dimensions=dimensions_t, |
|
748 y_array=altitude, |
|
749 positive_error_array=data_error_positive, |
|
750 negative_error_array=data_error_negative, |
547 xaxis_label=variables_axis, |
751 xaxis_label=variables_axis, |
548 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
752 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
549 title=station_location + " (" + station_id.upper() + ") - " + str( |
753 title=station_location + " (" + station_id.upper() + ") - " + str( |
550 datetime.fromtimestamp(dimensions['time'][0]).strftime('%d/%m/%Y')) + " - ELDA MWL " + groups_names[ |
754 datetime.fromtimestamp(dimensions_t['time'][0], tz=timezone.utc).strftime( |
551 g], |
755 '%d/%m/%Y %H:%M:%S')) + " - ELDA MWL - High and low resolution") |
552 timeinrows=timeinrows |
|
553 ) |
|
554 |
756 |
555 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
757 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
556 # fig.show() |
758 # fig.show() |
557 |
759 |
558 # Save the plot |
760 # Save the plot |
559 if timeinrows: |
761 |
560 filename = "ELDAmwl_" + station_id.upper() + "_" + datetime.fromtimestamp( |
762 # Timestamps for the filename |
561 dimensions['time'][0]).strftime('%Y%m%d%H%M%S') + '-' + datetime.fromtimestamp( |
763 t0 = datetime.fromtimestamp(timeiter[t], tz=timezone.utc).strftime('%Y%m%d%H%M') |
562 dimensions['time'][-1]).strftime('%Y%m%d%H%M%S') + "_" + groups[g] + "_timeinrows.html" |
764 if t + 1 < len(timeiter): |
|
765 t1 = datetime.fromtimestamp( |
|
766 timeiter[t + 1], tz=timezone.utc).strftime('%Y%m%d%H%M') |
563 else: |
767 else: |
564 filename = "ELDAmwl_" + station_id.upper() + "_" + datetime.fromtimestamp( |
768 t1 = netcdf_file[29:41] |
565 dimensions['time'][0]).strftime('%Y%m%d%H%M%S') + '-' + datetime.fromtimestamp( |
769 |
566 dimensions['time'][-1]).strftime('%Y%m%d%H%M%S') + "_" + groups[g] + ".html" |
770 filename = "ELDAmwl_" + netcdf_file[0:3].upper() + "_" + t0 + "-" + t1 + "_all.html" |
567 |
|
568 fig.write_html(html_path + filename) |
771 fig.write_html(html_path + filename) |
569 |
|
570 else: |
|
571 print(f'There is no data to be plotted in the {groups_names[g]} group.') |
|
572 |
|
573 # Plotting high and low resolution together |
|
574 if len(variables_with_data_lr) > 0 and len(variables_with_data_hr) > 0: |
|
575 print(f'We have low and high resolution data, let''s combine it!') |
|
576 |
|
577 # Variables with data |
|
578 variables_with_data = list(variables_with_data_lr) |
|
579 variables_with_data.extend(x for x in variables_with_data_hr if x not in variables_with_data) |
|
580 print(f'Variables with data: {variables_with_data}') |
|
581 |
|
582 # Variables axis |
|
583 variables_axis = list(variables_axis_lr) |
|
584 variables_axis.extend(x for x in variables_axis_hr if x not in variables_axis) |
|
585 |
|
586 # Joining dimensions for both resolutions |
|
587 # Wavelength |
|
588 wav = list(dimensions_lr['wavelength']) |
|
589 wav.extend(x for x in dimensions_hr['wavelength'] if x not in wav) |
|
590 dimensions['wavelength'] = wav |
|
591 # Add LR/HR to the wavelength |
|
592 wlr = list(dimensions_lr['wavelength']) |
|
593 for r in range(len(wlr)): |
|
594 wlr[r] = str(wlr[r]) + ' (LR)' |
|
595 whr = list(dimensions_hr['wavelength']) |
|
596 for r in range(len(whr)): |
|
597 whr[r] = str(whr[r]) + ' (HR)' |
|
598 dimensions['wavelength_res'] = wlr + whr |
|
599 # Time |
|
600 tim = list(dimensions_lr['time']) |
|
601 tim.extend(x for x in dimensions_hr['time'] if x not in tim) |
|
602 dimensions['time'] = tim |
|
603 # Level |
|
604 lev = list(dimensions_lr['level']) |
|
605 lev.extend(x for x in dimensions_hr['level'] if x not in lev) |
|
606 dimensions['level'] = lev |
|
607 |
|
608 # Populate the arrays with data and errors |
|
609 for v in variables_with_data: |
|
610 # Create array to store the joint data |
|
611 # data_var = np.ma.masked_all((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
612 data_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
613 data_error_positive_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
614 data_error_negative_var = np.ma.zeros((len(dimensions['wavelength_res']), len(tim), len(lev))) |
|
615 # ToDo check if needed |
|
616 data_var = np.ma.masked_values(data_var, 0) |
|
617 data_error_positive_var = np.ma.masked_values(data_error_positive_var, 0) |
|
618 data_error_negative_var = np.ma.masked_values(data_error_negative_var, 0) |
|
619 for w in range(len(dimensions['wavelength_res'])): |
|
620 for t in range(len(dimensions['time'])): |
|
621 # Incorporate data into the main array |
|
622 print(f"{v} - Wavelength: {dimensions['wavelength_res'][w]}. Time: {dimensions['time'][t]}.") |
|
623 |
|
624 # High resolution |
|
625 if dimensions['wavelength_res'][w].find('HR') >= 0: |
|
626 # Is there HR data? |
|
627 if v in data_hr: |
|
628 try: |
|
629 # Find position of w and t |
|
630 wl = float(dimensions['wavelength_res'][w].split(' ')[0]) |
|
631 wp = dimensions_hr['wavelength'].index(wl) |
|
632 tp = dimensions_hr['time'].index(dimensions['time'][t]) |
|
633 # Check if there is data |
|
634 a = data_hr[v][wp, tp, :] |
|
635 d = np.average(np.ma.masked_array(a, np.isnan(a))) |
|
636 if np.ma.min(d) is not np.ma.masked: |
|
637 print(f'\tWe have HR data for {v}') |
|
638 # Save data into common structure |
|
639 data_var[w, t, :] = a |
|
640 if np.average(np.ma.masked_array(data_error_positive_hr[v][wp, tp, :], np.isnan( |
|
641 data_error_positive_hr[v][wp, tp, :]))) is not np.ma.masked: |
|
642 data_error_positive_var[w, t, :] = data_error_positive_hr[v][wp, tp, :] |
|
643 if np.average(np.ma.masked_array(data_error_negative_hr[v][wp, tp, :], np.isnan( |
|
644 data_error_negative_hr[v][wp, tp, :]))) is not np.ma.masked: |
|
645 data_error_negative_var[w, t, :] = data_error_negative_hr[v][wp, tp, :] |
|
646 except ValueError: |
|
647 pass |
|
648 |
|
649 # Low resolution |
|
650 if dimensions['wavelength_res'][w].find('LR') >= 0: |
|
651 # Is there LR data? |
|
652 if v in data_lr: |
|
653 # Find position of w and t |
|
654 try: |
|
655 wl = float(dimensions['wavelength_res'][w].split(' ')[0]) |
|
656 wp = dimensions_hr['wavelength'].index(wl) |
|
657 if wl in dimensions_lr['wavelength']: |
|
658 wp = dimensions_lr['wavelength'].index(dimensions['wavelength'][w]) |
|
659 else: |
|
660 wp = -1 |
|
661 # if dimensions['time'][t] in dimensions_lr['time']: |
|
662 tp = dimensions_lr['time'].index(dimensions['time'][t]) |
|
663 # else: |
|
664 # tp = -1 |
|
665 if wp > -1 and tp > -1: |
|
666 # Check if there is data |
|
667 a = data_lr[v][wp, tp, :] |
|
668 d = np.average(np.ma.masked_array(a, np.isnan(a))) |
|
669 if np.ma.min(d) is not np.ma.masked: |
|
670 print(f'\tWe have LR data for {v}') |
|
671 # Save data into common structure |
|
672 data_var[w, t, :] = a |
|
673 if np.average(np.ma.masked_array(data_error_positive_lr[v][wp, tp, :], np.isnan( |
|
674 data_error_positive_lr[v][wp, tp, :]))) is not np.ma.masked: |
|
675 data_error_positive_var[w, t, :] = data_error_positive_lr[v][wp, tp, :] |
|
676 if np.average(np.ma.masked_array(data_error_negative_lr[v][wp, tp, :], np.isnan( |
|
677 data_error_negative_lr[v][wp, tp, :]))) is not np.ma.masked: |
|
678 data_error_negative_var[w, t, :] = data_error_negative_lr[v][wp, tp, :] |
|
679 except ValueError: |
|
680 # i.e. no 1064 wavelength in dimensions_lr |
|
681 pass |
|
682 # except IndexError: |
|
683 # pass |
|
684 |
|
685 # Store data in the global matrices |
|
686 if variables_with_data.index(v) == 0: |
|
687 data_all = {v: data_var} |
|
688 data_error_positive = {v: data_error_positive_var} |
|
689 data_error_negative = {v: data_error_negative_var} |
|
690 else: |
|
691 data_all[v] = data_var |
|
692 data_error_positive[v] = data_error_positive_var |
|
693 data_error_negative[v] = data_error_negative_var |
|
694 |
|
695 # Plot |
|
696 timeiter = dimensions['time'] |
|
697 # Default plotting |
|
698 dimensions_t = dimensions |
|
699 for t in range(len(dimensions['time'])): |
|
700 print(f'plotting hr & lr for {timeiter[t]}') |
|
701 dimensions_t['time'] = [timeiter[t]] |
|
702 for vr in range(len(variables_with_data)): |
|
703 if vr == 0: |
|
704 data_t = {variables_with_data[vr]: data_all[variables_with_data[vr]][:, t:t + 1, :]} |
|
705 else: |
|
706 data_t[variables_with_data[vr]] = data_all[variables_with_data[vr]][:, t:t + 1, :] |
|
707 |
|
708 fig = plot_vertical_profiles_plotly_allres( |
|
709 variables=variables_with_data, |
|
710 data=data_t, |
|
711 dimensions=dimensions_t, |
|
712 y_array=altitude, |
|
713 positive_error_array=data_error_positive, |
|
714 negative_error_array=data_error_negative, |
|
715 xaxis_label=variables_axis, |
|
716 yaxis_label=altitude['metadata']['long_name'] + ' [' + altitude['metadata']['units'] + ']', |
|
717 title=station_location + " (" + station_id.upper() + ") - " + str(datetime.fromtimestamp(dimensions_t['time'][0]).strftime('%d/%m/%Y %H:%M:%S')) + " - ELDA MWL - High and low resolution") |
|
718 |
|
719 # Show the plot (in Jupyter Notebook or Jupyter Lab) |
|
720 fig.show() |
|
721 |
|
722 # Save the plot |
|
723 filename = "ELDAmwl_" + netcdf_file[0:3].upper() + "_" + datetime.fromtimestamp( |
|
724 dimensions['time'][0]).strftime('%Y%m%d-%H%M%S') + "_all.html" |
|
725 fig.write_html(html_path + filename) |
|
726 |
|