From 0256dcead89e0f1d438bf6c9c94c40e9832033b4 Mon Sep 17 00:00:00 2001 From: Delphine Dobler <57707263+delphinedobler@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:31:04 +0200 Subject: [PATCH 1/5] A few v3.4 customisations - remove CTD from plot 09 when i_bgc=1. - 1-yr static string was replaced by the config value - add a new graph per profile year with DMQC and profile QC F + output values in a text file - add a log (diary) --- scripts/get_DMQC_stats.m | 427 +++++++++++++++++++++++++++++++-------- 1 file changed, 344 insertions(+), 83 deletions(-) diff --git a/scripts/get_DMQC_stats.m b/scripts/get_DMQC_stats.m index a8f9e34..53ab30f 100644 --- a/scripts/get_DMQC_stats.m +++ b/scripts/get_DMQC_stats.m @@ -118,6 +118,12 @@ % - change search for param name in index for a more robust means % - add x grid and minor grid for psal adjustment display by wmo. % - add an option to group prof QC A and B +% V3.4 (2024/02/23) : +% - remove CTD from plot 09 when i_bgc=1. +% - 1-yr static string was replaced by the config value +% - add a new graph per profile year with DMQC and profile QC F + +% output values in a text file +% - add a log (diary) %option explicit @@ -130,11 +136,11 @@ disp('Configuration') -icase = 6; +icase = 5; switch icase case 1 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/01_EuropeanFleet_case/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/01_EuropeanFleet_case/'; i_bgc = 1; wmo_list_file = [test_case_dir 'input_files/wmo_list_all_european_floats.csv']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; @@ -142,21 +148,21 @@ output_graphs_per_float = 0; case 3 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/03_RBR_case/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/03_RBR_case/'; i_bgc = 0; wmo_list_file = [test_case_dir 'input_files/wmo_list_all_rbr_floats.txt']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; project_name = 'RBR_Fleet'; output_graphs_per_float = 1; case 4 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/04_RC_AtlantOS/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/04_RC_AtlantOS/'; i_bgc = 1; wmo_list_file = [test_case_dir 'input_files/AtlantOS_EuroSea.csv']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; project_name = 'AtlantOS_BGC_Fleet'; output_graphs_per_float = 1; case 5 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/05_RC_Mocca/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/05_RC_Mocca/'; i_bgc = 0; wmo_list_file = [test_case_dir 'input_files/MOCCA.csv']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; @@ -164,7 +170,7 @@ output_graphs_per_float = 1; case 6 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/06_AllArgoFleet_case/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/06_AllArgoFleet_case/'; i_bgc = 1; wmo_list_file = [test_case_dir 'input_files/wmo_list_all_Argo_floats.txt']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; @@ -172,41 +178,56 @@ output_graphs_per_float = 0; case 7 - test_case_dir = '/home1/datahome/co_arg/ddobler/DMQC_Status/07_ASD_floats/'; + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/07_ASD_floats/'; i_bgc = 0; wmo_list_file = [test_case_dir 'input_files/wmo_list_asd_floats.csv']; country_code_file = [test_case_dir 'input_files/country_codes.csv']; project_name = 'ASD_Fleet'; output_graphs_per_float = 1; + + case 8 + test_case_dir = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/08_Atlantic_case/'; + i_bgc = 1; + wmo_list_file = [test_case_dir 'input_files/wmo_list_atlantic_case.csv']; + country_code_file = [test_case_dir 'input_files/country_codes.csv']; + project_name = 'Atlantic_Fleet'; + output_graphs_per_float = 0; end index_file = '/home/ref-argo/gdac/etc/argo_profile_detailled_index.txt'; +%index_file = [test_case_dir 'input_files/argo_profile_detailled_index_2023-01-08.txt']; + index_file_short = [test_case_dir 'input_files/argo_profile_detailed_index_subset.txt']; input_list_of_parameters_to_treat=["TEMP"; "PRES"; "PSAL"]; disp([newline ' Treating CTD parameters for ' project_name ' case']); if i_bgc == 1 index_file_synthetic = '/home/ref-argo/gdac/etc/argo_synthetic-profile_detailled_index.txt'; - index_file_synthetic_short = [test_case_dir 'input_files/argo_synthetic-profile_detailed_index_subset.txt']; - input_list_of_BGC_parameters_to_treat=["DOXY";"DOXY2";"CHLA";"NITRATE";"PH_IN_SITU_TOTAL";"TURBIDITY";"BISULFIDE";"CDOM";... - "BBP532";"BBP700";"DOWNWELLING_PAR";"DOWN_IRRADIANCE380";"DOWN_IRRADIANCE412";"DOWN_IRRADIANCE443";"DOWN_IRRADIANCE490";... - "DOWN_IRRADIANCE555";"DOWN_IRRADIANCE665";"DOWN_IRRADIANCE670";"CP660"]; + %index_file_synthetic = [test_case_dir 'input_files/argo_synthetic-profile_detailled_index_2023-07-13.txt']; + + index_file_synthetic_short = [test_case_dir 'input_files/argo_profile_detailled_index_subset.txt']; + input_list_of_BGC_parameters_to_treat=["DOXY";"CHLA";"NITRATE";"PH_IN_SITU_TOTAL";"BBP700";"DOWN_IRRADIANCE380"]; +% input_list_of_BGC_parameters_to_treat=["DOXY";"DOXY2";"CHLA";"NITRATE";"PH_IN_SITU_TOTAL";"TURBIDITY";"BISULFIDE";"CDOM";... +% "BBP532";"BBP700";"DOWNWELLING_PAR";"DOWN_IRRADIANCE380";"DOWN_IRRADIANCE412";"DOWN_IRRADIANCE443";"DOWN_IRRADIANCE490";... +% "DOWN_IRRADIANCE555";"DOWN_IRRADIANCE665";"DOWN_IRRADIANCE670";"CP660"]; disp([newline ' Treating BGC parameters for ' project_name ' case']); end greylist_file = '/home/ref-argo/gdac/ar_greylist.txt'; -script_path = '/home1/datahome/co_arg/ddobler/DMQC_Status/scripts/'; +script_path = '/home1/datahome/co_arg/ddobler/04_DMQC/01_DMQC_Status/scripts/'; i_descending_profile = 0; % 0 means not including descending profiles, 1 means including descending profiles -sage = 365; % threshold [days]. More than 1 year (floats and profiles) -print_svg=0; % (interesting for high quality, but a little longer to save). +sage = 720; % threshold [days]. More than 1 year (floats and profiles) +sage_yr_str= sprintf('%.1f',sage/365); % for plots and logs + +print_svg=1; % (interesting for high quality, but a little longer to save). %output_graphs_per_float = 1; % Indicate if graphs per float should be % recorded. For treatmant with a large % number of floats, this may not be relevant) -n_max_float_per_graph = 31; % associated to output_graphs_per_float. +n_max_float_per_graph = 30; % associated to output_graphs_per_float. i_group_AB_profQC = 1; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -233,6 +254,7 @@ % with data from the same date. For the seek of space: to be zipped once % finished. test_date=char(datetime('now','TimeZone','local','Format','yyyy-MM-dd_HHmmSS')); +%test_date='2023-01-08_000000'; output_dir=[ test_case_dir '/outputs_' test_date '/']; @@ -241,6 +263,9 @@ mkdir(output_dir) end +log_file=[output_dir 'matlab_log.txt']; +diary(log_file) +diary on disp('-- creating a local copy of the index file ...') local_index_file=[output_dir 'argo_profile_detailled_index_' test_date '.txt']; @@ -585,7 +610,9 @@ tEnd = toc(tStart); disp([newline 'End of reading index files (' char(string(floor(tEnd))) ' s)']) disp('######################') +diary off %% +diary on % Compute values for graphs: disp('') @@ -627,6 +654,12 @@ i_R_or_A_profile.(i_param)=(IndexData.param.(i_param).mode == 'R' | IndexData.param.(i_param).mode == 'A'); wmos_with_R_or_A_profile.(i_param)=unique(IndexData.profile_WMO(i_R_or_A_profile.(i_param))); + % Index the profiles that have profile_QC = 'F' + i_Fprof.(i_param)=(IndexData.param.(i_param).qc == 'F'); + + % Index the profiles that have param + i_pres.(i_param)=(IndexData.param.(i_param).presence == 1); + end @@ -660,7 +693,7 @@ nb_floats_per_country.(i_param)(loc)=val; nb_float_tot.(i_param)=sum(val); - fprintf('-- compute nb of floats with at least 1 profile > 1yr for %s per country\n',i_param) + fprintf('-- compute nb of floats with at least 1 profile > %s yr for %s per country\n',sage_yr_str,i_param) wmos_xage.param.(i_param)=unique(IndexData.profile_WMO(i_more_than_x_days & (IndexData.param.(i_param).presence==1))); [~,loc]=ismember(wmos_xage.param.(i_param),Floats_list.WMO); wmos_xage_country=string(Floats_list.COUNTRYCODE(loc,:)); @@ -681,7 +714,7 @@ nb_floats_DMQCed_per_country.(i_param)(loc)=val; nb_float_DMQCed_tot.(i_param)=sum(val); - fprintf('-- compute nb of floats with at least 1 profile DMQCed for %s and with at least 1 profile > 1yr per country\n',i_param) + fprintf('-- compute nb of floats with at least 1 profile DMQCed for %s and with at least 1 profile > %s yr per country\n',i_param,sage_yr_str) wmos_xage_DMQCed=unique(IndexData.profile_WMO(i_DMQCed.(i_param) & i_more_than_x_days)); [~,loc]=ismember(wmos_xage_DMQCed,Floats_list.WMO); wmos_xage_dmqced_country=string(Floats_list.COUNTRYCODE(loc,:)); @@ -713,7 +746,7 @@ [~,loc]=ismember(xx,nb_per_country_x); nb_profiles_per_country.(i_param)(loc)=val; - fprintf('-- compute nb of profiles > 1yr for %s per country\n',i_param) + fprintf('-- compute nb of profiles > %s yr for %s per country\n',sage_yr_str,i_param) [xx,~,ic]=unique(IndexData.country(i_more_than_x_days & IndexData.param.(i_param).presence==1)); val=accumarray(ic,1); [~,loc]=ismember(xx,nb_per_country_x); @@ -725,7 +758,7 @@ [~,loc]=ismember(xx,nb_per_country_x); nb_profiles_DMQCed_per_country.(i_param)(loc)=val; - fprintf('-- compute nb of profiles DMQCed and > 1yr for %s per country\n',i_param) + fprintf('-- compute nb of profiles DMQCed and > %s yr for %s per country\n',sage_yr_str, i_param) [xx,~,ic]=unique(IndexData.country(i_DMQCed.(i_param) & i_more_than_x_days)); val=accumarray(ic,1); [~,loc]=ismember(xx,nb_per_country_x); @@ -871,6 +904,8 @@ %output initialisation nb_profiles_per_year.(i_param)=zeros(n_years,1); nb_profiles_DMQCed_per_year.(i_param)=zeros(n_years,1); + nb_profiles_QCF_per_year.(i_param)=zeros(n_years,1); + nb_profiles_DMQCed_QCF_per_year.(i_param)=zeros(n_years,1); % Extract year from the profile date %i_missing_profile_date=ismissing(IndexData.date); @@ -885,17 +920,31 @@ IndexData.profile_year.(i_param)(i_not_missing_profile_date)=string(tmp(:,1:4)); end - % compute nb of profiles per year - [xx,~,ic]=unique(IndexData.profile_year.(i_param)); + % compute nb of profiles per profile year + [xx,~,ic]=unique(IndexData.profile_year.(i_param)(i_pres.(i_param))); val=accumarray(ic,1); [~,loc]=ismember(xx,nb_per_year_x); nb_profiles_per_year.(i_param)(loc)=val; - % compute nb of D-profile per year - [xx,~,ic]=unique(IndexData.profile_year.(i_param)(i_DMQCed.(i_param))); + % compute nb of D-profile per profile year + [xx,~,ic]=unique(IndexData.profile_year.(i_param)(i_DMQCed.(i_param) & i_pres.(i_param))); val=accumarray(ic,1); [~,loc]=ismember(xx,nb_per_year_x); nb_profiles_DMQCed_per_year.(i_param)(loc)=val; + + % compute nb of F-profile per profile year + [xx,~,ic]=unique(IndexData.profile_year.(i_param)(i_Fprof.(i_param) & i_pres.(i_param))); + val=accumarray(ic,1); + [~,loc]=ismember(xx,nb_per_year_x); + nb_profiles_QCF_per_year.(i_param)(loc)=val; + + % compute nb of DF-profile per profile year + [xx,~,ic]=unique(IndexData.profile_year.(i_param)(i_DMQCed.(i_param) & i_Fprof.(i_param) & i_pres.(i_param))); + val=accumarray(ic,1); + [~,loc]=ismember(xx,nb_per_year_x); + nb_profiles_DMQCed_QCF_per_year.(i_param)(loc)=val; + + end %nb_profiles_DMQCed_per_year.(i_param) @@ -910,8 +959,10 @@ disp('######################') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +diary off %% Make graphics +diary on + close all disp(' ') @@ -952,11 +1003,14 @@ 0.6863 0.5059 0.0157; ... % 17 - qc D for D profiles "verge d'or" with darker coefficients (not standard) 0 0.5020 0.5020; ... % 18 - qc E for D profiles "sarcelle" 0.1176 0.5647 1.0000; ... % 19 - qc F for D profiles "dodgerblue" - 0.2000 0.2000 0.2000]; % 20 - qc X for D profiles + 0.2000 0.2000 0.2000; ... % 20 - qc X for D profiles + 255/255 69/255 0/255; ... % 21 - qc F (perprofyear) "Orange Red" + 174/255 12/255 0/255]; % 22 - qc F (perprofyear) for D profiles "Mordant Red 19" - -%% +diary off +%% +diary on tStart = tic; for i=1:n_param close all @@ -1021,15 +1075,15 @@ legend([hndl(1,2), hndl(1,1), hndl(2,2), hndl(2,1), hp], ... {['Number of floats (Total: ', num2str(sum(nb_floats_per_country.(i_param),'omitnan')),')'],... ['Number of floats with D-profiles (Total: ', num2str(sum(nb_floats_DMQCed_per_country.(i_param),'omitnan')),')'], ... - ['Number of floats with profiles > 1-yr (Total: ', num2str(sum(nb_floats_xage_per_country.(i_param),'omitnan')),')'],... - ['Number of floats with D-profiles > 1-yr (Total: ',num2str(sum(nb_floats_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... + ['Number of floats with profiles > ' sage_yr_str '-yr (Total: ', num2str(sum(nb_floats_xage_per_country.(i_param),'omitnan')),')'],... + ['Number of floats with D-profiles > ' sage_yr_str '-yr (Total: ',num2str(sum(nb_floats_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... prof_included}) else legend([hndl(1,2), hndl(1,1), hndl(2,2), hndl(2,1), hp], ... {['Nb of floats to be managed at Euro-Argo (Total: ', num2str(sum(nb_floats_per_country.(i_param),'omitnan')),')'],... ['Nb of floats already addressed once in DMQC (Total: ', num2str(sum(nb_floats_DMQCed_per_country.(i_param),'omitnan')),')'], ... - ['Nb of floats for which DMQC can now be performed (older than 1-yr) (Total: ', num2str(sum(nb_floats_xage_per_country.(i_param),'omitnan')),')'],... - ['Nb of floats already addressed once in DMQC (and older than 1-yr) (Total: ',num2str(sum(nb_floats_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... + ['Nb of floats for which DMQC can now be performed (older than ' sage_yr_str '-yr) (Total: ', num2str(sum(nb_floats_xage_per_country.(i_param),'omitnan')),')'],... + ['Nb of floats already addressed once in DMQC (and older than ' sage_yr_str '-yr) (Total: ',num2str(sum(nb_floats_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... }) end @@ -1062,7 +1116,7 @@ floats_tobedone_str = num2str(round(floats_tobedone)); H = figure(1); set(H,'units','pix') - annotation('textbox', [0.8, 0.01, .1, .1], 'string', ['Floats older than 1-yr to be DMQCed: ',floats_tobedone_str,'%'],... + annotation('textbox', [0.8, 0.01, .1, .1], 'string', ['Floats older than ' sage_yr_str '-yr to be DMQCed: ',floats_tobedone_str,'%'],... 'FitBoxToText','on','verticalalignment', 'bottom','HorizontalAlignment', 'right','FontWeight','bold') % save figure @@ -1119,8 +1173,8 @@ legend([hndl(1,2), hndl(1,1), hndl(2,2), hndl(2,1), hp], ... {['Number of profiles (Total: ',num2str(sum(nb_profiles_per_country.(i_param),'omitnan')),')'],... ['Number of D-profiles (Total: ',num2str(sum(nb_profiles_DMQCed_per_country.(i_param),'omitnan')),')'], ... - ['Number of profiles older than 1-yr (Total: ',num2str(sum(nb_profiles_xage_per_country.(i_param),'omitnan')),')'],... - ['Number of D-profiles older than 1-yr (Total: ',num2str(sum(nb_profiles_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... + ['Number of profiles older than ' sage_yr_str '-yr (Total: ',num2str(sum(nb_profiles_xage_per_country.(i_param),'omitnan')),')'],... + ['Number of D-profiles older than ' sage_yr_str '-yr (Total: ',num2str(sum(nb_profiles_xage_DMQCed_per_country.(i_param),'omitnan')),')'], ... prof_included}) % background color set(gcf,'color','w'); @@ -1135,7 +1189,7 @@ obs_tobedone = sum(nb_profiles_xage_per_country.(i_param)-nb_profiles_xage_DMQCed_per_country.(i_param),'omitnan')/sum(nb_profiles_xage_per_country.(i_param),'omitnan')*100; H = figure(i_fig); set(H,'units','pix') - annotation('textbox', [0.8, 0.01, .1, .1], 'string', ['Profiles older than 1-yr to be DMQCed: ',num2str(round(obs_tobedone)),'%'],... + annotation('textbox', [0.8, 0.01, .1, .1], 'string', ['Profiles older than ' sage_yr_str '-yr to be DMQCed: ',num2str(round(obs_tobedone)),'%'],... 'FitBoxToText','on','verticalalignment', 'bottom','HorizontalAlignment', 'right','FontWeight','bold') % save figure @@ -1148,7 +1202,9 @@ end end -%% +diary off +%% +diary on for i=1:n_param close all @@ -1428,7 +1484,9 @@ end -%% +diary off +%% +diary on for i=1:n_param close all @@ -1465,9 +1523,9 @@ ylabel('Number of floats') % legend with total number legend(['All floats (' num2str(nb_float_tot.(i_param)) ')'],... - ['Floats > 1-yr (' num2str(nb_float_xage_tot.(i_param)) ')'],... + ['Floats > ' sage_yr_str '-yr (' num2str(nb_float_xage_tot.(i_param)) ')'],... ['Floats DMQC at least once (' num2str(nb_float_DMQCed_tot.(i_param)) ')'],... - ['Floats > 1-yr and DMQC at least once (' num2str(nb_floats_xage_DMQCed_tot.(i_param)) ')'],... + ['Floats > ' sage_yr_str '-yr and DMQC at least once (' num2str(nb_floats_xage_DMQCed_tot.(i_param)) ')'],... ['Active Floats in grey list (' num2str(nb_wmo_ope_in_greylist_with_qc_3_or_4.(i_param)) ... '/' num2str(nb_operational_floats.(i_param)) ' ->' ... num2str(round(100*nb_wmo_ope_in_greylist_with_qc_3_or_4.(i_param)/nb_operational_floats.(i_param),1)) '% of active floats)'],... @@ -1510,7 +1568,9 @@ end end -%% +diary off +%% +diary on for i=1:n_param close all @@ -1600,16 +1660,127 @@ if print_svg == 1 saveas(gcf,[out_name '.svg']) end -% end -% %% -% for i=1:n_param -% i_param=list_of_parameters_to_treat(i); -% fprintf('Making Plots for %s \n',i_param) -% -% close all + + + +end +diary off +%% +diary on +%for i=1:3 +for i=1:n_param + close all + + i_param=list_of_parameters_to_treat(i); + + if ismember("PSAL",list_of_parameters_to_treat) + if (i_param == "PRES") + % no need to output plot as mode fro PRES is the same as mode + % for PSAL eand TEMP and profile_qc unavailable in index. + continue + else + i_param_str=i_param; + end + else + i_param_str=i_param; + end + + fprintf('Making Plots for %s \n',i_param_str) + + close all + %%%%%%%%%%%%%% DMQC status per profile year %%%%%%%%%%%%%% + disp('DMQC and QC-F status per profile year') + i_fig=8; + figure(i_fig) + + % bigger figure + set(gcf, 'Position', [200, 200, 1000, 600]) + % figure name + set(gcf,'Name','DMQC and F status per profile year') + + if (nb_per_year_x(1) == string(1980)) + nb_per_year_x_cr=nb_per_year_x(2:end); + nb_profiles_DMQCed_per_year_cr=nb_profiles_DMQCed_per_year.(i_param)(2:end); + nb_profiles_per_year_cr=nb_profiles_per_year.(i_param)(2:end); + nb_profiles_QCF_per_year_cr=nb_profiles_QCF_per_year.(i_param)(2:end); + nb_profiles_DMQCed_QCF_per_year_cr=nb_profiles_DMQCed_QCF_per_year.(i_param)(2:end); + else + nb_per_year_x_cr=nb_per_year_x; + nb_profiles_DMQCed_per_year_cr=nb_profiles_DMQCed_per_year.(i_param); + nb_profiles_per_year_cr=nb_profiles_per_year.(i_param); + nb_profiles_QCF_per_year_cr=nb_profiles_QCF_per_year.(i_param); + nb_profiles_DMQCed_QCF_per_year_cr=nb_profiles_DMQCed_QCF_per_year.(i_param); + end + + stackData = cat(3,[(nb_profiles_per_year_cr-nb_profiles_QCF_per_year_cr) ... + (nb_profiles_DMQCed_per_year_cr-nb_profiles_DMQCed_QCF_per_year_cr)], ... + [ nb_profiles_QCF_per_year_cr ... + nb_profiles_DMQCed_QCF_per_year_cr]); + + hndl = plotBarStackGroups(stackData, 1:length(nb_per_year_x_cr)); + + + % FIGURE FORMAT + hold on + %plot(1,0,'w'); % for comment in legend + % bars colors + set(hndl(1,1),'facecolor',bars_colors(4,:)) + set(hndl(1,2),'facecolor',bars_colors(21,:)) + set(hndl(2,1),'facecolor',bars_colors(3,:)) + set(hndl(2,2),'facecolor',bars_colors(22,:)) + % xlabels + set(gca,'xtick',1:length(nb_per_year_x_cr),'xticklabel', nb_per_year_x_cr) + xtickangle(90) + % title with update date + title(['DMQC and profile-F status for ' char(i_param_str) ' per profile year (updated ',update_date_str,')'], 'Interpreter', 'none') + ylabel('Number of profiles') + % legend with total number + legend(['Number of profiles with prof_QC<>F(Total: ',num2str(sum(nb_profiles_per_year_cr,'omitnan')),')'],... + ['Number of profiles with prof_QC=F (Total: ',num2str(sum(nb_profiles_QCF_per_year_cr,'omitnan')),')'],... + ['Number of D-profiles with prof_QC<>F (Total: ',num2str(sum(nb_profiles_DMQCed_per_year_cr,'omitnan')),')'], ... + ['Number of D-profiles with prof_QC=F (Total: ',num2str(sum(nb_profiles_DMQCed_QCF_per_year_cr,'omitnan')),')'], ... + prof_included,'Location','southoutside', 'Interpreter', 'none') + % background color + set(gcf,'color','w'); + % grid in y axis + ax = gca; + ax.YGrid = 'on'; + + % figure labels + ymax=max(nb_profiles_per_year_cr); + set(gca,'YLim',[0 ymax+ymax/10]); +% for iyear = 1: length(nb_per_year_x_cr) +% if nb_profiles_per_year_cr(iyear) > 0 +% percent_str = [num2str(round(nb_profiles_DMQCed_per_year_cr(iyear)/nb_profiles_per_year_cr(iyear)*100,1)) ' %']; +% h=text(iyear + 0.15, nb_profiles_DMQCed_per_year_cr(iyear) + ymax/30 ,percent_str); +% set(h,'Rotation',90); +% end +% end + + % save figure + out_name = [output_plots_dir '/' sprintf('%02d',i_fig) '_' project_name '_' char(i_param_str) '_prof_DMQC-and-F_status_byyear_' working_date]; + disp(['saving ' out_name]) +% export_fig([out_name '.png']) + print('-dpng ', '-r100',[out_name '.png']) + if print_svg == 1 + saveas(gcf,[out_name '.svg']) + end + + + +end +diary off +%% +diary on +for i=1:n_param + i_param=list_of_parameters_to_treat(i); + fprintf('Making Plots for %s \n',i_param) + + close all + %%%%%%%%%%%%%% DMQC status by profile age histogram %%%%%%%%%%%%%% disp('DMQC status by profile age histogram') - i_fig=8; + i_fig=9; figure(i_fig) % bigger figure @@ -1645,7 +1816,9 @@ end tEnd = toc(tStart); -%% +diary off +%% +diary on % Additionnal graphs from previous get_DMQC_adjustment.m routine. % Thanks to the update of the index file with psal adjustment information % We can switch the making of the graphs to this routine. @@ -1654,8 +1827,8 @@ % - a series of graphs by wmo (R/A/D, QC, PSAL_adj) (and by parameter). disp('Number of R/A/D profiles by parameter') -i_fig=9; - +i_fig=10; +close all figure(i_fig) % bigger figure @@ -1663,15 +1836,26 @@ % figure name set(gcf,'Name','R/A/D profiles nb by parameter') +set(gca, 'units', 'normalized'); %Just making sure it's normalized +Tight = get(gca, 'TightInset'); %Gives you the bording spacing between plot box and any axis labels + %[Left Bottom Right Top] spacing +NewPos = [Tight(1) Tight(2) 1-Tight(1)-Tight(3) 1-Tight(2)-Tight(4)-0.1]; %New plot position [X Y W H] +set(gca, 'Position', NewPos); % To avoid the 3 same information for CTD: if list_of_parameters_to_treat(1)=="TEMP" && ... list_of_parameters_to_treat(2)=="PRES" && ... list_of_parameters_to_treat(3)=="PSAL" - - loc_list_of_parameters_to_treat=list_of_parameters_to_treat(3:end); - loc_n_param=size(loc_list_of_parameters_to_treat,1); - ctd_first=1; + + if i_bgc == 1 + loc_list_of_parameters_to_treat=list_of_parameters_to_treat(4:end); + loc_n_param=size(loc_list_of_parameters_to_treat,1); + ctd_first=0; + else + loc_list_of_parameters_to_treat=list_of_parameters_to_treat(3:end); + loc_n_param=size(loc_list_of_parameters_to_treat,1); + ctd_first=1; + end else loc_list_of_parameters_to_treat=list_of_parameters_to_treat; loc_n_param=n_param; @@ -1706,7 +1890,7 @@ % title with update date -title(['Number of R/A/D - profiles by variable (updated ',update_date_str,')']) +title(['Number of R/A/D - profiles by variable (updated ',update_date_str,')' newline project_name ], 'Interpreter', 'none') ylabel('Number of profiles') % legend with total number @@ -1714,7 +1898,7 @@ {['R-profiles (Total: ',num2str(sum(stackData(:,1))),')'],... ['A-profiles (Total: ',num2str(sum(stackData(:,2))),')'],... ['D-profiles (Total: ',num2str(sum(stackData(:,3))),')'],... - prof_included}) + prof_included},'Location','southoutside') % background color set(gcf,'color','w'); @@ -1731,11 +1915,13 @@ saveas(gcf,[out_name '.svg']) end -%% +diary off +%% +diary on if output_graphs_per_float ==1 disp('R/A/D status by float and by cycle number') - i_fig=10; + i_fig=11; for i=1:n_param close all i_param=list_of_parameters_to_treat(i); @@ -1845,12 +2031,14 @@ end end -%% +diary off +%% +diary on if output_graphs_per_float ==1 disp('Profile QC status by float and by cycle number') list_QCs=["A";"B";"C";"D";"E";"F";"X"]; - i_fig=11; + i_fig=12; for i=1:n_param close all @@ -1955,12 +2143,14 @@ end -%% +diary off +%% +diary on if output_graphs_per_float ==1 disp('PSAL adjustment by float and by cycle number') - i_fig=12; + i_fig=13; i_param = "PSAL"; subset_prof_WMO=IndexData.profile_WMO(IndexData.param.(i_param).presence==1); @@ -2081,7 +2271,9 @@ end end -%% +diary off +%% +diary on % Create output directory for text analyses: output_syntheses_dir = [output_dir '/Syntheses']; @@ -2092,7 +2284,9 @@ end disp([' Synthetic analyses will be saved in ' output_syntheses_dir]) -%% +diary off +%% +diary on % Warnings % for i=1:n_param @@ -2164,7 +2358,7 @@ warning_greyl(contains(wmos_in_warning.(i_param), wmos_with_RA_profiles_in_grey_list.(i_param))) = 'X'; header4=['PARAM,','WMO,','Country,','prof_QC=F_once,',... - 'prof_QC_not_filled_once,','No_DMQC_older_1yr,',... + 'prof_QC_not_filled_once,','No_DMQC_older_than_',sage_yr_str,'yr,',... 'grey_listed']; fprintf(fid, '%s \n', header4); @@ -2185,7 +2379,9 @@ end -%% +diary off +%% +diary on for i=1:n_param @@ -2228,11 +2424,11 @@ Floats_list.(i_param).wmo_dm_done = zeros(n_floats_par,1); Floats_list.(i_param).grey_list = zeros(n_floats_par,1); Floats_list.(i_param).prof_number = zeros(n_floats_par,1); - Floats_list.(i_param).prof_older_1yr_number = zeros(n_floats_par,1); + Floats_list.(i_param).prof_older_than_sage_number = zeros(n_floats_par,1); Floats_list.(i_param).prof_last_date = strings(n_floats_par,1); Floats_list.(i_param).prof_DMQCed_number = zeros(n_floats_par,1); Floats_list.(i_param).prof_DMQCed_last_update_date = strings(n_floats_par,1); - Floats_list.(i_param).prof_noDM_older_1yr_number = zeros(n_floats_par,1); + Floats_list.(i_param).prof_noDM_older_than_sage_number = zeros(n_floats_par,1); Floats_list.(i_param).prof_last_DM_date = strings(n_floats_par,1); Floats_list.(i_param).prof_DMQCed_percent = zeros(n_floats_par,1); Floats_list.(i_param).prof_QC_A = zeros(n_floats_par,1); @@ -2271,11 +2467,11 @@ [~,loc]=ismember(xx,string(Floats_list.(i_param).WMO)); Floats_list.(i_param).prof_number(loc)=val; - %'prof_older_1yr,' + %'prof_older_than_sage_number,' [xx,~,ic]=unique(IndexData.profile_WMO(IndexData.profile_age > sage & IndexData.param.(i_param).presence == 1)); val=accumarray(ic,1); [~,loc]=ismember(xx,string(Floats_list.(i_param).WMO)); - Floats_list.(i_param).prof_older_1yr_number(loc)=val; + Floats_list.(i_param).prof_older_than_sage_number(loc)=val; %'date_last_prof,' loc_wmos = IndexData.profile_WMO(IndexData.param.(i_param).presence == 1); @@ -2302,7 +2498,7 @@ IndexData.profile_age > sage)); val=accumarray(ic,1); [~,loc]=ismember(xx,string(Floats_list.(i_param).WMO)); - Floats_list.(i_param).prof_noDM_older_1yr_number(loc)=val; + Floats_list.(i_param).prof_noDM_older_than_sage_number(loc)=val; %'date_last_DMprof,' loc_wmos = IndexData.profile_WMO(IndexData.param.(i_param).mode == 'D'); @@ -2425,8 +2621,8 @@ % header header1 = ['PARAM,' 'WMO,' 'DAC,' 'COUNTRY,' 'PROGRAM,' 'launch_date,' ... 'prof_last_date,' 'DM_done,' ... - 'float_age,' 'float_more1year,' 'greylist,' 'nb_prof,' ... - 'nb_prof_more1year,' 'nb_prof_DM,' 'nb_prof_noDM_more1year,' ... + 'float_age,' 'float_more_' sage_yr_str '_year,' 'greylist,' 'nb_prof,' ... + 'nb_prof_more_' sage_yr_str '_year,' 'nb_prof_DM,' 'nb_prof_noDM_more_' sage_yr_str '_year,' ... 'prof_last_DM_date,' 'prof_last_DM_update_date,' 'percentage_DM_prof,'... 'nb_prof_QC_A,' 'nb_prof_DM_QC_A,' 'nb_prof_QC_B,' 'nb_prof_DM_QC_B,' ... 'nb_prof_QC_C,' 'nb_prof_DM_QC_C,' 'nb_prof_QC_D,' 'nb_prof_DM_QC_D,' ... @@ -2446,9 +2642,9 @@ num2cell(Floats_list.(i_param).more_1_yr),... num2cell(Floats_list.(i_param).grey_list),... num2cell(Floats_list.(i_param).prof_number),... - num2cell(Floats_list.(i_param).prof_older_1yr_number),... + num2cell(Floats_list.(i_param).prof_older_than_sage_number),... num2cell(Floats_list.(i_param).prof_DMQCed_number),... - num2cell(Floats_list.(i_param).prof_noDM_older_1yr_number),... + num2cell(Floats_list.(i_param).prof_noDM_older_than_sage_number),... cellstr(Floats_list.(i_param).prof_last_DM_date),... cellstr(Floats_list.(i_param).prof_DMQCed_last_update_date),... num2cell(Floats_list.(i_param).prof_DMQCed_percent),... @@ -2474,7 +2670,9 @@ end -%% +diary off +%% +diary on for i=1:n_param i_param=list_of_parameters_to_treat(i); @@ -2500,10 +2698,10 @@ % header header2 = ['Param_name,' 'Country,' ... - 'nb_floats,' 'nb_floats_more1year,' ... - 'Nb_floats_DM_done,' 'nb_floats_more1year_DM_done,' ... - 'nb_profiles,' 'nb_profiles_more1year,' ... - 'nb_profiles_DM_done,' 'nb_profiles_more1year_DM_done,']; + 'nb_floats,' 'nb_floats_more_' sage_yr_str '_year,' ... + 'Nb_floats_DM_done,' 'nb_floats_more_' sage_yr_str '_year_DM_done,' ... + 'nb_profiles,' 'nb_profiles_more_' sage_yr_str '_year,' ... + 'nb_profiles_DM_done,' 'nb_profiles_more_' sage_yr_str '_year_DM_done,']; fprintf(fid, '%s \n', header2); % data table2 = [cellstr(Param_name),... @@ -2537,7 +2735,67 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end -%% +diary off +%% +diary on +for i=1:n_param + i_param=list_of_parameters_to_treat(i); + +% if (nb_per_year_x(1) == string(1980)) +% nb_per_year_x_cr=nb_per_year_x(2:end); +% nb_profiles_DMQCed_per_year_cr=nb_profiles_DMQCed_per_year.(i_param)(2:end); +% nb_profiles_per_year_cr=nb_profiles_per_year.(i_param)(2:end); +% nb_profiles_QCF_per_year_cr=nb_profiles_QCF_per_year.(i_param)(2:end); +% nb_profiles_DMQCed_QCF_per_year_cr=nb_profiles_DMQCed_QCF_per_year.(i_param)(2:end); +% else + nb_per_year_x_cr=nb_per_year_x; + nb_profiles_DMQCed_per_year_cr=nb_profiles_DMQCed_per_year.(i_param); + nb_profiles_per_year_cr=nb_profiles_per_year.(i_param); + nb_profiles_QCF_per_year_cr=nb_profiles_QCF_per_year.(i_param); + nb_profiles_DMQCed_QCF_per_year_cr=nb_profiles_DMQCed_QCF_per_year.(i_param); +% end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Statistics per profile year (data for figures 7 and 8) + fprintf('\nComputing and recording by profile year stats for %s \n',i_param) + + outfile = [output_syntheses_dir '/' 'DMQC_status_per_profile_year_for_' char(i_param) '_' IndexData.index_update(1:8) '.txt']; + fprintf('\nSaving results in %s ...\n',outfile) + + fid=fopen(outfile,'w'); + + % File header + fprintf(fid, '# DMQC status and Data quality control statistics\n'); + fprintf(fid, '# Project : %s\n', project_name); + fprintf(fid, '# Update date : %s\n', IndexData.index_update); + fprintf(fid, ['# Statistics per profile year for parameter ' char(i_param) '\n']); + % + + Param_name=repmat(i_param,n_years,1); + + % header + header2 = ['Param_name,' 'Year,' ... + 'nb_profiles,' 'nb_profiles_DMQCed,' ... + 'nb_profiles_QCF,' 'nb_profiles_DMQCed_QCF']; + fprintf(fid, '%s \n', header2); + % data + table = [cellstr(Param_name),... + cellstr(nb_per_year_x_cr), ... + num2cell(nb_profiles_per_year_cr), ... + num2cell(nb_profiles_DMQCed_per_year_cr),... + num2cell(nb_profiles_QCF_per_year_cr),... + num2cell(nb_profiles_DMQCed_QCF_per_year_cr)]'; + + fprintf(fid, '%s,%s,%d,%d,%d,%d\n',table{:}); + + + fclose(fid); + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +end + +diary off +%% +diary on fprintf('\nAdditional information\n') @@ -2600,7 +2858,9 @@ fclose(fid); -%% +diary off +%% +diary on % Zipping the local index file: disp('- Zipping the local copy of the index file ...') @@ -2619,3 +2879,4 @@ end disp('- Zipping ended ...') +diary off From d406b00ba6f6a6d7728bbcc0cb7224e02b91daa6 Mon Sep 17 00:00:00 2001 From: Delphine Dobler <57707263+delphinedobler@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:41:50 +0200 Subject: [PATCH 2/5] Update README.md update for v3.4 release information --- README.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ac37b2e..30b881d 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,12 @@ This script computes DMQC statistics for a given list of floats
- change search for param name in index for a more robust means - add x grid and minor grid for psal adjustment display by wmo. - add an option to group prof QC A and B + - V3.4 (2024/02/23) : + - remove CTD from plot 09 when i_bgc=1. + - 1-yr static string was replaced by the config value + - add a new graph per profile year with DMQC and profile QC F + + output values in a text file + - add a log (diary) ## B. Graphical outputs for **get_DMQC_stats.m** Different outputs are produced: graphical and textual. Here after are examples of graphical outputs obtained for floats from the MOCCA project. @@ -180,10 +186,10 @@ This limit is arbitrary and can be tuned. src="OUTPUT_examples/MOCCA_case/Plots/06_MOCCA_Fleet_PSAL_DMQC_status_and_grey_list_20230713.png" width="400" />

