@@ -858,23 +858,98 @@ ParChangeSummarizer::ParChangeSummarizer(ParameterEnsemble *_base_pe_ptr, FileMa
858858}
859859
860860
861- void ParChangeSummarizer::summarize (ParameterEnsemble &pe, int iiter)
861+ void ParChangeSummarizer::summarize (ParameterEnsemble &pe, int iiter, string filename )
862862{
863-
864- pair<map<string, double >, map<string, double >> moments = pe.get_moment_maps ();
865- init_moments = base_pe_ptr->get_moment_maps (pe.get_real_names ());
863+
866864 stringstream ss;
867865 ofstream &frec = file_manager_ptr->rec_ofstream ();
868- ss << endl << " parameter group percent change summmary " << endl;
866+ ss << endl << " --- Parameter Group Change Summmary --- " << endl;
869867 ss << " (compared to the initial ensemble using active realizations)" << endl;
870868 cout << ss.str ();
871869 frec << ss.str ();
872870 ss.str (" " );
873871 ss << setw (15 ) << " group" << setw (12 ) << " mean change" << setw (12 ) << " std change" << setw (18 ) << " num at/near bnds" << setw (16 ) << " % at/near bnds" << endl;
874872 cout << ss.str ();
873+ frec << ss.str ();
874+ update (pe);
875+ vector<string> grp_names;// = base_pe_ptr->get_pest_scenario().get_ctl_ordered_par_group_names();
876+ vector<pair<double , string>> mean_pairs;
877+ for (auto m : mean_change)
878+ {
879+ mean_pairs.push_back (pair<double , string>(abs (m.second ), m.first ));
880+ }
881+ sort (mean_pairs.begin (), mean_pairs.end ());
882+ // for (auto m : mean_pairs)
883+ for (int i = mean_pairs.size () - 1 ; i >= 0 ; i--)
884+ {
885+ grp_names.push_back (mean_pairs[i].second );
886+ }
887+
888+ int i = 0 ;
889+ for (auto &grp_name : grp_names)
890+ {
891+ double mean_diff = mean_change[grp_name];
892+ double std_diff = std_change[grp_name];
893+ int num_out = num_at_bounds[grp_name];
894+ int percent_out = percent_at_bounds[grp_name];
895+ ss.str (" " );
896+ ss << setw (15 ) << pest_utils::lower_cp (grp_name) << setw (12 ) << mean_diff * 100.0 << setw (12 ) << std_diff * 100.0 << setw (18 );
897+ ss << num_out << setw (16 ) << setprecision (2 ) << percent_out << endl;
898+ if (i < 15 )
899+ cout << ss.str ();
900+ frec << ss.str ();
901+ i++;
902+ }
903+
904+ ss.str (" " );
905+ ss << " Note: parameter change summary sorted according to abs 'mean change'." << endl;
906+ cout << ss.str ();
875907 frec << ss.str ();
908+ if (grp_names.size () > 15 )
909+ {
910+ ss.str (" " );
911+ ss << " Note: Only the first 15 parameter groups shown, see rec file for full listing" << endl;
912+ cout << ss.str ();
913+ }
914+
915+ cout << endl;
916+ frec << endl;
917+
918+ if (filename.size () > 0 )
919+ write_to_csv (filename);
920+
921+ }
922+
923+ void ParChangeSummarizer::write_to_csv (string& filename)
924+ {
925+ ofstream f (filename);
926+ if (f.bad ())
927+ throw runtime_error (" ParChangeSummarizer::write_to_csv() error opening file " + filename);
928+
929+ f << " group,mean_change,std_change,num_at_near_bounds,percent_at_near_bounds" << endl;
930+ for (auto grp_name : base_pe_ptr->get_pest_scenario_ptr ()->get_ctl_ordered_par_group_names ())
931+ {
932+ f << pest_utils::lower_cp (grp_name) << " ," << mean_change[grp_name] << " ," << std_change[grp_name] << " ," ;
933+ f << num_at_bounds[grp_name] << " ," << percent_at_bounds[grp_name] << endl;
934+ }
935+ f.close ();
936+ file_manager_ptr->rec_ofstream () << " ...saved parameter change summary to " << filename << endl;
937+ cout << " ...saved parameter change summary to " << filename << endl;
938+
939+ }
940+
941+
942+ void ParChangeSummarizer::update (ParameterEnsemble& pe)
943+ {
944+ mean_change.clear ();
945+ std_change.clear ();
946+ num_at_bounds.clear ();
947+ percent_at_bounds.clear ();
948+ pair<map<string, double >, map<string, double >> moments = pe.get_moment_maps ();
949+ init_moments = base_pe_ptr->get_moment_maps (pe.get_real_names ());
950+
876951 double mean_diff = 0.0 , std_diff = 0.0 ;
877- double dsize, value1, value2,v;
952+ double dsize, value1, value2, v;
878953 vector<string> pnames = pe.get_var_names ();
879954 Parameters lb = pe.get_pest_scenario_ptr ()->get_ctl_parameter_info ().get_low_bnd (pnames);
880955 pe.get_pest_scenario_ptr ()->get_base_par_tran_seq ().active_ctl2numeric_ip (lb);
@@ -884,25 +959,23 @@ void ParChangeSummarizer::summarize(ParameterEnsemble &pe, int iiter)
884959 map<string, int > idx_map;
885960 for (int i = 0 ; i < pnames.size (); i++)
886961 idx_map[pnames[i]] = i;
887- int num_out,num_pars;
962+ int num_out, num_pars;
888963 int num_reals = pe.get_real_names ().size ();
889964 Eigen::ArrayXd arr;
890- for (auto & grp_name : grp_names)
965+ for (auto & grp_name : grp_names)
891966 {
892967 mean_diff = 0.0 , std_diff = 0.0 ;
893968 num_pars = pargp2par_map[grp_name].size ();
894969 num_out = 0 ;
895- for (auto & par_name : pargp2par_map[grp_name])
970+ for (auto & par_name : pargp2par_map[grp_name])
896971 {
897-
898972 arr = pe.get_eigen_ptr ()->col (idx_map[par_name]).array ();
899973 for (int i = 0 ; i < num_reals; i++)
900974 {
901975 v = arr[i];
902976 if ((v > (ub[par_name] * 1.01 )) || (v < (lb[par_name] * 0.99 )))
903977 num_out++;
904978 }
905-
906979 value1 = init_moments.first [par_name];
907980 value2 = value1 - moments.first [par_name];
908981 if ((value1 != 0.0 ) && (value2 != 0.0 ))
@@ -917,20 +990,17 @@ void ParChangeSummarizer::summarize(ParameterEnsemble &pe, int iiter)
917990 mean_diff = mean_diff / dsize;
918991 if (std_diff != 0.0 )
919992 std_diff = std_diff / dsize;
920-
921- ss.str (" " );
993+
922994 double percent_out = 0 ;
923995 if (num_pars > 0 )
924996 percent_out = double (num_out) / double (num_pars * num_reals) * 100 ;
925- // ss << setw(15) << "group" << setw(12) << "mean change" << setw(12) << "std change" << setw(18) << "num at/near bnds" << setw(16) << "% at/near bnds" << endl;
926- ss << setw ( 15 ) << pest_utils::lower_cp ( grp_name) << setw ( 12 ) << mean_diff * 100.0 << setw ( 12 ) << std_diff * 100.0 << setw ( 18 ) ;
927- ss << num_out << setw ( 16 ) << setprecision ( 2 ) << percent_out << endl ;
928- cout << ss. str () ;
929- frec << ss. str () ;
997+
998+ mean_change[ grp_name] = mean_diff;
999+ std_change[grp_name] = std_diff ;
1000+ num_at_bounds[grp_name] = num_out ;
1001+ percent_at_bounds[grp_name] = percent_out ;
9301002
9311003 }
932- cout << endl;
933- frec << endl;
9341004}
9351005
9361006
0 commit comments