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