-- __Plot 07 and 08__ DMQC status per profile year, and age histogram of non-DMQC profiles (one plot per parameter)
+- __Plot 07 and 09__ DMQC status per profile year, and age histogram of non-DMQC profiles (one plot per parameter)
Plot 07 presents the time evolution of the percentage of profiles processed in delayed mode with respect to the profile date. -Plot 08 presents the age histogram of profiles with no DMQC performed yet. +Plot 09 presents the age histogram of profiles with no DMQC performed yet.

-- __Plot 09__ R-A-D status for all parameters
-Plot 09 presents by parameter (x axis), the number of R-profiles, A-profiles and D-profiles. +- __Plot 08 (new v3.4)__ DMQC and profile -F status per profile year
+ +- __Plot 10__ R-A-D status for all parameters
+Plot 10 presents by parameter (x axis), the number of R-profiles, A-profiles and D-profiles.

-- __Plot 10 and 11__ DMQC and quality profile status by batch of WMOs per cycle (one plot per parameter)
-These plots show the DMQC (plot 10) and quality profile status (plot 11) by batch of WMOs per cycle (one plot per parameter). +- __Plot 11 and 12__ DMQC and quality profile status by batch of WMOs per cycle (one plot per parameter)
+These plots show the DMQC (plot 11) and quality profile status (plot 12) by batch of WMOs per cycle (one plot per parameter). These plots are output only on demand. The number of WMOs shown by graph can be tuned.

