@@ -98,6 +98,7 @@ observable snapshots are stored in the dataset.
98
98
#include " RooCategory.h"
99
99
#include " RooTrace.h"
100
100
#include " RooUniformBinning.h"
101
+ #include " RooSimultaneous.h"
101
102
102
103
#include " RooRealVar.h"
103
104
#include " RooGlobalFunc.h"
@@ -1596,6 +1597,116 @@ TList* RooAbsData::split(const RooAbsCategory& splitCat, Bool_t createEmptyDataS
1596
1597
return dsetList;
1597
1598
}
1598
1599
1600
+ // //////////////////////////////////////////////////////////////////////////////
1601
+ // / Split dataset into subsets based on the categorisation of the RooSimultaneous
1602
+ // / A TList of RooDataSets is returned in which each RooDataSet is named
1603
+ // / after the state name of splitCat of which it contains the dataset subset.
1604
+ // / The observables splitCat itself is no longer present in the sub datasets, as well as the
1605
+ // / observables of the other categories.
1606
+ // / If createEmptyDataSets is kFALSE (default) this method only creates datasets for states
1607
+ // / which have at least one entry The caller takes ownership of the returned list and its contents
1608
+
1609
+ TList* RooAbsData::split (const RooSimultaneous& simpdf, Bool_t createEmptyDataSets) const
1610
+ {
1611
+ RooAbsCategoryLValue& splitCat = const_cast <RooAbsCategoryLValue&>(simpdf.indexCat ());
1612
+
1613
+ // Sanity check
1614
+ if (!splitCat.dependsOn (*get ())) {
1615
+ coutE (InputArguments) << " RooTreeData::split(" << GetName () << " ) ERROR category " << splitCat.GetName ()
1616
+ << " doesn't depend on any variable in this dataset" << endl ;
1617
+ return 0 ;
1618
+ }
1619
+
1620
+ // Clone splitting category and attach to self
1621
+ RooAbsCategory* cloneCat =0 ;
1622
+ RooArgSet* cloneSet = 0 ;
1623
+ if (splitCat.isDerived ()) {
1624
+ cloneSet = (RooArgSet*) RooArgSet (splitCat).snapshot (kTRUE ) ;
1625
+ if (!cloneSet) {
1626
+ coutE (InputArguments) << " RooTreeData::split(" << GetName () << " ) Couldn't deep-clone splitting category, abort." << endl ;
1627
+ return 0 ;
1628
+ }
1629
+ cloneCat = (RooAbsCategory*) cloneSet->find (splitCat.GetName ()) ;
1630
+ cloneCat->attachDataSet (*this ) ;
1631
+ } else {
1632
+ cloneCat = dynamic_cast <RooAbsCategory*>(get ()->find (splitCat.GetName ())) ;
1633
+ if (!cloneCat) {
1634
+ coutE (InputArguments) << " RooTreeData::split(" << GetName () << " ) ERROR category " << splitCat.GetName ()
1635
+ << " is fundamental and does not appear in this dataset" << endl ;
1636
+ return 0 ;
1637
+ }
1638
+ }
1639
+
1640
+ // Split a dataset in a series of subsets, each corresponding
1641
+ // to a state of splitCat
1642
+ TList* dsetList = new TList ;
1643
+
1644
+ // Construct set of variables to be included in split sets = full set - split category
1645
+ RooArgSet subsetVars (*get ()) ;
1646
+ if (splitCat.isDerived ()) {
1647
+ RooArgSet* vars = splitCat.getVariables () ;
1648
+ subsetVars.remove (*vars,kTRUE ,kTRUE ) ;
1649
+ delete vars ;
1650
+ } else {
1651
+ subsetVars.remove (splitCat,kTRUE ,kTRUE ) ;
1652
+ }
1653
+
1654
+ // Add weight variable explicitly if dataset has weights, but no top-level weight
1655
+ // variable exists (can happen with composite datastores)
1656
+ Bool_t addWV (kFALSE ) ;
1657
+ RooRealVar newweight (" weight" ," weight" ,-1e9 ,1e9 ) ;
1658
+ if (isWeighted () && !IsA ()->InheritsFrom (RooDataHist::Class ())) {
1659
+ subsetVars.add (newweight) ;
1660
+ addWV = kTRUE ;
1661
+ }
1662
+
1663
+ // By default, remove all category observables from the subdatasets
1664
+ RooArgSet allObservables;
1665
+ for ( const auto & catPair : splitCat) {
1666
+ const auto & catPdf = simpdf.getPdf (catPair.first .c_str ());
1667
+ allObservables.add (*(catPdf->getObservables (this )));
1668
+ }
1669
+ subsetVars.remove (allObservables, kTRUE , kTRUE );
1670
+
1671
+
1672
+ // If createEmptyDataSets is true, prepopulate with empty sets corresponding to all states
1673
+ if (createEmptyDataSets) {
1674
+ for (const auto & nameIdx : *cloneCat) {
1675
+ // Add in the subset only the observables corresponding to this category
1676
+ RooArgSet subsetVarsCat (subsetVars);
1677
+ const auto & catPdf = simpdf.getPdf (nameIdx.first .c_str ());
1678
+ subsetVarsCat.add (*(catPdf->getObservables (this )));
1679
+
1680
+ RooAbsData* subset = emptyClone (nameIdx.first .c_str (), nameIdx.first .c_str (), &subsetVarsCat,(addWV?" weight" :0 )) ;
1681
+ dsetList->Add ((RooAbsArg*)subset) ;
1682
+ }
1683
+ }
1684
+
1685
+
1686
+ // Loop over dataset and copy event to matching subset
1687
+ const bool propWeightSquared = isWeighted ();
1688
+ for (Int_t i = 0 ; i < numEntries (); ++i) {
1689
+ const RooArgSet* row = get (i);
1690
+ RooAbsData* subset = (RooAbsData*) dsetList->FindObject (cloneCat->getCurrentLabel ());
1691
+ if (!subset) {
1692
+ // Add in the subset only the observables corresponding to this category
1693
+ RooArgSet subsetVarsCat (subsetVars);
1694
+ const auto & catPdf = simpdf.getPdf (cloneCat->getCurrentLabel ());
1695
+ subsetVarsCat.add (*(catPdf->getObservables (this )));
1696
+ subset = emptyClone (cloneCat->getCurrentLabel (),cloneCat->getCurrentLabel (),&subsetVarsCat,(addWV?" weight" :0 ));
1697
+ dsetList->Add ((RooAbsArg*)subset);
1698
+ }
1699
+ if (!propWeightSquared) {
1700
+ subset->add (*row, weight ());
1701
+ } else {
1702
+ subset->add (*row, weight (), weightSquared ());
1703
+ }
1704
+ }
1705
+
1706
+ delete cloneSet;
1707
+ return dsetList;
1708
+ }
1709
+
1599
1710
// //////////////////////////////////////////////////////////////////////////////
1600
1711
// / Plot dataset on specified frame.
1601
1712
// /
0 commit comments