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