@@ -211,7 +219,7 @@ src="OUTPUT_examples/MOCCA_case/Plots/10_MOCCA_Fleet_CTD_RAD_mode_per_wmo_per_cy src="OUTPUT_examples/MOCCA_case/Plots/11_MOCCA_Fleet_PSAL_profile_QC_per_wmo_per_cycle_001_20230713.png" width="400" />

-- __Plot 12__ PSAL adjustment by batch of WMOs per cycle
+- __Plot 13__ PSAL adjustment by batch of WMOs per cycle
This plot shows PSAL_adjustment by batch of WMOs per cycle. This plot is output only on demand. The number of WMOs shown by graph can be tuned. In grey color: the profiles that are not yet processed in delayed mode and that are not profile QC F. @@ -226,7 +234,7 @@ src="OUTPUT_examples/ASD_case/Plots/12_ASD_Fleet_PSAL_PSAL_adj_per_wmo_per_cycle ## C. Syntheses outputs for **get_DMQC_stats.m** -There are 4 kinds of syntheses produced by the script: +There are 5 kinds of syntheses produced by the script: - Additional_Info_{yyyymmdd}.txt This file indicates which WMO, if any, were not found in the Argo detailed index, and in the Argo detailed synthetic index if i_bgc = 1. @@ -239,6 +247,8 @@ If i_bgc=1, it also indicates which BGC parameters, if any, were not found in th - The nb_prof_QC_X and nb_prof_DM_QC_X refer to profiles with no value for profile QC (see Plot 03 comment above). - DM_done column refers to the fact that this WMO has been seen in delayed mode at least once. To get the delayed mode completeness, refer to percentage_DM_prof column. - greylist means that the float was put on greylist with QC3 or QC4 for the given parameter. + +- DMQC_status_per_profile_year_for_{param}_{yyyymmdd}.txt (NEW V3.4) is the numbered information for new plot 08. - The DMQC_status_warnings_per_wmo_for_{param}_{yyyymmdd}.txt is an output of what was thought should raise the attention such as: - there is at least one profile_QC set to F (prof_QC=F_once) From 049a46f8a9f3d4dfb01ce61965ab766eccfe6e8a Mon Sep 17 00:00:00 2001 From: Delphine Dobler <57707263+delphinedobler@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:43:07 +0200 Subject: [PATCH 3/5] New plot output v3.4 --- ...L_prof_DMQC-and-F_status_byyear_20240731.png | Bin 0 -> 36106 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 OUTPUT_examples/MOCCA_case/Plots/08_MOCCA_Fleet_PSAL_prof_DMQC-and-F_status_byyear_20240731.png diff --git a/OUTPUT_examples/MOCCA_case/Plots/08_MOCCA_Fleet_PSAL_prof_DMQC-and-F_status_byyear_20240731.png b/OUTPUT_examples/MOCCA_case/Plots/08_MOCCA_Fleet_PSAL_prof_DMQC-and-F_status_byyear_20240731.png new file mode 100644 index 0000000000000000000000000000000000000000..591e7726bef89be555cdd9e0526832fcd74d3b8c GIT binary patch literal 36106 zcmd431yq)6+b#O4OGOmHKoA856_r#$Kq-9{QIL?96s5a648SCmk_IUe2}x-i0Ria_ z1q1{{TKdcf*IM8Dzy1AVpEJ(cd!Kg_u ziS!2}iL}~*Vl{q~;IoMVKQ>sLzidq+QEL-_Ry`F>G{i60+gy+mTR*UV57my7tWqma0nmn za8}>mUsO7#Pq(8tf#r$PgTQd7pG;i$SZnUk-`hZGv@4sHAzSG_-}tc)lCpJ$^>Ip} zSqJ%!<|G~9lM-rt9H+Ee@$UYu2bd)k6}H#!ySo2S_};xQ)18+d*A4DyZt=WKZ#Ofs zWNaVl7`a$EJp9VOKjUO(3kNQjbZTu;<67b$7EZmyfRT(IvJ*d^ilq`iqIcvGgLYl@ zf9;cwMjE8(BIlVO9R>DjYPn{SkrGi9{$&cv%Kd%Bqah^Q_2=vLNeQ0-IUW}N| zC*%2mhzQsDX;bERuWqc_{mZ_6 z^VS;;DAO^@aV+?-&VAw6m~m68Cmy$N+rRr2QBskyOe@7I@9J7a^QNh(sa4k7+q+TK z)Xsc;pR&pA4+AhB>o)m`Zl)Ic`6^YTK(%;o zD6K@qs`tEO&eGz%nonJfSx5eXq5(DYqJ|S`hmJCMZ`rbCoTWO1r__Y6`ti{-6g36* z=7y1aGHtKNIsLQEU&V_1a%mO2%#Qcjk9Ll{&zIP`FzxRZm!dF#2^*%a06@^M;UCgHhPYp6e_ zBrB)oEF5YX<~m_F{CMHv!ooy#V1<&~`yjz{7nGEOvRB#vXg8d7oSB~1OuzD)zsqG` zwZ%wlc3(ws>AQF5&rFSWb!E&Kj25$dP;A_2Y-A*tx?A>C>UHbKqV8_VuN{8<{L+-B zWq!i9Z+UU!4i3LWZmnYVP!%<``OjylFKiPQ5?WYT=yiPL@84G}B_*|C!v-t=sHmvi z+}z2R);rXb)tOzF52koii~Q=o&s}^ZtP+bY0*h*4b|T)femSh+d)xPskq)02P4`9H zr1=Oz`;)1XYT5Y=jBi>GvM@8B4*k*>tQEvRdi^@du)s9WtjlSLv*Nh<&U#L*zRxjd ze4Z5=8_h}|Z)>gOddSXa(!AG$UewK{^k3umBx~1bU1IgGu^y^*w|JMozP}&e$X)!4 z97<15e`q<)e72F@KDfTIQI&~vcCt=})+lH8UW!}3Ck^EWcT6x76Vuz<)b0Z@w|iOo z7;m;*-531FAAhLWnHw2BD%LfgsyO~idiRdo{w?{o#%Ir-Ra9&+cbf>?c2IizjvXIL zOQS?wRnwMp?|XK-OjL5J<=6~0raXD_wc35jy26srv~_Z}KWZbh-lxYeoM+73-IptZ zxn)9*_0`5p3SvHw=}KI^`h@1{#J9@z)J)sSSioyWi|12quK&V)q!mqvW>ZSB){XU) zva_-M=qwr<96Vw0IU3{pF(pwZYUx{;d0|n}!HbV&@la6MPEY@9an!xb%42SB?$f7F zUS3|7Js)Q0=h@R}Dpr-ueNVnm$2~pNWL_J0fs#jP{Np}mW@fpeJnMeSjT?9E+BH8l z#Bcfatl{xU5!bnQcemAU>RS9^zqq(KKQqeh;V}H7^vRPay*drgHqvp0pRi7N@xrqE z)eUOVg>r{g>`OcTOx83^%yIv@rsgO%aIj60g zT~V~XGc9QIZULHY+vHVL1dJP>Bj7L!IsB~PF4@ha_bF;=@*p!N>D`NKrExqgRS|+S zOY@`rLy?h@Tpj~WX>X6BGW`H;qk9gq$Xy(p(+*95a55ZIkY@rkHlaaXvn?u3`-e?ODb9 zl_?#Oxr&a#4aL4OQ{=`?53hyU^pt z56)e~{bO7#EPmdjWzRA1Dn_^tWLK8Zzkk?1I4&VUv)JVX8=HjcjdGLXuh=*o%F&Zl zswyhYn3)vsJe{&fT?^m%YX^N0&xv`$on>TZ_U%0Pfc^!-*1*63f`FuZ6UX4xTuY{Y z$#^+?Tduj*ON*FFF_LPcZThO=+V3+7Js-UNS>2Eff+pU5_&~`_Y}Cw_g|GLyDVZNV zdKAYx=pZI9FMsOPb(%MAZEfR{88V`a3ZbU0S%$R%okh+YnT3RedSh9pgW2xix%1L- zBB7qmy)Ps@oTHj%&mM035~rzWE=EDGul$-ybLSM!nN|!J>V6`2zjxIh*U3w>_w^mU z^dlWVSlM>u+p>#@bY@iDShHTD>%|2Pjtgn2E=&r#y77H47@6O#p%x+{TTXEbrJS5x zC@r7;5A_Mr5~-}ofmmO*61v9x$Ccm2_qf)N55}Ci9k0fh5K!0NeH5$p`i>63~@ikFW(%Oa2R_}XKELmuv^gXBE^<%+xG1tDF|rR zG%5#F$!;ZM!Mv?nYl84ob(i6!jX{NyVF#a}rZ!(#W=2LFU53y@dV_60)~`L7<1}S7 zcsespQz=FDfQQ3GCBGD_e^#*hbV;}8M!GojTTJc?mKCGH+jh?N*DcnvoUC*J>Pa{ai&WPIi>scEl--u zmoML@-V+r1?Nf;L;+!q>yY@V5_qn<#z9EB3?0hS0Yk4_2Cdb|_%O4J6#7JgrFG)#B)8g>eo>DcDobRgEnh&i@ zD{K{Xx}}w467u?r0cOo-^9JVW(JpQedJ&hGla)o4F~jZ2htl%7OBUoPw$RXAS?>H~ zWns+T{*5b{anG4P+S=lXxM3ics z(aeqM-BzpqwcD-2{feg^_8$$atSwoKY_NlTR$RQIG$6i*c8~kQ3te%^+GU+}w@y3q z=_1|hSB201>hYy!5<0Z_+Aqz|zhoyT2L~_SoToy*Gt!nDR{2dbnCpT}l+*XahD!)i z67m7Q%D8aui8$RoN3NX8+!>el;y{0OR4{9~{^XCAO!3eR+aaaQmO_ku5WD&p2T!4H zgl~@Q^2Bx>eSLf&arwTUz&)WU>idse`|v<1SV2Tyx73G`->luB(P)Ij)N|&ID&1hk z`Po993UiAiSGid|TrW=E_eaUH zTV_l9=g)g1mX^xd)0#yCgo#amP^|Pelha45CvO_fsws1^=@V8qeW`S9EfP(9n8oB^ zop|fUGIw!~v||5+taiHWVKct4__t?klXHbMYpj}@5|jhZ+$rQ!Wt0y!bDR#Kxr(TI z;J^V+<(t_(w0fB>rKRE&FYHEC!;H5Y&^9T*x_cpaVH-J1sD$st3CF4L4YgcuEg8C% zs>s|2h5dZRD**TpdJHtCgwc>ib``f&skVff7w73!hU#gA3R6)~_;EG(ne*6wd9#-J z9oBSQ;y5kc_>4;V>NRUd3r0l-Efo~%kv7t_O3aRh^rmqxE-XYkeBI#aHtU&iF@#0f zPli^|dHT6_>0X?h3gb7|)X<2~9eR2xcGJ3BH3mX1zkXsOdb?sjR#f;eO-kIpCH{aO z!N&pvTC%)23dk_NXU$st&tKZw_wL z24spswWmQ+R^qc8Gp85JZwOtvc<~b|M9#3d#2Ytm1RcD{zmXcjGoYAX(d{nkqvbEu z?!Qo|aI3$xSX!8U{`~p1QXfSnrJT9@EOy0ojUPkg?}d&e$MmtBr#4BQ)*B68J@{zm z)vH%1gL0mK`Eq+t5SIfd7gvyUK0E#n?X~6uTm&9FnO8A8(LXUh9w({L_IhPPA2#Q8 zo3?f{7H4l1V390;sa#=qbcnV7LLAHXzzIO`8zwC`8~c|8bP{3#$AQN z$wevsr?ao!a>p=w&>&Tv+#u0e*1Y>!iZiWoT-fOg%1$4*(dO7WE4{4LP!bgJDrb*l z6ubaP`+EJJ^IhKnaywDKe~F4~92hV#Tr1I*4(kGwVjW1q2Mt;?mXj=Ok4$JS}Xc?M%x_Jvke69D!yR zuYq6TcDX+uZS*$_WA%SxixMXDdFRFCnm6APo)&s$9ahe=y_K8S+7`-g!X+&^KDvg2 zd2VLZe73r1T-LNBSp{|5A@6Im{-%^_1rhA(f0s-{(zOfKzPGYDFBf}hBX*CwzUAPy zmHlB>7CC>qW#XP*<}CJgZGMJbX`Y@34Z_ZamB%=BuNVLf51<3?4v&h_jLFFe`_6}Y zer7_tN9ecPwO&7FwKn`#-!lKYTQMj-F{*}!hCu~We0`LLU!N%^$8F5k zHqd&+Oq*^{!(tqt5FcOWJQ5JFeK0L!G4Dx6hTPJw#uE2s%=4k;vVisN#jXXD-l4Z| ziz5wI>qTlMitVQCG{XS1{KxT*2aazvtMs}$iAIVEc5G*+648QMyk$lM&{zFvYO#a z7x=?zQ#9z3g%rZ3*(l?>w&$vAtV{v{L|yls@uaP7jEHOTxnhB3ePYVd!GS|H>uF9- z_+O7dC{gT#TXapLF3XF!;``uc6w1#xzMlvPz#LFS!l&pSrnBNbrx^!PD6 z_wH_PFdOj%i$TqJvi`LB?E~}tV#n3)gi;mXQYu)yzi(OORHpps@J@+E&G!q{{&pDo z&n8_@(zDz0-UQlT9^ul|_G~WkH>s;&L{TQ}fi`pD){Az1xo7*&O?m?*B?i?$>Kkg<;NaUH9v-)E^A8!PT!`6-w{$=FNXsWQ z({A16GU2^YZ@|lX;DBjcjueIVu@F>nPSe9JckbLNEG%qpZqCZ$HRLmvqSV0qNd01| z>C9LkZZ1InzkdB1tV@)XsjI8oNJ)8&hv(MKn;@9K_Vgg3Z{50ed+7Fj;!RcehuB-M zbQQaTg`*ap^qb_}w{IT`;zNhdQ*6QO=;(q21LND{J`=ZLq1j969C9&%pmT4FF2o4M zr>7q|c1+HVfr%+HEG+q-FYD{=RZvpGwO^3&J{Mc2Gd@24NPnOvR{YGFTV#JS9X{?= zlBKI>(e#fFaGlM5el&wgnq3n6{aICwL_jxDkgoK1lZ{HMcoNv{4ukiqhG)&9D z@XU6D^euJmV31XNz|$y~%moU)fBW|Bl_Q87GIxifzOnYkT9~V zs(pSr^VqRt(orIu9)QXfWo03P_Ni8XUcRFxQ-CSrT|Sfm+_) z>N+$u1YWGqS@<$;hY)oHxPNcYEG`a?2SeMBQ4%a zs%KFqe*F8Y`ak&Ocss8BW)hvtUen7F2XqJ}}W!F&Ap)KC+*kWhQZVNubN!a||_`{P<{JXt-ta6#93Sd^RX zpeiXQE4hM3-U%*3Q?rw(tUNsaVD>1}QO&m*1TDIcg#|13>a}ZiNT6JefA1P~?YHrg z!Aj3n#%d+Gr3m>8+p~CaS}p0Yuy9dy^j;nwo@$y$k#2OZzB3+k$Ge)@!+*2mX>7}Ka5>e}K4}yc6 zK85h?aT;JwN=i?+`0~bcJp9X-FN8R-vQ7tBK3Q(wC1L+j`^+j*zJQe{RbXHsfIidF zt7pmNHz@LVaH;?Lo}9+Ie?Q7w|FYh`z5~@Qkhr|O)-iizW4szYJUz3+ABThtUSGQ= z{{dJ*0}XQGRmWAY?s|B68EM?C+pFBXgNEkkhh63r%m^BgA_`F3VkC=-1LZ%)-6if_ zMIPKi)st2IU(5s2O$abD_oUlOOlwQC=thgQ~?0L&68?99gd z=gwp(Wj7(j9h9;QSs59%SB{+bjeYV2rG1}dJ~I6_M#dB(0$H$x^HP&Yq0Gw7KYRUU zs>1k3d&~SEK75F(mf+Y4Xq<34Q!fR7Itv{^zJq1N)^-FL5D4^31|;4V;mDJd({fuI2Kl607vIp*a{2L$Ef;$rY@C|2-I<$s0bc%HCI z)u!u>P(3X>`11EgNcT7Q&}z7F$03b4cPXxngMj8LQbhR+QQA`X5z=+8o5&n|0@Ej_ z7MC{fGSc&Y>$RG6>HzXc^DEo$BvSLc(f>QKVE*)~&-5kzSn3=1DwF>DXSWb;=>L%D z{GW5JSp@robFoBlCy`QLd0Tmw=}1UOr31IeFU)Zt>c zxYEwfPDoa*v}<1$d|Ws$PGxJwTgtSG^x11y-@WecZWP1eBCh#yadA00cAuk9lPO|r znm>Q;9vw}ywZ-LJ-)5brK8DK`8GE;ld=hsaY{tqtA|0syn+$Kgu=7vS)=bOG3`QyX|0HDXYKXU~Rm9b)@&5J4mSay}hL* zCFRXlzQE<1z-_Ado~y#7AC=x#??E#{JfEnSm$@vBD)}h=riO+FN;=hxkB@vI__T^a zJTT$F2&Ye<*45QT;RfIW!iDm$-Pd=nN%`@`1SM(-WP`z}k;~LOckaA<_paPtyz1`# z`xWKoax33WBxg)_k<%3Favlcnpl!apPdsTFf?iL1at9q`*A|Au?a0@!cfxaTom8 zQ8N`{9Cq^Pov(Rgz#Dpzm7AN}u?mF`FE8(*zhYkKE)6YakMlAzUFq6yAq%1q=>HVb z17^@}q*d(xj>9$~LXJ=*{Nqcl`>VX~-**P>5yYw1_&rI!_AG%6pKpM!f8r<)k9^F= z?r*8;c~5LNL_8bfHg8J%e52h+dlmnd-228#E`pVOklt4996aPS2PxurmUUe*yY!>@Q=4em)sc~|Ucze$EpT0~ZV zb86ZtI>c%_dV2w*ES)n}I>m2mr^;#$G8W5N{~G@>V_$#es-E}2oj%)P8Cm7>s!?UQpW?w-xPbN#0;G${|aW>-{KndO`vuXucC-cQk{Xd1-0xDqgl z6oyOR1ZsS=v#9pkED`TW>#Y{kzE?*G=IT{43|fkbdFH$)e$7=jW$j7x6%qpZ&b@p0 zfc1?vR;q`a_y~Z11qB6U^OTLmXQ&4aX=!1WzxVYWzxs}%NYngSh}UMuR+Du_np!F< zPcN9_Mc0ij77=y?+!lT{Br9Wnn^M$*BO_C7PY_QgTi(Z$^x$`*qVSexh<@3r#3frC z|M7_3g9af5rTSJfz7{5;p{cp(=xC77#u^09@1ATwgc$*K3dwPd&{)bpKHN7m(w3-w zf%x!^7K`(zFNYq{CRaxaXJ%%~pn?V$D(pNB69x1+`Jt6krT^QxQg-A9Az@+BrC-+^ zB_QPkvpqg~?fdudF0QV}pHmSRWQ0xleQ3xTMUcr=aI948&X}5V=B+-}|M+)gw;^Gx zgTms*Ru8%8v{+KL#0J%h!5d##pMHd7cHo$3?WHpjyIt}3DpK?#>_N*e*BL7MBUkF5 zUc$O$=OiA44*?2T$m7QbN9eOsHxple)y$@lOkoLNiOrd!Rif$ieQ+@E%Ill`QSO>; z&+rnGe!phkSFGn+85IRZMery;dkBbs{mjc6M_J$mXsm%u>({N@N`!inxMi&Rm;U}l z+YQ8PjICnTkHX;r|HW=02iYMq@e<`8ggJ~mBmf~`L$J0vLUu7tL*P2%w6%%1Wm*#% z<>$=Io?|-aGw+^^koLbyyfgUAxjYsDfnTw{BDML%dVRGvuV!kc;5d0_7h{?qKGmcx zX9QxdQ;{27AxN%(v#NB&%nR_(oYZ^)m&jTuluP5a8Ltiyk~E{*O6>4`Q*c zYl#nIcJ%0_$d|T5ji4O2)6yEM5Ej1f;r0OsF-J$o^XKpAKBXZ)SIe!ctIK@ygq*xG zV07K*^4^q|!i<$04%KO4aZ#{@iMUwZmzPp0sHor-X@inye!{XYK?ZjbZ zC+glk%GjExR=Z%4=5L+0<21eKJLF)yVM6BEOBAaGCLyUEGPn>TO5R)npe zk&%HI1kD~Lz+V;Dgw^6u&H;i%#v&v_NaLZI;~^KTg=gB4U=|mbNBSdBYj54Q4JpTi z2I#}m(h|M`B29GH+xR3*twu1*@>biO=J&_?^`ouXk`y4pFKK81BjGLi_M>K*J&-eZ z!b(9$Hv^eSRhpZF10qw*0xyhe*-e@&NJC%W$GTZo{W!v9xX-RWN@l{f)#EFwdHM2T znVl!BdW&7>x90~01S|~7xX%q~Ew`HF*BC&1156qZ_*a5{!OFq$yzkwoPZvG8EU1)I z)ob$q(C;%#u1X2Y9pW}=N~1ZY=J~rmvPe@us{O`e{zm~^6|P{X$#*dI$g+rT*2_za zjrq?Z8Nj80I9i!7G?fxgW|hin{FB4*RC;-2`s&EHe||LSBrg3PyeTp=)liRAB3U{D z3_m?S3hN~b5zd0%-rjI<{g?~jK?=*I1;+^KTvS>>%}&nFyEb{XwyHXQ`(0sC5*8g* z(+s|%eTcVJFM?GbSL&_zSw|v$euOUpNQE4AJgm9M*?!P{QOQ~io+K1e&#CBXX#>N; z1YPHB1_wiU^q<7W1`_pC(DZy;WT`Zd@d_h${Wx|DCP!0AN$*$)hm7#=VB5Hvfyi{g z8{>6=dd`lHW%AIWv+)Ob$(!Lg8}QJ5&9$lZCTbm{Oc})Uw73?PV(7(BEz8O3GjiWjIgjU9f!(K z2$O9si=bW2`5?995#JD!a-66^qk9AvaxGulZM=S9hNuk&4{{)ZfksYx0<{lPK8%o@vik1CPKn> z;Xj!Xt2A{>SZq@y@k^4rABO+Un>R`FiAEYLA9xd2{cCpCP=i1a-J$s3CI;T8u-_s! z)aTRSm#-RL*0}1y4+zmA(sjB8C`pZ};PcSb?agD!F?hkLc?=;9`PckB_0D5)EoUR7 z6E7Ua?}-vZear6M3(x`$|N6FpIm#CB93U*?O0l%?Xl*2}S3nRWfSLl}G7QNYj2FJq zg9c?qAKD_8v5;38Wx#5(I zgiEC2E)oocnEZUze?)(sV>>r_1=WRxhE6*1tD?9kU4NTbvt0KZup8Tz*Flf`&7&wO z65q{*N|IQnx2Q$1NDnObPGgFpI24++WI#_b(qO=gy4%|aW&mDLM_?tYWa>#>yVipZ z2`Q!#Mq!9NDIn$$CBmE$CEl$d;})y_Dn{nBNDz&EcnT%!h?S?uS>ihd{Mz~e#qNQu zh0{ektw|=7_wb1mgh^xQ3GrG0m?qPW%<%Gw0A&pi4`XNL=jUVR!xG)!+iUO}E#ayh z-ordY=*G~P4zRM8Zv*v^4|5aSbk56*Gn@y_;3xssQqL!H*V8X^P0Hce zMj`r<52F$i5{f5lB?%ZtcEN@~?FKt%tKxd%b5=K1V+T~!g?nw<$s!u$_MV(rXDGXk z^r}x_npz^c|HtZ6!F_XiSDVwd;c$4^sEF0vtV_1h>&`=IBt%3MbU|Pbg0NVh3M~y=r1E+}L0?fztl(-c^ zbuXFk7;UYu&^Z=?#E#O0d$tv1OmwCqYI9r=n*E`8;Jh#NmJ zAmXBP4{2Eb6D`RKhjq+fRS$8WD=3mfv+yNu32VeZ5l|jtL&&XGIa0*7R@0iE3t%6H%+Bu1V*Z>#r}j zbIrRV`AkE3|CA3RiTuOQul#obN8mvV3yVy_Pp#l?m&*=DZ6_1fJ1{sXs&|n8#Zxx^ z<|%(;45@+VOsVSt5fC-)U^W#%6|uZDx~!+C2ct~kRHNE9){6#H(%Ju38P|2zu449} zS;^oYRXs`@*~7IR^&16Dp8BXXGk#$7VPI?V8-5zIUt_rv_3i5K|H|q>A06K(QR%Qx zj{p4m69nMYltz}prPHThgSv#Zviom3v*oukak#R}2>O9B0>!X8@2MMVBilNRv^{w^ z%yr!2MnZ-ytR~A+OVWKBrh;>alqsTl5FbG%5X5K2py^zZDK~doe*Q_qiKSp>_5%fA zd?KolyFNZj|DrPT%>)7KAA3SBwLu9)zGL6zsvOec;dCaPQieh3N;|Z%co+09;>JQXv=0xfausIpAMjXug z=G{~)niJ{zbo1zFdW;_S>>-lsm;X$1H$m|M`3TI+{LYX03<{C@=g0q&hW0}!s#;m} zHoH5RQ`kw}`H*4vA2>iuM+Yu&991N0bF{!XEY0@Eqq`}~X0SF>zxv$Svk*+)fB1k* zeRxGfjE)^S^24HDw#-Wh81L0_KXwzsy1Y$B=*!R$yT?b=3l}bceB34Ml=VM}%CA~1 z<@b?(Jb>6#CnL%!N?@zR#C|}Tcy$oM4p$PD=QWM4jewp&B;kggJ??G0}l}# z3LZ4)Vrz7cq24UxnS^>96GP;S`^UAlwK)$Wu0GS+{StVJ5QO?IlRat8atc9!-Rv8= zn(yE^Ab>Tg8r;qMk#<@Y1Zr-V8!Dht37M%mrOi|4w-KoNMFN7GaQ5ous+8%wcxXMD9VrR@QHJ;aW+D3zb8?QfWG4PoPBuktIuA7q zOxr#UbI$)vI6^2#DMWSR#0i**6A}~kS1hH95SHqB(KYhm!2@i_jm!}KtgNiQRYm+u z*bZN>`xYDBfR|z0wrzcf;aczA$X&SC37hq({ zl*20zQ=>l>;low8h%NTNsq61Q3o!pXO&u#93fLxKkF2^88?sVm+H4`N;4>4CaaQW7 zhd=!GiMJ7ZIscc_npSVZMA5qMAADTdKZy=?`lkOXg{=&yg_%#$b9D>d6Rn=a+q)+T z0kr%@aN%25KlWic4GmW;4%nyg;5RO>u11{+7>%uv`xgOBI51qMTl4|;QlCBBN-l)F zgjZPk|3_JPMKi=KR^3<$;k=o1a=B|Yyeu678fr**e>*Z zrJw|kr<=Kzp$(8MpKvh`Wvwb7a`Apv)^%&wZeWI+04Wq)%0IrL#tmWU;lt&*3(>$E z?d^YNYH(L9%31#ZiKZZeeKbck#&z?!lE#8ADjqWapJQt)g^(xCheiR@mGL{t@Kp#@z-+IA&M_E1>gkfNf zhfJ`d!zexlCl=7*HZq{-b~-vReQj`47Z-~hKdxBZ8W>;U1NhE<6F+J6)IV0{q|u>h zNoM8f*x|pDi`@VwR%7SC?SMb+Mt`yiU-M1zqQpeOINP-r&MP}TvA?+Z48vIRn6iRv~O$XNO2U;OinjC}Q<7;aN}a`{X|<0Aei9nS9;qq81DThP>G zf-=Lzlxj;rl4Y+jff&Y*v=Nm$$2c|eClNy-;UXI$k-?<7LPY=MemMKkhv9qgfWHp| zrN-{OCz*(oW8^P`H9^~=6cUT#}3+&Hs>RL4||A}h+O>93Urw*9>-eo6q z=zlAG+AF}(30>UJZK=%O8SwhhAN>j>W~#0p&fE8vTC^P*1z=aL3SQmDyoM9C@9)!P zbDb`8hpXYF-KktvP3*1L<8}vD(xYN2a@@+EF&5{D0VZzm*fG-g{L$V6}8S{r)%qcKkU3{bYUBYg$m=20nafIX7v@ z44FhzTDl4}el{0kElJjMi2bD6|7cd?G^ZvYslYz;kKyMj&i}GRmJ>i$fR`C!>(=>5 zJMe@{BY(fB8(4(WmG%uj#5@pr#wv>9Na^P#B-l7P8}j|C>gwyWAb=c}PteiT-N4-G zHa~*r5xfA33^Y`4BleVM8P-8T{(|45cNGq77-`y6=^Abz{UQRw2?=6J1fP#*FNX0| zrsP;KzatnD*l3J2JbMCzf_7}*&g;w%c6AX=yvB-hx93Jt`T;V76QN)xJTuMBD#6PO zbpg>cfKUj;!$bZN{N?;zS0&~trK zSXg6-fiVHJJ=)pH6hM!OV66^{&R!rGAu-$MmtxP&&dq_V*TT1eyPPMO2Kd9!rABn3 zqgJ0o=Vvz8=ZE0Lh$oip$n z9li4EI#?OBT#GKxR--Z79Z3ppEYECjMD(ICLvID@gu+Hofm$!BT}$J^B@WKc{JgxI zFnFlbYHfnmRhZvFeT4`BeN6H40j z%)9U3zbD@rbscqfDq2F<0YkvrgYOojKhr8IDK=uI2R*{p-zyg6=84|U~ zbn`VdEeGxkGR8*^wB@Ev3J3_OB-T+eo>XvxtT{9~Y97KCp`okWhq;KCW%dBI3oP4) zS|k&FiOE`vY(heXsi{@tS{C~D@WNr`<>a3QPXab3?demC5PoH1q>tKuS7;I(sDDP3 zn}c=wxKHvO^w_|?j%EPDCq1=U{yfrd9h#B`-wMKI07(R`Rr7LnVAw9Q%7Y9Bw{SeA zMjOO{`?!BpTw>xVsDU>g8*1NyRY0HPkB($RLyKc(FZey`b_!Tr!CSz^&=8szvbBGh zbi_$THMJp$)2<{qe~p<&9)&}W^EHfAu} z5COB3t6oF=#}!^X(br~P5_mPx*Vk7wEiEOb;c3?9FK7dU8mSb9Fr@$%8dy%6E9nfZ zEgP6cmKP=_IEnt+q3^pP>|GY=cyUb}niqW4N>et6Dqcd-^`Jpxj+MV=nz@0&=Y$NO zF%<8v<7EeNbp*o!E;@^Aebqhn8>wje?WyGNLRkkhhE<2=OmuqQj!+{=-FV*-zBE?}nqY2J^8~K9|Bj#B`{1FZLS#q*IBIWaxU0bnA z!F>%63`A>5UA%~8b8aXg22?WQ(y=r1_1W3kEiEm=^Q=@6%X4YVb7&?~u50`jN9gMGnzBLa7&SmvXRs zz@~ClXUwPk%Dn2=>onsX_FYuh-g@1+^xjzE_11m&o1WhEjJZ{~I#T|_gp$Kmoj-qf zJm9)EV_?ii=#6@@W|zy7a%o;mG$ z{}z0T-sz(s5TsBbdBt8j^Zx101Lt<6U0N$?$ZeT!SeF1QTeHB<^kpb-+<*BB#%qrE z*6q80sff1o@3%ZKzq=;(9xn3tM{GPp>9|%X5r9wAWlU_uiYr)fF6bT)F6JR|KUR6_ z&d&2_uks!T%s{Sx%%v(6O0P)V0Y=H2O@&@grGzNcNu*7lO9Xx*k&bNtX8Lv_IWA5I zd>dr>fsv5|9*@JqWF8-3K7PF6^=s{yVSK-S4fX*vjKq+v{BMWX=TTC1 zR89_`NYwJLv1=nzK)Nm>%Pstd1N4gNCA)|z7#_W&Tsc6@*J8)Y_-minc3Ugti#5(F z6{=%qmRe-k`26yY9XoIj4$~Bt00_etD8Uv8f)yp2 z8*~QrK)tcZwfu|=|LcPo8~(XURyI1i7zqBdrsi}BmNrJn1#uV}I%B67)!M&T-RZ*E zlmA$QTY71ate%{n&QRgl=csx0ul0N2j=jR)OW;j685UgP;YD1qTXt3!%rse9Sx@Oi zoF)%JOU1gg`NwQ-C7(0@$NFG-oJ&=m1RW19#E{U?>B-5Ld3hQyEpD_-{<(E-{xxm? zK8c&>*t;F;TUyXjYKyGc+SX$EHZn7`%^7!w*bo)4^gS7Wfo^y*sFz?_17pP7r)kk*9{bTmUZU1qDCqLpU zc_CW*`1pXtlPda&JWm`JGd|9cszkNr9~bH2SF`IMi8Pk4Kl_g% zUD8(g@UQ5?>^X&?hsP_~ffaI|L^{L#|Mfp!+%8x}`Y9BOtZ2c%iqyS43(tsG!3NT2 z(Oz0o^sXiG&7|rzLf=UAhp}N-E@zWx;a`!!QkL}D7X`_to)&i$LE1usc*Q1~aZ1ua z*H~xITdU5J#|vVM#-K{&<^5$3Wu>P_9{{>Rh4F1-)+_t~G>c=$tl**bQh1_eZ$ATl z`7BEfiZn=#N47WMOb|*>GJ}|dgTRF2p(9fjeO7#7m3qr1%Yj1F%5w2?M0N)I+wERZ5+u3PV-!hY;$WXFv3+(U0%8OmUNG4F)}i)S-qNq8R-ews{oSwxpQ9A zmpFC|p&hd3a?A(M5y=u!C@Ny87OkxbdVTX|O^7O-qTpfVk`%glSXgep{c=PLwpnC5 zBuV6`4a|_H%gf4=($aFXvLMc8=jQTvNX5$`8sP{W?DHuV5J{$=lLoR&%2NpFhgj}3P^TGM}TB==qIJe~o^d54nU3$;7#SQq^YhCYlz%uw2`u~zmGDQ8$P{^YBcbYC ziSxuM2hf0lvOitIRt8g#)5+kQn!HUM!iB?aP>Gmz7S6UBr@`uY??(xaVM3<}dab^H zH=0tx6-?t0A}B=z=Axtr$B_T8><__G1C)oy<~S1>Iy3r9zRjjyWQ}!Yn9MWB^1*>A znEc(lccTU4Zd_j82`FKUjz5u8+1S{C{m#v32LuO8#@DXhxC5E0ZmVjdIu~*JPGVvr z*2LVBM1026ryt+Fd)L$icu}(myf^DoOxUH96hsfFAYdDXtIlssVh2h<*7^C`<3aK@P#pv?F;aA{woi= zYwM2cj5vtS4a5RTg2Rj8V?~@r{=!7wpB zZKtKx_4VsjCg1*nf##-24;uU*m0l8YiWeTWRUQCNb#H$DwAg(6t&47Io>SaOZWELM zKwx?5s28lKc+Z?6lUGl)baV)_vEBPd3pl4!j$a`c#=0FvVO;`aFqTU~FW@=|*e6jb z&!2;rGSDR4M)AL%i++yb?ep!=3^nBYHKqR6K}u$0-gPFX%99E&?g-&?IKRGc?oI)upE=7z}5hr zXOL6R&20(0WY)zE1A~QVV#2}Pi_8gs9ELqJC&vvZ`z%lAmej0o%c@#faN+0AMdSKZ zVh7+n^p~t<;?(Z8%%N#qn zLDHdGV09OgGB+`Ko|=j-rR4~O0=UH?mUz&x?6{Ajv7%=TmLeR3BlGqW{~hLJtqbHk za!D5@C2@ENhyNEEGRO>m80Ij|H%|GX+zAOO+fVC31Kwh!H!(K02a~AfI;Dt7MWF<} z1;kGgh7M*pn3vO3vn7hw38SGH{{04PzKE=4Jv3Y%=Yk8{IQiK#2cb^be*-0SEiGSw zYjHXNvJdm!a9)|$#@69>1k|H_%9Ro^YHl7uxzJnn4n}$+UtR+dMsl9_cMvS zf2>;~fcW43<%?b=#7EEoK(uipH{PPn@PaVb*{SL7?mk6^cZZ!l`NM~Ed|@4JZ9{M>yY7vb zJyaDX>W-ZTlOy~n?@CM8uU%X70VM3gY_&UDw5vXSYA2nj2}euW#Nt{Tp;XzDza%qW-9NxOe*8NvvR zwePOJP~l*8-=q{XFD@=_e2^BS1%or>f00FWY0Se=TDwKS$skI#XS<9tCv#jH4bHXc zvzkQBLqRpZ@BF7c1CM)~%J)M@0jt*M=j`Q*w z4AX4cf|I2ZC$_6|*`reqU6m%r#&uP~1b+g@*-&%ybhDsfK`}$2Q3D%RL+IK; zelU9@cB@|vc%fRNcLWPG^!O=QjCvk=s$0f*N!`9@}0r)Vql$k z`kEDz)3b)mQ6zR@QVAQ7*^(bysxeR|PIw8t+ZB4Ps)WN(AAmLhks zM7*7yosBV+-w#UP>H*EnAS-}*Gc|3PU?sR#moI3;S3aW|cnnj_rY&-5Z zJ-@tf>sRi?>;9fd9JD1?fN$#Rk+(K4hQ!KgmigYDlC9?SX``3ZaMZ?eg zfOHj(Z+epRInTAQ);{(7_-w{5#Q1^#f^hiMmt*DdMmSk zn`J&K96=E0jf~isJ(ijPUi1wOFYNQacP}4B9~kHL0!3%p0&96zUmtsw`3H&qA+!Rp zeKtKGsOC^=3W|zGxryNPCI3b{u=Q0{(&Y1C^wBy9w+zOozcMTry_~EXNzb0uYTd;y zynlb=#JWiMCef8O;BxTM5;1Nbe#K-1W8+x+=}8f}`BUcRqp7K>sC~Fp(y!BO#hFQ8 z-))HC*(R`CTI;R(Bz?XgAyvRA2|zcOjYdF_kZ4s;T;sfXk4X6A#}0V8)9C;ST?vVD zIBOrj#Z*KD1k~5mY}vC%>+Rk-d@URJ%fwA#WqROBNj>tk5+fMNZ&i)i~o#SUA5`6FK0wyY(7AxP2fX3w`5p(oA`R1` zJ=cBNP0!fO%uG)15gIIzX7lo9p~`{VOt`cGAG~412?UR7(dCQQOfj;*5JM6A3a49* z*HH7IHsj`&SyWOx7(t9PlW(r$gr2>d zC2nrtonez$!>!HDn{=u+G4B@^UWA|XcTYMJsw>WSG<3w>!)XI*7OejOD{Ci^TZ9zA zgvlo&g|wTJuJ>2r=o9x}U)Ik#f_Qw}{OHE=u6Vhm{af#5W=@=1=RQQx{65wF#=BEx z58=1K>ygSvMh1q4+Ama`SWAxKsLm;bX`=D4KPf6-mFnafho9Z2_4N}GQFxgCST-Ri z-13AMsMB?ZI2+N(WaP(>gtQjMU*>Z*5Z%_UzVTt+!uC7AoF}=ayxc=$9fyZs)L+;oy%@ER~`-1q%F_x<1V^vArIG5PiV zp678MpXK`eQF#}3y0!```sOXQLX12B+k^!rA%uuZA8mpRXl=S;}HcBq;K3}(b zLxLjoc{T z4Rk<*ry5Hg+K4i=UrpAV;JLG3=1HDz1s(zA%WIqF881GewT(Y__pVxq{v5hw`q#_R zhqT2WW@WXLio>zao+ANPbjBY4j+fH~7{4v$oKRRm@t0Rb=9klnl)F?1q|_DNIIJxG zM(O8pGEpsftXd)ZuN{Hs_>0{rfXD@YT21eEvFNBxv;32pD71V?zj+9}QdMO+%YXQ= zVM#7$$%R}D9t#;;kkhQmg5#d#A~ z*P9xn5?O8)-#R|YMmRw{WGX*WAKuRak|Ks$acO69^u?v)28eY7Qj*3iCMNc|TIE~q z`}b3QHBU#f?OFIKKoOKwt&r6WE4SWsc3Z5iJ>TwyYVF9=Jrx;6vq8nkw1q=#L*}im z=8UZiH+emyZl=$sTYzX`dtbWLK~$aIG<2W<&R+_BLc%BTFK&;fhEx<+U=>k3y9gZw zQBi$EDnUmS?WV>?|JnBI7|#W}``w1JIG<`GV%j^`gv$4jffpfKn2dps6064@Lj#zu zv(sY6kotlkoxPkL(Q9s1RaGsjsG8ubdB)!#s--YcLWNvlv|>E=(p$bxo+k7gSP12n zltRbGElV_ZM}wtZ^-hSNc;XS>en@(r`OTRg##5uCqF{;W^m&Qx7vm;|FORU_SZ~l| zWaH@QXwo++UR}nc@W~U}H0Tan*o(R)hH@wP!;6cQbtj(Kns~N$_`0Zx^H0G?%*|Lo z1L|n<5t(BTNtUa7^X6h>a@anpYfedc^Yc)R0ldqG4j4Evp7VgA*E2nKqNVcWkS9$? z2_sOh-#Xj^25aw&j&6X7Z+fR|Bz)asngSTS8ox&NOFL3hB2)acgW{%{{|>eXOj#xD z)=tDc>XLXNTk!($?bRzWSuhso&bapO+ulbnpGeCgBw7^MiUTJ&wq)R%B<^16wM@)@ z`*!5m^AirK%Ftu2yL!5o>HXIp@NkRzImrl5ap*!jTaXuRc1nrGB1xg8z~E>bhn| zcA+Czj5e3`Xo}A?S-7x^LnL+b%~lt78`A>W0x>$ZrPJ z(L)Ch2KW7imC3<}%+4>s89ii`M>@a#k07-RjMs9NF&NhwG7SkyzjG%T@gOTJl7E(z zB*w)xc`KFcRy1M}lJrWKez=s6sI4vTnbz;128To$QG+d!EvEag1XF|)5{fD+OpWl3;9q5sw+HN{FWB4nSKO2)n2=MQF`tt^r5Q^3)&Em{uP=9I^;2`l(g z9qcv)F(LYrbz%s zz%;#8s}_sZB5WE>nlwpBywSI2_?}78tYMY)^#P|(&%Qkl@Vx(v@M?JKSAeg0?Ycfw z88_~ia#b+uqspyS@9kiW*bGgLz?K?yTOw1T==SdY;h@G=X4`0>t{N^4wae`{+3_3Q zQ~kyBjM0UJR1zp1YGQ6~&XD+nl>4s~;&dYI4~1SnDUrWYjB2qp@hc8w$EnxuZx}Vp ze~N?{VFvlnpK}Bar*k$oUMe5a7DSi_4!0HAp_8nOR(q|M*YFB#hssva&LA~nh}fUaM+PHj@K4I|m*X#QoT zrG*augwJnG7$9<3ycJsaO$mb!j4jbri(XT3sK{*X+6aSw%6&!PXt+3VGh`JGW1q8U zGmk@}u&eWON|mBLe1Lw<)}l?m4x2Wyp)Q}Rvi_ZExO!F3N(@LqT~Sorh6UvM_3Ip& zz54cDsglbA8`Gcih&8UesAv>p$>GZnrLSur&|9wga{FO*@bEYf%`rz;nz;R(Y&`Kq zX-P?5Bs8zIQTRyr&%q%fKixX};58Evj1cbZfKY2b`@FF5c;c6*)-M+FJr{@Q2kT~3 zZhg{F8`wv?5!u{tp;l@~>su6~=3z&1q!E)(Zdo5s2XZTl*6#2gGClqEN9TDXWY;5N zV3z3DbHC$EPLri#b<-0}A|oSpRtLAvw}2){O;tJa z0QI~AiTAYed6Q$~w9ya*j>I!AKE9t?jdt;X09W0JkhZ3QY6NhQwxkuJ+&SxfkIt&l zv$XBYmynAWVI#O^0*-M(V4#nWsg;$I&#^xDB=%>%{P_SYU~f56}~|5bL#h(*Ovi*(tr{MMnjWht*#oDHg*$}Ww)@II3A5-OuNXAk&$`9qE)sU z$1%F6Z-!a#H5q~pk8TV`u^ng!!&b_%Q6{VqdOA!OL4!5ImosaX`zezewl@DK^Nlw~ zKthq85O8jIQ@0TJAz7K3%O?)Z8mp|V%<%2`H9rH%u|zv1(!0n>Ivzd-29=YH+nIGn zkstBsV?gM=dm7XX<>%+4+u0B`WAXnWnK$CY*F1KX#`)$x{qV0KX2z{ex3i!0EjEwrO4^a?DaS9|uSyjgHhTTi}K3eM@vNY_l zKk+d!r;*nnhC9sUnX`)09J7^Snb=tBq7W5z(_rY@DIp3Tcy|(S-1zWiCk2kNWfswf zq`?Q$*Rc^MNcL=9UiLqQT5D%oq%n4e8ESe$m2&gIv|o!zbA27#j~e@?a>L#gUOy+)f?uXcrhm2Zu($ zt8o1Tl0uWViHFahA=qCfGQk*Yt#2@ z1wH6kU(K@t0nO1ySE@eju?zsC0P>oXGSe#iG)2rgfZhcZgB-2Ni9R+TiGUfuS(-<=l|ua>#)p4-z;I9;=efvS55#_TOaS_M@4(8{n`;6)REIqWL}Ou zwvJY%sqgY0bS*PPNSjUb!b_ndwoT!iQCDYCZhc%J=2CfySP_korQ(shlgrz?IjMg zhXphg&*xT`;QFq+eftWqvTO1gb-c;sO1a-K`nXhFD`SS=W*lSE5HTM(>*~hx9F$jv zNR6VJOFveW?omHNRz!XoMjsJn(-&Pt=8gZ5)9<$C9+$FC=xQo=c;64Z-FX?7QaQga zVCHsrzb?XGw56)q4?()Y%1vc*HP+tU;{_di(P6MZ!OX$B8_diWE`ezor*m%U;4iKl z(TzCrbmD$UJ61=-aLvL?bIcifPAHwzTc!KSQiJ{c{h8UH-#pYuv|Pl%z#v#x^R;;2 zzE%tRcE9AFXq;^s>v!s8pVx|3Vap?+>jn-Q1jfN3jXmznqyQ7Zirg4 z>)R2+jXU2EN2NBzUSCA&B^^va;hkU#mA0JYwKD>>VyB5fQcY|Y2Rnog<*h=WupJo6eA~2PasHFqZ4P&xbigc zj}}Cu@s+xyqaPF4ts%yERLEHRoXLY8KX~9Nan~}o?a`!}Q@5IkZv9BofskSh^-B#& zf%L)x!XvxsR4=_I&R=3HKQsS<8+-bxq4tbeu#*cnigI(gT4(eiFK9+FSt>pc1oi&< zwQI_bHM+}|^;z?J9SQ|K3e&(eq;*$?@ED*AGi7-dvqYS2v2g76T@Uj9vCpsrzyA8v zId1Z?hZvqtkB^_>ceuqmcl?d#&z~1XtzoNPNbd3v9sA+?-*xOudFHxn*G@g5#gAZW zYrAa8h5$N4f=T${r7x?(dj11Rzd8HQNcy$?HB}kLf+gFZ<>!-y8tc~PF`+CB+2!CjAe0$h&nsnTAn1GNHBe15~;9C{X-1jB+SDgxh<9uNW3 zvd3PQ5Ef3zzh+7v6WTW%Yx_?L-F7oEk>ivp=P;!UNlDM{+~IgK18m?*p|A1q!R&m6 zXBrk(gPPq625#19GL zebgDZm`SKV4O>Oq6B6PEaH(roqu0Jg=%Bs*^yfFZ)=SWhv8!wtuR?>tmSMQ*x0V*$ z4I5-UP}j?{va*Vbl%`Da{_@s!6jnLXVcMtejT#=`@)M57dKh9de6b`n)YX;dTNHu_b&s!GySV>x|*o-@kn6d+gYNe*G4Tp^vn3=F_PBi1x^goSLIc$9t@}uYqDp9PIf&Z?KJ!9{Zs6+pjXx8}Lf0WH61Ed!1^#SNPB6AoeJzvFC5{f zFyByi6M-2GIO{%rS~)F_38HJ)Hg4X$KDLCU1u~VCcgd(7Pz#>DtK%!dJk&x4E|6qK zN=j-B9m!Y%T;&|}4h01VGh4gc+n$qbOkW{{%;h$C#9n=#MORXQg9=K zBVhf_W~hgnurbYArDbJ`{mldJ&>kl-23xm3a92kn$j$ZfzhG_cUc9@G?70o_d%y4t=6*^;(&DBq+w*>HF*D zA+udaf9Bqyh~*R0N49QcADz3|#jX3MEnB9YdW;`LD^z+@h2*u8&3jbs$eN(4uundJ zc2?e{A02 z>Qa}OwDs1@z*XTPaZuwo=2jxGdFiuOZ^lPOEi<3wP=`u^I}cGS?)vpQ7b{izHFb4$ z(ry?$C=BiT@yl1F=$38A>0iLz1&!MuZqTClfw7VdVJcg53Ntpuz<6a{;CV^husyo&9=cImpideEPO zdhJpr!*&*;*#b0S@`)gBF`G^qJzCu@DAE1jP<__Z+t7Emq}OmH@Kx9Fwy-4Q&c@y6 zO!58j_4C9hG@K+0vy+3T&n{=wckI~xk1IvFz|qj~!YGpO)sgxI6AQqyXUpE3FVJ0-v{j zz}S;)hM7I*i}sJ#7$tC0sA>}y{_SrMRB!ewq@+Ekz97cbH7*sC74GwagP6JY?CqdN z8#;go-b2aJ`zf?ULJj0<9eA)q-~whSIEk3vyJOJhKT)~ul}#^j@?N>JnILFZ1f>d! zaniA<+#YvaZ*czJxFPTGi2P7y8G;+N|5l0+jW~s-;Og264E(W}2dHXthdq%ucgG;F zCq?x^xMo(aEP_a<;ZharAtpv-u1Cw8Zhbrp8hnP@s1N?_C4B0z**?_kR0wjSlbkpL zJB=0eu*R`yM-b6!=g7Mdb@!>ZfMaoy621xoQ*9icl#m7>hME zozH`xUR72$W1+6C2#pSVGVL0VS}WvyB6;l(2z-ir%lD)W&2u?KXN8_DSmCgl{5`) zO&||)`U>>(sFKoBw*0=@GY5_w$;r;X&fp1-yF<;7Pfjyg;83-6kE#&4E%*&Td8~zf ziI0DB_wG8*KX`N3`%&_QQ)5R#@(2i6Ltjj9nCi)x)R7?y_nA~diGvy2MEno&@v}ZG zk}em~vWlVg{#Pa3{n$U0aM9B5oB~IX^evl`YnAZasNXtqgUWOFClM0GDrMHOS1&K# zXU-YLN#n*@Li%Su#U08mG1NJ*ETA6?L;j9+-o{!LD@gECA?u3P(o z_MYP6S&ttZq&|7N*s8E@Fgrx>X9*2@QPJbalL-F5b(H3fJ7v~dwF87u)BR@K6Aa9k zP^C2=b9gVo6Xg9+$b02OA~kVKS1Nd)Ip5)rn@Cv`<|L{9XSwT?P(aAh8mU<1Nfaa) zFEpIoRzK&)#>Q>428t~5n4bErqs=a%i^#dTz^Zoa+BMaJ1>1ayXvY>P!=svGSoG~F z4ws_S=;J=`Ou7FOC3uwY4O%sqIhTIH_BP1tr@)F|#!D*isTBEhtcBtRn&&jRHVswuOmh)M zD%Ud^T}k=ydpN$8BZon)&AMeQYTWox0=NHya?myZ$zl9>VWMJ)bJU$z$mI^fxAk;x zrHY9x8U(W-GF<+Hh{(ACpR2`8FWycPM$3gsnEMO6sH!Y_)cJdju%x&2hOqDZZ_Kle@PEnjXzl018n3_DKB5{ z)u+!TgR5wHKx8yuCgAPtQ_*WsyqRAL#ZRSlYhqd{i6hqg~C?U^W_Jo$w=3;pmZo-_AdZO>~e~v~33E`N;%DszJ+?mnE06rWpUS3Pc%XS({?+bUq=q4FhwK-@0 z)IHyICn_h@Zj(~i|NYF4VtaWFlu5GdlY#<+*Tb*; z(eIuTV>0y=tWM*Xorv%N{f{xLWF*dF&UeQVNZ3_LircOGWrt25gQoUgv{C6&g(#=c zr{>#6a}Curd5P#`@BA#hxDMuG{`24d1Z{UU-4Tw*?$gj%_2#zBGZh{ZkjY_Ta%WbG{n6Ln9bbEuP1oC+oW{KW z3+_tl+I}-af`WFtpM1C;;>)pn1?|C>(zu5l3rMp%yIKtpz<4`oX;MRnzQyBltUYzl z3dT@7)#a@8^!+aB)f6(wS~yg0CCx)gGrs9~@MMAV^JmX6Yk(sQ{q@$aegEPGGp*qI z5%>$q2vf@-Se~hVzM7sIZE+(A#PvK@;^J5<9Wrb6!wZY!oIk#zBiN**e_?u8YgL*( zC#UO++TFU};&@~(mYvq{EYYBCZR}q`|B}-4#f3^8X4Aursnw=9epav7ILN zHvHR9+V{vmf1fw|W-r`;|+7S(nZn766BI?L3 zQ&Ld4jAv$!gQcdXSYVC`R}>;*aYG`v5PPM=nJ{f8oBS~%EQ~7^er;8E+elz7iTjMd zd-yPNhF_8S41R$docO~B#m9-A#1=~0XUo2|0p5ihGI3_L+U(XGlfNK3+mz-H^AY{; z;MOFQxn(_i_vV5$+JAdHI}*>fIXDorz0JvKDoNX~y_HTsU-0#V`c=a#(|3m=7xVL^ zy*!|Co>3kf;ttzZ?1)i&3NKiW37z{E)^0#Ywy=0oT%2JU3r=Iu*|9?vpjeogpN=Yx z7ZbS{&$(?S+U%9&)yCAR>^pjOjvcbrCih7hoH2YmEZKLGv#vQVAz{!T9 z5GSKV;+f|{NFid6Zr8Q6kxX~Uqy4sS+0uZF)o%8~ zZMl7airu$(QA7mnp7VF??!s7qQ(ioAS7b^pT(}2&m0R0&OzDP`0q}2**iZON`TTFn zQI;=iY+gmDc0}lhOYW+<>?`f0p?%^rOd#0LM~xnxmYI2l95Hjx0|&%P_g!2TqTf#qa(frUoUl(V zoK(z}=ay?f$FxPUGQ+PJD-Mtm%vnZ8{;qu#1b=yp$e;Vm#s4#ZIkuXn*p?|1WG}MM z+ z*Q#*Wsg#x>=l=uKd7Y3ZW^J7}wfdto0LVjPL0~HP%FMS?QdA7t-r_dISr<<{=ZTyo zTr6i(`;!^Pn_I91d|;*_KWUka1Y9qKSKjS-T;>PTU$N~EXpAbg+E!nxIQ7($vb4Vt z*Pr$hSu|2;O@5m_XO0cB1GM{6e6j0nBX}Tzaca$T)BnX^E}y88%G_`vge0PKUwrqY zJ#vkr_6YO$cvZ0v@^w1Fsim`d{c{-Jt>XU{hRd;CZ$=i97Fm#V-UNsp7vMI;RQGo) zx#b4ta$z<9 zp1Sl$xjpe6bml2XeBdKYDT4nMz5NTL5%~oLwL5xYnICiPVa+Z3+M2m%w#u7-==MXG z0hYG5Q)Sl+X0dV<_SM1vP}nnjaU0vC0mo)f+(>oOjlAe!B9gbBmbh2PE$O|_ZOwz`9t2p$ibw6 z@h~M~2cTt$s~C(KmO>-hv%8yXeRcJAet;J*Oue7~w=LtdKAe2Z6&kdz50?7pg+~V! zP8)sXK^d$sxDe5hvW!o12vBi8GY?KKn>W9M=z!g^pljihF$+t}{0^T#0^8FJ_?|ga zx5WxyfuCOqzIBuU?(jXzUvb!tT)Lu?F(Ojwe<`<58S*(5T19J=FHXR>CfRzlGd|I7PeT?_3>6r-H z#Kw$imv!ZsYVCA~=a<7aym_-;`Cx@z9ro(mjlCNIh9gH;)^_zu-@1Lf(i^*gV{UVX z{hDpx;@bN|_ZvFF(ceGQCL5c`t1T6=GYe(QpmmFj$#VmMxADQHcd6mA)yZpr63yNA zmvfFbJXYQN%5Jt!a*U{F+VnRnLoW3XXvh~t_C1PSZyz9{Ld3M&2Y9@Mgpu!8%rn^6 z|Ju@V{-kI!AT3vDnD^}A!^PDRlIr*J^7N|pcVGC$DW|W9RM&sSx~lY4HM2+)erYRA ze;=0meJ1_o{Mb$uY%0f25WfEZFaDo+2w~rPB{kLVYaHSJR(R`+e_EyyrDnSKe*xZX BGN1qe literal 0 HcmV?d00001 From f539c25652d70ae13998a452a65ce39c05a81a9f Mon Sep 17 00:00:00 2001 From: Delphine Dobler <57707263+delphinedobler@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:44:07 +0200 Subject: [PATCH 4/5] Update README.md add link to the new v3.4 plot --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 30b881d..cb3812b 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,10 @@ src="OUTPUT_examples/MOCCA_case/Plots/08_MOCCA_Fleet_CTD_prof_DMQCstatus_agehist

- __Plot 08 (new v3.4)__ DMQC and profile -F status per profile year
+

+ +

- __Plot 10__ R-A-D status for all parameters
Plot 10 presents by parameter (x axis), the number of R-profiles, A-profiles and D-profiles. From 315983c1238ec7673bbfad6a355062d9e9158c8a Mon Sep 17 00:00:00 2001 From: Delphine Dobler <57707263+delphinedobler@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:45:12 +0200 Subject: [PATCH 5/5] new synthesis files for new plot 08 in v3.4 --- ...status_per_profile_year_for_PRES_20240731.txt | 16 ++++++++++++++++ ...status_per_profile_year_for_PSAL_20240731.txt | 16 ++++++++++++++++ ...status_per_profile_year_for_TEMP_20240731.txt | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PRES_20240731.txt create mode 100644 OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PSAL_20240731.txt create mode 100644 OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_TEMP_20240731.txt diff --git a/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PRES_20240731.txt b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PRES_20240731.txt new file mode 100644 index 0000000..26c19f7 --- /dev/null +++ b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PRES_20240731.txt @@ -0,0 +1,16 @@ +# DMQC status and Data quality control statistics +# Project : MOCCA_Fleet +# Update date : 20240731022802 + +# Statistics per profile year for parameter PRES +Param_name,Year,nb_profiles,nb_profiles_DMQCed,nb_profiles_QCF,nb_profiles_DMQCed_QCF +PRES,1980,1,1,0,0 +PRES,2016,574,574,0,0 +PRES,2017,4052,3970,0,0 +PRES,2018,6434,5714,0,0 +PRES,2019,7203,5880,0,0 +PRES,2020,6048,4240,0,0 +PRES,2021,5107,3310,0,0 +PRES,2022,3899,2209,0,0 +PRES,2023,2943,1240,0,0 +PRES,2024,1161,244,0,0 diff --git a/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PSAL_20240731.txt b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PSAL_20240731.txt new file mode 100644 index 0000000..dd151d1 --- /dev/null +++ b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_PSAL_20240731.txt @@ -0,0 +1,16 @@ +# DMQC status and Data quality control statistics +# Project : MOCCA_Fleet +# Update date : 20240731022802 + +# Statistics per profile year for parameter PSAL +Param_name,Year,nb_profiles,nb_profiles_DMQCed,nb_profiles_QCF,nb_profiles_DMQCed_QCF +PSAL,1980,1,1,0,0 +PSAL,2016,574,574,14,14 +PSAL,2017,4052,3970,124,124 +PSAL,2018,6434,5714,480,472 +PSAL,2019,7203,5880,1351,1267 +PSAL,2020,6048,4240,1930,1246 +PSAL,2021,5107,3310,2085,1246 +PSAL,2022,3899,2209,1798,978 +PSAL,2023,2943,1240,1705,655 +PSAL,2024,1161,244,706,141 diff --git a/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_TEMP_20240731.txt b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_TEMP_20240731.txt new file mode 100644 index 0000000..451772e --- /dev/null +++ b/OUTPUT_examples/MOCCA_case/Synteses/DMQC_status_per_profile_year_for_TEMP_20240731.txt @@ -0,0 +1,16 @@ +# DMQC status and Data quality control statistics +# Project : MOCCA_Fleet +# Update date : 20240731022802 + +# Statistics per profile year for parameter TEMP +Param_name,Year,nb_profiles,nb_profiles_DMQCed,nb_profiles_QCF,nb_profiles_DMQCed_QCF +TEMP,1980,1,1,0,0 +TEMP,2016,574,574,14,14 +TEMP,2017,4052,3970,61,61 +TEMP,2018,6434,5714,85,77 +TEMP,2019,7203,5880,222,222 +TEMP,2020,6048,4240,101,101 +TEMP,2021,5107,3310,102,102 +TEMP,2022,3899,2209,37,37 +TEMP,2023,2943,1240,37,37 +TEMP,2024,1161,244,21,10