Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsCollection.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooAbsCollection.cxx
19\class RooAbsCollection
20\ingroup Roofitcore
21
22RooAbsCollection is an abstract container object that can hold
23multiple RooAbsArg objects. Collections are ordered and can
24contain multiple objects of the same name, (but a derived
25implementation can enforce unique names). The storage of objects is
26implemented using the container denoted by RooAbsCollection::Storage_t.
27**/
28
29#include "RooAbsCollection.h"
30
31#include "TClass.h"
32#include "TRegexp.h"
33#include "RooStreamParser.h"
34#include "RooAbsRealLValue.h"
36#include "RooStringVar.h"
37#include "RooTrace.h"
38#include "RooArgList.h"
39#include "RooLinkedListIter.h"
40#include "RooCmdConfig.h"
41#include "RooRealVar.h"
42#include "RooGlobalFunc.h"
43#include "RooMsgService.h"
44#include <RooHelpers.h>
45
46#include <strlcpy.h>
47#include <algorithm>
48#include <iomanip>
49#include <iostream>
50#include <fstream>
51#include <memory>
52
54
55namespace RooFit {
56namespace Detail {
57
58/**
59 * Helper for hash-map-assisted finding of elements by name.
60 * Create this helper if finding of elements by name is needed.
61 * Upon creation, this object checks the global
62 * RooNameReg::renameCounter()
63 * and tracks elements of this collection by name. If an element
64 * gets renamed, this counter will be increased, and the name to
65 * object map becomes invalid. In this case, it has to be recreated.
66 */
68
69 /// Initialise empty hash map for fast finding by name.
70 template<typename It_t>
71 HashAssistedFind(It_t first, It_t last) :
72 currentRooNameRegCounter{ RooNameReg::instance().renameCounter() },
74 {
75 nameToItemMap.reserve(std::distance(first, last));
76 for (auto it = first; it != last; ++it) {
77 nameToItemMap.emplace((*it)->namePtr(), *it);
78 }
79 }
80
81 bool isValid() const {
83 }
84
85 RooAbsArg * find(const TNamed * nptr) const {
86 assert(isValid());
87
88 auto item = nameToItemMap.find(nptr);
89 return item != nameToItemMap.end() ? const_cast<RooAbsArg *>(item->second) : nullptr;
90 }
91
92 void replace(const RooAbsArg * out, const RooAbsArg * in) {
93 nameToItemMap.erase(out->namePtr());
94 nameToItemMap.emplace(in->namePtr(), in);
95 }
96
97 void insert(const RooAbsArg * elm) {
98 nameToItemMap.emplace(elm->namePtr(), elm);
99 }
100
101 void erase(const RooAbsArg * elm) {
102 nameToItemMap.erase(elm->namePtr());
103 }
104
105 std::unordered_map<const TNamed *, const RooAbsArg * const> nameToItemMap;
106 const std::size_t & currentRooNameRegCounter;
108};
109
110}
111}
112
113
114////////////////////////////////////////////////////////////////////////////////
115/// Default constructor
116
118{
119 _list.reserve(8);
120}
121
122
123
124////////////////////////////////////////////////////////////////////////////////
125/// Empty collection constructor
126
128 _name(name)
130 _list.reserve(8);
131}
132
133
134
135////////////////////////////////////////////////////////////////////////////////
136/// Copy constructor. Note that a copy of a collection is always non-owning,
137/// even the source collection is owning. To create an owning copy of
138/// a collection (owning or not), use the snapshot() method.
139
141 TObject(other),
142 RooPrintable(other),
143 _name(name),
144 _allRRV(other._allRRV),
145 _sizeThresholdForMapSearch(100)
146{
147 RooTrace::create(this) ;
148 if (!name) setName(other.GetName()) ;
149
150 _list.reserve(other._list.size());
152 for (auto item : other._list) {
153 insert(item);
154 }
155}
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Move constructor.
160
162 TObject(other),
163 RooPrintable(other),
164 _list(std::move(other._list)),
165 _ownCont(other._ownCont),
166 _name(std::move(other._name)),
167 _allRRV(other._allRRV),
168 _sizeThresholdForMapSearch(other._sizeThresholdForMapSearch)
169{
170}
171
172
173////////////////////////////////////////////////////////////////////////////////
174/// Destructor
175
177{
178 // Delete all variables in our list if we own them
179 if(_ownCont){
180 deleteList() ;
181 }
182}
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Delete contents of the list.
187/// The RooAbsArg destructor ensures clients and servers can be deleted in any
188/// order.
189/// Also cleans the hash-map for fast lookups if present.
190
192{
193 _hashAssistedFind = nullptr;
194
195 // Built-in delete remaining elements
196 for (auto item : _list) {
197 delete item;
198 }
199 _list.clear();
200}
201
202
203
204////////////////////////////////////////////////////////////////////////////////
205/// Take a snap shot of current collection contents.
206/// An owning collection is returned containing clones of
207/// - Elements in this collection
208/// - External dependents of all elements and recursively any dependents of those dependents
209/// (if deepCopy flag is set)
210///
211/// This is useful to save the values of variables or parameters. It doesn't require
212/// deep copying if the parameters are direct members of the collection.
213///
214/// If deepCopy is specified, the client-server links between the cloned
215/// list elements and the cloned external dependents are reconnected to
216/// each other, making the snapshot a completely self-contained entity.
217///
218///
219
221{
222 // First create empty list
223 TString snapName ;
224 if (TString(GetName()).Length()>0) {
225 snapName.Append("Snapshot of ") ;
226 snapName.Append(GetName()) ;
227 }
228 auto* output = static_cast<RooAbsCollection*>(create(snapName.Data())) ;
229
230 if (snapshot(*output,deepCopy)) {
231 delete output ;
232 return nullptr ;
233 }
234
235 return output ;
236}
237
238
239
240////////////////////////////////////////////////////////////////////////////////
241/// Take a snap shot of current collection contents:
242/// A collection that owns its elements is returned containing clones of
243/// - Elements in this collection
244/// - External dependents of those elements
245/// and recursively any dependents of those dependents
246/// (if deepCopy flag is set)
247///
248/// If deepCopy is specified, the client-server links between the cloned
249/// list elements and the cloned external dependents are reconnected to
250/// each other, making the snapshot a completely self-contained entity.
251///
252///
253
255{
256 return RooHelpers::Detail::snapshotImpl(*this, output, deepCopy, nullptr);
257}
258
259
260////////////////////////////////////////////////////////////////////////////////
261/// Assign values from the elements in `other` to our elements.
262/// \warning This is not a conventional assignment operator. To avoid confusion, prefer using RooAbsCollection::assign().
263
265{
266 assign(other);
267 return *this;
268}
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Sets the value, cache and constant attribute of any argument in our set
273/// that also appears in the other set. Note that this function changes the
274/// values of the elements in this collection, but is still marked `const` as
275/// it does not change which elements this collection points to.
276
278{
279 if (&other==this) return ;
280
281 for (auto elem : _list) {
282 auto theirs = other.find(*elem);
283 if(!theirs) continue;
284 theirs->syncCache() ;
285 elem->copyCache(theirs) ;
286 elem->setAttribute("Constant",theirs->isConstant()) ;
287 }
288 return ;
289}
290
291
292////////////////////////////////////////////////////////////////////////////////
293/// Sets the value of any argument in our set that also appears in the other set.
294/// \param[in] other Collection holding the arguments to synchronize values with.
295/// \param[in] forceIfSizeOne If set to true and both our collection
296/// and the other collection have a size of one, the arguments are
297/// always synchronized without checking if they have the same name.
298
300{
301 if (&other==this) return *this;
302
303 // Short cut for 1 element assignment
304 if (size()==1 && size() == other.size() && forceIfSizeOne) {
305 other.first()->syncCache() ;
306 first()->copyCache(other.first(),true) ;
307 return *this;
308 }
309
310 for (auto elem : _list) {
311 auto theirs = other.find(*elem);
312 if(!theirs) continue;
313 theirs->syncCache() ;
314 elem->copyCache(theirs,true) ;
315 }
316 return *this;
317}
318
319
320
321////////////////////////////////////////////////////////////////////////////////
322/// Functional equivalent of assign() but assumes this and other collection
323/// have same layout. Also no attributes are copied
324
325void RooAbsCollection::assignFast(const RooAbsCollection& other, bool setValDirty) const
326{
327 if (&other==this) return ;
328 assert(hasSameLayout(other));
329
330 auto iter2 = other._list.begin();
331 for (auto iter1 = _list.begin();
332 iter1 != _list.end() && iter2 != other._list.end();
333 ++iter1, ++iter2) {
334 // Identical size of iterators is documented assumption of method
335
336 if (_allRRV) {
337 // All contents are known to be RooRealVars - fast version of assignment
338 auto ours = static_cast<RooRealVar*>(*iter1);
339 auto theirs = static_cast<RooRealVar*>(*iter2);
340 ours->copyCacheFast(*theirs,setValDirty);
341 } else {
342 (*iter2)->syncCache() ;
343 (*iter1)->copyCache(*iter2,true,setValDirty) ;
344 }
345 }
346
347}
348
349
350////////////////////////////////////////////////////////////////////////////////
351/// Add an argument and transfer the ownership to the collection. Returns `true`
352/// if successful, or `false` if the argument could not be added to the
353/// collection (e.g. in the RooArgSet case when an argument with the same name
354/// is already in the list). This method can only be called on a list that is
355/// flagged as owning all of its contents, or else on an empty list (which will
356/// force the list into that mode).
357///
358/// If the argument you want to add is owned by a `std::unique_ptr`, you should
359/// prefer RooAbsCollection::addOwned(std::unique_ptr<RooAbsArg>, bool).
360
362{
363 if(!canBeAdded(var, silent)) return false;
364
365 // check that we own our variables or else are empty
366 if(!_ownCont && !empty() && !silent) {
367 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addOwned: can only add to an owned list" << std::endl;
368 return false;
369 }
370 _ownCont= true;
371
372 insert(&var);
373
374 return true;
375}
376
377
378////////////////////////////////////////////////////////////////////////////////
379/// Add an argument and transfer the ownership to the collection from a
380/// `std::unique_ptr`. Always returns `true`. If the argument can not be added
381/// to the collection (e.g. in the RooArgSet case when an argument with the
382/// same name is already in the list), a `std::runtime_exception` will be
383/// thrown, as nobody is owning the argument anymore. This method can only be
384/// called on a list that is flagged as owning all of its contents, or else on
385/// an empty list (which will force the list into that mode).
386///
387/// If you want to pass an argument that is not owned by a `std::unique_ptr`,
388/// you can use RooAbsCollection::addOwned(RooAbsArg&, bool).
389
390bool RooAbsCollection::addOwned(std::unique_ptr<RooAbsArg> var, bool silent) {
391 bool result = addOwned(*var.release(), silent);
392 if(!result) {
393 throw std::runtime_error(std::string("RooAbsCollection::addOwned could not add the argument to the")
394 + " collection! The ownership would not be well defined if we ignore this.");
395 }
396 return result;
397}
398
399
400
401////////////////////////////////////////////////////////////////////////////////
402/// Add a clone of the specified argument to list. Returns a pointer to
403/// the clone if successful, or else zero if a variable of the same name
404/// is already in the list or the list does *not* own its variables (in
405/// this case, try add() instead.) Calling addClone() on an empty list
406/// forces it to take ownership of all its subsequent variables.
407
409{
410 if(!canBeAdded(var, silent)) return nullptr;
411
412 // check that we own our variables or else are empty
413 if(!_ownCont && !empty() && !silent) {
414 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addClone: can only add to an owned list" << std::endl;
415 return nullptr;
416 }
417 _ownCont= true;
418
419 // add a pointer to a clone of this variable to our list (we now own it!)
420 auto clone2 = static_cast<RooAbsArg*>(var.Clone());
421 assert(clone2);
422
423 insert(clone2);
424
425 return clone2;
426}
427
428
429
430////////////////////////////////////////////////////////////////////////////////
431/// Add the specified argument to list. Returns true if successful, or
432/// else false if a variable of the same name is already in the list
433/// or the list owns its variables (in this case, try addClone() or addOwned() instead).
434
435bool RooAbsCollection::add(const RooAbsArg& var, bool silent)
436{
437 if(!canBeAdded(var, silent)) return false;
438
439 // check that this isn't a copy of a list
440 if(_ownCont && !silent) {
441 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::add: cannot add to an owned list" << std::endl;
442 return false;
443 }
444
445 // add a pointer to this variable to our list (we don't own it!)
446 insert(const_cast<RooAbsArg*>(&var)); //FIXME const_cast
447
448 return true;
449}
450
451
452////////////////////////////////////////////////////////////////////////////////
453// Add a collection of arguments to this collection by calling addOwned()
454/// for each element in the source collection. The input list can't be an
455/// owning collection itself, otherwise the arguments would be owned by two
456/// collections.
457///
458/// If you want to transfer arguments from one owning collection to another,
459/// you have two options:
460/// 1. `std::move` the input collection and use
461/// RooAbsCollection::addOwned(RooAbsCollection&&, bool) (preferred)
462/// 2. release the ownership of the input collection first, using
463/// RooAbsCollection::releaseOwnership()
464
465bool RooAbsCollection::addOwned(const RooAbsCollection& list, bool silent)
466{
467 if(list.isOwning()) {
468 throw std::invalid_argument("Passing an owning RooAbsCollection by const& to"
469 " RooAbsCollection::addOwned is forbidden because the ownership"
470 " would be ambiguous! Please std::move() the RooAbsCollection in this case."
471 " Note that the passed RooAbsCollection is invalid afterwards.");
472
473 }
474
475 bool result(false) ;
476 _list.reserve(_list.size() + list._list.size());
477
478 for (auto item : list._list) {
479 result |= addOwned(*item, silent) ;
480 }
481
482 return result;
483}
484
485
486////////////////////////////////////////////////////////////////////////////////
487/// Add a collection of arguments to this collection by calling addOwned()
488/// for each element in the source collection. Unlike
489/// RooAbsCollection::addOwned(const RooAbsCollection&, bool), this function
490/// also accepts owning source collections because their content will be
491/// moved out.
492
494{
495 if(list.isOwning()) {
496 list.releaseOwnership();
497 }
498 if(list.empty()) return false;
499
500 bool result = addOwned(list, silent);
501
502 if(!result) {
503 throw std::runtime_error(std::string("RooAbsCollection::addOwned could not add the argument to the")
504 + " collection! The ownership would not be well defined if we ignore this.");
505 }
506
507 // So far, comps has only released the ownership, but it is still valid.
508 // However, we don't want users to keep using objects after moving them, so
509 // we make sure to keep our promise that the RooArgSet is really moved.
510 // Just like a `std::unique_ptr` is also reset when moved.
511 list.clear();
512
513 return result;
514}
515
516
517////////////////////////////////////////////////////////////////////////////////
518/// Add a collection of arguments to this collection by calling addOwned()
519/// for each element in the source collection
520
521void RooAbsCollection::addClone(const RooAbsCollection& list, bool silent)
522{
523 _list.reserve(_list.size() + list._list.size());
524
525 for (auto item : list._list) {
526 addClone(*item, silent);
527 }
528}
529
530
531
532////////////////////////////////////////////////////////////////////////////////
533/// Replace any args in our set with args of the same name from the other set
534/// and return true for success. Fails if this list is a copy of another.
535
537{
538 // check that this isn't a copy of a list
539 if(_ownCont) {
540 coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << std::endl;
541 return false;
542 }
543
544 // loop over elements in the other list
545 for (const auto * arg : other._list) {
546 // do we have an arg of the same name in our set?
547 auto found = find(*arg);
548 if (found) replace(*found,*arg);
549 }
550 return true;
551}
552
553
554
555////////////////////////////////////////////////////////////////////////////////
556/// Replace var1 with var2 and return true for success. Fails if
557/// this list is a copy of another, if var1 is not already in this set,
558/// or if var2 is already in this set. var1 and var2 do not need to have
559/// the same name.
560
561bool RooAbsCollection::replace(const RooAbsArg& var1, const RooAbsArg& var2)
562{
563 // check that this isn't a copy of a list
564 if(_ownCont) {
565 coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << std::endl;
566 return false;
567 }
568
569 // is var1 already in this list?
570 const char *name= var1.GetName();
571 auto var1It = std::find(_list.begin(), _list.end(), &var1);
572
573 if (var1It == _list.end()) {
574 coutE(ObjectHandling) << "RooAbsCollection: variable \"" << name << "\" is not in the list"
575 << " and cannot be replaced" << std::endl;
576 return false;
577 }
578
579
580 // is var2's name already in this list?
581 if (dynamic_cast<RooArgSet*>(this)) {
582 RooAbsArg *other = find(var2);
583 if(other != nullptr && other != &var1) {
584 coutE(ObjectHandling) << "RooAbsCollection: cannot replace \"" << name
585 << "\" with already existing \"" << var2.GetName() << "\"" << std::endl;
586 return false;
587 }
588 }
589
590 // replace var1 with var2
591 if (_hashAssistedFind) {
592 _hashAssistedFind->replace(*var1It, &var2);
593 }
594 *var1It = const_cast<RooAbsArg*>(&var2); //FIXME try to get rid of const_cast
595
596 if (_allRRV && dynamic_cast<const RooRealVar*>(&var2)==nullptr) {
597 _allRRV=false ;
598 }
599
600 return true;
601}
602
603
604
605////////////////////////////////////////////////////////////////////////////////
606/// Remove the specified argument from our list. Return false if
607/// the specified argument is not found in our list. An exact pointer
608/// match is required, not just a match by name.
609/// If `matchByNameOnly` is set, items will be looked up by name. In this case, if
610/// the collection also owns the item, it will delete it.
611bool RooAbsCollection::remove(const RooAbsArg& var, bool , bool matchByNameOnly)
612{
613 // is var already in this list?
614 const auto sizeBefore = _list.size();
615
616 if (matchByNameOnly) {
617 const std::string name(var.GetName());
618 auto nameMatch = [&name](const RooAbsArg* elm) {
619 return elm->GetName() == name;
620 };
621 std::set<RooAbsArg*> toBeDeleted;
622
623 if (_ownCont) {
624 std::for_each(_list.begin(), _list.end(), [&toBeDeleted, nameMatch](RooAbsArg* elm){
625 if (nameMatch(elm)) {
626 toBeDeleted.insert(elm);
627 }
628 });
629 }
630
631 _list.erase(std::remove_if(_list.begin(), _list.end(), nameMatch), _list.end());
632
633 for (auto arg : toBeDeleted)
634 delete arg;
635 } else {
636 _list.erase(std::remove(_list.begin(), _list.end(), &var), _list.end());
637 }
638
639 if (_hashAssistedFind && sizeBefore != _list.size()) {
640 _hashAssistedFind->erase(&var);
641 }
642
643 return sizeBefore != _list.size();
644}
645
646
647
648////////////////////////////////////////////////////////////////////////////////
649/// Remove each argument in the input list from our list.
650/// An exact pointer match is required, not just a match by name.
651/// If `matchByNameOnly` is set, items will be looked up by name. In this case, if
652/// the collection also owns the items, it will delete them.
653/// Return false in case of problems.
654
655bool RooAbsCollection::remove(const RooAbsCollection& list, bool /*silent*/, bool matchByNameOnly)
656{
657
658 auto oldSize = _list.size();
659 std::vector<const RooAbsArg*> markedItems;
660
661 if (matchByNameOnly) {
662
663 // Instead of doing two passes on the list as in remove(RooAbsArg&), we do
664 // everything in one pass, by using side effects of the predicate.
665 auto nameMatchAndMark = [&list, &markedItems](const RooAbsArg* elm) {
666 if( list.contains(*elm) ) {
667 markedItems.push_back(elm);
668 return true;
669 }
670 return false;
671 };
672
673 _list.erase(std::remove_if(_list.begin(), _list.end(), nameMatchAndMark), _list.end());
674
675 }
676 else {
677 auto argMatchAndMark = [&list, &markedItems](const RooAbsArg* elm) {
678 if( list.containsInstance(*elm) ) {
679 markedItems.push_back(elm);
680 return true;
681 }
682 return false;
683 };
684
685 _list.erase(std::remove_if(_list.begin(), _list.end(), argMatchAndMark), _list.end());
686 }
687
688 if (_hashAssistedFind && oldSize != _list.size()) {
689 for( auto& var : markedItems ) {
690 _hashAssistedFind->erase(var);
691 }
692 }
693
694 if (matchByNameOnly && _ownCont) {
695 std::set<const RooAbsArg*> toBeDeleted(markedItems.begin(), markedItems.end());
696 for (auto arg : toBeDeleted) {
697 delete arg;
698 }
699 }
700
701 return oldSize != _list.size();
702}
703
704
705
706////////////////////////////////////////////////////////////////////////////////
707/// Remove all arguments from our set, deleting them if we own them.
708/// This effectively restores our object to the state it would have
709/// just after calling the RooAbsCollection(const char*) constructor.
710
712{
713 _hashAssistedFind = nullptr;
714
715 if(_ownCont) {
716 deleteList() ;
717 _ownCont= false;
718 }
719 else {
720 _list.clear();
721 }
722}
723
724
725
726////////////////////////////////////////////////////////////////////////////////
727/// Set given attribute in each element of the collection by
728/// calling each elements setAttribute() function.
729
731{
732 for (auto arg : _list) {
733 arg->setAttribute(name, value);
734 }
735}
736
737
738
739
740////////////////////////////////////////////////////////////////////////////////
741/// Create a subset of the current collection, consisting only of those
742/// elements with the specified attribute set. The caller is responsible
743/// for deleting the returned collection
744
746{
747 TString selName(GetName()) ;
748 selName.Append("_selection") ;
750
751 // Scan set contents for matching attribute
752 for (auto arg : _list) {
753 if (arg->getAttribute(name)==value)
754 sel->add(*arg) ;
755 }
756
757 return sel ;
758}
759
760
761////////////////////////////////////////////////////////////////////////////////
762/// Create a subset of the current collection, consisting only of those
763/// elements that are contained as well in the given reference collection.
764/// Returns `true` only if something went wrong.
765/// The complement of this function is getParameters().
766/// \param[in] refColl The collection to check for common elements.
767/// \param[out] outColl Output collection.
768
770{
771 outColl.clear();
772 outColl.setName((std::string(GetName()) + "_selection").c_str());
773
774 // Scan set contents for matching attribute
775 for (auto arg : _list) {
776 if (refColl.find(*arg))
777 outColl.add(*arg) ;
778 }
779
780 return false;
781}
782
783
784////////////////////////////////////////////////////////////////////////////////
785/// Create a subset of the current collection, consisting only of those
786/// elements that are contained as well in the given reference collection.
787/// The caller is responsible for deleting the returned collection
788
790{
791 auto sel = static_cast<RooAbsCollection*>(create("")) ;
792 selectCommon(refColl, *sel);
793 return sel ;
794}
795
796
797////////////////////////////////////////////////////////////////////////////////
798/// Create a subset of the current collection, consisting only of those
799/// elements with names matching the wildcard expressions in nameList,
800/// supplied as a comma separated list
801
802RooAbsCollection* RooAbsCollection::selectByName(const char* nameList, bool verbose) const
803{
804 // Create output set
805 TString selName(GetName()) ;
806 selName.Append("_selection") ;
808
809 const size_t bufSize = strlen(nameList) + 1;
810 std::vector<char> buf(bufSize);
811 strlcpy(buf.data(),nameList,bufSize) ;
812 char* wcExpr = strtok(buf.data(),",") ;
813 while(wcExpr) {
814 TRegexp rexp(wcExpr,true) ;
815 if (verbose) {
816 cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") processing expression '" << wcExpr << "'" << std::endl;
817 }
818
819 for (auto const* arg : *this) {
820 if (TString(arg->GetName()).Index(rexp)>=0) {
821 if (verbose) {
822 cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") selected element " << arg->GetName() << std::endl;
823 }
824 sel->add(*arg) ;
825 }
826 }
827 wcExpr = strtok(nullptr,",") ;
828 }
829
830 return sel ;
831}
832
833
834
835
836////////////////////////////////////////////////////////////////////////////////
837/// Check if this and other collection have identically-named contents
838
839bool RooAbsCollection::equals(const RooAbsCollection& otherColl) const
840{
841 // First check equal length
842 if (size() != otherColl.size()) return false ;
843
844 // Then check that each element of our list also occurs in the other list
845 auto compareByNamePtr = [](const RooAbsArg * left, const RooAbsArg * right) {
846 return left->namePtr() == right->namePtr();
847 };
848
849 return std::is_permutation(_list.begin(), _list.end(),
850 otherColl._list.begin(),
851 compareByNamePtr);
852}
853
854
855namespace {
856////////////////////////////////////////////////////////////////////////////////
857/// Linear search through list of stored objects.
858template<class Collection_t>
859RooAbsArg* findUsingNamePointer(const Collection_t& coll, const TNamed* ptr) {
860 auto findByNamePtr = [ptr](const RooAbsArg* elm) {
861 return ptr == elm->namePtr();
862 };
863
864 auto item = std::find_if(coll.begin(), coll.end(), findByNamePtr);
865
866 return item != coll.end() ? *item : nullptr;
867}
868}
869
870
871////////////////////////////////////////////////////////////////////////////////
872/// Find object with given name in list. A null pointer
873/// is returned if no object with the given name is found.
875{
876 if (!name)
877 return nullptr;
878
879 // If an object with such a name exists, its name has been registered.
880 const TNamed* nptr = RooNameReg::known(name);
881 if (!nptr) return nullptr;
882
884 if (!_hashAssistedFind || !_hashAssistedFind->isValid()) {
885 _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
886 }
887
888 return _hashAssistedFind->find(nptr);
889 }
890
891 return findUsingNamePointer(_list, nptr);
892}
893
894
895
896////////////////////////////////////////////////////////////////////////////////
897/// Find object with given name in list. A null pointer
898/// is returned if no object with the given name is found.
900{
901 const auto nptr = arg.namePtr();
902
904 if (!_hashAssistedFind || !_hashAssistedFind->isValid()) {
905 _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
906 }
907
908 return _hashAssistedFind->find(nptr);
909 }
910
911 return findUsingNamePointer(_list, nptr);
912}
913
914
915////////////////////////////////////////////////////////////////////////////////
916/// Return index of item with given name, or -1 in case it's not in the collection.
918 const std::string theName(name);
919 auto item = std::find_if(_list.begin(), _list.end(), [&theName](const RooAbsArg * elm){
920 return elm->GetName() == theName;
921 });
922 return item != _list.end() ? item - _list.begin() : -1;
923}
924
925
926////////////////////////////////////////////////////////////////////////////////
927/// Get value of a RooAbsReal stored in set with given name. If none is found, value of defVal is returned.
928/// No error messages are printed unless the verbose flag is set
929
930double RooAbsCollection::getRealValue(const char* name, double defVal, bool verbose) const
931{
932 RooAbsArg* raa = find(name) ;
933 if (!raa) {
934 if (verbose) coutE(InputArguments) << "RooAbsCollection::getRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
935 return defVal ;
936 }
937 RooAbsReal* rar = dynamic_cast<RooAbsReal*>(raa) ;
938 if (!rar) {
939 if (verbose) coutE(InputArguments) << "RooAbsCollection::getRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsReal" << std::endl;
940 return defVal ;
941 }
942 return rar->getVal() ;
943}
944
945
946
947////////////////////////////////////////////////////////////////////////////////
948/// Set value of a RooAbsRealLValue stored in set with given name to newVal
949/// No error messages are printed unless the verbose flag is set
950
951bool RooAbsCollection::setRealValue(const char* name, double newVal, bool verbose)
952{
953 RooAbsArg* raa = find(name) ;
954 if (!raa) {
955 if (verbose) coutE(InputArguments) << "RooAbsCollection::setRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
956 return true ;
957 }
958 auto* rar = dynamic_cast<RooAbsRealLValue*>(raa) ;
959 if (!rar) {
960 if (verbose) coutE(InputArguments) << "RooAbsCollection::setRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsRealLValue" << std::endl;
961 return true;
962 }
963 rar->setVal(newVal) ;
964 return false ;
965}
966
967
968
969////////////////////////////////////////////////////////////////////////////////
970/// Get state name of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
971/// No error messages are printed unless the verbose flag is set
972
973const char* RooAbsCollection::getCatLabel(const char* name, const char* defVal, bool verbose) const
974{
975 RooAbsArg* raa = find(name) ;
976 if (!raa) {
977 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
978 return defVal ;
979 }
980 auto* rac = dynamic_cast<RooAbsCategory*>(raa) ;
981 if (!rac) {
982 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << std::endl;
983 return defVal ;
984 }
985 return rac->getCurrentLabel() ;
986}
987
988
989
990////////////////////////////////////////////////////////////////////////////////
991/// Set state name of a RooAbsCategoryLValue stored in set with given name to newVal.
992/// No error messages are printed unless the verbose flag is set
993
994bool RooAbsCollection::setCatLabel(const char* name, const char* newVal, bool verbose)
995{
996 RooAbsArg* raa = find(name) ;
997 if (!raa) {
998 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
999 return true ;
1000 }
1001 auto* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
1002 if (!rac) {
1003 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << std::endl;
1004 return true ;
1005 }
1006 rac->setLabel(newVal) ;
1007 return false ;
1008}
1009
1010
1011
1012////////////////////////////////////////////////////////////////////////////////
1013/// Get index value of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
1014/// No error messages are printed unless the verbose flag is set
1015
1016Int_t RooAbsCollection::getCatIndex(const char* name, Int_t defVal, bool verbose) const
1017{
1018 RooAbsArg* raa = find(name) ;
1019 if (!raa) {
1020 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
1021 return defVal ;
1022 }
1023 auto* rac = dynamic_cast<RooAbsCategory*>(raa) ;
1024 if (!rac) {
1025 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << std::endl;
1026 return defVal ;
1027 }
1028 return rac->getCurrentIndex() ;
1029}
1030
1031
1032
1033////////////////////////////////////////////////////////////////////////////////
1034/// Set index value of a RooAbsCategoryLValue stored in set with given name to newVal.
1035/// No error messages are printed unless the verbose flag is set
1036
1037bool RooAbsCollection::setCatIndex(const char* name, Int_t newVal, bool verbose)
1038{
1039 RooAbsArg* raa = find(name) ;
1040 if (!raa) {
1041 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
1042 return true ;
1043 }
1044 auto* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
1045 if (!rac) {
1046 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << std::endl;
1047 return true ;
1048 }
1049 rac->setIndex(newVal) ;
1050 return false ;
1051}
1052
1053
1054
1055////////////////////////////////////////////////////////////////////////////////
1056/// Get string value of a RooStringVar stored in set with given name. If none is found, value of defVal is returned.
1057/// No error messages are printed unless the verbose flag is set
1058
1059const char* RooAbsCollection::getStringValue(const char* name, const char* defVal, bool verbose) const
1060{
1061 RooAbsArg* raa = find(name) ;
1062 if (!raa) {
1063 if (verbose) coutE(InputArguments) << "RooAbsCollection::getStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
1064 return defVal ;
1065 }
1066 auto ras = dynamic_cast<const RooStringVar*>(raa) ;
1067 if (!ras) {
1068 if (verbose) coutE(InputArguments) << "RooAbsCollection::getStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooStringVar" << std::endl;
1069 return defVal ;
1070 }
1071
1072 return ras->getVal() ;
1073}
1074
1075
1076
1077////////////////////////////////////////////////////////////////////////////////
1078/// Set string value of a RooStringVar stored in set with given name to newVal.
1079/// No error messages are printed unless the verbose flag is set
1080
1081bool RooAbsCollection::setStringValue(const char* name, const char* newVal, bool verbose)
1082{
1083 RooAbsArg* raa = find(name) ;
1084 if (!raa) {
1085 if (verbose) coutE(InputArguments) << "RooAbsCollection::setStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << std::endl;
1086 return true ;
1087 }
1088 auto ras = dynamic_cast<RooStringVar*>(raa);
1089 if (!ras) {
1090 if (verbose) coutE(InputArguments) << "RooAbsCollection::setStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooStringVar" << std::endl;
1091 return true ;
1092 }
1093 ras->setVal(newVal);
1094
1095 return false;
1096}
1097
1098////////////////////////////////////////////////////////////////////////////////
1099/// Return comma separated list of contained object names as STL string
1101{
1102 std::string retVal ;
1103 for (auto arg : _list) {
1104 retVal += arg->GetName();
1105 retVal += ",";
1106 }
1107
1108 retVal.erase(retVal.end()-1);
1109
1110 return retVal;
1111}
1112
1113
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Return collection name
1117
1118void RooAbsCollection::printName(std::ostream& os) const
1119{
1120 os << GetName() ;
1121}
1122
1123
1124
1125////////////////////////////////////////////////////////////////////////////////
1126/// Return collection title
1127
1128void RooAbsCollection::printTitle(std::ostream& os) const
1129{
1130 os << GetTitle() ;
1131}
1132
1133
1134
1135////////////////////////////////////////////////////////////////////////////////
1136/// Return collection class name
1137
1138void RooAbsCollection::printClassName(std::ostream& os) const
1139{
1140 os << ClassName() ;
1141}
1142
1143
1144
1145////////////////////////////////////////////////////////////////////////////////
1146/// Define default RooPrinable print options for given Print() flag string
1147/// For inline printing only show value of objects, for default print show
1148/// name,class name value and extras of each object. In verbose mode
1149/// also add object address, argument and title
1150
1152{
1153 if (opt && TString(opt)=="I") {
1154 return kValue ;
1155 }
1156 if (opt && TString(opt).Contains("v")) {
1158 }
1159 return kName|kClassName|kValue ;
1160}
1161
1162
1163
1164
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// Print value of collection, i.e. a comma separated list of contained
1168/// object names
1169
1170void RooAbsCollection::printValue(std::ostream& os) const
1171{
1172 bool first2(true) ;
1173 os << "(" ;
1174 for (auto arg : _list) {
1175 if (!first2) {
1176 os << "," ;
1177 } else {
1178 first2 = false ;
1179 }
1180 if (arg->IsA()->InheritsFrom(RooStringVar::Class())) {
1181 os << '\'' << ((RooStringVar *)arg)->getVal() << '\'';
1182 } else {
1183 os << arg->GetName();
1184 }
1185 }
1186 os << ")" ;
1187}
1188
1189
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// Implement multiline printing of collection, one line for each contained object showing
1193/// the requested content
1194
1195void RooAbsCollection::printMultiline(std::ostream&os, Int_t contents, bool /*verbose*/, TString indent) const
1196{
1197 if (TString(GetName()).Length()>0 && (contents&kCollectionHeader)) {
1198 os << indent << ClassName() << "::" << GetName() << ":" << (_ownCont?" (Owning contents)":"") << std::endl;
1199 }
1200
1201 TString deeper(indent);
1202 deeper.Append(" ");
1203
1204 // Adjust the width of the name field to fit the largest name, if requested
1205 Int_t maxNameLen(1) ;
1206 Int_t nameFieldLengthSaved = RooPrintable::_nameLength ;
1207 if (nameFieldLengthSaved==0) {
1208 for (auto next : _list) {
1209 Int_t len = strlen(next->GetName()) ;
1210 if (len>maxNameLen) maxNameLen = len ;
1211 }
1212 RooPrintable::nameFieldLength(maxNameLen+1) ;
1213 }
1214
1215 unsigned int idx = 0;
1216 for (auto next : _list) {
1217 os << indent << std::setw(3) << ++idx << ") ";
1218 next->printStream(os,contents,kSingleLine,"");
1219 }
1220
1221 // Reset name field length, if modified
1222 RooPrintable::nameFieldLength(nameFieldLengthSaved) ;
1223}
1224
1225
1226
1227////////////////////////////////////////////////////////////////////////////////
1228/// Base contents dumper for debugging purposes
1229
1231{
1232 for (auto arg : _list) {
1233 std::cout << arg << " " << arg->ClassName() << "::" << arg->GetName() << " (" << arg->GetTitle() << ")" << std::endl ;
1234 }
1235}
1236
1237
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Output content of collection as LaTex table. By default a table with two columns is created: the left
1241/// column contains the name of each variable, the right column the value.
1242///
1243/// The following optional named arguments can be used to modify the default behavior
1244/// <table>
1245/// <tr><th> Argument <th> Effect
1246/// <tr><td> `Columns(Int_t ncol)` <td> Fold table into multiple columns, i.e. ncol=3 will result in 3 x 2 = 6 total columns
1247/// <tr><td> `Sibling(const RooAbsCollection& other)` <td> Define sibling list.
1248/// The sibling list is assumed to have objects with the same
1249/// name in the same order. If this is not the case warnings will be printed. If a single
1250/// sibling list is specified, 3 columns will be output: the (common) name, the value of this
1251/// list and the value in the sibling list. Multiple sibling lists can be specified by
1252/// repeating the Sibling() command.
1253/// <tr><td> `Format(const char* str)` <td> Classic format string, provided for backward compatibility
1254/// <tr><td> `Format()` <td> Formatting arguments.
1255/// <table>
1256/// <tr><td> const char* what <td> Controls what is shown. "N" adds name, "E" adds error,
1257/// "A" shows asymmetric error, "U" shows unit, "H" hides the value
1258/// <tr><td> `FixedPrecision(int n)` <td> Controls precision, set fixed number of digits
1259/// <tr><td> `AutoPrecision(int n)` <td> Controls precision. Number of shown digits is calculated from error
1260/// and n specified additional digits (1 is sensible default)
1261/// <tr><td> `VerbatimName(bool flag)` <td> Put variable name in a \\verb+ + clause.
1262/// </table>
1263/// <tr><td> `OutputFile(const char* fname)` <td> Send output to file with given name rather than standard output
1264///
1265/// </table>
1266///
1267/// Example use:
1268/// ```
1269/// list.printLatex(Columns(2), Format("NEU",AutoPrecision(1),VerbatimName()) );
1270/// ```
1271
1273 const RooCmdArg& arg3, const RooCmdArg& arg4,
1274 const RooCmdArg& arg5, const RooCmdArg& arg6,
1275 const RooCmdArg& arg7, const RooCmdArg& arg8) const
1276{
1277
1278
1279 // Define configuration for this method
1280 RooCmdConfig pc("RooAbsCollection::printLatex()") ;
1281 pc.defineInt("ncol","Columns",0,1) ;
1282 pc.defineString("outputFile","OutputFile",0,"") ;
1283 pc.defineString("format","Format",0,"NEYVU") ;
1284 pc.defineInt("sigDigit","Format",0,1) ;
1285 pc.defineObject("siblings","Sibling",0,nullptr,true) ;
1286 pc.defineInt("dummy","FormatArgs",0,0) ;
1287 pc.defineMutex("Format","FormatArgs") ;
1288
1289 // Stuff all arguments in a list
1290 RooLinkedList cmdList;
1291 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
1292 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
1293 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
1294 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
1295
1296 // Process & check varargs
1297 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1298 if (!pc.ok(true)) {
1299 return ;
1300 }
1301
1302 const char* outFile = pc.getString("outputFile") ;
1303 if (outFile && strlen(outFile)) {
1304 std::ofstream ofs(outFile) ;
1305 if (pc.hasProcessed("FormatArgs")) {
1306 auto* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
1307 formatCmd->addArg(RooFit::LatexTableStyle()) ;
1308 printLatex(ofs,pc.getInt("ncol"),nullptr,0,pc.getObjectList("siblings"),formatCmd) ;
1309 } else {
1310 printLatex(ofs,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
1311 }
1312 } else {
1313 if (pc.hasProcessed("FormatArgs")) {
1314 auto* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
1315 formatCmd->addArg(RooFit::LatexTableStyle()) ;
1316 printLatex(std::cout,pc.getInt("ncol"),nullptr,0,pc.getObjectList("siblings"),formatCmd) ;
1317 } else {
1318 printLatex(std::cout,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
1319 }
1320 }
1321}
1322
1323
1324
1325
1326////////////////////////////////////////////////////////////////////////////////
1327/// Internal implementation function of printLatex
1328
1329void RooAbsCollection::printLatex(std::ostream& ofs, Int_t ncol, const char* option, Int_t sigDigit, const RooLinkedList& siblingList, const RooCmdArg* formatCmd) const
1330{
1331 // Count number of rows to print
1332 Int_t nrow = (Int_t) (getSize() / ncol + 0.99) ;
1333 Int_t i,j,k ;
1334
1335 // Sibling list do not need to print their name as it is supposed to be the same
1336 TString sibOption ;
1337 RooCmdArg sibFormatCmd ;
1338 if (option) {
1339 sibOption = option ;
1340 sibOption.ReplaceAll("N","") ;
1341 sibOption.ReplaceAll("n","") ;
1342 } else {
1343 sibFormatCmd = *formatCmd ;
1344 TString tmp = formatCmd->getString(0) ;
1345 tmp.ReplaceAll("N","") ;
1346 tmp.ReplaceAll("n","") ;
1347 static char buf[100] ;
1348 strlcpy(buf,tmp.Data(),100) ;
1349 sibFormatCmd.setString(0, buf);
1350 }
1351
1352
1353 // Make list of lists ;
1354 RooLinkedList listList ;
1355 listList.Add((RooAbsArg*)this) ;
1356 for(auto * col : static_range_cast<RooAbsCollection*>(siblingList)) {
1357 listList.Add(col) ;
1358 }
1359
1360 RooLinkedList listListRRV ;
1361
1362 // Make list of RRV-only components
1363 RooArgList* prevList = nullptr ;
1364 for(auto * col : static_range_cast<RooAbsCollection*>(listList)) {
1365 RooArgList* list = new RooArgList ;
1366 for (auto* arg : *col) {
1367 auto* rrv = dynamic_cast<RooRealVar*>(arg) ;
1368 if (rrv) {
1369 list->add(*rrv) ;
1370 } else {
1371 coutW(InputArguments) << "RooAbsCollection::printLatex: can only print RooRealVar in LateX, skipping non-RooRealVar object named "
1372 << arg->GetName() << std::endl;
1373 }
1374 if (prevList && TString(rrv->GetName()).CompareTo(prevList->at(list->getSize()-1)->GetName())) {
1375 coutW(InputArguments) << "RooAbsCollection::printLatex: WARNING: naming and/or ordering of sibling list is different" << std::endl;
1376 }
1377 }
1378 listListRRV.Add(list) ;
1379 if (prevList && list->size() != prevList->size()) {
1380 coutW(InputArguments) << "RooAbsCollection::printLatex: ERROR: sibling list(s) must have same length as self" << std::endl;
1381 delete list ;
1382 listListRRV.Delete() ;
1383 return ;
1384 }
1385 prevList = list ;
1386 }
1387
1388 // Construct table header
1389 Int_t nlist = listListRRV.GetSize() ;
1390 TString subheader = "l" ;
1391 for (k=0 ; k<nlist ; k++) subheader += "c" ;
1392
1393 TString header = "\\begin{tabular}{" ;
1394 for (j=0 ; j<ncol ; j++) {
1395 if (j>0) header += "|" ;
1396 header += subheader ;
1397 }
1398 header += "}" ;
1399 ofs << header << std::endl;
1400
1401
1402 // Print contents, delegating actual printing to RooRealVar::format()
1403 for (i=0 ; i<nrow ; i++) {
1404 for (j=0 ; j<ncol ; j++) {
1405 for (k=0 ; k<nlist ; k++) {
1406 RooRealVar* par = (RooRealVar*) ((RooArgList*)listListRRV.At(k))->at(i+j*nrow) ;
1407 if (par) {
1408 if (option) {
1409 ofs << *std::unique_ptr<TString>{par->format(sigDigit,(k==0)?option:sibOption.Data())};
1410 } else {
1411 ofs << *std::unique_ptr<TString>{par->format((k==0)?*formatCmd:sibFormatCmd)};
1412 }
1413 }
1414 if (!(j==ncol-1 && k==nlist-1)) {
1415 ofs << " & " ;
1416 }
1417 }
1418 }
1419 ofs << "\\\\" << std::endl;
1420 }
1421
1422 ofs << "\\end{tabular}" << std::endl;
1423 listListRRV.Delete() ;
1424}
1425
1426
1427
1428
1429////////////////////////////////////////////////////////////////////////////////
1430/// Return true if all contained object report to have their
1431/// value inside the specified range
1432
1433bool RooAbsCollection::allInRange(const char* rangeSpec) const
1434{
1435 if (!rangeSpec) return true ;
1436
1437 // Parse rangeSpec specification
1438 std::vector<std::string> cutVec ;
1439 if (rangeSpec && strlen(rangeSpec)>0) {
1440 if (strchr(rangeSpec,',')==nullptr) {
1441 cutVec.push_back(rangeSpec) ;
1442 } else {
1443 const size_t bufSize = strlen(rangeSpec)+1;
1444 std::vector<char> buf(bufSize);
1445 strlcpy(buf.data(),rangeSpec,bufSize) ;
1446 const char* oneRange = strtok(buf.data(),",") ;
1447 while(oneRange) {
1448 cutVec.push_back(oneRange) ;
1449 oneRange = strtok(nullptr,",") ;
1450 }
1451 }
1452 }
1453
1454 // Apply range based selection criteria
1455 bool selectByRange = true ;
1456 for (auto arg : _list) {
1457 bool selectThisArg = false ;
1458 UInt_t icut ;
1459 for (icut=0 ; icut<cutVec.size() ; icut++) {
1460 if (arg->inRange(cutVec[icut].c_str())) {
1461 selectThisArg = true ;
1462 break ;
1463 }
1464 }
1465 if (!selectThisArg) {
1466 selectByRange = false ;
1467 break ;
1468 }
1469 }
1470
1471 return selectByRange ;
1472}
1473
1474////////////////////////////////////////////////////////////////////////////////
1475/// If one of the TObject we have a referenced to is deleted, remove the
1476/// reference.
1477
1479{
1480 if (obj && obj->InheritsFrom(RooAbsArg::Class())) remove(*(RooAbsArg*)obj,false,false);
1481}
1482
1483////////////////////////////////////////////////////////////////////////////////
1484/// Sort collection using std::sort and name comparison
1485
1486void RooAbsCollection::sort(bool reverse) {
1487 //Windows seems to need an implementation where two different std::sorts are written
1488 //down in two different blocks. Switching between the two comparators using a ternary
1489 //operator does not compile on windows, although the signature is identical.
1490 if (reverse) {
1491 const auto cmpReverse = [](const RooAbsArg * l, const RooAbsArg * r) {
1492 return strcmp(l->GetName(), r->GetName()) > 0;
1493 };
1494
1495 std::sort(_list.begin(), _list.end(), cmpReverse);
1496 }
1497 else {
1498 const auto cmp = [](const RooAbsArg * l, const RooAbsArg * r) {
1499 return strcmp(l->GetName(), r->GetName()) < 0;
1500 };
1501
1502 std::sort(_list.begin(), _list.end(), cmp);
1503 }
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Sort collection topologically: the servers of any RooAbsArg will be before
1508/// that RooAbsArg in the collection.
1509
1511 std::unordered_set<TNamed const *> seenArgs;
1512 for (std::size_t iArg = 0; iArg < _list.size(); ++iArg) {
1513 RooAbsArg *arg = _list[iArg];
1514 bool movedArg = false;
1515 for (RooAbsArg *server : arg->servers()) {
1516 if (seenArgs.find(server->namePtr()) == seenArgs.end()) {
1517 auto found = std::find_if(_list.begin(), _list.end(),
1518 [server](RooAbsArg *elem) { return elem->namePtr() == server->namePtr(); });
1519 if (found != _list.end()) {
1520 _list.erase(found);
1521 _list.insert(_list.begin() + iArg, server);
1522 movedArg = true;
1523 break;
1524 }
1525 }
1526 }
1527 if (movedArg) {
1528 --iArg;
1529 continue;
1530 }
1531 seenArgs.insert(arg->namePtr());
1532 }
1533}
1534
1535////////////////////////////////////////////////////////////////////////////////
1536/// Factory for legacy iterators.
1537
1538std::unique_ptr<RooAbsCollection::LegacyIterator_t> RooAbsCollection::makeLegacyIterator (bool forward) const {
1539 if (!forward)
1540 ccoutE(DataHandling) << "The legacy RooFit collection iterators don't support reverse iterations, any more. "
1541 << "Use begin() and end()" << std::endl;
1542 return std::make_unique<LegacyIterator_t>(_list);
1543}
1544
1545
1546////////////////////////////////////////////////////////////////////////////////
1547/// Insert an element into the owned collections.
1549 _list.push_back(item);
1550
1551 if (_allRRV && dynamic_cast<const RooRealVar*>(item)==nullptr) {
1552 _allRRV= false;
1553 }
1554
1555 if (_hashAssistedFind) {
1556 _hashAssistedFind->insert(item);
1557 }
1558}
1559
1560
1561////////////////////////////////////////////////////////////////////////////////
1562/// \param[in] flag Switch hash map on or off.
1564 if (flag && !_hashAssistedFind) _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
1565 if (!flag) _hashAssistedFind = nullptr;
1566}
1567
1568
1569////////////////////////////////////////////////////////////////////////////////
1570/// Check that all entries where the collections overlap have the same name.
1572 for (unsigned int i=0; i < std::min(_list.size(), other.size()); ++i) {
1573 if (_list[i]->namePtr() != other._list[i]->namePtr())
1574 return false;
1575 }
1576
1577 return true;
1578}
static Roo_reg_AGKInteg1D instance
#define ccoutE(a)
#define cxcoutD(a)
#define coutW(a)
#define coutE(a)
int Int_t
Definition RtypesCore.h:45
char Text_t
Definition RtypesCore.h:62
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:110
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:80
virtual void copyCache(const RooAbsArg *source, bool valueOnly=false, bool setValDirty=true)=0
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
Definition RooAbsArg.h:564
virtual void syncCache(const RooArgSet *nset=nullptr)=0
const RefCountList_t & servers() const
List of all servers of this object.
Definition RooAbsArg.h:209
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:92
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
virtual bool setIndex(value_type index, bool printError=true)=0
Change category state by specifying the index code of the desired state.
virtual bool setLabel(const char *label, bool printError=true)=0
Change category state by specifying a state name.
A space to attach TBranches.
virtual const char * getCurrentLabel() const
Return label string of current state.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
RooAbsCollection * selectByAttrib(const char *name, bool value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
bool equals(const RooAbsCollection &otherColl) const
Check if this and other collection have identically-named contents.
std::unique_ptr< HashAssistedFind > _hashAssistedFind
!
double getRealValue(const char *name, double defVal=0.0, bool verbose=false) const
Get value of a RooAbsReal stored in set with given name.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
void deleteList()
Delete contents of the list.
Int_t getCatIndex(const char *name, Int_t defVal=0, bool verbose=false) const
Get index value of a RooAbsCategory stored in set with given name.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
virtual TObject * create(const char *newname) const =0
Int_t defaultPrintContents(Option_t *opt) const override
Define default RooPrinable print options for given Print() flag string For inline printing only show ...
bool allInRange(const char *rangeSpec) const
Return true if all contained object report to have their value inside the specified range.
void assignFast(const RooAbsCollection &other, bool setValDirty=true) const
Functional equivalent of assign() but assumes this and other collection have same layout.
void sortTopologically()
Sort collection topologically: the servers of any RooAbsArg will be before that RooAbsArg in the coll...
const char * getStringValue(const char *name, const char *defVal="", bool verbose=false) const
Get string value of a RooStringVar stored in set with given name.
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
virtual bool canBeAdded(const RooAbsArg &arg, bool silent) const =0
Determine whether it's possible to add a given RooAbsArg to the collection or not.
RooAbsCollection * snapshot(bool deepCopy=true) const
Take a snap shot of current collection contents.
RooAbsCollection()
Default constructor.
void printValue(std::ostream &os) const override
Print value of collection, i.e.
void printLatex(const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Output content of collection as LaTex table.
Int_t getSize() const
Return the number of elements in the collection.
~RooAbsCollection() override
Destructor.
bool setStringValue(const char *name, const char *newVal="", bool verbose=false)
Set string value of a RooStringVar stored in set with given name to newVal.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void setAttribAll(const Text_t *name, bool value=true)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
void printTitle(std::ostream &os) const override
Return collection title.
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
bool _allRRV
All contents are RRV.
bool hasSameLayout(const RooAbsCollection &other) const
Check that all entries where the collections overlap have the same name.
void RecursiveRemove(TObject *obj) override
If one of the TObject we have a referenced to is deleted, remove the reference.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
Storage_t::size_type size() const
RooAbsArg * first() const
virtual bool replace(const RooAbsArg &var1, const RooAbsArg &var2)
Replace var1 with var2 and return true for success.
bool setCatIndex(const char *name, Int_t newVal=0, bool verbose=false)
Set index value of a RooAbsCategoryLValue stored in set with given name to newVal.
void clear()
Clear contents. If the collection is owning, it will also delete the contents.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Implement multiline printing of collection, one line for each contained object showing the requested ...
bool setCatLabel(const char *name, const char *newVal="", bool verbose=false)
Set state name of a RooAbsCategoryLValue stored in set with given name to newVal.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
Storage_t _list
Actual object storage.
RooAbsCollection * selectByName(const char *nameList, bool verbose=false) const
Create a subset of the current collection, consisting only of those elements with names matching the ...
bool setRealValue(const char *name, double newVal=0.0, bool verbose=false)
Set value of a RooAbsRealLValue stored in set with given name to newVal No error messages are printed...
bool _ownCont
Flag to identify a list that owns its contents.
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
void printName(std::ostream &os) const override
Return collection name.
void sort(bool reverse=false)
Sort collection using std::sort and name comparison.
std::unique_ptr< LegacyIterator_t > makeLegacyIterator(bool forward=true) const
Factory for legacy iterators.
std::size_t _sizeThresholdForMapSearch
!
void dump() const
Base contents dumper for debugging purposes.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
const char * getCatLabel(const char *name, const char *defVal="", bool verbose=false) const
Get state name of a RooAbsCategory stored in set with given name.
virtual bool containsInstance(const RooAbsArg &var) const
Check if this exact instance is in this collection.
void useHashMapForFind(bool flag) const
bool isOwning() const
std::string contentsString() const
Return comma separated list of contained object names as STL string.
void printClassName(std::ostream &os) const override
Return collection class name.
void setName(const char *name)
RooAbsCollection & operator=(const RooAbsCollection &other)
Assign values from the elements in other to our elements.
void insert(RooAbsArg *)
Insert an element into the owned collections.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition RooCmdArg.h:26
void addArg(const RooCmdArg &arg)
Utility function to add nested RooCmdArg to payload of this RooCmdArg.
const char * getString(Int_t idx) const
Return string stored in slot idx.
Definition RooCmdArg.h:95
void setString(Int_t idx, const char *value)
Definition RooCmdArg.h:78
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
const RooLinkedList & getObjectList(const char *name) const
Return list of objects registered with name 'name'.
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Int_t GetSize() const
TObject * At(int index) const
Return object stored in sequential position given by index.
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
TObject * FindObject(const char *name) const override
Return pointer to object with given name.
RooNameReg is a registry for const char* names.
Definition RooNameReg.h:25
static const TNamed * known(const char *stringPtr)
If the name is already known, return its TNamed pointer. Otherwise return 0 (don't register the name)...
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
static Int_t _nameLength
static void nameFieldLength(Int_t newLen)
Set length of field reserved from printing name of RooAbsArgs in multi-line collection printing to gi...
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:37
TString * format(const RooCmdArg &formatArg) const
Format contents of RooRealVar for pretty printing on RooPlot parameter boxes.
void copyCacheFast(const RooRealVar &other, bool setValDirty=true)
Definition RooRealVar.h:131
RooStringVar is a RooAbsArg implementing string values.
void setVal(const char *newVal)
const char * getVal() const
static TClass * Class()
static void create(const TObject *obj)
Register creation of object 'obj'.
Definition RooTrace.cxx:124
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
static TClass * Class()
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
Regular expression class.
Definition TRegexp.h:31
Basic string class.
Definition TString.h:139
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:451
const char * Data() const
Definition TString.h:380
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
TString & Append(const char *cs)
Definition TString.h:576
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
RooCmdArg LatexTableStyle(bool flag=true)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
bool snapshotImpl(RooAbsCollection const &input, RooAbsCollection &output, bool deepCopy, RooArgSet const *observables)
Implementation of RooAbsCollection::snapshot() with some extra parameters.
Definition first.py:1
Helper for hash-map-assisted finding of elements by name.
RooAbsArg * find(const TNamed *nptr) const
std::unordered_map< const TNamed *, const RooAbsArg *const > nameToItemMap
const std::size_t & currentRooNameRegCounter
void erase(const RooAbsArg *elm)
void replace(const RooAbsArg *out, const RooAbsArg *in)
void insert(const RooAbsArg *elm)
HashAssistedFind(It_t first, It_t last)
Initialise empty hash map for fast finding by name.
TLine l
Definition textangle.C:4
static void output()