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