diff --git a/src/libraries/UTILITIES/AmplitudeParser.cc b/src/libraries/UTILITIES/AmplitudeParser.cc index bbc57d3e5..b5fed42ba 100644 --- a/src/libraries/UTILITIES/AmplitudeParser.cc +++ b/src/libraries/UTILITIES/AmplitudeParser.cc @@ -10,6 +10,7 @@ #include #include "AmplitudeParser.h" +#include "IUAmpTools/ConfigurationInfo.h" #include "IUAmpTools/report.h" const char *AmplitudeParser::kModule = "AmplitudeParser"; @@ -62,7 +63,7 @@ AmplitudeParser::filterAmplitudesByScheme( const std::string amp_name = ampName(full_amp); if (inferNamingScheme(amp_name) == scheme) filtered.push_back(full_amp); - else + else if (!m_suppress_warnings) { report(WARNING, kModule) << "Amplitude '" << full_amp @@ -84,6 +85,11 @@ AmplitudeParser::parseAmplitudeName(const std::string &_name, NamingScheme sc ParsedAmplitude parsed; parsed.amp_name = amp_name; + if (scheme == NamingScheme::Auto) + { + scheme = inferNamingScheme(amp_name); + } + // Parse quantum numbers according to the structure of the naming scheme switch (scheme) { @@ -106,7 +112,8 @@ AmplitudeParser::parseAmplitudeName(const std::string &_name, NamingScheme sc parsed.L = amp_name.substr(amp_name.size() - 1, 1); break; default: - report(WARNING, kModule) << "Unknown naming scheme, cannot parse amplitude name '" << amp_name << "'.\n"; + if (!m_suppress_warnings) + report(WARNING, kModule) << "Unknown naming scheme, cannot parse amplitude name '" << amp_name << "'.\n"; break; } @@ -126,7 +133,7 @@ AmplitudeParser::sumsForScheme(NamingScheme scheme) const }; } - if (scheme == NamingScheme::JLme) + else if (scheme == NamingScheme::JLme) { return { {{'e'}}, @@ -137,7 +144,7 @@ AmplitudeParser::sumsForScheme(NamingScheme scheme) const {{'J', 'L', 'm'}}, }; } - if (scheme == NamingScheme::eJPmL) + else if (scheme == NamingScheme::eJPmL) { return { {{'e'}}, @@ -150,7 +157,8 @@ AmplitudeParser::sumsForScheme(NamingScheme scheme) const } else { - report(WARNING, kModule) << "Unknown naming scheme, cannot determine sum groups.\n"; + if(!m_suppress_warnings) + report(WARNING, kModule) << "Unknown naming scheme, cannot determine sum groups.\n"; return {}; } } @@ -181,7 +189,8 @@ std::string AmplitudeParser::buildSumLabel( value = parsed.L; break; default: - report(WARNING, kModule) << "Unknown quantum number '" << qn << "' in sum group definition.\n"; + if(!m_suppress_warnings) + report(WARNING, kModule) << "Unknown quantum number '" << qn << "' in sum group definition.\n"; break; } label += value; @@ -198,7 +207,8 @@ AmplitudeParser::buildSumGroups(const std::vector &full_amplitudes) if (full_amplitudes.empty()) { - report(WARNING, kModule) << "No amplitudes found in fit results, so no sums will be built.\n"; + if(!m_suppress_warnings) + report(WARNING, kModule) << "No amplitudes found in fit results, so no sums will be built.\n"; return groups; } @@ -212,12 +222,15 @@ AmplitudeParser::buildSumGroups(const std::vector &full_amplitudes) // see the header file for instructions to do so. if (effective_scheme == NamingScheme::Auto) { - report(WARNING, kModule) << "Amplitude naming scheme could not be inferred, and so no sums will be built.\n"; - report(WARNING, kModule) << "This likely means your amplitude names don't follow a recognized pattern. Supported patterns include:\n"; - report(WARNING, kModule) << "\t1) JLme: e.g. 1P-1+ \n"; - report(WARNING, kModule) << "\t2) Lme: e.g. P1+ \n"; - report(WARNING, kModule) << "\t3) eJPmL: e.g. p1ppS \n"; - report(WARNING, kModule) << "You can also specify the naming scheme pattern (from the choices above) directly in the FitConverter constructor to avoid inference.\n"; + if(!m_suppress_warnings) + { + report(WARNING, kModule) << "Amplitude naming scheme could not be inferred, and so no sums will be built.\n"; + report(WARNING, kModule) << "This likely means your amplitude names don't follow a recognized pattern. Supported patterns include:\n"; + report(WARNING, kModule) << "\t1) JLme: e.g. 1P-1+ \n"; + report(WARNING, kModule) << "\t2) Lme: e.g. P1+ \n"; + report(WARNING, kModule) << "\t3) eJPmL: e.g. p1ppS \n"; + report(WARNING, kModule) << "You can also specify the naming scheme pattern (from the choices above) directly in the FitConverter constructor to avoid inference.\n"; + } return groups; } @@ -256,4 +269,169 @@ AmplitudeParser::buildSumGroups(const std::vector &full_amplitudes) } return groups; +} + + +std::set +AmplitudeParser::uniqueAmpNames(const FitResults &result) +{ + std::set unique_names; + for (const auto &litude : result.ampList()) + { + size_t last_colon = amplitude.rfind("::"); + if (last_colon != std::string::npos) + { + std::string amp_name = amplitude.substr(last_colon + 2); + unique_names.insert(amp_name); + } + } + return unique_names; +} + + +std::set +AmplitudeParser::uniqueSumAmpNames(const FitResults &result) +{ + std::set unique_names; + for (const auto &litude : result.ampList()) + { + size_t first_colon = amplitude.find("::"); + size_t last_colon = amplitude.rfind("::"); + if (first_colon != std::string::npos && last_colon != std::string::npos && first_colon != last_colon) + { + std::string sum_amp_name = amplitude.substr(first_colon + 2); + unique_names.insert(sum_amp_name); + } + } + return unique_names; +} + +std::map> +AmplitudeParser::findConstrainedAmps(const FitResults &result) +{ + std::map> constrained_amp_map; + + if (ampNamesAreConstrained(result)) + { + for (const auto &unique_amp : uniqueAmpNames(result)) + { + // the bool assures us that all terms with this amp name are constrained to + // each other + std::vector shared_terms = result.configInfo()->termList("", "", unique_amp); + + // store the full names of the constrained amplitudes + for (const auto &term : shared_terms) + constrained_amp_map[unique_amp].push_back(term->fullName()); + } + return constrained_amp_map; + } + + if (sumAmpNamesAreConstrained(result)) + { + for (const auto &unique_sum_amp : uniqueSumAmpNames(result)) + { + std::string sum = unique_sum_amp.substr(0, unique_sum_amp.find("::")); + std::string amp = unique_sum_amp.substr(unique_sum_amp.find("::") + 2); + // the bool assures us that all terms with this sum::amp name are + // constrained to each other + std::vector shared_terms = result.configInfo()->termList("", sum, amp); + + // store the full names of the constrained amplitudes + for (const auto &term : shared_terms) + constrained_amp_map[unique_sum_amp].push_back(term->fullName()); + } + return constrained_amp_map; + } + + // if we reach here, neither assumption held, so just map full amplitude names to + // themselves + for (const auto &litude : result.ampList()) + { + constrained_amp_map[amplitude] = {amplitude}; + } + return constrained_amp_map; +} + +bool AmplitudeParser::ampNamesAreConstrained(const FitResults &result) +{ + for (const auto &unique_amp : uniqueAmpNames(result)) + { + std::vector shared_terms = result.configInfo()->termList("", "", unique_amp); + + // we assume terms with common amplitude names are all constrained to each + // other, so use first term to check this + std::vector constrained_terms = shared_terms[0]->constraints(); + + // filter constrained terms to only those with the same amplitude name + for (auto it = constrained_terms.begin(); it != constrained_terms.end();) + { + if ((*it)->fullName().find(unique_amp) == std::string::npos) + it = constrained_terms.erase(it); + else + ++it; + } + + // The constrained terms does not include the self term, so add it back in for + // comparison + constrained_terms.push_back(shared_terms[0]); + + // Compare the two sets of terms to ensure they are the same + std::sort(shared_terms.begin(), shared_terms.end()); + std::sort(constrained_terms.begin(), constrained_terms.end()); + if (shared_terms != constrained_terms) + { + return false; + } + } + return true; +} + +bool AmplitudeParser::sumAmpNamesAreConstrained(const FitResults &result) +{ + for (const auto &unique_sum_amp : uniqueSumAmpNames(result)) + { + std::string sum = unique_sum_amp.substr(0, unique_sum_amp.find("::")); + std::string amp = unique_sum_amp.substr(unique_sum_amp.find("::") + 2); + + std::vector shared_terms = result.configInfo()->termList("", sum, amp); + + // we assume terms with common sum::amp names are all constrained to each + // other, so use first term to check this + std::vector constrained_terms = shared_terms[0]->constraints(); + + // filter constrained terms to only those with the same sum::amp name + for (auto it = constrained_terms.begin(); it != constrained_terms.end();) + { + if ((*it)->fullName().find(unique_sum_amp) == std::string::npos) + it = constrained_terms.erase(it); + else + ++it; + } + + // The constrained terms does not include the self term, so add it back in for + // comparison + constrained_terms.push_back(shared_terms[0]); + + // Compare the two sets of terms to ensure they are the same + std::sort(shared_terms.begin(), shared_terms.end()); + std::sort(constrained_terms.begin(), constrained_terms.end()); + if (shared_terms != constrained_terms) + { + return false; + } + } + return true; +} + +std::string AmplitudeParser::getReactionString(const std::string &full_amplitude) +{ + size_t first_colon = full_amplitude.find("::"); + size_t second_colon = full_amplitude.find("::", first_colon + 2); + if (first_colon == std::string::npos || second_colon == std::string::npos) + { + report(ERROR, kModule) << "Amplitude name " << full_amplitude << " does not match expected format 'reaction::sum::amp'.\n"; + assert(false); + } + std::string reaction = full_amplitude.substr(0, first_colon); + return reaction; } \ No newline at end of file diff --git a/src/libraries/UTILITIES/AmplitudeParser.h b/src/libraries/UTILITIES/AmplitudeParser.h index 570dbd506..58d29b5b6 100644 --- a/src/libraries/UTILITIES/AmplitudeParser.h +++ b/src/libraries/UTILITIES/AmplitudeParser.h @@ -32,21 +32,27 @@ #define FIT_AMPLITUDE_PARSER_H #include +#include #include #include +#include "IUAmpTools/FitResults.h" + /** * @class AmplitudeParser * @brief Parses amplitude names and builds coherent sums based on naming schemes * - * This class is responsible for parsing amplitude names from AmpTools fit results and - * grouping them into coherent sums based on shared quantum numbers. It supports - * multiple naming schemes, which can be selected by the user or inferred from the - * amplitude labels. The parser identifies the relevant quantum numbers from the + * This class is primarily responsible for parsing amplitude names from AmpTools fit + * results and grouping them into coherent sums based on shared quantum numbers. It + * supports multiple naming schemes, which can be selected by the user or inferred from + * the amplitude labels. The parser identifies the relevant quantum numbers from the * amplitude names and groups amplitudes that share those quantum numbers into sums, * which can then be used to calculate intensities of sums e.g. total reflectivity * contributions, or total spin contributions. * + * It also contains several static methods for helping identify the unique/constrained + * amplitudes from a fit result. + * * @note All amplitudes that match the criteria for a sum group will be included, * meaning amplitudes will be gathered across reactions and sums as long as they share * the relevant quantum numbers based on the selected naming scheme. For example, if we @@ -61,14 +67,6 @@ class AmplitudeParser { public: - enum class NamingScheme - { - Auto, - JLme, - eJPmL, - Lme - }; - /** * @brief Construct a new Amplitude Parser object * @@ -81,16 +79,25 @@ class AmplitudeParser */ explicit AmplitudeParser(const std::string &naming_scheme = "auto"); + enum class NamingScheme + { + Auto, + JLme, + eJPmL, + Lme + }; + /** - * @brief + * @brief Set the naming scheme based on the input string from the user. * - * @param full_amplitudes - * @return std::map> + * If the input is "auto" or is an unrecognized string, we will attempt to infer the + * naming scheme from the amplitude labels later. + * + * @param scheme_name user string indicating the naming scheme + * @return NamingScheme objective naming scheme enum value */ - std::map> - buildSumGroups(const std::vector &full_amplitudes) const; + static NamingScheme namingSchemeFromString(const std::string &scheme_name); -private: /** * @brief struct to contain the parsed quantum numbers from an amplitude name * @@ -121,18 +128,99 @@ class AmplitudeParser std::string L; ///< Orbital angular momentum }; - NamingScheme m_requested_scheme; ///< The naming scheme to use, or "Auto" to infer from amplitude labels + /** + * @brief Extract quantum numbers from the amplitude name according to the scheme + * + * @param amp_name ampName in "reaction::sum::ampName" + * @param scheme naming scheme to use for parsing + * @return ParsedAmplitude object that contains the original amp_name and the parsed quantum numbers + */ + ParsedAmplitude parseAmplitudeName(const std::string &_name, NamingScheme scheme) const; /** - * @brief Set the naming scheme based on the input string from the user. + * @brief * - * If the input is "auto" or is an unrecognized string, we will attempt to infer the - * naming scheme from the amplitude labels later. + * @param full_amplitudes + * @return std::map> + */ + std::map> + buildSumGroups(const std::vector &full_amplitudes) const; + + /** + * @brief return set of all unique amplitude names in a fit result * - * @param scheme_name user string indicating the naming scheme - * @return NamingScheme objective naming scheme enum value + * A "full" amplitude is a "reaction::sum::ampName" string, so this extracts all + * unique "ampName" strings */ - static NamingScheme namingSchemeFromString(const std::string &scheme_name); + static std::set uniqueAmpNames(const FitResults &result); + + /** + * @brief return set of all unique coherent sum + amp names in a fit result + * + * A "full" amplitude is a "reaction::sum::ampName" string, so this extracts all + * unique "sum::ampName" strings + */ + static std::set uniqueSumAmpNames(const FitResults &result); + + /** + * @brief Get map of unique amplitude groups to their constrained full amplitudes + * + * This attempts to identify the unique strings that can be a coupled to a set of + * constrained amplitudes. For a "full" amplitude string of the form + * "reaction::sum::ampName", it first assumes that amplitudes with the same ampName + * are constrained to each other, across reactions and sums. If not, it peels back a + * layer and assumes that amplitudes with the same "sum::ampName" are constrained to + * each other, across reactions. If that fails, it simply saves a mapping of the + * full amplitude to itself. The map keys are whats extracted as the unique + * amplitude names (ampName, sum::ampName, or full amplitude), and the values are + * vectors of the full amplitude strings that are constrained to each other. + */ + static std::map> findConstrainedAmps(const FitResults &results); + + /** + * @brief Checks if amplitude names are constrained to each other + * + * A "full" amplitude is a "reaction::sum::ampName" string, so this checks if all + * amplitudes with the same "ampName" are constrained to each other across reactions + * and sums. + */ + static bool ampNamesAreConstrained(const FitResults &results); + + /** + * @brief Checks if coherent sum + amplitude names are constrained to each other + * + * A "full" amplitude is a "reaction::sum::ampName" string, so this checks if all + * amplitudes with the same "sum::ampName" are constrained to each other across + * reactions. + */ + static bool sumAmpNamesAreConstrained(const FitResults &results); + + /** + * @brief Get the reaction string from a full amplitude name + * + * This extracts the reaction part from a "reaction::sum::ampName" string. + * + * @param full_amp_name The full amplitude name + * @return The reaction string + */ + static std::string getReactionString(const std::string &full_amp_name); + + /** + * @brief Extract the amplitude name from the full amplitude string. + * + * For example, for "reaction::sum::amp", this would return "amp". This is the part + * of the amplitude label that typically contains the quantum numbers and is used + * for grouping into sums. + * + * @param full_name "reaction::sum::ampName" style amplitude string + * @return std::string ampName, the part of the full amplitude string after the last "::" + */ + static std::string ampName(const std::string &full_name); + + mutable bool m_suppress_warnings = false; ///< User can set to true to avoid redundant warnings for many files + +private: + NamingScheme m_requested_scheme; ///< The naming scheme to use, or "Auto" to infer from amplitude labels /** * @brief Infer the naming scheme from the amplitude name format if "auto" is selected. @@ -162,27 +250,6 @@ class AmplitudeParser */ std::vector filterAmplitudesByScheme(const std::vector &full_amplitudes, NamingScheme scheme) const; - /** - * @brief Extract the amplitude name from the full amplitude string. - * - * For example, for "reaction::sum::amp", this would return "amp". This is the part - * of the amplitude label that typically contains the quantum numbers and is used - * for grouping into sums. - * - * @param full_name "reaction::sum::ampName" style amplitude string - * @return std::string ampName, the part of the full amplitude string after the last "::" - */ - static std::string ampName(const std::string &full_name); - - /** - * @brief Extract quantum numbers from the amplitude name according to the scheme - * - * @param amp_name ampName in "reaction::sum::ampName" - * @param scheme naming scheme to use for parsing - * @return ParsedAmplitude object that contains the original amp_name and the parsed quantum numbers - */ - ParsedAmplitude parseAmplitudeName(const std::string &_name, NamingScheme scheme) const; - /** * @brief Define the grouping of quantum numbers that will become a sum label */ diff --git a/src/libraries/UTILITIES/FitConverter.cc b/src/libraries/UTILITIES/FitConverter.cc index 11acb3c97..0e0c68b28 100644 --- a/src/libraries/UTILITIES/FitConverter.cc +++ b/src/libraries/UTILITIES/FitConverter.cc @@ -20,7 +20,6 @@ const char *FitConverter::kModule = "FitConverter"; FitConverter::FitConverter(const std::string &filename, const bool &acceptance_correct, bool mute_warning, const std::string &naming_scheme) : m_fit_file(filename), m_fit_results(filename, mute_warning), - m_cfg_info(m_fit_results.configInfo()), m_is_acceptance_corrected(acceptance_correct), m_amplitude_parser(naming_scheme), m_error_matrix(m_fit_results.errorMatrix()) @@ -30,6 +29,9 @@ FitConverter::FitConverter(const std::string &filename, const bool &acceptance_c report(ERROR, kModule) << "FitConverter ERROR: Unable to read fit results from file " + m_fit_file << "\n"; assert(false); } + + m_amplitude_parser.m_suppress_warnings = mute_warning; + extract(); } @@ -61,7 +63,7 @@ void FitConverter::extract() } // Build map of unique amplitude names and their constrained amplitudes - m_constrained_amps = findConstrainedAmps(); + m_constrained_amps = m_amplitude_parser.findConstrainedAmps(m_fit_results); for (const auto &pair : m_constrained_amps) { report(DEBUG, kModule) << "Unique amplitude: " @@ -120,7 +122,7 @@ void FitConverter::extract() continue; const std::string &full_amp_name = pair.second[0]; - m_production_coefficients[unique_amp] = m_fit_results.scaledProductionParameter(full_amp_name); + m_production_coefficients[unique_amp] = m_fit_results.productionParameter(full_amp_name); } // Calculate phase differences between all pairs of unique amplitude names that @@ -181,37 +183,6 @@ void FitConverter::extract() } } -std::set FitConverter::uniqueAmpNames() const -{ - std::set unique_names; - for (const auto &litude : m_fit_results.ampList()) - { - size_t last_colon = amplitude.rfind("::"); - if (last_colon != std::string::npos) - { - std::string amp_name = amplitude.substr(last_colon + 2); - unique_names.insert(amp_name); - } - } - return unique_names; -} - -std::set FitConverter::uniqueSumAmpNames() const -{ - std::set unique_names; - for (const auto &litude : m_fit_results.ampList()) - { - size_t first_colon = amplitude.find("::"); - size_t last_colon = amplitude.rfind("::"); - if (first_colon != std::string::npos && last_colon != std::string::npos && first_colon != last_colon) - { - std::string sum_amp_name = amplitude.substr(first_colon + 2); - unique_names.insert(sum_amp_name); - } - } - return unique_names; -} - std::string FitConverter::getCSVHeader() const { std::string header = "file,"; @@ -424,14 +395,14 @@ std::string FitConverter::getCSVNormIntMatrix() const for (size_t row_idx = 0; row_idx < m_fit_results.ampList().size(); row_idx++) { const std::string &row_amp = amp_list.at(row_idx); - std::string row_reaction = getReactionString(row_amp); + std::string row_reaction = m_amplitude_parser.getReactionString(row_amp); csv += m_fit_file + "," + row_amp; // write file name and this amplitude name as first two columns of this row for (size_t col_idx = 0; col_idx < m_fit_results.ampList().size(); col_idx++) { const std::string &col_amp = amp_list.at(col_idx); - std::string col_reaction = getReactionString(col_amp); + std::string col_reaction = m_amplitude_parser.getReactionString(col_amp); if (row_reaction != col_reaction) { @@ -446,17 +417,21 @@ std::string FitConverter::getCSVNormIntMatrix() const assert(false); } - std::complex value = normInt->normInt(row_amp, col_amp); + std::complex value = m_is_acceptance_corrected ? normInt->ampInt(row_amp, col_amp) : normInt->normInt(row_amp, col_amp); // Format as pandas-readable complex number e.g. 1+2j or 1-2j std::ostringstream oss; oss << std::scientific << std::setprecision(std::numeric_limits::max_digits10 - 1); oss << value.real(); - if (value.imag() >= 0) + // Avoid emitting "+-0" when the imaginary part is "negative zero". + double imag = value.imag(); + if (imag == 0.0) + imag = 0.0; + if (imag >= 0.0) { oss << "+"; } - oss << value.imag() << "j"; + oss << imag << "j"; csv += "," + oss.str(); } // end column loop @@ -469,134 +444,6 @@ std::string FitConverter::getCSVNormIntMatrix() const return csv; } -std::map> FitConverter::findConstrainedAmps() const -{ - std::map> constrained_amp_map; - - if (ampNamesAreConstrained()) - { - for (const auto &unique_amp : uniqueAmpNames()) - { - // the bool assures us that all terms with this amp name are constrained to - // each other - std::vector shared_terms = m_cfg_info->termList("", "", unique_amp); - - // store the full names of the constrained amplitudes - for (const auto &term : shared_terms) - constrained_amp_map[unique_amp].push_back(term->fullName()); - } - return constrained_amp_map; - } - - if (sumAmpNamesAreConstrained()) - { - for (const auto &unique_sum_amp : uniqueSumAmpNames()) - { - std::string sum = unique_sum_amp.substr(0, unique_sum_amp.find("::")); - std::string amp = unique_sum_amp.substr(unique_sum_amp.find("::") + 2); - // the bool assures us that all terms with this sum::amp name are - // constrained to each other - std::vector shared_terms = m_cfg_info->termList("", sum, amp); - - // store the full names of the constrained amplitudes - for (const auto &term : shared_terms) - constrained_amp_map[unique_sum_amp].push_back(term->fullName()); - } - return constrained_amp_map; - } - - // if we reach here, neither assumption held, so just map full amplitude names to - // themselves - for (const auto &litude : m_fit_results.ampList()) - { - constrained_amp_map[amplitude] = {amplitude}; - } - return constrained_amp_map; -} - -bool FitConverter::ampNamesAreConstrained() const -{ - for (const auto &unique_amp : uniqueAmpNames()) - { - std::vector shared_terms = m_cfg_info->termList("", "", unique_amp); - - // we assume terms with common amplitude names are all constrained to each - // other, so use first term to check this - std::vector constrained_terms = shared_terms[0]->constraints(); - - // filter constrained terms to only those with the same amplitude name - for (auto it = constrained_terms.begin(); it != constrained_terms.end();) - { - if ((*it)->fullName().find(unique_amp) == std::string::npos) - it = constrained_terms.erase(it); - else - ++it; - } - - // The constrained terms does not include the self term, so add it back in for - // comparison - constrained_terms.push_back(shared_terms[0]); - - // Compare the two sets of terms to ensure they are the same - std::sort(shared_terms.begin(), shared_terms.end()); - std::sort(constrained_terms.begin(), constrained_terms.end()); - if (shared_terms != constrained_terms) - { - return false; - } - } - return true; -} - -bool FitConverter::sumAmpNamesAreConstrained() const -{ - for (const auto &unique_sum_amp : uniqueSumAmpNames()) - { - std::string sum = unique_sum_amp.substr(0, unique_sum_amp.find("::")); - std::string amp = unique_sum_amp.substr(unique_sum_amp.find("::") + 2); - - std::vector shared_terms = m_cfg_info->termList("", sum, amp); - - // we assume terms with common sum::amp names are all constrained to each - // other, so use first term to check this - std::vector constrained_terms = shared_terms[0]->constraints(); - - // filter constrained terms to only those with the same sum::amp name - for (auto it = constrained_terms.begin(); it != constrained_terms.end();) - { - if ((*it)->fullName().find(unique_sum_amp) == std::string::npos) - it = constrained_terms.erase(it); - else - ++it; - } - - // The constrained terms does not include the self term, so add it back in for - // comparison - constrained_terms.push_back(shared_terms[0]); - - // Compare the two sets of terms to ensure they are the same - std::sort(shared_terms.begin(), shared_terms.end()); - std::sort(constrained_terms.begin(), constrained_terms.end()); - if (shared_terms != constrained_terms) - { - return false; - } - } - return true; -} - -std::string FitConverter::getReactionString(const std::string &full_amplitude) -{ - size_t first_colon = full_amplitude.find("::"); - size_t second_colon = full_amplitude.find("::", first_colon + 2); - if (first_colon == std::string::npos || second_colon == std::string::npos) - { - report(ERROR, kModule) << "Amplitude name " << full_amplitude << " does not match expected format 'reaction::sum::amp'.\n"; - assert(false); - } - std::string reaction = full_amplitude.substr(0, first_colon); - return reaction; -} std::string FitConverter::preciseDoubleToString(double value) const { diff --git a/src/libraries/UTILITIES/FitConverter.h b/src/libraries/UTILITIES/FitConverter.h index 179818346..dc58823b5 100644 --- a/src/libraries/UTILITIES/FitConverter.h +++ b/src/libraries/UTILITIES/FitConverter.h @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -63,7 +62,7 @@ class FitConverter * @brief Construct a FitConverter for a single fit file * @param[in] filename Path to the .fit file * @param[in] acceptance_correct Whether to use acceptance-corrected intensities - * @param[in] mute_warning Suppress warning about free parameters if true + * @param[in] mute_warning Suppress warnings from FitResults and AmplitudeParser * @param[in] naming_scheme Amplitude naming scheme: auto, JLme, eJPmL, or Lme * @throw ERROR If the fit file cannot be read or is invalid */ @@ -151,24 +150,6 @@ class FitConverter */ std::string getCSVNormIntMatrix() const; - /** - * @brief return set of all unique amplitude names in a fit result - * - * A "full" amplitude is a "reaction::sum::ampName" string, so this extracts all - * unique "ampName" strings - */ - std::set uniqueAmpNames() const; - - /** - * @brief return set of all unique coherent sum + amp names in a fit result - * - * A "full" amplitude is a "reaction::sum::ampName" string, so this extracts all - * unique "sum::ampName" strings - * - * @return std::set - */ - std::set uniqueSumAmpNames() const; - bool isValid() const { return m_fit_results.valid(); } /** @@ -273,7 +254,6 @@ class FitConverter private: const std::string m_fit_file; ///< Path to the .fit file const FitResults m_fit_results; ///< AmpTools FitResults object - const ConfigurationInfo *m_cfg_info; ///< ConfigurationInfo from the fit const bool m_is_acceptance_corrected; ///< Whether to use acceptance-corrected intensities const AmplitudeParser m_amplitude_parser; ///< Parser for amplitude labels and sums @@ -288,59 +268,13 @@ class FitConverter std::vector> m_error_matrix; /** - * @brief Get map of unique amplitude groups to their constrained full amplitudes - * - * This attempts to identify the unique strings that can be a coupled to a set of - * constrained amplitudes. For a "full" amplitude string of the form - * "reaction::sum::ampName", it first assumes that amplitudes with the same ampName - * are constrained to each other, across reactions and sums. If not, it peels back a - * layer and assumes that amplitudes with the same "sum::ampName" are constrained to - * each other, across reactions. If that fails, it simply saves a mapping of the - * full amplitude to itself. The map keys are whats extracted as the unique - * amplitude names (ampName, sum::ampName, or full amplitude), and the values are - * vectors of the full amplitude strings that are constrained to each other. - * - * @note the keys are whats written to the CSV, and is why it first attempts to - * extract just the ampName for simplicity. - */ - std::map> findConstrainedAmps() const; - - /** - * @brief Checks if amplitude names are constrained to each other - * - * A "full" amplitude is a "reaction::sum::ampName" string, so this checks if all - * amplitudes with the same "ampName" are constrained to each other across reactions - * and sums. - */ - bool ampNamesAreConstrained() const; - - /** - * @brief Checks if coherent sum + amplitude names are constrained to each other - * - * A "full" amplitude is a "reaction::sum::ampName" string, so this checks if all - * amplitudes with the same "sum::ampName" are constrained to each other across - * reactions. - */ - bool sumAmpNamesAreConstrained() const; - - /** - * @brief Get the reaction string from a full amplitude name + * @brief Convert a double to string with max precision * - * This extracts the reaction part from a "reaction::sum::ampName" string. + * Uses std::numeric_limits::max_digits10 to ensure that the string + * representation is precise enough to reconstruct the original double value. * - * @param full_amp_name The full amplitude name - * @return The reaction string - */ - static std::string getReactionString(const std::string &full_amp_name); - - /** - * @brief Convert a double to string with max precision - * - * Uses std::numeric_limits::max_digits10 to ensure that the string - * representation is precise enough to reconstruct the original double value. - * - * @param value - * @return std::string + * @param value + * @return std::string */ std::string preciseDoubleToString(double value) const; diff --git a/src/programs/AmplitudeAnalysis/convert_to_csv/convert_to_csv.cc b/src/programs/AmplitudeAnalysis/convert_to_csv/convert_to_csv.cc index 8393f5869..0824ec023 100644 --- a/src/programs/AmplitudeAnalysis/convert_to_csv/convert_to_csv.cc +++ b/src/programs/AmplitudeAnalysis/convert_to_csv/convert_to_csv.cc @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) report(INFO, kModule) << " -l --lower-vertex-indices:\tSpecify indices of lower vertex particles in the data 4-vectors\n"; report(INFO, kModule) << " -n --naming-scheme:\t\tAmp naming scheme for coherent sum groupings. Default is auto (infers scheme from the amp names)\n"; report(INFO, kModule) << " -p --preview:\t\t\tPrint files to be processed, but don't run\n"; - report(INFO, kModule) << " -v --verbose:\t\t\tPrint information from converter scripts as they run\n"; + report(INFO, kModule) << " -v --verbose:\t\t\tPrint information and 'WARNING' reports from converter scripts as they run\n"; report(INFO, kModule) << " --correlation:\t\tSave correlation matrix to separate csv file\n"; report(INFO, kModule) << " --covariance:\t\t\tSave covariance matrix to separate csv file\n"; report(INFO, kModule) << " --norm-int:\t\t\tSave normalization integral matrix to separate csv file\n";