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