Logo ROOT  
Reference Guide
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());
114
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);
137
138
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){
202 }
203}
204
205
206////////////////////////////////////////////////////////////////////////////////
207/// Examine client server dependencies in list and
208/// delete contents in safe order: any client
209/// is deleted before a server is deleted
210
212{
213 _hashAssistedFind = nullptr;
214
215 // Handle trivial case here
216 if (_list.size() > 1) {
217 std::vector<RooAbsArg*> tmp;
218 tmp.reserve(_list.size());
219 do {
220 tmp.clear();
221 for (auto arg : _list) {
222 // Check if arg depends on remainder of list
223 if (!arg->dependsOn(*this, arg)) tmp.push_back(arg);
224 }
225
226 // sort and uniquify, in case some elements occur more than once
227 std::sort(tmp.begin(), tmp.end());
228
229 tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
230 // okay, can remove and delete what's in tmp
231 auto newEnd = _list.end();
232 for (auto item : tmp) {
233 newEnd = std::remove(_list.begin(), newEnd, item);
234 delete item;
235 }
236 _list.erase(newEnd, _list.end());
237 } while (!tmp.empty() && _list.size() > 1);
238
239 // Check if there are any remaining elements
240 if (_list.size() > 1) {
241 coutW(ObjectHandling) << "RooAbsCollection::safeDeleteList(" << GetName()
242 << ") WARNING: unable to delete following elements in client-server order " ;
243 Print("1") ;
244 }
245 }
246
247 // Built-in delete remaining elements
248 for (auto item : _list) {
249 delete item;
250 }
251 _list.clear();
252}
253
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// Take a snap shot of current collection contents.
258/// An owning collection is returned containing clones of
259/// - Elements in this collection
260/// - External dependents of all elements and recursively any dependents of those dependents
261/// (if deepCopy flag is set)
262///
263/// This is useful to save the values of variables or parameters. It doesn't require
264/// deep copying if the parameters are direct members of the collection.
265///
266/// If deepCopy is specified, the client-server links between the cloned
267/// list elements and the cloned external dependents are reconnected to
268/// each other, making the snapshot a completely self-contained entity.
269///
270///
271
273{
274 // First create empty list
275 TString snapName ;
276 if (TString(GetName()).Length()>0) {
277 snapName.Append("Snapshot of ") ;
278 snapName.Append(GetName()) ;
279 }
281
282 Bool_t error = snapshot(*output,deepCopy) ;
283 if (error) {
284 delete output ;
285 return 0 ;
286 }
287
288 return output ;
289}
290
291
292
293////////////////////////////////////////////////////////////////////////////////
294/// Take a snap shot of current collection contents:
295/// A collection that owns its elements is returned containing clones of
296/// - Elements in this collection
297/// - External dependents of those elements
298/// and recursively any dependents of those dependents
299/// (if deepCopy flag is set)
300///
301/// If deepCopy is specified, the client-server links between the cloned
302/// list elements and the cloned external dependents are reconnected to
303/// each other, making the snapshot a completely self-contained entity.
304///
305///
306
308{
309 // Copy contents
310 output.reserve(_list.size());
311 for (auto orig : _list) {
312 RooAbsArg *copy= (RooAbsArg*)orig->Clone();
313 output.add(*copy);
314 }
315
316 // Add external dependents
317 Bool_t error(kFALSE) ;
318 if (deepCopy) {
319 // Recursively add clones of all servers
320 // Can only do index access because collection might reallocate when growing
321 for (Storage_t::size_type i = 0; i < output._list.size(); ++i) {
322 const auto var = output._list[i];
323 error |= output.addServerClonesToList(*var);
324 }
325 }
326
327 // Handle eventual error conditions
328 if (error) {
329 coutE(ObjectHandling) << "RooAbsCollection::snapshot(): Errors occurred in deep clone process, snapshot not created" << endl ;
330 output._ownCont = kTRUE ;
331 return kTRUE ;
332 }
333
334
335
336 // Redirect all server connections to internal list members
337 for (auto var : output) {
338 var->redirectServers(output,deepCopy);
339 }
340
341
342 // Transfer ownership of contents to list
343 output._ownCont = kTRUE ;
344 return kFALSE ;
345}
346
347
348
349////////////////////////////////////////////////////////////////////////////////
350/// Add clones of servers of given argument to end of list
351
353{
354 Bool_t ret(kFALSE) ;
355
356 // This can be a very heavy operation if existing elements depend on many others,
357 // so make sure that we have the hash map available for faster finding.
358 if (var.servers().size() > 20 || _list.size() > 30)
359 useHashMapForFind(true);
360
361 for (const auto server : var.servers()) {
362 RooAbsArg* tmp = find(*server) ;
363
364 if (!tmp) {
365 RooAbsArg* serverClone = (RooAbsArg*)server->Clone() ;
366 serverClone->setAttribute("SnapShot_ExtRefClone") ;
367 insert(serverClone);
368 ret |= addServerClonesToList(*server) ;
369 }
370 }
371
372 return ret ;
373}
374
375
376
377////////////////////////////////////////////////////////////////////////////////
378/// Assign values from the elements in `other` to our elements.
379/// \warning This is not a conventional assignment operator. To avoid confusion, prefer using RooAbsCollection::assign().
380
382{
383 assign(other);
384 return *this;
385}
386
387
388////////////////////////////////////////////////////////////////////////////////
389/// Sets the value, cache and constant attribute of any argument in our set
390/// that also appears in the other set. Note that this function changes the
391/// values of the elements in this collection, but is still marked `const` as
392/// it does not change which elements this collection points to.
393
395{
396 if (&other==this) return ;
397
398 for (auto elem : _list) {
399 auto theirs = other.find(*elem);
400 if(!theirs) continue;
401 theirs->syncCache() ;
402 elem->copyCache(theirs) ;
403 elem->setAttribute("Constant",theirs->isConstant()) ;
404 }
405 return ;
406}
407
408
409////////////////////////////////////////////////////////////////////////////////
410/// Sets the value of any argument in our set that also appears in the other set.
411/// \param[in] other Collection holding the arguments to syncronize values with.
412/// \param[in] forceIfSizeOne If set to true and both our collection
413/// and the other collection have a size of one, the arguments are
414/// always syncronized without checking if they have the same name.
415
417{
418 if (&other==this) return *this;
419
420 // Short cut for 1 element assignment
421 if (size()==1 && size() == other.size() && forceIfSizeOne) {
422 other.first()->syncCache() ;
423 first()->copyCache(other.first(),kTRUE) ;
424 return *this;
425 }
426
427 for (auto elem : _list) {
428 auto theirs = other.find(*elem);
429 if(!theirs) continue;
430 theirs->syncCache() ;
431 elem->copyCache(theirs,kTRUE) ;
432 }
433 return *this;
434}
435
436
437
438////////////////////////////////////////////////////////////////////////////////
439/// Functional equivalent of assign() but assumes this and other collection
440/// have same layout. Also no attributes are copied
441
442void RooAbsCollection::assignFast(const RooAbsCollection& other, bool setValDirty) const
443{
444 if (&other==this) return ;
445 assert(hasSameLayout(other));
446
447 auto iter2 = other._list.begin();
448 for (auto iter1 = _list.begin();
449 iter1 != _list.end() && iter2 != other._list.end();
450 ++iter1, ++iter2) {
451 // Identical size of iterators is documented assumption of method
452
453 if (_allRRV) {
454 // All contents are known to be RooRealVars - fast version of assignment
455 auto ours = static_cast<RooRealVar*>(*iter1);
456 auto theirs = static_cast<RooRealVar*>(*iter2);
457 ours->copyCacheFast(*theirs,setValDirty);
458 } else {
459 (*iter2)->syncCache() ;
460 (*iter1)->copyCache(*iter2,kTRUE,setValDirty) ;
461 }
462 }
463
464}
465
466
467
468////////////////////////////////////////////////////////////////////////////////
469/// Add the specified argument to list. Returns kTRUE if successful, or
470/// else kFALSE if a variable of the same name is already in the list.
471/// This method can only be called on a list that is flagged as owning
472/// all of its contents, or else on an empty list (which will force the
473/// list into that mode).
474
476{
477 if(!canBeAdded(var, silent)) return false;
478
479 // check that we own our variables or else are empty
480 if(!_ownCont && (getSize() > 0) && !silent) {
481 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addOwned: can only add to an owned list" << endl;
482 return kFALSE;
483 }
485
486 insert(&var);
487
488 return kTRUE;
489}
490
491
492
493////////////////////////////////////////////////////////////////////////////////
494/// Add a clone of the specified argument to list. Returns a pointer to
495/// the clone if successful, or else zero if a variable of the same name
496/// is already in the list or the list does *not* own its variables (in
497/// this case, try add() instead.) Calling addClone() on an empty list
498/// forces it to take ownership of all its subsequent variables.
499
501{
502 if(!canBeAdded(var, silent)) return nullptr;
503
504 // check that we own our variables or else are empty
505 if(!_ownCont && (getSize() > 0) && !silent) {
506 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::addClone: can only add to an owned list" << endl;
507 return 0;
508 }
510
511 // add a pointer to a clone of this variable to our list (we now own it!)
512 auto clone2 = static_cast<RooAbsArg*>(var.Clone());
513 assert(clone2);
514
515 insert(clone2);
516
517 return clone2;
518}
519
520
521
522////////////////////////////////////////////////////////////////////////////////
523/// Add the specified argument to list. Returns kTRUE if successful, or
524/// else kFALSE if a variable of the same name is already in the list
525/// or the list owns its variables (in this case, try addClone() or addOwned() instead).
526
528{
529 if(!canBeAdded(var, silent)) return false;
530
531 // check that this isn't a copy of a list
532 if(_ownCont && !silent) {
533 coutE(ObjectHandling) << ClassName() << "::" << GetName() << "::add: cannot add to an owned list" << endl;
534 return kFALSE;
535 }
536
537 // add a pointer to this variable to our list (we don't own it!)
538 insert(const_cast<RooAbsArg*>(&var)); //FIXME const_cast
539
540 return kTRUE;
541}
542
543
544////////////////////////////////////////////////////////////////////////////////
545/// Add a collection of arguments to this collection by calling addOwned()
546/// for each element in the source collection
547
549{
550 Bool_t result(false) ;
551 _list.reserve(_list.size() + list._list.size());
552
553 for (auto item : list._list) {
554 result |= addOwned(*item, silent) ;
555 }
556
557 return result;
558}
559
560
561
562////////////////////////////////////////////////////////////////////////////////
563/// Add a collection of arguments to this collection by calling addOwned()
564/// for each element in the source collection
565
567{
568 _list.reserve(_list.size() + list._list.size());
569
570 for (auto item : list._list) {
571 addClone(*item, silent);
572 }
573}
574
575
576
577////////////////////////////////////////////////////////////////////////////////
578/// Replace any args in our set with args of the same name from the other set
579/// and return kTRUE for success. Fails if this list is a copy of another.
580
582{
583 // check that this isn't a copy of a list
584 if(_ownCont) {
585 coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << endl;
586 return kFALSE;
587 }
588
589 // loop over elements in the other list
590 for (const auto * arg : other._list) {
591 // do we have an arg of the same name in our set?
592 auto found = find(*arg);
593 if (found) replace(*found,*arg);
594 }
595 return kTRUE;
596}
597
598
599
600////////////////////////////////////////////////////////////////////////////////
601/// Replace var1 with var2 and return kTRUE for success. Fails if
602/// this list is a copy of another, if var1 is not already in this set,
603/// or if var2 is already in this set. var1 and var2 do not need to have
604/// the same name.
605
607{
608 // check that this isn't a copy of a list
609 if(_ownCont) {
610 coutE(ObjectHandling) << "RooAbsCollection: cannot replace variables in a copied list" << endl;
611 return kFALSE;
612 }
613
614 // is var1 already in this list?
615 const char *name= var1.GetName();
616 auto var1It = std::find(_list.begin(), _list.end(), &var1);
617
618 if (var1It == _list.end()) {
619 coutE(ObjectHandling) << "RooAbsCollection: variable \"" << name << "\" is not in the list"
620 << " and cannot be replaced" << endl;
621 return kFALSE;
622 }
623
624
625 // is var2's name already in this list?
626 if (dynamic_cast<RooArgSet*>(this)) {
627 RooAbsArg *other = find(var2);
628 if(other != 0 && other != &var1) {
629 coutE(ObjectHandling) << "RooAbsCollection: cannot replace \"" << name
630 << "\" with already existing \"" << var2.GetName() << "\"" << endl;
631 return kFALSE;
632 }
633 }
634
635 // replace var1 with var2
636 if (_hashAssistedFind) {
637 _hashAssistedFind->replace(*var1It, &var2);
638 }
639 *var1It = const_cast<RooAbsArg*>(&var2); //FIXME try to get rid of const_cast
640
641 if (_allRRV && dynamic_cast<const RooRealVar*>(&var2)==0) {
643 }
644
645 return kTRUE;
646}
647
648
649
650////////////////////////////////////////////////////////////////////////////////
651/// Remove the specified argument from our list. Return kFALSE if
652/// the specified argument is not found in our list. An exact pointer
653/// match is required, not just a match by name.
654/// If `matchByNameOnly` is set, items will be looked up by name. In this case, if
655/// the collection also owns the item, it will delete it.
657{
658 // is var already in this list?
659 const auto sizeBefore = _list.size();
660
661 if (matchByNameOnly) {
662 const std::string name(var.GetName());
663 auto nameMatch = [&name](const RooAbsArg* elm) {
664 return elm->GetName() == name;
665 };
666 std::set<RooAbsArg*> toBeDeleted;
667
668 if (_ownCont) {
669 std::for_each(_list.begin(), _list.end(), [&toBeDeleted, nameMatch](RooAbsArg* elm){
670 if (nameMatch(elm)) {
671 toBeDeleted.insert(elm);
672 }
673 });
674 }
675
676 _list.erase(std::remove_if(_list.begin(), _list.end(), nameMatch), _list.end());
677
678 for (auto arg : toBeDeleted)
679 delete arg;
680 } else {
681 _list.erase(std::remove(_list.begin(), _list.end(), &var), _list.end());
682 }
683
684 if (_hashAssistedFind && sizeBefore != _list.size()) {
685 _hashAssistedFind->erase(&var);
686 }
687
688 return sizeBefore != _list.size();
689}
690
691
692
693////////////////////////////////////////////////////////////////////////////////
694/// Remove each argument in the input list from our list.
695/// An exact pointer match is required, not just a match by name.
696/// If `matchByNameOnly` is set, items will be looked up by name. In this case, if
697/// the collection also owns the items, it will delete them.
698/// Return kFALSE in case of problems.
699
700Bool_t RooAbsCollection::remove(const RooAbsCollection& list, Bool_t /*silent*/, Bool_t matchByNameOnly)
701{
702
703 auto oldSize = _list.size();
704 std::vector<const RooAbsArg*> markedItems;
705
706 if (matchByNameOnly) {
707
708 // Instead of doing two passes on the list as in remove(RooAbsArg&), we do
709 // everything in one pass, by using side effects of the predicate.
710 auto nameMatchAndMark = [&list, &markedItems](const RooAbsArg* elm) {
711 if( list.contains(*elm) ) {
712 markedItems.push_back(elm);
713 return true;
714 }
715 return false;
716 };
717
718 _list.erase(std::remove_if(_list.begin(), _list.end(), nameMatchAndMark), _list.end());
719
720 std::set<const RooAbsArg*> toBeDeleted(markedItems.begin(), markedItems.end());
721 if (_ownCont) {
722 for (auto arg : toBeDeleted) {
723 delete arg;
724 }
725 }
726 }
727 else {
728 auto argMatchAndMark = [&list, &markedItems](const RooAbsArg* elm) {
729 if( list.containsInstance(*elm) ) {
730 markedItems.push_back(elm);
731 return true;
732 }
733 return false;
734 };
735
736 _list.erase(std::remove_if(_list.begin(), _list.end(), argMatchAndMark), _list.end());
737 }
738
739 if (_hashAssistedFind && oldSize != _list.size()) {
740 for( auto& var : markedItems ) {
741 _hashAssistedFind->erase(var);
742 }
743 }
744
745 return oldSize != _list.size();
746}
747
748
749
750////////////////////////////////////////////////////////////////////////////////
751/// Remove all arguments from our set, deleting them if we own them.
752/// This effectively restores our object to the state it would have
753/// just after calling the RooAbsCollection(const char*) constructor.
754
756{
757 _hashAssistedFind = nullptr;
758
759 if(_ownCont) {
762 }
763 else {
764 _list.clear();
765 }
766}
767
768
769
770////////////////////////////////////////////////////////////////////////////////
771/// Set given attribute in each element of the collection by
772/// calling each elements setAttribute() function.
773
775{
776 for (auto arg : _list) {
777 arg->setAttribute(name, value);
778 }
779}
780
781
782
783
784////////////////////////////////////////////////////////////////////////////////
785/// Create a subset of the current collection, consisting only of those
786/// elements with the specified attribute set. The caller is responsibe
787/// for deleting the returned collection
788
790{
791 TString selName(GetName()) ;
792 selName.Append("_selection") ;
793 RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ;
794
795 // Scan set contents for matching attribute
796 for (auto arg : _list) {
797 if (arg->getAttribute(name)==value)
798 sel->add(*arg) ;
799 }
800
801 return sel ;
802}
803
804
805////////////////////////////////////////////////////////////////////////////////
806/// Create a subset of the current collection, consisting only of those
807/// elements that are contained as well in the given reference collection.
808/// Returns `true` only if something went wrong.
809/// The complement of this function is getParameters().
810/// \param[in] refColl The collection to check for common elements.
811/// \param[out] outColl Output collection.
812
814{
815 outColl.clear();
816 outColl.setName((std::string(GetName()) + "_selection").c_str());
817
818 // Scan set contents for matching attribute
819 for (auto arg : _list) {
820 if (refColl.find(*arg))
821 outColl.add(*arg) ;
822 }
823
824 return false;
825}
826
827
828////////////////////////////////////////////////////////////////////////////////
829/// Create a subset of the current collection, consisting only of those
830/// elements that are contained as well in the given reference collection.
831/// The caller is responsible for deleting the returned collection
832
834{
835 auto sel = static_cast<RooAbsCollection*>(create("")) ;
836 selectCommon(refColl, *sel);
837 return sel ;
838}
839
840
841////////////////////////////////////////////////////////////////////////////////
842/// Create a subset of the current collection, consisting only of those
843/// elements with names matching the wildcard expressions in nameList,
844/// supplied as a comma separated list
845
847{
848 // Create output set
849 TString selName(GetName()) ;
850 selName.Append("_selection") ;
851 RooAbsCollection *sel = (RooAbsCollection*) create(selName.Data()) ;
852
853 const size_t bufSize = strlen(nameList) + 1;
854 char* buf = new char[bufSize] ;
855 strlcpy(buf,nameList,bufSize) ;
856 char* wcExpr = strtok(buf,",") ;
857 while(wcExpr) {
858 TRegexp rexp(wcExpr,kTRUE) ;
859 if (verbose) {
860 cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") processing expression '" << wcExpr << "'" << endl ;
861 }
862
863 RooFIter iter = fwdIterator() ;
864 RooAbsArg* arg ;
865 while((arg=iter.next())) {
866 if (TString(arg->GetName()).Index(rexp)>=0) {
867 if (verbose) {
868 cxcoutD(ObjectHandling) << "RooAbsCollection::selectByName(" << GetName() << ") selected element " << arg->GetName() << endl ;
869 }
870 sel->add(*arg) ;
871 }
872 }
873 wcExpr = strtok(0,",") ;
874 }
875 delete[] buf ;
876
877 return sel ;
878}
879
880
881
882
883////////////////////////////////////////////////////////////////////////////////
884/// Check if this and other collection have identically-named contents
885
887{
888 // First check equal length
889 if (getSize() != otherColl.getSize()) return kFALSE ;
890
891 // Then check that each element of our list also occurs in the other list
892 auto compareByNamePtr = [](const RooAbsArg * left, const RooAbsArg * right) {
893 return left->namePtr() == right->namePtr();
894 };
895
896 return std::is_permutation(_list.begin(), _list.end(),
897 otherColl._list.begin(),
898 compareByNamePtr);
899}
900
901
902namespace {
903////////////////////////////////////////////////////////////////////////////////
904/// Linear search through list of stored objects.
905template<class Collection_t>
906RooAbsArg* findUsingNamePointer(const Collection_t& coll, const TNamed* ptr) {
907 auto findByNamePtr = [ptr](const RooAbsArg* elm) {
908 return ptr == elm->namePtr();
909 };
910
911 auto item = std::find_if(coll.begin(), coll.end(), findByNamePtr);
912
913 return item != coll.end() ? *item : nullptr;
914}
915}
916
917
918////////////////////////////////////////////////////////////////////////////////
919/// Find object with given name in list. A null pointer
920/// is returned if no object with the given name is found.
922{
923 if (!name)
924 return nullptr;
925
926 // If an object with such a name exists, its name has been registered.
927 const TNamed* nptr = RooNameReg::known(name);
928 if (!nptr) return nullptr;
929
931 if (!_hashAssistedFind || !_hashAssistedFind->isValid()) {
932 _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
933 }
934
935 return _hashAssistedFind->find(nptr);
936 }
937
938 return findUsingNamePointer(_list, nptr);
939}
940
941
942
943////////////////////////////////////////////////////////////////////////////////
944/// Find object with given name in list. A null pointer
945/// is returned if no object with the given name is found.
947{
948 const auto nptr = arg.namePtr();
949
951 if (!_hashAssistedFind || !_hashAssistedFind->isValid()) {
952 _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
953 }
954
955 return _hashAssistedFind->find(nptr);
956 }
957
958 return findUsingNamePointer(_list, nptr);
959}
960
961
962////////////////////////////////////////////////////////////////////////////////
963/// Return index of item with given name, or -1 in case it's not in the collection.
965 const std::string theName(name);
966 auto item = std::find_if(_list.begin(), _list.end(), [&theName](const RooAbsArg * elm){
967 return elm->GetName() == theName;
968 });
969 return item != _list.end() ? item - _list.begin() : -1;
970}
971
972
973////////////////////////////////////////////////////////////////////////////////
974/// Get value of a RooAbsReal stored in set with given name. If none is found, value of defVal is returned.
975/// No error messages are printed unless the verbose flag is set
976
978{
979 RooAbsArg* raa = find(name) ;
980 if (!raa) {
981 if (verbose) coutE(InputArguments) << "RooAbsCollection::getRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
982 return defVal ;
983 }
984 RooAbsReal* rar = dynamic_cast<RooAbsReal*>(raa) ;
985 if (!rar) {
986 if (verbose) coutE(InputArguments) << "RooAbsCollection::getRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsReal" << endl ;
987 return defVal ;
988 }
989 return rar->getVal() ;
990}
991
992
993
994////////////////////////////////////////////////////////////////////////////////
995/// Set value of a RooAbsRealLValye stored in set with given name to newVal
996/// No error messages are printed unless the verbose flag is set
997
999{
1000 RooAbsArg* raa = find(name) ;
1001 if (!raa) {
1002 if (verbose) coutE(InputArguments) << "RooAbsCollection::setRealValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1003 return kTRUE ;
1004 }
1005 RooAbsRealLValue* rar = dynamic_cast<RooAbsRealLValue*>(raa) ;
1006 if (!rar) {
1007 if (verbose) coutE(InputArguments) << "RooAbsCollection::setRealValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsRealLValue" << endl ;
1008 return kTRUE;
1009 }
1010 rar->setVal(newVal) ;
1011 return kFALSE ;
1012}
1013
1014
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// Get state name of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
1018/// No error messages are printed unless the verbose flag is set
1019
1020const char* RooAbsCollection::getCatLabel(const char* name, const char* defVal, Bool_t verbose) const
1021{
1022 RooAbsArg* raa = find(name) ;
1023 if (!raa) {
1024 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1025 return defVal ;
1026 }
1027 RooAbsCategory* rac = dynamic_cast<RooAbsCategory*>(raa) ;
1028 if (!rac) {
1029 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
1030 return defVal ;
1031 }
1032 return rac->getCurrentLabel() ;
1033}
1034
1035
1036
1037////////////////////////////////////////////////////////////////////////////////
1038/// Set state name of a RooAbsCategoryLValue stored in set with given name to newVal.
1039/// No error messages are printed unless the verbose flag is set
1040
1041Bool_t RooAbsCollection::setCatLabel(const char* name, const char* newVal, Bool_t verbose)
1042{
1043 RooAbsArg* raa = find(name) ;
1044 if (!raa) {
1045 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1046 return kTRUE ;
1047 }
1048 RooAbsCategoryLValue* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
1049 if (!rac) {
1050 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
1051 return kTRUE ;
1052 }
1053 rac->setLabel(newVal) ;
1054 return kFALSE ;
1055}
1056
1057
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Get index value of a RooAbsCategory stored in set with given name. If none is found, value of defVal is returned.
1061/// No error messages are printed unless the verbose flag is set
1062
1064{
1065 RooAbsArg* raa = find(name) ;
1066 if (!raa) {
1067 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1068 return defVal ;
1069 }
1070 RooAbsCategory* rac = dynamic_cast<RooAbsCategory*>(raa) ;
1071 if (!rac) {
1072 if (verbose) coutE(InputArguments) << "RooAbsCollection::getCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
1073 return defVal ;
1074 }
1075 return rac->getCurrentIndex() ;
1076}
1077
1078
1079
1080////////////////////////////////////////////////////////////////////////////////
1081/// Set index value of a RooAbsCategoryLValue stored in set with given name to newVal.
1082/// No error messages are printed unless the verbose flag is set
1083
1085{
1086 RooAbsArg* raa = find(name) ;
1087 if (!raa) {
1088 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1089 return kTRUE ;
1090 }
1091 RooAbsCategoryLValue* rac = dynamic_cast<RooAbsCategoryLValue*>(raa) ;
1092 if (!rac) {
1093 if (verbose) coutE(InputArguments) << "RooAbsCollection::setCatLabel(" << GetName() << ") ERROR object '" << name << "' is not of type RooAbsCategory" << endl ;
1094 return kTRUE ;
1095 }
1096 rac->setIndex(newVal) ;
1097 return kFALSE ;
1098}
1099
1100
1101
1102////////////////////////////////////////////////////////////////////////////////
1103/// Get string value of a RooStringVar stored in set with given name. If none is found, value of defVal is returned.
1104/// No error messages are printed unless the verbose flag is set
1105
1106const char* RooAbsCollection::getStringValue(const char* name, const char* defVal, Bool_t verbose) const
1107{
1108 RooAbsArg* raa = find(name) ;
1109 if (!raa) {
1110 if (verbose) coutE(InputArguments) << "RooAbsCollection::getStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1111 return defVal ;
1112 }
1113 auto ras = dynamic_cast<const RooStringVar*>(raa) ;
1114 if (!ras) {
1115 if (verbose) coutE(InputArguments) << "RooAbsCollection::getStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooStringVar" << endl ;
1116 return defVal ;
1117 }
1118
1119 return ras->getVal() ;
1120}
1121
1122
1123
1124////////////////////////////////////////////////////////////////////////////////
1125/// Set string value of a RooStringVar stored in set with given name to newVal.
1126/// No error messages are printed unless the verbose flag is set
1127
1129{
1130 RooAbsArg* raa = find(name) ;
1131 if (!raa) {
1132 if (verbose) coutE(InputArguments) << "RooAbsCollection::setStringValue(" << GetName() << ") ERROR no object with name '" << name << "' found" << endl ;
1133 return kTRUE ;
1134 }
1135 auto ras = dynamic_cast<RooStringVar*>(raa);
1136 if (!ras) {
1137 if (verbose) coutE(InputArguments) << "RooAbsCollection::setStringValue(" << GetName() << ") ERROR object '" << name << "' is not of type RooStringVar" << endl ;
1138 return kTRUE ;
1139 }
1140 ras->setVal(newVal);
1141
1142 return false;
1143}
1144
1145////////////////////////////////////////////////////////////////////////////////
1146/// Return comma separated list of contained object names as STL string
1148{
1149 string retVal ;
1150 for (auto arg : _list) {
1151 retVal += arg->GetName();
1152 retVal += ",";
1153 }
1154
1155 retVal.erase(retVal.end()-1);
1156
1157 return retVal;
1158}
1159
1160
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Return collection name
1164
1165void RooAbsCollection::printName(ostream& os) const
1166{
1167 os << GetName() ;
1168}
1169
1170
1171
1172////////////////////////////////////////////////////////////////////////////////
1173/// Return collection title
1174
1175void RooAbsCollection::printTitle(ostream& os) const
1176{
1177 os << GetTitle() ;
1178}
1179
1180
1181
1182////////////////////////////////////////////////////////////////////////////////
1183/// Return collection class name
1184
1186{
1187 os << IsA()->GetName() ;
1188}
1189
1190
1191
1192////////////////////////////////////////////////////////////////////////////////
1193/// Define default RooPrinable print options for given Print() flag string
1194/// For inline printing only show value of objects, for default print show
1195/// name,class name value and extras of each object. In verbose mode
1196/// also add object adress, argument and title
1197
1199{
1200 if (opt && TString(opt)=="I") {
1201 return kValue ;
1202 }
1203 if (opt && TString(opt).Contains("v")) {
1205 }
1206 return kName|kClassName|kValue ;
1207}
1208
1209
1210
1211
1212
1213////////////////////////////////////////////////////////////////////////////////
1214/// Print value of collection, i.e. a comma separated list of contained
1215/// object names
1216
1217void RooAbsCollection::printValue(ostream& os) const
1218{
1219 Bool_t first2(kTRUE) ;
1220 os << "(" ;
1221 for (auto arg : _list) {
1222 if (!first2) {
1223 os << "," ;
1224 } else {
1225 first2 = kFALSE ;
1226 }
1227 if (arg->IsA()->InheritsFrom(RooStringVar::Class())) {
1228 os << '\'' << ((RooStringVar *)arg)->getVal() << '\'';
1229 } else {
1230 os << arg->GetName();
1231 }
1232 }
1233 os << ")" ;
1234}
1235
1236
1237
1238////////////////////////////////////////////////////////////////////////////////
1239/// Implement multiline printing of collection, one line for each contained object showing
1240/// the requested content
1241
1242void RooAbsCollection::printMultiline(ostream&os, Int_t contents, Bool_t /*verbose*/, TString indent) const
1243{
1244 if (TString(GetName()).Length()>0 && (contents&kCollectionHeader)) {
1245 os << indent << ClassName() << "::" << GetName() << ":" << (_ownCont?" (Owning contents)":"") << endl;
1246 }
1247
1248 TString deeper(indent);
1249 deeper.Append(" ");
1250
1251 // Adjust the width of the name field to fit the largest name, if requested
1252 Int_t maxNameLen(1) ;
1253 Int_t nameFieldLengthSaved = RooPrintable::_nameLength ;
1254 if (nameFieldLengthSaved==0) {
1255 for (auto next : _list) {
1256 Int_t len = strlen(next->GetName()) ;
1257 if (len>maxNameLen) maxNameLen = len ;
1258 }
1259 RooPrintable::nameFieldLength(maxNameLen+1) ;
1260 }
1261
1262 unsigned int idx = 0;
1263 for (auto next : _list) {
1264 os << indent << std::setw(3) << ++idx << ") ";
1265 next->printStream(os,contents,kSingleLine,"");
1266 }
1267
1268 // Reset name field length, if modified
1269 RooPrintable::nameFieldLength(nameFieldLengthSaved) ;
1270}
1271
1272
1273
1274////////////////////////////////////////////////////////////////////////////////
1275/// Base contents dumper for debugging purposes
1276
1278{
1279 for (auto arg : _list) {
1280 cout << arg << " " << arg->IsA()->GetName() << "::" << arg->GetName() << " (" << arg->GetTitle() << ")" << endl ;
1281 }
1282}
1283
1284
1285
1286////////////////////////////////////////////////////////////////////////////////
1287/// Output content of collection as LaTex table. By default a table with two columns is created: the left
1288/// column contains the name of each variable, the right column the value.
1289///
1290/// The following optional named arguments can be used to modify the default behavior
1291/// <table>
1292/// <tr><th> Argument <th> Effect
1293/// <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
1294/// <tr><td> `Sibling(const RooAbsCollection& other)` <td> Define sibling list.
1295/// The sibling list is assumed to have objects with the same
1296/// name in the same order. If this is not the case warnings will be printed. If a single
1297/// sibling list is specified, 3 columns will be output: the (common) name, the value of this
1298/// list and the value in the sibling list. Multiple sibling lists can be specified by
1299/// repeating the Sibling() command.
1300/// <tr><td> `Format(const char* str)` <td> Classic format string, provided for backward compatibility
1301/// <tr><td> `Format()` <td> Formatting arguments.
1302/// <table>
1303/// <tr><td> const char* what <td> Controls what is shown. "N" adds name, "E" adds error,
1304/// "A" shows asymmetric error, "U" shows unit, "H" hides the value
1305/// <tr><td> `FixedPrecision(int n)` <td> Controls precision, set fixed number of digits
1306/// <tr><td> `AutoPrecision(int n)` <td> Controls precision. Number of shown digits is calculated from error
1307/// and n specified additional digits (1 is sensible default)
1308/// <tr><td> `VerbatimName(Bool_t flag)` <td> Put variable name in a \\verb+ + clause.
1309/// </table>
1310/// <tr><td> `OutputFile(const char* fname)` <td> Send output to file with given name rather than standard output
1311///
1312/// </table>
1313///
1314/// Example use:
1315/// ```
1316/// list.printLatex(Columns(2), Format("NEU",AutoPrecision(1),VerbatimName()) );
1317/// ```
1318
1320 const RooCmdArg& arg3, const RooCmdArg& arg4,
1321 const RooCmdArg& arg5, const RooCmdArg& arg6,
1322 const RooCmdArg& arg7, const RooCmdArg& arg8) const
1323{
1324
1325
1326 // Define configuration for this method
1327 RooCmdConfig pc("RooAbsCollection::printLatex()") ;
1328 pc.defineInt("ncol","Columns",0,1) ;
1329 pc.defineString("outputFile","OutputFile",0,"") ;
1330 pc.defineString("format","Format",0,"NEYVU") ;
1331 pc.defineInt("sigDigit","Format",0,1) ;
1332 pc.defineObject("siblings","Sibling",0,0,kTRUE) ;
1333 pc.defineInt("dummy","FormatArgs",0,0) ;
1334 pc.defineMutex("Format","FormatArgs") ;
1335
1336 // Stuff all arguments in a list
1337 RooLinkedList cmdList;
1338 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
1339 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
1340 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
1341 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
1342
1343 // Process & check varargs
1344 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1345 if (!pc.ok(kTRUE)) {
1346 return ;
1347 }
1348
1349 const char* outFile = pc.getString("outputFile") ;
1350 if (outFile && strlen(outFile)) {
1351 std::ofstream ofs(outFile) ;
1352 if (pc.hasProcessed("FormatArgs")) {
1353 RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
1354 formatCmd->addArg(RooFit::LatexTableStyle()) ;
1355 printLatex(ofs,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;
1356 } else {
1357 printLatex(ofs,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
1358 }
1359 } else {
1360 if (pc.hasProcessed("FormatArgs")) {
1361 RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
1362 formatCmd->addArg(RooFit::LatexTableStyle()) ;
1363 printLatex(cout,pc.getInt("ncol"),0,0,pc.getObjectList("siblings"),formatCmd) ;
1364 } else {
1365 printLatex(cout,pc.getInt("ncol"),pc.getString("format"),pc.getInt("sigDigit"),pc.getObjectList("siblings")) ;
1366 }
1367 }
1368}
1369
1370
1371
1372
1373////////////////////////////////////////////////////////////////////////////////
1374/// Internal implementation function of printLatex
1375
1376void RooAbsCollection::printLatex(ostream& ofs, Int_t ncol, const char* option, Int_t sigDigit, const RooLinkedList& siblingList, const RooCmdArg* formatCmd) const
1377{
1378 // Count number of rows to print
1379 Int_t nrow = (Int_t) (getSize() / ncol + 0.99) ;
1380 Int_t i,j,k ;
1381
1382 // Sibling list do not need to print their name as it is supposed to be the same
1383 TString sibOption ;
1384 RooCmdArg sibFormatCmd ;
1385 if (option) {
1386 sibOption = option ;
1387 sibOption.ReplaceAll("N","") ;
1388 sibOption.ReplaceAll("n","") ;
1389 } else {
1390 sibFormatCmd = *formatCmd ;
1391 TString tmp = formatCmd->_s[0] ;
1392 tmp.ReplaceAll("N","") ;
1393 tmp.ReplaceAll("n","") ;
1394 static char buf[100] ;
1395 strlcpy(buf,tmp.Data(),100) ;
1396 sibFormatCmd._s[0] = buf ;
1397 }
1398
1399
1400 // Make list of lists ;
1401 RooLinkedList listList ;
1402 listList.Add((RooAbsArg*)this) ;
1403 for(auto * col : static_range_cast<RooAbsCollection*>(siblingList)) {
1404 listList.Add(col) ;
1405 }
1406
1407 RooLinkedList listListRRV ;
1408
1409 // Make list of RRV-only components
1410 RooArgList* prevList = 0 ;
1411 for(auto * col : static_range_cast<RooAbsCollection*>(listList)) {
1412 RooArgList* list = new RooArgList ;
1413 RooFIter iter = col->fwdIterator() ;
1414 RooAbsArg* arg ;
1415 while((arg=iter.next())) {
1416
1417 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
1418 if (rrv) {
1419 list->add(*rrv) ;
1420 } else {
1421 coutW(InputArguments) << "RooAbsCollection::printLatex: can only print RooRealVar in LateX, skipping non-RooRealVar object named "
1422 << arg->GetName() << endl ;
1423 }
1424 if (prevList && TString(rrv->GetName()).CompareTo(prevList->at(list->getSize()-1)->GetName())) {
1425 coutW(InputArguments) << "RooAbsCollection::printLatex: WARNING: naming and/or ordering of sibling list is different" << endl ;
1426 }
1427 }
1428 listListRRV.Add(list) ;
1429 if (prevList && list->getSize() != prevList->getSize()) {
1430 coutW(InputArguments) << "RooAbsCollection::printLatex: ERROR: sibling list(s) must have same length as self" << endl ;
1431 delete list ;
1432 listListRRV.Delete() ;
1433 return ;
1434 }
1435 prevList = list ;
1436 }
1437
1438 // Construct table header
1439 Int_t nlist = listListRRV.GetSize() ;
1440 TString subheader = "l" ;
1441 for (k=0 ; k<nlist ; k++) subheader += "c" ;
1442
1443 TString header = "\\begin{tabular}{" ;
1444 for (j=0 ; j<ncol ; j++) {
1445 if (j>0) header += "|" ;
1446 header += subheader ;
1447 }
1448 header += "}" ;
1449 ofs << header << endl ;
1450
1451
1452 // Print contents, delegating actual printing to RooRealVar::format()
1453 for (i=0 ; i<nrow ; i++) {
1454 for (j=0 ; j<ncol ; j++) {
1455 for (k=0 ; k<nlist ; k++) {
1456 RooRealVar* par = (RooRealVar*) ((RooArgList*)listListRRV.At(k))->at(i+j*nrow) ;
1457 if (par) {
1458 if (option) {
1459 TString* tmp = par->format(sigDigit,(k==0)?option:sibOption.Data()) ;
1460 ofs << *tmp ;
1461 delete tmp ;
1462 } else {
1463 TString* tmp = par->format((k==0)?*formatCmd:sibFormatCmd) ;
1464 ofs << *tmp ;
1465 delete tmp ;
1466 }
1467 }
1468 if (!(j==ncol-1 && k==nlist-1)) {
1469 ofs << " & " ;
1470 }
1471 }
1472 }
1473 ofs << "\\\\" << endl ;
1474 }
1475
1476 ofs << "\\end{tabular}" << endl ;
1477 listListRRV.Delete() ;
1478}
1479
1480
1481
1482
1483////////////////////////////////////////////////////////////////////////////////
1484/// Return true if all contained object report to have their
1485/// value inside the specified range
1486
1487Bool_t RooAbsCollection::allInRange(const char* rangeSpec) const
1488{
1489 if (!rangeSpec) return kTRUE ;
1490
1491 // Parse rangeSpec specification
1492 vector<string> cutVec ;
1493 if (rangeSpec && strlen(rangeSpec)>0) {
1494 if (strchr(rangeSpec,',')==0) {
1495 cutVec.push_back(rangeSpec) ;
1496 } else {
1497 const size_t bufSize = strlen(rangeSpec)+1;
1498 char* buf = new char[bufSize] ;
1499 strlcpy(buf,rangeSpec,bufSize) ;
1500 const char* oneRange = strtok(buf,",") ;
1501 while(oneRange) {
1502 cutVec.push_back(oneRange) ;
1503 oneRange = strtok(0,",") ;
1504 }
1505 delete[] buf ;
1506 }
1507 }
1508
1509 // Apply range based selection criteria
1510 Bool_t selectByRange = kTRUE ;
1511 for (auto arg : _list) {
1512 Bool_t selectThisArg = kFALSE ;
1513 UInt_t icut ;
1514 for (icut=0 ; icut<cutVec.size() ; icut++) {
1515 if (arg->inRange(cutVec[icut].c_str())) {
1516 selectThisArg = kTRUE ;
1517 break ;
1518 }
1519 }
1520 if (!selectThisArg) {
1521 selectByRange = kFALSE ;
1522 break ;
1523 }
1524 }
1525
1526 return selectByRange ;
1527}
1528
1529
1530
1531////////////////////////////////////////////////////////////////////////////////
1532
1534{
1535}
1536
1537
1538////////////////////////////////////////////////////////////////////////////////
1539
1541{
1542}
1543
1544////////////////////////////////////////////////////////////////////////////////
1545/// If one of the TObject we have a referenced to is deleted, remove the
1546/// reference.
1547
1549{
1550 if (obj && obj->InheritsFrom(RooAbsArg::Class())) remove(*(RooAbsArg*)obj,false,false);
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Sort collection using std::sort and name comparison
1555
1557 //Windows seems to need an implementation where two different std::sorts are written
1558 //down in two different blocks. Switching between the two comparators using a ternary
1559 //operator does not compile on windows, although the signature is identical.
1560 if (reverse) {
1561 const auto cmpReverse = [](const RooAbsArg * l, const RooAbsArg * r) {
1562 return strcmp(l->GetName(), r->GetName()) > 0;
1563 };
1564
1565 std::sort(_list.begin(), _list.end(), cmpReverse);
1566 }
1567 else {
1568 const auto cmp = [](const RooAbsArg * l, const RooAbsArg * r) {
1569 return strcmp(l->GetName(), r->GetName()) < 0;
1570 };
1571
1572 std::sort(_list.begin(), _list.end(), cmp);
1573 }
1574}
1575
1576////////////////////////////////////////////////////////////////////////////////
1577/// Factory for legacy iterators.
1578
1579std::unique_ptr<RooAbsCollection::LegacyIterator_t> RooAbsCollection::makeLegacyIterator (bool forward) const {
1580 if (!forward)
1581 ccoutE(DataHandling) << "The legacy RooFit collection iterators don't support reverse iterations, any more. "
1582 << "Use begin() and end()" << endl;
1583 return std::make_unique<LegacyIterator_t>(_list);
1584}
1585
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// Insert an element into the owned collections.
1590 _list.push_back(item);
1591
1592 if (_allRRV && dynamic_cast<const RooRealVar*>(item)==0) {
1593 _allRRV= false;
1594 }
1595
1596 if (_hashAssistedFind) {
1597 _hashAssistedFind->insert(item);
1598 }
1599}
1600
1601
1602////////////////////////////////////////////////////////////////////////////////
1603/// \param[in] flag Switch hash map on or off.
1605 if (flag && !_hashAssistedFind) _hashAssistedFind = std::make_unique<HashAssistedFind>(_list.begin(), _list.end());
1606 if (!flag) _hashAssistedFind = nullptr;
1607}
1608
1609
1610////////////////////////////////////////////////////////////////////////////////
1611/// Check that all entries where the collections overlap have the same name.
1613 for (unsigned int i=0; i < std::min(_list.size(), other.size()); ++i) {
1614 if (_list[i]->namePtr() != other._list[i]->namePtr())
1615 return false;
1616 }
1617
1618 return true;
1619}
void Class()
Definition: Class.C:29
ROOT::R::TRInterface & r
Definition: Object.C:4
#define ccoutE(a)
Definition: RooMsgService.h:41
#define cxcoutD(a)
Definition: RooMsgService.h:81
#define coutW(a)
Definition: RooMsgService.h:32
#define coutE(a)
Definition: RooMsgService.h:33
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:74
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
Definition: RooAbsArg.h:563
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:86
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.
Definition: RooAbsArg.cxx:291
const RefCountList_t & servers() const
List of all servers of this object.
Definition: RooAbsArg.h:201
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.
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.
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 the specified argument to list.
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
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 ...
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
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...
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.
void safeDeleteList()
Examine client server dependencies in list and delete contents in safe order: any client is deleted b...
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:63
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:93
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.
Definition: RooCmdArg.cxx:196
std::string _s[3]
Definition: RooCmdArg.h:119
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
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 ...
Definition: RooLinkedList.h:38
Int_t GetSize() const
Definition: RooLinkedList.h:63
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)
Definition: RooLinkedList.h:67
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)...
Definition: RooNameReg.cxx:113
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
Definition: RooPrintable.h:25
static Int_t _nameLength
Definition: RooPrintable.h:57
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.
Definition: RooRealVar.cxx:882
void copyCacheFast(const RooRealVar &other, Bool_t setValDirty=kTRUE)
Definition: RooRealVar.h:133
std::size_t size() const
Number of contained objects (neglecting the ref count).
RooStringVar is a RooAbsArg implementing string values.
Definition: RooStringVar.h:23
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:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:403
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)
static Roo_reg_AGKInteg1D instance
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition: Common.h:18
@ DataHandling
Definition: RooGlobalFunc.h:62
@ InputArguments
Definition: RooGlobalFunc.h:61
@ ObjectHandling
Definition: RooGlobalFunc.h:61
static constexpr double pc
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
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