|
1 | | -// Copyright (C) 2019 - 2025 by Pedro Mendes, Rector and Visitors of the |
| 1 | +// Copyright (C) 2019 - 2026 by Pedro Mendes, Rector and Visitors of the |
2 | 2 | // University of Virginia, University of Heidelberg, and University |
3 | 3 | // of Connecticut School of Medicine. |
4 | 4 | // All rights reserved. |
@@ -927,7 +927,6 @@ CFitConstraint & CFitProblem::addFitConstraint(const CRegisteredCommonName & obj |
927 | 927 | return *pItem; |
928 | 928 | } |
929 | 929 |
|
930 | | - |
931 | 930 | bool CFitProblem::calculate() |
932 | 931 | { |
933 | 932 | sCounter Counters; |
@@ -1795,6 +1794,12 @@ bool CFitProblem::calcCov(const CMatrix< C_FLOAT64 >& fim, CMatrix< C_FLOAT64 >& |
1795 | 1794 | corr = std::numeric_limits<C_FLOAT64>::quiet_NaN(); |
1796 | 1795 | sd = std::numeric_limits<C_FLOAT64>::quiet_NaN(); |
1797 | 1796 | CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 12); |
| 1797 | + |
| 1798 | + // verify that we dont have duplicates in the list of |
| 1799 | + // fit items, as they are a common cause |
| 1800 | + bool logWarnings = true; |
| 1801 | + checkForDuplicateFitItems(logWarnings); |
| 1802 | + |
1798 | 1803 | return false; |
1799 | 1804 | } |
1800 | 1805 |
|
@@ -2184,6 +2189,56 @@ bool CFitProblem::calculateStatistics(const C_FLOAT64 & factor, |
2184 | 2189 | return true; |
2185 | 2190 | } |
2186 | 2191 |
|
| 2192 | +bool CFitProblem::checkForDuplicateFitItems(bool logWarnings) const |
| 2193 | +{ |
| 2194 | + if (!mpOptItems) |
| 2195 | + return false; |
| 2196 | + |
| 2197 | + // map counting how many time a specific |
| 2198 | + // fit item (and experiment combination) appears in the list of fit items |
| 2199 | + std::map< std::string, size_t > FitItemNames; |
| 2200 | + |
| 2201 | + // map counting for each object underlying a fit item |
| 2202 | + // how many times a combination of experiments appears in the list of |
| 2203 | + // fit items |
| 2204 | + std::map< std::string, std::map<std::string, size_t> > ObjectsWithExperiments; |
| 2205 | + |
| 2206 | + bool hasDuplicates = false; |
| 2207 | + for (auto * optItem : *mpOptItems) |
| 2208 | + { |
| 2209 | + auto * item = static_cast< CFitItem * >(optItem); |
| 2210 | + auto * obj = item->getItemObject(); |
| 2211 | + std::string name = obj != NULL ? obj->getObjectDisplayName() : "Not found"; |
| 2212 | + auto experiments = item->getExperiments(); |
| 2213 | + if (!experiments.empty()) |
| 2214 | + name += " {" + experiments + "}"; |
| 2215 | + |
| 2216 | + if (FitItemNames.find(name) == FitItemNames.end()) |
| 2217 | + { |
| 2218 | + FitItemNames[name] = 1; |
| 2219 | + } |
| 2220 | + else |
| 2221 | + { |
| 2222 | + hasDuplicates = true; |
| 2223 | + FitItemNames[name] += 1; |
| 2224 | + } |
| 2225 | + } |
| 2226 | + |
| 2227 | + if (hasDuplicates && logWarnings) |
| 2228 | + { |
| 2229 | + std::stringstream ss; |
| 2230 | + ss << "Duplicate fit items detected. This prevents calculation of summary statistics." << std::endl; |
| 2231 | + for (const auto & pair : FitItemNames) |
| 2232 | + { |
| 2233 | + if (pair.second > 1) |
| 2234 | + ss << "Fit item '" << pair.first << "' appears " << pair.second << " times." << std::endl; |
| 2235 | + } |
| 2236 | + |
| 2237 | + CCopasiMessage(CCopasiMessage::WARNING, "%s", ss.str().c_str()); |
| 2238 | + } |
| 2239 | + return hasDuplicates; |
| 2240 | +} |
| 2241 | + |
2187 | 2242 | const C_FLOAT64 & CFitProblem::getRMS() const |
2188 | 2243 | { |
2189 | 2244 | return mRMS; |
|
0 commit comments