• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rlalik / HelloFitty / 16568410904

28 Jul 2025 11:58AM UTC coverage: 83.411% (-1.6%) from 84.992%
16568410904

push

github

rlalik
Add functions to update param properrties

2 of 14 new or added lines in 2 files covered. (14.29%)

538 of 645 relevant lines covered (83.41%)

20.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.95
/source/entry.cpp
1
/*
2
    HelloFitty - a versatile histogram fitting tool for ROOT-based projects
3
    Copyright (C) 2015-2023  Rafał Lalik <rafallalik@gmail.com>
4

5
    This program is free software: you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 3 of the License, or
8
    (at your option) any later version.
9

10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14

15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

19
#include <fmt/core.h>
20

21
#include "hellofitty.hpp"
22

23
#include "details.hpp"
24

25
template<>
26
struct fmt::formatter<hf::entry>
27
{
28
    // Presentation format: 'f' - fixed, 'e' - exponential, 'g' - either.
29
    char presentation = 'g';
30

31
    // Parses format specifications of the form ['f' | 'e' | 'g'].
32
    CONSTEXPR auto parse(format_parse_context& ctx) -> format_parse_context::iterator
×
33
    {
34
        // Parse the presentation format and store it in the formatter:
35
        auto it = ctx.begin(), end = ctx.end();
×
36
        if (it != end && *it != '}') { FMT_THROW(format_error("invalid format")); }
×
37

38
        // Return an iterator past the end of the parsed range:
39
        return it;
×
40
    }
41

42
    auto format(const hf::entry& /*fitentry*/, format_context& ctx) const -> format_context::iterator
×
43
    {
44
        return ctx.out();
×
45
    }
46
};
47

