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