48
namespace hf
49
{
50

51
entry::entry()
×
52
    : m_d {make_unique<detail::entry_impl>()}
×
53
{
54
}
×
55

56
entry::entry(Double_t range_lower, Double_t range_upper)
32✔
57
    : m_d {make_unique<detail::entry_impl>()}
32✔
58
{
59
    if (range_lower == range_upper) { throw hf::range_error("fitting range cannot be empty"); }
32✔
60

61
    m_d->range_min = range_lower;
32✔
62
    m_d->range_max = range_upper;
32✔
63
}
32✔
64

65
entry::entry(const entry& other) { m_d = make_unique<detail::entry_impl>(*other.m_d); }
6✔
66

67
auto entry::operator=(const entry& other) -> entry&
×
68
{
69
    m_d = make_unique<detail::entry_impl>(*other.m_d);
×
70
    return *this;
×
71
}
72

73
entry::~entry() noexcept = default;
69✔
74

75
auto entry::is_valid() const -> bool { return m_d->range_max > m_d->range_min; }
×
76

77
auto entry::clear() -> void { drop(); }
1✔
78

79
auto entry::add_function(std::string formula) -> int
14✔
80
{
81
    auto current_function_idx = m_d->add_function_lazy(std::move(formula));
14✔
82
    m_d->compile();
14✔
83
    return current_function_idx;
14✔
84
}
85

86
auto entry::get_function(int function_index) const -> const char*
45✔
87
{
88
    return m_d->funcs.at(int2size_t(function_index)).body_string.c_str();
90✔
89
}
90

91
auto entry::set_param(int par_id, hf::param par) -> void
90✔
92
{
93
    const auto upar_id = int2size_t(par_id);
90✔
94
    m_d->pars.at(upar_id) = std::move(par);
90✔
95
}
86✔
96

97
auto entry::set_param(int par_id, Double_t value, hf::param::fit_mode mode) -> void
58✔
98
{
99
    set_param(par_id, hf::param(value, mode));
58✔
100
}
55✔
101

102
auto entry::set_param(int par_id, Double_t value, Double_t l, Double_t u, param::fit_mode mode) -> void
28✔
103
{
104
    set_param(par_id, hf::param(value, l, u, mode));
28✔
105
}
27✔
106

107
auto entry::update_param_value(int par_id, Double_t value) -> void
46✔
108
{
109
    const auto upar_id = int2size_t(par_id);
46✔
110
    auto& par = m_d->pars.at(upar_id);
46✔
111

112
    par.value = value;
46✔
113
}
46✔
114

NEW
115
auto entry::update_param_limits(int par_id, Double_t min, Double_t max) -> void
×
116
{
NEW
117
    const auto upar_id = int2size_t(par_id);
×
NEW
118
    auto& par = m_d->pars.at(upar_id);
×
119

NEW
120
    par.min = min;
×
NEW
121
    par.max = max;
×
NEW
122
}
×
123

NEW
124
auto entry::update_param_mode(int par_id, hf::param::fit_mode mode) -> void
×
125
{
NEW
126
    const auto upar_id = int2size_t(par_id);
×
NEW
127
    auto& par = m_d->pars.at(upar_id);
×
128

NEW
129
    par.mode = mode;
×
NEW
130
}
×
131

132
auto entry::get_param(int par_id) const -> hf::param { return param(par_id); }
40✔
133

134
auto get_param_name_index(TF1* fun, const char* name) -> Int_t
4✔
135
{
136
    auto par_index = fun->GetParNumber(name);
4✔
137
    if (par_index == -1) { throw hf::index_error("No such parameter"); }
4✔
138
    return par_index;
3✔
139
}
140

141
auto entry::get_param(const char* name) const -> hf::param
×
142
{
143
    return get_param(get_param_name_index(&m_d->complete_function_object, name));
×
144
}
145

146
auto entry::param(int par_id) const -> const hf::param&
187✔
147
{
148
    const auto upar_id = int2size_t(par_id);
187✔
149
    try
187✔
150
    {
151
        return m_d->pars.at(upar_id);
187✔
152
    }
153
    catch (std::out_of_range& e)
1✔
154
    {
155
        throw hf::index_error(e.what());
1✔
156
    }
1✔
157
}
158

159
auto entry::param(int par_id) -> hf::param&
97✔
160
{
161
    return const_cast<hf::param&>(const_cast<const entry*>(this)->param(par_id));
97✔
162
}
163

164
auto entry::param(const char* name) const -> const hf::param&
4✔
165
{
166
    return param(get_param_name_index(&m_d->complete_function_object, name));
4✔
167
}
168

169
auto entry::param(const char* name) -> hf::param&
3✔
170
{
171
    return const_cast<hf::param&>(const_cast<const entry*>(this)->param(name));
3✔
172
}
173

174
auto entry::set_fit_range(Double_t range_lower, Double_t range_upper) -> void
1✔
175
{
176
    if (range_lower == range_upper) { throw hf::range_error("fitting range cannot be empty"); }
1✔
177

178
    m_d->range_min = range_lower;
1✔
179
    m_d->range_max = range_upper;
1✔
180

181
    m_d->complete_function_object.SetRange(range_lower, range_upper);
1✔
182
    for (auto& f : m_d->funcs)
2✔
183
    {
184
        f.function_obj.SetRange(range_lower, range_upper);
1✔
185
    }
186
}
1✔
187

188
auto entry::get_fit_range_min() const -> Double_t { return m_d->range_min; }
34✔
189

190
auto entry::get_fit_range_max() const -> Double_t { return m_d->range_max; }
34✔
191

192
auto entry::get_functions_count() const -> int { return size_t2int(m_d->funcs.size()); }
32✔
193

194
auto entry::get_function_object(int function_index) const -> const TF1&
69✔
195
{
196
    return m_d->funcs.at(int2size_t(function_index)).function_obj;
138✔
197
}
198

199
auto entry::get_function_object(int function_index) -> TF1&
69✔
200
{
201
    return const_cast<TF1&>(const_cast<const entry*>(this)->get_function_object(function_index));
69✔
202
}
203

204
auto entry::get_function_object() const -> const TF1&
65✔
205
{
206
    if (!m_d->complete_function_object.IsValid()) { m_d->compile(); }
65✔
207
    return m_d->complete_function_object;
65✔
208
}
209

210
auto entry::get_function_object() -> TF1&
9✔
211
{
212
    return const_cast<TF1&>(const_cast<const entry*>(this)->get_function_object());
9✔
213
}
214

215
auto entry::clone_function(int function_index, const char* new_name) -> std::unique_ptr<TF1>
×
216
{
217
    return std::unique_ptr<TF1>(dynamic_cast<TF1*>(get_function_object(function_index).Clone(new_name)));
×
218
}
219

220
auto entry::clone_function(const char* new_name) -> std::unique_ptr<TF1>
×
221
{
222
    return std::unique_ptr<TF1>(dynamic_cast<TF1*>(get_function_object().Clone(new_name)));
×
223
}
224

225
auto entry::get_function_params_count() const -> int { return get_function_object().GetNpar(); }
56✔
226

227
auto entry::get_flag_rebin() const -> int { return m_d->rebin; }
25✔
228

229
auto entry::get_flag_disabled() const -> bool { return m_d->fit_disabled; }
32✔
230

NEW
231
auto entry::set_flag_disabled(bool new_state) -> void { m_d->fit_disabled = new_state; }
×
232

233
auto entry::print(const std::string& name, bool detailed) const -> void
16✔
234
{
235
    fmt::print("## name: {:s}    rebin: {:d}   range: {:g} -- {:g}  param num: {:d}  {:s}\n", name, m_d->rebin,
16✔
236
               m_d->range_min, m_d->range_max, get_function_params_count(), get_flag_disabled() ? "DISABLED" : "");
32✔
237

238
    for (const auto& func : m_d->funcs)
45✔
239
    {
240
        func.print(detailed);
29✔
241
    }
242

243
    auto s = m_d->pars.size();
16✔
244
    for (decltype(s) i = 0; i < s; ++i)
85✔
245
    {
246
        fmt::print("   {}: ", i);
69✔
247
        m_d->pars[i].print();
69✔
248
    }
249

250
    // auto s = m_d->pars.size();
251
    // for (decltype(s) i = 0; i < s; ++i)
252
    // {
253
    //     fmt::print("   {}: ", i);
254
    //     m_d->pars[i].print();
255
    // }
256
    //
257
    // if (detailed)
258
    // {
259
    //     fmt::print("{}\n", "+++++++++ SIG function +++++++++");
260
    //     m_d->function_sig.Print("V");
261
    //     fmt::print("{}\n", "+++++++++ BKG function +++++++++");
262
    //     m_d->function_bkg.Print("V");
263
    //     fmt::print("{}\n", "+++++++++ SUM function +++++++++");
264
    //     m_d->function_sum.Print("V");
265
    //     fmt::print("{}\n", "++++++++++++++++++++++++++++++++");
266
    // } FIXME
267
}
16✔
268

269
auto entry::backup() -> void { m_d->backup(); }
13✔
270

271
auto entry::restore() -> void { m_d->restore(); }
4✔
272

273
auto entry::drop() -> void { m_d->parameters_backup.clear(); }
3✔
274

275
auto entry::set_function_style(int function_index) -> draw_opts&
4✔
276
{
277
    auto res = m_d->partial_functions_styles.insert({function_index, draw_opts()});
8✔
278
    return res.first->second;
4✔
279
}
280

281
auto entry::set_function_style() -> draw_opts& { return set_function_style(-1); }
2✔
282

283
} // namespace hf
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc